r314067 - Don't warn about runtime behavior problems in variable initializers that we

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 23 11:27:11 PDT 2017


Author: rsmith
Date: Sat Sep 23 11:27:11 2017
New Revision: 314067

URL: http://llvm.org/viewvc/llvm-project?rev=314067&view=rev
Log:
Don't warn about runtime behavior problems in variable initializers that we
know are going to be constant-evaluated.

Any relevant diagnostics should be produced by constant expression evaluation.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp
    cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=314067&r1=314066&r2=314067&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Sep 23 11:27:11 2017
@@ -15179,10 +15179,24 @@ bool Sema::DiagRuntimeBehavior(SourceLoc
     if (Statement && getCurFunctionOrMethodDecl()) {
       FunctionScopes.back()->PossiblyUnreachableDiags.
         push_back(sema::PossiblyUnreachableDiag(PD, Loc, Statement));
+      return true;
     }
-    else
-      Diag(Loc, PD);
-      
+
+    // The initializer of a constexpr variable or of the first declaration of a
+    // static data member is not syntactically a constant evaluated constant,
+    // but nonetheless is always required to be a constant expression, so we
+    // can skip diagnosing.
+    // FIXME: Using the mangling context here is a hack.
+    if (auto *VD = dyn_cast_or_null<VarDecl>(
+            ExprEvalContexts.back().ManglingContextDecl)) {
+      if (VD->isConstexpr() ||
+          (VD->isStaticDataMember() && VD->isFirstDecl() && !VD->isInline()))
+        break;
+      // FIXME: For any other kind of variable, we should build a CFG for its
+      // initializer and check whether the context in question is reachable.
+    }
+
+    Diag(Loc, PD);
     return true;
   }
 

Modified: cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp?rev=314067&r1=314066&r2=314067&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp (original)
+++ cfe/trunk/test/CXX/class/class.static/class.static.data/p3.cpp Sat Sep 23 11:27:11 2017
@@ -50,4 +50,4 @@ U<NonLit> u2; // expected-note {{here}}
 
 static_assert(U<int>::a == 0, "");
 
-constexpr int outofline = (U<NonLit>::d, 0); // expected-note {{here}} expected-warning {{unused}}
+constexpr int outofline = (U<NonLit>::d, 0); // expected-note {{here}}

Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=314067&r1=314066&r2=314067&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Sat Sep 23 11:27:11 2017
@@ -145,19 +145,19 @@ namespace UndefinedBehavior {
 
   constexpr int int_min = ~0x7fffffff;
   constexpr int minus_int_min = -int_min; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
-  constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}}
-  constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}} expected-warning {{undefined}}
+  constexpr int div0 = 3 / 0; // expected-error {{constant expression}} expected-note {{division by zero}}
+  constexpr int mod0 = 3 % 0; // expected-error {{constant expression}} expected-note {{division by zero}}
   constexpr int int_min_div_minus_1 = int_min / -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
   constexpr int int_min_mod_minus_1 = int_min % -1; // expected-error {{constant expression}} expected-note {{value 2147483648 is outside the range}}
 
-  constexpr int shl_m1 = 0 << -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}}
+  constexpr int shl_m1 = 0 << -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}}
   constexpr int shl_0 = 0 << 0; // ok
   constexpr int shl_31 = 0 << 31; // ok
-  constexpr int shl_32 = 0 << 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type 'int' (32}} expected-warning {{>= width of type}}
+  constexpr int shl_32 = 0 << 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type 'int' (32}}
   constexpr int shl_unsigned_negative = unsigned(-3) << 1; // ok
   constexpr int shl_unsigned_into_sign = 1u << 31; // ok
   constexpr int shl_unsigned_overflow = 1024u << 31; // ok
-  constexpr int shl_signed_negative = (-3) << 1; // expected-warning {{shifting a negative signed value is undefined}} // expected-error {{constant expression}} expected-note {{left shift of negative value -3}}
+  constexpr int shl_signed_negative = (-3) << 1; // expected-error {{constant expression}} expected-note {{left shift of negative value -3}}
   constexpr int shl_signed_ok = 1 << 30; // ok
   constexpr int shl_signed_into_sign = 1 << 31; // ok (DR1457)
   constexpr int shl_signed_into_sign_2 = 0x7fffffff << 1; // ok (DR1457)
@@ -166,10 +166,10 @@ namespace UndefinedBehavior {
   constexpr int shl_signed_overflow = 1024 << 31; // expected-error {{constant expression}} expected-note {{signed left shift discards bits}} expected-warning {{requires 43 bits to represent}}
   constexpr int shl_signed_ok2 = 1024 << 20; // ok
 
-  constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}} expected-warning {{negative}}
+  constexpr int shr_m1 = 0 >> -1; // expected-error {{constant expression}} expected-note {{negative shift count -1}}
   constexpr int shr_0 = 0 >> 0; // ok
   constexpr int shr_31 = 0 >> 31; // ok
-  constexpr int shr_32 = 0 >> 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type}} expected-warning {{>= width of type}}
+  constexpr int shr_32 = 0 >> 32; // expected-error {{constant expression}} expected-note {{shift count 32 >= width of type}}
 
   struct S {
     int m;

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=314067&r1=314066&r2=314067&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sat Sep 23 11:27:11 2017
@@ -328,7 +328,7 @@ struct Str {
 
 extern char externalvar[];
 constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}} expected-note {{reinterpret_cast}}
-constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}}
+constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}}
 static_assert(0 != "foo", "");
 
 }
@@ -364,7 +364,7 @@ void foo() {
   constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
 }
 
-constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); // expected-warning 4{{unused}}
+constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} });
 static_assert(&b4 != &b2, "");
 
 // Proposed DR: copy-elision doesn't trigger lifetime extension.
@@ -1965,7 +1965,7 @@ namespace NeverConstantTwoWays {
 
   constexpr int n = // expected-error {{must be initialized by a constant expression}}
       (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}}
-        1 / 0 : // expected-warning {{division by zero}}
+        1 / 0 :
         0;
 }
 

Modified: cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp?rev=314067&r1=314066&r2=314067&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-static-var.cpp Sat Sep 23 11:27:11 2017
@@ -5,7 +5,7 @@
 template<typename T, T Divisor>
 class X {
 public:
-  static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}} expected-warning {{division by zero}}
+  static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}
 };
 
 int array1[X<int, 2>::value == 5? 1 : -1];




More information about the cfe-commits mailing list