r312703 - P0702R1: in class template argument deduction from a list of one element, if

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 7 00:22:36 PDT 2017


Author: rsmith
Date: Thu Sep  7 00:22:36 2017
New Revision: 312703

URL: http://llvm.org/viewvc/llvm-project?rev=312703&view=rev
Log:
P0702R1: in class template argument deduction from a list of one element, if
that element's type is (or is derived from) a specialization of the deduced
template, skip the std::initializer_list special case.

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=312703&r1=312702&r2=312703&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Sep  7 00:22:36 2017
@@ -8339,6 +8339,16 @@ Sema::PerformCopyInitialization(const In
   return Result;
 }
 
+/// Determine whether RD is, or is derived from, a specialization of CTD.
+static bool isOrIsDerivedFromSpecializationOf(CXXRecordDecl *RD,
+                                              ClassTemplateDecl *CTD) {
+  auto NotSpecialization = [&] (const CXXRecordDecl *Candidate) {
+    auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Candidate);
+    return !CTSD || !declaresSameEntity(CTSD->getSpecializedTemplate(), CTD);
+  };
+  return !(NotSpecialization(RD) && RD->forallBases(NotSpecialization));
+}
+
 QualType Sema::DeduceTemplateSpecializationFromInitializer(
     TypeSourceInfo *TSInfo, const InitializedEntity &Entity,
     const InitializationKind &Kind, MultiExprArg Inits) {
@@ -8483,6 +8493,17 @@ QualType Sema::DeduceTemplateSpecializat
           break;
         }
       }
+    } else if (ListInit->getNumInits() == 1) {
+      // C++ [over.match.class.deduct]:
+      //   As an exception, the first phase in [over.match.list] (considering
+      //   initializer-list constructors) is omitted if the initializer list
+      //   consists of a single expression of type cv U, where U is a
+      //   specialization of C or a class derived from a specialization of C.
+      Expr *E = ListInit->getInit(0);
+      auto *RD = E->getType()->getAsCXXRecordDecl();
+      if (!isa<InitListExpr>(E) && RD &&
+          isOrIsDerivedFromSpecializationOf(RD, Template))
+        TryListConstructors = false;
     }
 
     if (TryListConstructors)

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=312703&r1=312702&r2=312703&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Sep  7 00:22:36 2017
@@ -2695,6 +2695,17 @@ static bool isSimpleTemplateIdType(QualT
         = T->getAs<TemplateSpecializationType>())
     return Spec->getTemplateName().getAsTemplateDecl() != nullptr;
 
+  // C++17 [temp.local]p2:
+  //   the injected-class-name [...] is equivalent to the template-name followed
+  //   by the template-arguments of the class template specialization or partial
+  //   specialization enclosed in <>
+  // ... which means it's equivalent to a simple-template-id.
+  //
+  // This only arises during class template argument deduction for a copy
+  // deduction candidate, where it permits slicing.
+  if (T->getAs<InjectedClassNameType>())
+    return true;
+
   return false;
 }
 

Modified: cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp?rev=312703&r1=312702&r2=312703&view=diff
==============================================================================
--- cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp (original)
+++ cfe/trunk/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp Thu Sep  7 00:22:36 2017
@@ -23,3 +23,34 @@ namespace Explicit {
   using Y = decltype(b);
   using X = decltype(c);
 }
+
+namespace std {
+  template<typename T> struct initializer_list {
+    const T *ptr;
+    __SIZE_TYPE__ size;
+    initializer_list();
+  };
+}
+
+namespace p0702r1 {
+  template<typename T> struct X { // expected-note {{candidate}}
+    X(std::initializer_list<T>); // expected-note {{candidate}}
+  };
+
+  X xi = {0};
+  X xxi = {xi};
+  extern X<int> xi;
+  // Prior to P0702R1, this is X<X<int>>.
+  extern X<int> xxi;
+
+  struct Y : X<int> {};
+  Y y {{0}};
+  X xy {y};
+  extern X<int> xy;
+
+  struct Z : X<int>, X<float> {};
+  Z z = {{0}, {0.0f}};
+  // This is not X<Z> even though that would work. Instead, it's ambiguous
+  // between X<int> and X<float>.
+  X xz = {z}; // expected-error {{no viable constructor or deduction guide}}
+}

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=312703&r1=312702&r2=312703&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Thu Sep  7 00:22:36 2017
@@ -828,7 +828,7 @@ as the draft C++2a standard evolves.
     <tr>
       <td>Initializer list constructors in class template argument deduction</td>
       <td><a href="http://wg21.link/p0702r1">P0702R1</a></td>
-      <td class="none" align="center">No</td>
+      <td class="svn" align="center">SVN <a href="#p0702">(13)</a></td>
     </tr>
     <tr id="p0374">
       <td>Concepts</td>
@@ -838,6 +838,12 @@ as the draft C++2a standard evolves.
 </table>
 </details>
 
+<p>
+<span id="p0702">(13): This is the resolution to a Defect Report, so is applied
+to all language versions supporting class template argument deduction.
+</span>
+</p>
+
 <h2 id="ts">Technical specifications and standing documents</h2>
 
 <p>ISO C++ also publishes a number of documents describing additional language




More information about the cfe-commits mailing list