Fix rejects-valid on constexpr function that accesses a not-yet-defined 'extern
const' variable. That variable might be defined as 'constexpr', so we cannot prove that a use of it could never be a constant expression. llvm-svn: 270774
This commit is contained in:
parent
dca7651d59
commit
c0d04a2567
|
@ -2706,7 +2706,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
|
|||
}
|
||||
} else {
|
||||
// FIXME: Allow folding of values of any literal type in all languages.
|
||||
if (Info.getLangOpts().CPlusPlus11) {
|
||||
if (Info.checkingPotentialConstantExpression() &&
|
||||
VD->getType().isConstQualified() && !VD->hasDefinition(Info.Ctx)) {
|
||||
// The definition of this variable could be constexpr. We can't
|
||||
// access it right now, but may be able to in future.
|
||||
} else if (Info.getLangOpts().CPlusPlus11) {
|
||||
Info.Diag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
|
||||
Info.Note(VD->getLocation(), diag::note_declared_at);
|
||||
} else {
|
||||
|
@ -5456,8 +5460,9 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
|
|||
}
|
||||
|
||||
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
|
||||
Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
|
||||
std::distance(RD->field_begin(), RD->field_end()));
|
||||
if (Result.isUninit())
|
||||
Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
|
||||
std::distance(RD->field_begin(), RD->field_end()));
|
||||
unsigned ElementNo = 0;
|
||||
bool Success = true;
|
||||
|
||||
|
|
|
@ -1181,6 +1181,20 @@ namespace ExternConstexpr {
|
|||
constexpr int j = 0;
|
||||
constexpr int k; // expected-error {{default initialization of an object of const type}}
|
||||
}
|
||||
|
||||
extern const int q;
|
||||
constexpr int g() { return q; }
|
||||
constexpr int q = g();
|
||||
static_assert(q == 0, "zero-initialization should precede static initialization");
|
||||
|
||||
extern int r; // expected-note {{here}}
|
||||
constexpr int h() { return r; } // expected-error {{never produces a constant}} expected-note {{read of non-const}}
|
||||
|
||||
struct S { int n; };
|
||||
extern const S s;
|
||||
constexpr int x() { return s.n; }
|
||||
constexpr S s = {x()};
|
||||
static_assert(s.n == 0, "zero-initialization should precede static initialization");
|
||||
}
|
||||
|
||||
namespace ComplexConstexpr {
|
||||
|
|
Loading…
Reference in New Issue