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
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp
index 58980be..f09a6f7 100644
--- a/clang/lib/Sema/SemaPseudoObject.cpp
+++ b/clang/lib/Sema/SemaPseudoObject.cpp
@@ -132,7 +132,8 @@
                                              uop->getType(),
                                              uop->getValueKind(),
                                              uop->getObjectKind(),
-                                             uop->getOperatorLoc());
+                                             uop->getOperatorLoc(),
+                                             uop->canOverflow());
       }
 
       if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
@@ -524,15 +525,18 @@
   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 @@
   // 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 @@
 /// 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(),