diff options
author | Leonard Chan <leonardchan@google.com> | 2019-03-06 00:28:43 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2019-03-06 00:28:43 +0000 |
commit | 8f7caae00af070fb13416dbed207f3fe18e043e8 (patch) | |
tree | 37b625e87df8172cf0fe29a715d2467c8d32e880 /clang/lib/Sema/SemaChecking.cpp | |
parent | f0c21e2ff53a2745a325136f3812b4a0e6f61ea1 (diff) | |
download | llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.zip llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.tar.gz llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.tar.bz2 |
[Fixed Point Arithmetic] Fixed Point and Integer Conversions
This patch includes the necessary code for converting between a fixed point type and integer.
This also includes constant expression evaluation for conversions with these types.
Differential Revision: https://reviews.llvm.org/D56900
llvm-svn: 355462
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5d9ae18..8dc9c7f 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -11018,10 +11018,9 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, return; } + // Valid casts involving fixed point types should be accounted for here. if (Source->isFixedPointType()) { - // TODO: Only CK_FixedPointCast is supported now. The other valid casts - // should be accounted for here. - if (Target->isFixedPointType()) { + if (Target->isUnsaturatedFixedPointType()) { Expr::EvalResult Result; if (E->EvaluateAsFixedPoint(Result, S.Context, Expr::SE_AllowSideEffects)) { @@ -11037,6 +11036,46 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, return; } } + } else if (Target->isIntegerType()) { + Expr::EvalResult Result; + if (E->EvaluateAsFixedPoint(Result, S.Context, + Expr::SE_AllowSideEffects)) { + APFixedPoint FXResult = Result.Val.getFixedPoint(); + + bool Overflowed; + llvm::APSInt IntResult = FXResult.convertToInt( + S.Context.getIntWidth(T), + Target->isSignedIntegerOrEnumerationType(), &Overflowed); + + if (Overflowed) { + S.DiagRuntimeBehavior(E->getExprLoc(), E, + S.PDiag(diag::warn_impcast_fixed_point_range) + << FXResult.toString() << T + << E->getSourceRange() + << clang::SourceRange(CC)); + return; + } + } + } + } else if (Target->isUnsaturatedFixedPointType()) { + if (Source->isIntegerType()) { + Expr::EvalResult Result; + if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) { + llvm::APSInt Value = Result.Val.getInt(); + + bool Overflowed; + APFixedPoint IntResult = APFixedPoint::getFromIntValue( + Value, S.Context.getFixedPointSemantics(T), &Overflowed); + + if (Overflowed) { + S.DiagRuntimeBehavior(E->getExprLoc(), E, + S.PDiag(diag::warn_impcast_fixed_point_range) + << Value.toString(/*radix=*/10) << T + << E->getSourceRange() + << clang::SourceRange(CC)); + return; + } + } } } |