From: Eli Friedman Date: Thu, 5 Jan 2012 22:34:08 +0000 (+0000) Subject: Tweak the fix to PR8977: an empty expression-list represents value initialization... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6aeaa60217e1ed11a621409acf1b53df0d14b591;p=clang Tweak the fix to PR8977: an empty expression-list represents value initialization, not default initialization. Fixes PR11712. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147620 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index e4382ec17f..07e6c64b24 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1172,6 +1172,8 @@ def err_auto_var_requires_init : Error< "declaration of variable %0 with type %1 requires an initializer">; def err_auto_new_requires_ctor_arg : Error< "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< "initializer for variable %0 with type %1 contains multiple expressions">; def err_auto_new_ctor_multiple_expressions : Error< diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 46a47a2215..56b526b1d7 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8898,8 +8898,6 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl, MultiExprArg Exprs, SourceLocation RParenLoc, bool TypeMayContainAuto) { - assert(Exprs.size() != 0 && Exprs.get() && "missing expressions"); - // If there is no declaration, there was an error parsing it. Just ignore // the initializer. if (RealDecl == 0) @@ -8912,9 +8910,18 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl, 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()) { - // 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) { Diag(Exprs.get()[1]->getSourceRange().getBegin(), diag::err_auto_var_init_multiple_expressions) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1f87983805..00addc2d83 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -393,16 +393,15 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc, InitArgs, RParenLoc)) { bool TypeMayContainAuto = true; - // Attach the initializer to the declaration, if we have one. - if (InitArgs.size() == 0) - SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto); - else if (D->hasCXXDirectInitializer()) { + if (D->hasCXXDirectInitializer()) { // Add the direct initializer to the declaration. SemaRef.AddCXXDirectInitializerToDecl(Var, LParenLoc, move_arg(InitArgs), RParenLoc, TypeMayContainAuto); + } else if (InitArgs.size() == 0) { + SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto); } else { assert(InitArgs.size() == 1); Expr *Init = InitArgs.take()[0]; diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp index 05e492167c..71e6927b20 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp @@ -37,7 +37,8 @@ template void initializer_list_expansion<1, 2, 3, 4, 5, 6>(); // expected-note{{ namespace PR8977 { struct A { }; template void f(Args... args) { - T t(args...); + // An empty expression-list performs value initialization. + constexpr T t(args...); }; template void f(); diff --git a/test/SemaCXX/dependent-auto.cpp b/test/SemaCXX/dependent-auto.cpp index 1be1566bb3..6d37f7ab3d 100644 --- a/test/SemaCXX/dependent-auto.cpp +++ b/test/SemaCXX/dependent-auto.cpp @@ -8,7 +8,7 @@ struct only { template 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 check = x; }