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 | |
parent | f0c21e2ff53a2745a325136f3812b4a0e6f61ea1 (diff) | |
download | bcm5719-llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.tar.gz bcm5719-llvm-8f7caae00af070fb13416dbed207f3fe18e043e8.zip |
[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')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 45 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 6 |
2 files changed, 44 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5d9ae18267b..8dc9c7ffcdb 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; + } + } } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 19ed62d1fe6..187d8e2fddd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6152,6 +6152,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_Bool: return CK_FixedPointToBoolean; case Type::STK_Integral: + return CK_FixedPointToIntegral; case Type::STK_Floating: case Type::STK_IntegralComplex: case Type::STK_FloatingComplex: @@ -6196,10 +6197,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); case Type::STK_FixedPoint: - Diag(Src.get()->getExprLoc(), - diag::err_unimplemented_conversion_with_fixed_point_type) - << SrcTy; - return CK_IntegralCast; + return CK_IntegralToFixedPoint; } llvm_unreachable("Should have returned before this"); |