diff options
| author | Aaron Ballman <aaron@aaronballman.com> | 2018-01-09 13:07:03 +0000 |
|---|---|---|
| committer | Aaron Ballman <aaron@aaronballman.com> | 2018-01-09 13:07:03 +0000 |
| commit | a503855906b3e8ecc42393f6ce9db5aed5a0fdf8 (patch) | |
| tree | 5d365564e46b84339b1b252308be182782d91ec3 /clang/lib/Sema/SemaExpr.cpp | |
| parent | 1f97363e5f09ee4336d0132d9f9da982f9e12a4b (diff) | |
| download | bcm5719-llvm-a503855906b3e8ecc42393f6ce9db5aed5a0fdf8.tar.gz bcm5719-llvm-a503855906b3e8ecc42393f6ce9db5aed5a0fdf8.zip | |
Track in the AST whether the operand to a UnaryOperator can overflow and then use that logic when evaluating constant expressions and emitting codegen.
llvm-svn: 322074
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a6f3ee2c094..1d7a5d2e128 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12178,6 +12178,16 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr); } +static bool isOverflowingIntegerType(ASTContext &Ctx, QualType T) { + if (T.isNull() || T->isDependentType()) + return false; + + if (!T->isPromotableIntegerType()) + return true; + + return Ctx.getIntWidth(T) >= Ctx.getIntWidth(Ctx.IntTy); +} + ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr) { @@ -12185,6 +12195,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; QualType resultType; + bool CanOverflow = false; + bool ConvertHalfVec = false; if (getLangOpts().OpenCL) { QualType Ty = InputExpr->getType(); @@ -12210,6 +12222,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, Opc == UO_PostInc, Opc == UO_PreInc || Opc == UO_PreDec); + CanOverflow = isOverflowingIntegerType(Context, resultType); break; case UO_AddrOf: resultType = CheckAddressOfOperand(Input, OpLoc); @@ -12223,6 +12236,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, } case UO_Plus: case UO_Minus: + CanOverflow = Opc == UO_Minus && + isOverflowingIntegerType(Context, Input.get()->getType()); Input = UsualUnaryConversions(Input.get()); if (Input.isInvalid()) return ExprError(); // Unary plus and minus require promoting an operand of half vector to a @@ -12259,6 +12274,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (Input.isInvalid()) return ExprError(); resultType = Input.get()->getType(); + if (resultType->isDependentType()) break; // C99 6.5.3.3p1. We allow complex int and float as a GCC extension. @@ -12373,7 +12389,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, CheckArrayAccess(Input.get()); auto *UO = new (Context) - UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc); + UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow); // Convert the result back to a half vector. if (ConvertHalfVec) return convertVector(UO, Context.HalfTy, *this); |

