forked from OSchip/llvm-project
[C++17] Fix class template argument deduction for default constructors without an initializer
Summary: As the title says, this makes following code compile: ``` template<typename> struct Foo {}; Foo() -> Foo<void>; Foo f; // ok ``` Thanks Nicolas Lesser for coining the fix. Reviewers: rsmith, lichray Reviewed By: rsmith, lichray Subscribers: lichray, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D38216 llvm-svn: 328409
This commit is contained in:
parent
40eb34607c
commit
2c5471ddc7
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue