]> granicus.if.org Git - clang/commitdiff
Emit CCEDiags when evaluating a const variable.
authorGeorge Burgess IV <george.burgess.iv@gmail.com>
Tue, 27 Dec 2016 05:33:20 +0000 (05:33 +0000)
committerGeorge Burgess IV <george.burgess.iv@gmail.com>
Tue, 27 Dec 2016 05:33:20 +0000 (05:33 +0000)
This addresses post-review feedback from r290577.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290584 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/SemaCXX/constant-expression-cxx11.cpp
test/SemaCXX/constant-expression-cxx1y.cpp

index 2caaaab9ef2869707e1b8bc8ec6187263037bd8c..b3f8925b64643ae6552592ac2134e3b1f34a6b5a 100644 (file)
@@ -2903,7 +2903,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         // All the remaining cases only permit reading.
         Info.FFDiag(E, diag::note_constexpr_modify_global);
         return CompleteObject();
-      } else if (VD->isConstexpr() || BaseType.isConstQualified()) {
+      } else if (VD->isConstexpr()) {
         // OK, we can read this variable.
       } else if (BaseType->isIntegralOrEnumerationType()) {
         // In OpenCL if a variable is in constant address space it is a const value.
@@ -2928,6 +2928,9 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         } else {
           Info.CCEDiag(E);
         }
+      } else if (BaseType.isConstQualified() && VD->hasDefinition(Info.Ctx)) {
+        Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
+        // Keep evaluating to see what we can do.
       } else {
         // FIXME: Allow folding of values of any literal type in all languages.
         if (Info.checkingPotentialConstantExpression() &&
index 9ec8318b9e02d0f07885bf982dcb7867c959ff1e..581a524339e752326005e91fe31a88497bd1d517 100644 (file)
@@ -1195,7 +1195,7 @@ struct S {
   int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
   int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}}
   int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
-  int m : t.n; // expected-warning{{width of bit-field 'm' (42 bits)}}
+  int m : t.n; // expected-warning{{width of bit-field 'm' (42 bits)}} expected-warning{{expression is not an integral constant expression}} expected-note{{read of non-constexpr variable 't' is not allowed}}
 };
 
 }
index 0a1877cc8c31f63d904900421c3d2fa9bd2e4a80..dfdf50ad54849dcd3e926f4b2c87451047c7c15c 100644 (file)
@@ -959,18 +959,21 @@ namespace PR27989 {
 }
 
 namespace const_char {
-template <int M, int N>
+template <int N>
 constexpr int sum(const char (&Arr)[N]) {
-  static_assert(N >= M, "");
   int S = 0;
-  for (unsigned I = 0; I != M; ++I)
-    S += Arr[I];
+  for (unsigned I = 0; I != N; ++I)
+    S += Arr[I]; // expected-note 2{{read of non-constexpr variable 'Cs' is not allowed}}
   return S;
 }
 
 // As an extension, we support evaluating some things that are `const` as though
-// they were `constexpr`.
-const char Cs[] = {'a', 'b', 'c'};
-const int N = 2;
-static_assert(sum<N>(Cs) == 'a' + 'b', "");
+// they were `constexpr` when folding, but it should not be allowed in normal
+// constexpr evaluation.
+const char Cs[] = {'a', 'b'};
+void foo() __attribute__((enable_if(sum(Cs) == 'a' + 'b', "")));
+void run() { foo(); }
+
+static_assert(sum(Cs) == 'a' + 'b', ""); // expected-error{{not an integral constant expression}} expected-note{{in call to 'sum(Cs)'}}
+constexpr int S = sum(Cs); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}}
 }