def err_auto_not_allowed_var_inst : Error<
"'auto' variable template instantiation is not allowed">;
def err_auto_var_requires_init : Error<
- "declaration of variable %0 with type %1 requires an initializer">;
+ "declaration of variable %0 with deduced 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_new_list_init : Error<
DeducedType *Deduced = Type->getContainedDeducedType();
assert(Deduced && "deduceVarTypeFromInitializer for non-deduced type");
- ArrayRef<Expr*> DeduceInits = Init ? ArrayRef<Expr*>(Init) : None;
+ // 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();
+ }
+
+ ArrayRef<Expr*> DeduceInits = Init;
if (DirectInit) {
if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init))
DeduceInits = PL->exprs();
InitsCopy);
}
- // 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();
- }
-
if (DirectInit) {
if (auto *IL = dyn_cast<InitListExpr>(Init))
DeduceInits = IL->inits();
}
void g() {
- decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}}
+ decltype(auto) a; // expected-error{{declaration of variable 'a' with deduced type 'decltype(auto)' requires an initializer}}
- decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}}
+ decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with deduced type 'decltype(auto) *' requires an initializer}}
if (decltype(auto) b) {} // expected-error {{must have an initializer}}
for (;decltype(auto) b;) {} // expected-error {{must have an initializer}}
}
void g() {
- auto a; // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}}
+ auto a; // expected-error{{declaration of variable 'a' with deduced type 'auto' requires an initializer}}
- auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
+ auto *b; // expected-error{{declaration of variable 'b' with deduced type 'auto *' requires an initializer}}
if (auto b) {} // expected-error {{must have an initializer}}
for (;auto b;) {} // expected-error {{must have an initializer}}
};
struct S {
- static const auto a; // expected-error {{declaration of variable 'a' with type 'const auto' requires an initializer}}
+ static const auto a; // expected-error {{declaration of variable 'a' with deduced type 'const auto' requires an initializer}}
static const auto b = 0;
static const int c;
};
A(int) -> A<char>;
static constexpr inline const volatile A a = {}; // ok, specifiers are permitted
-A b; // FIXME: An initializer is required
+// FIXME: There isn't really a good reason to reject this.
+A b; // expected-error {{requires an initializer}}
A c [[]] {};
A d = {}, e = {};
A f(0), g{}; // expected-error {{template arguments deduced as 'A<char>' in declaration of 'f' and deduced as 'A<int>' in declaration of 'g'}}
+
+struct B {
+ static A a; // expected-error {{requires an initializer}}
+};
+extern A x; // expected-error {{requires an initializer}}
operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
- static A x; // FIXME: We deduce A<int> from the initializer despite this not being a definition!
+ static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
static constexpr A y = 0;
};
auto k() -> A; // expected-error{{requires template arguments}}
- A a; // FIXME: This is (technically) syntactically invalid.
+ A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}}
A b = 0;
const A c = 0;
A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
template<typename T> extern int v; // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}}
#ifndef PRECXX11
- template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}}
+ template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with deduced type 'auto' requires an initializer}}
#endif
template<typename T> T var = T(); // expected-note {{previous definition is here}}
#ifndef PRECXX11
namespace pvt_auto {
- template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}}
+ template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with deduced type 'auto' requires an initializer}}
template<typename T> auto v1 = T(); // expected-note {{previous definition is here}}
template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}}
template<typename T> auto v2 = T(); // expected-note {{previous definition is here}}
template<typename T> auto v3 = T(); // expected-note {{previous definition is here}}
template<typename T> extern T v3; // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}}
template<typename T> auto v4 = T();
- template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}}
+ template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with deduced type 'auto' requires an initializer}}
}
#endif