When we're building a CXXExprWithTemporaries, only include those
temporaries that are within our current evaluation context. That way, nested evaluation contexts (e.g., within a sizeof() expression) won't see temporaries from outer contexts. Also, make sure to push a new evaluation context when instantiating the initializer of a variable; this may be an unevaluated context or a potentially-evaluated context, depending on whether it's an in-class initializer or not. Fixes PR5672. llvm-svn: 90460
This commit is contained in:
parent
5f49883488
commit
580cd4a23e
|
@ -2069,14 +2069,17 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr,
|
|||
bool ShouldDestroyTemps) {
|
||||
assert(SubExpr && "sub expression can't be null!");
|
||||
|
||||
if (ExprTemporaries.empty())
|
||||
unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
|
||||
assert(ExprTemporaries.size() >= FirstTemporary);
|
||||
if (ExprTemporaries.size() == FirstTemporary)
|
||||
return SubExpr;
|
||||
|
||||
Expr *E = CXXExprWithTemporaries::Create(Context, SubExpr,
|
||||
&ExprTemporaries[0],
|
||||
ExprTemporaries.size(),
|
||||
&ExprTemporaries[FirstTemporary],
|
||||
ExprTemporaries.size() - FirstTemporary,
|
||||
ShouldDestroyTemps);
|
||||
ExprTemporaries.clear();
|
||||
ExprTemporaries.erase(ExprTemporaries.begin() + FirstTemporary,
|
||||
ExprTemporaries.end());
|
||||
|
||||
return E;
|
||||
}
|
||||
|
|
|
@ -193,6 +193,11 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
|||
TSK_ImplicitInstantiation);
|
||||
|
||||
if (D->getInit()) {
|
||||
if (Var->isStaticDataMember() && !D->isOutOfLine())
|
||||
SemaRef.PushExpressionEvaluationContext(Sema::Unevaluated);
|
||||
else
|
||||
SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
|
||||
|
||||
OwningExprResult Init
|
||||
= SemaRef.SubstExpr(D->getInit(), TemplateArgs);
|
||||
if (Init.isInvalid())
|
||||
|
@ -235,6 +240,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
|||
} else
|
||||
SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), move(Init),
|
||||
D->hasCXXDirectInitializer());
|
||||
SemaRef.PopExpressionEvaluationContext();
|
||||
} else if (!Var->isStaticDataMember() || Var->isOutOfLine())
|
||||
SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
|
||||
|
||||
|
|
|
@ -897,6 +897,9 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
|
|||
break;
|
||||
}
|
||||
|
||||
if (T.isNull())
|
||||
return T;
|
||||
|
||||
if (T == Context.UndeducedAutoTy) {
|
||||
int Error = -1;
|
||||
|
||||
|
|
|
@ -72,3 +72,23 @@ void Test() {
|
|||
Z1<Y2<X2>::value> x2;
|
||||
int y2[Y2<X2>::value];
|
||||
}
|
||||
|
||||
// PR5672
|
||||
template <int n>
|
||||
struct X3 {};
|
||||
|
||||
class Y3 {
|
||||
public:
|
||||
~Y3(); // The error isn't triggered without this dtor.
|
||||
|
||||
void Foo(X3<1>);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SizeOf {
|
||||
static const int value = sizeof(T);
|
||||
};
|
||||
|
||||
void MyTest3() {
|
||||
Y3().Foo(X3<SizeOf<char>::value>());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue