From a5c7040f4d3316305921ac27de113eb9b807f4c3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 31 Aug 2019 00:05:50 +0000 Subject: [PATCH] [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.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370555 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateDeduction.cpp | 12 ++++++++++++ .../cxx0x-initializer-stdinitializerlist.cpp | 15 +++++++++++++-- test/SemaTemplate/deduction.cpp | 7 +++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index a75af62bf3..db50830a15 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3702,6 +3702,12 @@ static Sema::TemplateDeductionResult DeduceFromInitializerList( 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(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 *&Init, QualType &Result, if (!Type.getType().getNonReferenceType()->getAs()) 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(E)) + return DAR_Failed; + SourceRange DeducedFromInitRange; for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { Expr *Init = InitList->getInit(i); diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index 9a82ec4a7b..b5d6bd68f1 100644 --- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -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_deduction { struct Y { using T = std::initializer_list(*)(); 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, ""); +} diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp index be86f18729..64fef8e5f5 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -539,3 +539,10 @@ namespace dependent_list_deduction { #endif } } + +namespace designators { + template 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}} +} -- 2.40.0