summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaDecl.cpp18
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp5
-rw-r--r--clang/test/Parser/cxx1z-class-template-argument-deduction.cpp3
3 files changed, 18 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6319e4b34ce..d583646a38b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10396,12 +10396,22 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
// C++11 [dcl.spec.auto]p3
if (!Init) {
assert(VDecl && "no init for init capture deduction?");
- Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
- << VDecl->getDeclName() << Type;
- return QualType();
+
+ // Except for class argument deduction, and then for an initializing
+ // declaration only, i.e. no static at class scope or extern.
+ if (!isa<DeducedTemplateSpecializationType>(Deduced) ||
+ VDecl->hasExternalStorage() ||
+ VDecl->isStaticDataMember()) {
+ Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
+ << VDecl->getDeclName() << Type;
+ return QualType();
+ }
}
- ArrayRef<Expr*> DeduceInits = Init;
+ ArrayRef<Expr*> DeduceInits;
+ if (Init)
+ DeduceInits = Init;
+
if (DirectInit) {
if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init))
DeduceInits = PL->exprs();
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
index cfb9a61f1ac..96be58f8eb5 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.class.deduct/p1.cpp
@@ -5,8 +5,7 @@ A() -> A<int>;
A(int) -> A<char>;
static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
-// FIXME: There isn't really a good reason to reject this.
-A b; // expected-error {{requires an initializer}}
+A b;
A c [[]] {};
A d = {}, e = {};
@@ -16,3 +15,5 @@ struct B {
static A a; // expected-error {{requires an initializer}}
};
extern A x; // expected-error {{requires an initializer}}
+static A y;
+
diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
index bf1d004c8d2..532c893f213 100644
--- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -137,7 +137,6 @@ namespace expr {
(void)A{n};
(void)new A(n);
(void)new A{n};
- // FIXME: We should diagnose the lack of an initializer here.
(void)new A;
}
}
@@ -150,7 +149,7 @@ namespace decl {
auto k() -> A; // expected-error{{requires template arguments}}
- A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}}
+ A a;
A b = 0;
const A c = 0;
A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
OpenPOWER on IntegriCloud