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