forked from OSchip/llvm-project
Emit CCEDiags when evaluating a const variable.
This addresses post-review feedback from r290577. llvm-svn: 290584
This commit is contained in:
parent
2da265b7bf
commit
b531698ff0
|
@ -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() &&
|
||||
|
|
|
@ -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}}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue