before retrying the initialization to produce diagnostics. Otherwise, we may
fail to produce any diagnostics, and silently produce invalid AST in a -Asserts
build. Also add a note to this codepath to make it more clear why we were
trying to create a temporary.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217197
91177308-0d34-0410-b5e6-
96231b3b80d8
def note_in_omitted_aggregate_initializer : Note<
"in implicit initialization of %select{array element %1|field %1}0 "
"with omitted initializer">;
+def note_in_reference_temporary_list_initializer : Note<
+ "in initialization of temporary of type %0 created to "
+ "list-initialize this reference">;
def note_var_fixit_add_initialization : Note<
"initialize the variable %0 to silence this warning">;
def note_uninit_fixit_remove_cond : Note<
return diagnoseListInit(S, HiddenArray, InitList);
}
+ if (DestType->isReferenceType()) {
+ // A list-initialization failure for a reference means that we tried to
+ // create a temporary of the inner type (per [dcl.init.list]p3.6) and the
+ // inner initialization failed.
+ QualType T = DestType->getAs<ReferenceType>()->getPointeeType();
+ diagnoseListInit(S, InitializedEntity::InitializeTemporary(T), InitList);
+ SourceLocation Loc = InitList->getLocStart();
+ if (auto *D = Entity.getDecl())
+ Loc = D->getLocation();
+ S.Diag(Loc, diag::note_in_reference_temporary_list_initializer) << T;
+ return;
+ }
+
InitListChecker DiagnoseInitList(S, Entity, InitList, DestType,
/*VerifyOnly=*/false);
assert(DiagnoseInitList.HadError() &&
typedef decltype(sizeof(int)) size_t;
template <typename E>
- struct initializer_list // expected-note 2{{candidate}}
+ struct initializer_list
{
const E *p;
size_t n;
}
namespace rdar13395022 {
- struct MoveOnly {
- MoveOnly(MoveOnly&&);
+ struct MoveOnly { // expected-note {{candidate}}
+ MoveOnly(MoveOnly&&); // expected-note 2{{copy constructor is implicitly deleted because}} expected-note {{candidate}}
};
void test(MoveOnly mo) {
- // FIXME: These diagnostics are poor.
- auto &&list1 = {mo}; // expected-error{{no viable conversion}}
- MoveOnly (&&list2)[1] = {mo}; // expected-error{{no viable conversion}}
+ auto &&list1 = {mo}; // expected-error {{call to implicitly-deleted copy constructor}} expected-note {{in initialization of temporary of type 'std::initializer_list}}
+ MoveOnly (&&list2)[1] = {mo}; // expected-error {{call to implicitly-deleted copy constructor}} expected-note {{in initialization of temporary of type 'rdar13395022::MoveOnly [1]'}}
std::initializer_list<MoveOnly> &&list3 = {};
- MoveOnly (&&list4)[1] = {}; // expected-error{{uninitialized}}
+ MoveOnly (&&list4)[1] = {}; // expected-error {{no matching constructor}}
+ // expected-note@-1 {{in implicit initialization of array element 0 with omitted initializer}}
+ // expected-note@-2 {{in initialization of temporary of type 'rdar13395022::MoveOnly [1]' created to list-initialize this reference}}
}
}
F f2 { { 0 } }; // expected-error {{chosen constructor is explicit}}
F f3 { { { 0 } } }; // expected-error {{chosen constructor is explicit}}
}
+
+namespace PR20844 {
+ struct A {};
+ struct B { operator A&(); } b;
+ A &a{b}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'PR20844::A'}}
+}
// Y is an aggregate, so aggregate-initialization is performed and the
// conversion function is not considered.
const Y y10{z}; // expected-error {{excess elements}}
- const Y& y11{z}; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
+ const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'const Y'}}
const int& y12{z};
// X is not an aggregate, so constructors are considered.