Temporary fix for PR18473: Don't try to evaluate the initializer for a

type-dependent variable, even if the initializer isn't value-dependent. This
happens for ParenListExprs composed of non-value-dependent subexpressions, for
instance.

We should really give ParenListExprs (and InitListExprs) the type of the
initialized entity if they're used to represent a dependent initialization (and
if so, set them to be type-, value- and instantiation-dependent).

llvm-svn: 200954
This commit is contained in:
Richard Smith 2014-02-06 23:35:16 +00:00
parent 6d92e50263
commit c941ba9047
2 changed files with 21 additions and 7 deletions

View File

@ -5815,17 +5815,16 @@ static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var,
assert(DefVD);
if (DefVD->isWeak()) return false;
EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt();
Expr *Init = cast<Expr>(Eval->Value);
if (Var->getType()->isDependentType() || Init->isValueDependent()) {
if (!Init->isValueDependent())
return !DefVD->checkInitIsICE();
// FIXME: We might still be able to do some analysis of Init here
// to conclude that even in a dependent setting, Init can never
// be a constexpr - but for now admit agnosticity.
// FIXME: Teach the constant evaluator to deal with the non-dependent parts
// of value-dependent expressions, and use it here to determine whether the
// initializer is a potential constant expression.
return false;
}
}
return !IsVariableAConstantExpression(Var, Context);
}

View File

@ -344,3 +344,18 @@ namespace PR18128 {
int d = []{ return [=]{ return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}}
};
}
namespace PR18473 {
template<typename T> void f() {
T t(0);
(void) [=]{ int n = t; }; // expected-error {{deleted}}
}
template void f<int>();
struct NoCopy {
NoCopy(int);
NoCopy(const NoCopy &) = delete; // expected-note {{deleted}}
operator int() const;
};
template void f<NoCopy>(); // expected-note {{instantiation}}
}