r370555 - [c++20] Disallow template argument deduction from a braced-init-list

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 30 17:05:50 PDT 2019


Author: rsmith
Date: Fri Aug 30 17:05:50 2019
New Revision: 370555

URL: http://llvm.org/viewvc/llvm-project?rev=370555&view=rev
Log:
[c++20] Disallow template argument deduction from a braced-init-list
containing designators. The C++20 wording doesn't actually say what
happens in this case, but treating this as a non-deduced context seems
like the most natural behavior.

(We might want to consider deducing through array designators as an
extension in the future, but will need to be careful to deduce the array
bound properly if we do so. That's not permitted herein.)

Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
    cfe/trunk/test/SemaTemplate/deduction.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=370555&r1=370554&r2=370555&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Aug 30 17:05:50 2019
@@ -3702,6 +3702,12 @@ static Sema::TemplateDeductionResult Ded
     return Sema::TDK_Success;
   }
 
+  // Resolving a core issue: a braced-init-list containing any designators is
+  // a non-deduced context.
+  for (Expr *E : ILE->inits())
+    if (isa<DesignatedInitExpr>(E))
+      return Sema::TDK_Success;
+
   // Deduction only needs to be done for dependent types.
   if (ElTy->isDependentType()) {
     for (Expr *E : ILE->inits()) {
@@ -4509,6 +4515,12 @@ Sema::DeduceAutoType(TypeLoc Type, Expr
     if (!Type.getType().getNonReferenceType()->getAs<AutoType>())
       return DAR_Failed;
 
+    // Resolving a core issue: a braced-init-list containing any designators is
+    // a non-deduced context.
+    for (Expr *E : InitList->inits())
+      if (isa<DesignatedInitExpr>(E))
+        return DAR_Failed;
+
     SourceRange DeducedFromInitRange;
     for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) {
       Expr *Init = InitList->getInit(i);

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=370555&r1=370554&r2=370555&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Fri Aug 30 17:05:50 2019
@@ -29,9 +29,9 @@ namespace std {
     typedef const _E* iterator;
     typedef const _E* const_iterator;
 
-    initializer_list() : __begin_(nullptr), __size_(0) {}
+    constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
 
-    size_t    size()  const {return __size_;}
+    constexpr size_t    size()  const {return __size_;}
     const _E* begin() const {return __begin_;}
     const _E* end()   const {return __begin_ + __size_;}
   };
@@ -354,3 +354,14 @@ namespace no_conversion_after_auto_list_
   struct Y { using T = std::initializer_list<Y>(*)(); operator T(); };
   auto (*y)() = { Y() }; // expected-error {{from initializer list}}
 }
+
+namespace designated_init {
+  constexpr auto a = {.a = 1, .b = 2}; // expected-error {{cannot deduce}}
+  constexpr auto b = {[0] = 1, [4] = 2}; // expected-error {{cannot deduce}} expected-warning {{C99}}
+  constexpr auto c = {1, [4] = 2}; // expected-error {{cannot deduce}} expected-warning 2{{C99}} expected-note {{here}}
+  constexpr auto d = {1, [0] = 2}; // expected-error {{cannot deduce}} expected-warning 2{{C99}} expected-note {{here}}
+
+  // If we ever start accepting the above, these assertions should pass.
+  static_assert(c.size() == 5, "");
+  static_assert(d.size() == 1, "");
+}

Modified: cfe/trunk/test/SemaTemplate/deduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/deduction.cpp?rev=370555&r1=370554&r2=370555&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/deduction.cpp (original)
+++ cfe/trunk/test/SemaTemplate/deduction.cpp Fri Aug 30 17:05:50 2019
@@ -539,3 +539,10 @@ namespace dependent_list_deduction {
 #endif
   }
 }
+
+namespace designators {
+  template<typename T, int N> constexpr int f(T (&&)[N]) { return N; } // expected-note 2{{couldn't infer template argument 'T'}}
+  static_assert(f({1, 2, [20] = 3}) == 3, ""); // expected-error {{no matching function}} expected-warning 2{{C99}} expected-note {{}}
+
+  static_assert(f({.a = 1, .b = 2}) == 3, ""); // expected-error {{no matching function}}
+}




More information about the cfe-commits mailing list