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 | de3473e38c50b0bc4f6040187c3345a23819a114 (patch) | |
tree | ccce40c1c95e9838fb2b3fc07ea2b0e2c2723da3 /lib/Sema/SemaPseudoObject.cpp | |
parent | 87bfdf90ba9e94ecc89cc413013597c6fab9b0c8 (diff) | |
download | clang-de3473e38c50b0bc4f6040187c3345a23819a114.tar.gz |
Track in the AST whether the operand to a UnaryOperator can overflow and then use that logic when evaluating constant expressions and emitting codegen.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322074 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaPseudoObject.cpp')
-rw-r--r-- | lib/Sema/SemaPseudoObject.cpp | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index 58980be64a..f09a6f7158 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -132,7 +132,8 @@ namespace { uop->getType(), uop->getValueKind(), uop->getObjectKind(), - uop->getOperatorLoc()); + uop->getOperatorLoc(), + uop->canOverflow()); } if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { @@ -524,15 +525,18 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, addSemanticExpr(result.get()); if (UnaryOperator::isPrefix(opcode) && !captureSetValueAsResult() && !result.get()->getType()->isVoidType() && - (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) - setResultToLastSemantic(); - - UnaryOperator *syntactic = - new (S.Context) UnaryOperator(syntacticOp, opcode, resultType, - VK_LValue, OK_Ordinary, opcLoc); - return complete(syntactic); -} - + (result.get()->isTypeDependent() || CanCaptureValue(result.get())))
+ setResultToLastSemantic();
+
+ UnaryOperator *syntactic = new (S.Context) UnaryOperator(
+ syntacticOp, opcode, resultType, VK_LValue, OK_Ordinary, opcLoc,
+ !resultType->isDependentType()
+ ? S.Context.getTypeSize(resultType) >=
+ S.Context.getTypeSize(S.Context.IntTy)
+ : false);
+ return complete(syntactic);
+}
+
//===----------------------------------------------------------------------===// // Objective-C @property and implicit property references @@ -1550,7 +1554,7 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, // Do nothing if the operand is dependent. if (op->isTypeDependent()) return new (Context) UnaryOperator(op, opcode, Context.DependentTy, - VK_RValue, OK_Ordinary, opcLoc); + VK_RValue, OK_Ordinary, opcLoc, false); assert(UnaryOperator::isIncrementDecrementOp(opcode)); Expr *opaqueRef = op->IgnoreParens(); @@ -1630,15 +1634,15 @@ static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) { /// capable of rebuilding a tree without stripping implicit /// operations. Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { - Expr *syntax = E->getSyntacticForm(); - if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) { - Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); - return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(), - uop->getValueKind(), uop->getObjectKind(), - uop->getOperatorLoc()); - } else if (CompoundAssignOperator *cop - = dyn_cast<CompoundAssignOperator>(syntax)) { - Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); + Expr *syntax = E->getSyntacticForm();
+ if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
+ Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
+ return new (Context) UnaryOperator(
+ op, uop->getOpcode(), uop->getType(), uop->getValueKind(),
+ uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow());
+ } else if (CompoundAssignOperator *cop
+ = dyn_cast<CompoundAssignOperator>(syntax)) {
+ Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr(); return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(), cop->getType(), |