r217197 - PR20844: If we fail to list-initialize a reference, map to the referenced type
Richard Smith
richard-llvm at metafoo.co.uk
Thu Sep 4 15:13:39 PDT 2014
Author: rsmith
Date: Thu Sep 4 17:13:39 2014
New Revision: 217197
URL: http://llvm.org/viewvc/llvm-project?rev=217197&view=rev
Log:
PR20844: If we fail to list-initialize a reference, map to the referenced type
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.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
cfe/trunk/test/SemaCXX/explicit.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=217197&r1=217196&r2=217197&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 4 17:13:39 2014
@@ -1517,6 +1517,9 @@ def note_block_var_fixit_add_initializat
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<
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=217197&r1=217196&r2=217197&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Sep 4 17:13:39 2014
@@ -6431,6 +6431,19 @@ static void diagnoseListInit(Sema &S, co
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() &&
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp?rev=217197&r1=217196&r2=217197&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp Thu Sep 4 17:13:39 2014
@@ -4,7 +4,7 @@ namespace std {
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;
@@ -112,15 +112,16 @@ namespace bullet8 {
}
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 at -1 {{in implicit initialization of array element 0 with omitted initializer}}
+ // expected-note at -2 {{in initialization of temporary of type 'rdar13395022::MoveOnly [1]' created to list-initialize this reference}}
}
}
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp?rev=217197&r1=217196&r2=217197&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp Thu Sep 4 17:13:39 2014
@@ -118,3 +118,9 @@ namespace inner_init {
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'}}
+}
Modified: cfe/trunk/test/SemaCXX/explicit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/explicit.cpp?rev=217197&r1=217196&r2=217197&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/explicit.cpp (original)
+++ cfe/trunk/test/SemaCXX/explicit.cpp Thu Sep 4 17:13:39 2014
@@ -86,7 +86,7 @@ namespace Conversion {
// 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.
More information about the cfe-commits
mailing list