From: George Burgess IV Date: Tue, 27 Dec 2016 05:33:20 +0000 (+0000) Subject: Emit CCEDiags when evaluating a const variable. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=621133ba1a3886823bd34eeee7046bfd53dee346;p=clang Emit CCEDiags when evaluating a const variable. This addresses post-review feedback from r290577. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290584 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 2caaaab9ef..b3f8925b64 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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() && diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 9ec8318b9e..581a524339 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -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}} }; } diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp index 0a1877cc8c..dfdf50ad54 100644 --- a/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -959,18 +959,21 @@ namespace PR27989 { } namespace const_char { -template +template 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(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}} }