Tweak the fix to PR8977: an empty expression-list represents value initialization, not default initialization. Fixes PR11712.
llvm-svn: 147620
This commit is contained in:
parent
b3163e574e
commit
de30e523b4
|
@ -1172,6 +1172,8 @@ def err_auto_var_requires_init : Error<
|
||||||
"declaration of variable %0 with type %1 requires an initializer">;
|
"declaration of variable %0 with type %1 requires an initializer">;
|
||||||
def err_auto_new_requires_ctor_arg : Error<
|
def err_auto_new_requires_ctor_arg : Error<
|
||||||
"new expression for type %0 requires a constructor argument">;
|
"new expression for type %0 requires a constructor argument">;
|
||||||
|
def err_auto_var_init_no_expression : Error<
|
||||||
|
"initializer for variable %0 with type %1 is empty">;
|
||||||
def err_auto_var_init_multiple_expressions : Error<
|
def err_auto_var_init_multiple_expressions : Error<
|
||||||
"initializer for variable %0 with type %1 contains multiple expressions">;
|
"initializer for variable %0 with type %1 contains multiple expressions">;
|
||||||
def err_auto_new_ctor_multiple_expressions : Error<
|
def err_auto_new_ctor_multiple_expressions : Error<
|
||||||
|
|
|
@ -8898,8 +8898,6 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
|
||||||
MultiExprArg Exprs,
|
MultiExprArg Exprs,
|
||||||
SourceLocation RParenLoc,
|
SourceLocation RParenLoc,
|
||||||
bool TypeMayContainAuto) {
|
bool TypeMayContainAuto) {
|
||||||
assert(Exprs.size() != 0 && Exprs.get() && "missing expressions");
|
|
||||||
|
|
||||||
// If there is no declaration, there was an error parsing it. Just ignore
|
// If there is no declaration, there was an error parsing it. Just ignore
|
||||||
// the initializer.
|
// the initializer.
|
||||||
if (RealDecl == 0)
|
if (RealDecl == 0)
|
||||||
|
@ -8912,9 +8910,18 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
|
// C++0x [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
|
||||||
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
|
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
|
||||||
// FIXME: n3225 doesn't actually seem to indicate this is ill-formed
|
if (Exprs.size() == 0) {
|
||||||
|
// It isn't possible to write this directly, but it is possible to
|
||||||
|
// end up in this situation with "auto x(some_pack...);"
|
||||||
|
Diag(LParenLoc, diag::err_auto_var_init_no_expression)
|
||||||
|
<< VDecl->getDeclName() << VDecl->getType()
|
||||||
|
<< VDecl->getSourceRange();
|
||||||
|
RealDecl->setInvalidDecl();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Exprs.size() > 1) {
|
if (Exprs.size() > 1) {
|
||||||
Diag(Exprs.get()[1]->getSourceRange().getBegin(),
|
Diag(Exprs.get()[1]->getSourceRange().getBegin(),
|
||||||
diag::err_auto_var_init_multiple_expressions)
|
diag::err_auto_var_init_multiple_expressions)
|
||||||
|
|
|
@ -393,16 +393,15 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||||
if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc,
|
if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc,
|
||||||
InitArgs, RParenLoc)) {
|
InitArgs, RParenLoc)) {
|
||||||
bool TypeMayContainAuto = true;
|
bool TypeMayContainAuto = true;
|
||||||
// Attach the initializer to the declaration, if we have one.
|
if (D->hasCXXDirectInitializer()) {
|
||||||
if (InitArgs.size() == 0)
|
|
||||||
SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto);
|
|
||||||
else if (D->hasCXXDirectInitializer()) {
|
|
||||||
// Add the direct initializer to the declaration.
|
// Add the direct initializer to the declaration.
|
||||||
SemaRef.AddCXXDirectInitializerToDecl(Var,
|
SemaRef.AddCXXDirectInitializerToDecl(Var,
|
||||||
LParenLoc,
|
LParenLoc,
|
||||||
move_arg(InitArgs),
|
move_arg(InitArgs),
|
||||||
RParenLoc,
|
RParenLoc,
|
||||||
TypeMayContainAuto);
|
TypeMayContainAuto);
|
||||||
|
} else if (InitArgs.size() == 0) {
|
||||||
|
SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto);
|
||||||
} else {
|
} else {
|
||||||
assert(InitArgs.size() == 1);
|
assert(InitArgs.size() == 1);
|
||||||
Expr *Init = InitArgs.take()[0];
|
Expr *Init = InitArgs.take()[0];
|
||||||
|
|
|
@ -37,7 +37,8 @@ template void initializer_list_expansion<1, 2, 3, 4, 5, 6>(); // expected-note{{
|
||||||
namespace PR8977 {
|
namespace PR8977 {
|
||||||
struct A { };
|
struct A { };
|
||||||
template<typename T, typename... Args> void f(Args... args) {
|
template<typename T, typename... Args> void f(Args... args) {
|
||||||
T t(args...);
|
// An empty expression-list performs value initialization.
|
||||||
|
constexpr T t(args...);
|
||||||
};
|
};
|
||||||
|
|
||||||
template void f<A>();
|
template void f<A>();
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct only {
|
||||||
|
|
||||||
template<typename ...T>
|
template<typename ...T>
|
||||||
void f(T ...t) {
|
void f(T ...t) {
|
||||||
auto x(t...); // expected-error {{requires an initializer}} expected-error {{contains multiple expressions}}
|
auto x(t...); // expected-error {{is empty}} expected-error {{contains multiple expressions}}
|
||||||
only<int> check = x;
|
only<int> check = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue