r306346 - Revert r301742, which caused us to try to evaluate all full-expressions.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 26 16:19:32 PDT 2017


Author: rsmith
Date: Mon Jun 26 16:19:32 2017
New Revision: 306346

URL: http://llvm.org/viewvc/llvm-project?rev=306346&view=rev
Log:
Revert r301742, which caused us to try to evaluate all full-expressions.

Also add testcases for a bunch of expression forms that cause our evaluator to
crash. See PR33140 and PR32864 for crashes that this was causing.

This reverts r305287, which reverted r305239, which reverted r301742. The
previous revert claimed that buildbots were broken, but did not add any
testcases and the buildbots have lost all memory of what was wrong here.

Changes to test/OpenMP are not reverted; another change has triggered those
tests to change their output in the same way that r301742 did.

Added:
    cfe/trunk/test/SemaCXX/eval-crashes.cpp
Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=306346&r1=306345&r2=306346&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jun 26 16:19:32 2017
@@ -10276,6 +10276,7 @@ private:
   void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
   void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
   void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
+  void CheckForIntOverflow(Expr *E);
   void CheckUnsequencedOperations(Expr *E);
 
   /// \brief Perform semantic checks on a completed expression. This will either

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=306346&r1=306345&r2=306346&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jun 26 16:19:32 2017
@@ -6226,10 +6226,6 @@ bool RecordExprEvaluator::VisitInitListE
     // the initializer list.
     ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
     const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE;
-    if (Init->isValueDependent()) {
-      Success = false;
-      continue;
-    }
 
     // Temporarily override This, in case there's a CXXDefaultInitExpr in here.
     ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
@@ -9940,8 +9936,7 @@ static bool EvaluateAsRValue(EvalInfo &I
 }
 
 static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
-                                 const ASTContext &Ctx, bool &IsConst,
-                                 bool IsCheckingForOverflow) {
+                                 const ASTContext &Ctx, bool &IsConst) {
   // Fast-path evaluations of integer literals, since we sometimes see files
   // containing vast quantities of these.
   if (const IntegerLiteral *L = dyn_cast<IntegerLiteral>(Exp)) {
@@ -9962,7 +9957,7 @@ static bool FastEvaluateAsRValue(const E
   // performance problems. Only do so in C++11 for now.
   if (Exp->isRValue() && (Exp->getType()->isArrayType() ||
                           Exp->getType()->isRecordType()) &&
-      !Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) {
+      !Ctx.getLangOpts().CPlusPlus11) {
     IsConst = false;
     return true;
   }
@@ -9977,7 +9972,7 @@ static bool FastEvaluateAsRValue(const E
 /// will be applied to the result.
 bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
   bool IsConst;
-  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false))
+  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
     return IsConst;
   
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
@@ -10102,7 +10097,7 @@ APSInt Expr::EvaluateKnownConstInt(const
 void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
   bool IsConst;
   EvalResult EvalResult;
-  if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst, true)) {
+  if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) {
     EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
     (void)::EvaluateAsRValue(Info, this, EvalResult.Val);
   }

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=306346&r1=306345&r2=306346&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jun 26 16:19:32 2017
@@ -9936,6 +9936,28 @@ void Sema::CheckBoolLikeConversion(Expr
   ::CheckBoolLikeConversion(*this, E, CC);
 }
 
+/// Diagnose when expression is an integer constant expression and its evaluation
+/// results in integer overflow
+void Sema::CheckForIntOverflow (Expr *E) {
+  // Use a work list to deal with nested struct initializers.
+  SmallVector<Expr *, 2> Exprs(1, E);
+
+  do {
+    Expr *E = Exprs.pop_back_val();
+
+    if (isa<BinaryOperator>(E->IgnoreParenCasts())) {
+      E->IgnoreParenCasts()->EvaluateForOverflow(Context);
+      continue;
+    }
+
+    if (auto InitList = dyn_cast<InitListExpr>(E))
+      Exprs.append(InitList->inits().begin(), InitList->inits().end());
+
+    if (isa<ObjCBoxedExpr>(E))
+      E->IgnoreParenCasts()->EvaluateForOverflow(Context);
+  } while (!Exprs.empty());
+}
+
 namespace {
 /// \brief Visitor for expressions which looks for unsequenced operations on the
 /// same object.
@@ -10437,7 +10459,7 @@ void Sema::CheckCompletedExpr(Expr *E, S
   if (!E->isInstantiationDependent())
     CheckUnsequencedOperations(E);
   if (!IsConstexpr && !E->isValueDependent())
-    E->EvaluateForOverflow(Context);
+    CheckForIntOverflow(E);
   DiagnoseMisalignedMembers();
 }
 

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=306346&r1=306345&r2=306346&view=diff
==============================================================================
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Mon Jun 26 16:19:32 2017
@@ -152,13 +152,7 @@ uint64_t check_integer_overflows(int i)
   uint64_t b2 = b[4608 * 1024 * 1024] + 1;
 
 // expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
-  int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
-
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
-  int j2 = -(4608 * 1024 * 1024);
-
-// expected-warning at +1 {{overflow in expression; result is 536870912 with type 'int'}}
-  uint64_t j3 = b[4608 * 1024 * 1024];
+  (void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1);
 
 // expected-warning at +1 2{{overflow in expression; result is 536870912 with type 'int'}}
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));

Added: cfe/trunk/test/SemaCXX/eval-crashes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/eval-crashes.cpp?rev=306346&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/eval-crashes.cpp (added)
+++ cfe/trunk/test/SemaCXX/eval-crashes.cpp Mon Jun 26 16:19:32 2017
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+namespace pr32864_0 {
+  struct transfer_t {
+    void *fctx;
+  };
+  template <typename Ctx> class record {
+    void run() {
+      transfer_t t;
+      Ctx from{t.fctx};
+    }
+  };
+}
+
+namespace pr33140_0a {
+  struct S {
+    constexpr S(const int &a = 0) {}
+  };
+  void foo(void) { S s[2] = {}; }
+}
+
+namespace pr33140_0b {
+  bool bar(float const &f = 0);
+  bool foo() { return bar() && bar(); }
+}
+
+namespace pr33140_2 {
+  // FIXME: The declaration of 'b' below should lifetime-extend two int
+  // temporaries, invalidating this warning to some extent.
+  struct A { int &&r = 0; }; // expected-warning {{binding reference member 'r' to a temporary}} expected-note {{here}}
+  struct B { A x, y; };
+  B b = {};
+}
+
+namespace pr33140_3 {
+  typedef struct Y { unsigned int c; } Y_t;
+  struct X {
+    Y_t a;
+  };
+  struct X foo[2] = {[0 ... 1] = {.a = (Y_t){.c = 0}}};
+}
+
+namespace pr33140_6 {
+  struct Y { unsigned int c; };
+  struct X { struct Y *p; };
+  int f() {
+    // FIXME: This causes clang to crash.
+    //return (struct X[2]){ [0 ... 1] = { .p = &(struct Y&)(struct Y&&)(struct Y){0} } }[0].p->c;
+    return 0;
+  }
+}
+
+namespace pr33140_10 {
+  int a(const int &n = 0);
+  bool b() { return a() == a(); }
+}




More information about the cfe-commits mailing list