From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id D85523883F2F; Thu, 15 Dec 2022 05:26:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D85523883F2F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1671081979; bh=TncdRCETX6AeS6wYkcyB3jZaVBkpCGLP/U3lUqCviLQ=; h=From:To:Subject:Date:From; b=c/bJSwYpok55z6Cu30dp59c0EvvOC8a8xWxc5+pH2L+PwKuwOU6D+xBIcPVlR6uUG s7EFqMpNbAHGWkfWF4F3V0UPTxXdXiyxwY13IPltj/d4VjWzdeeSn6FUNZyDS8ZGbR Npke6FWsR32pNF6FeQ+BxC7k2IqK3SkeI6PLIphc= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4712] c++: fix initializer_list transformation [PR108071] X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/master X-Git-Oldrev: 26f4aefaebc056acacc2a842f5b092ed9e671ef0 X-Git-Newrev: 4ef521bbc63f8a3883d507a8b6c1f95f442df3fe Message-Id: <20221215052619.D85523883F2F@sourceware.org> Date: Thu, 15 Dec 2022 05:26:19 +0000 (GMT) List-Id: https://gcc.gnu.org/g:4ef521bbc63f8a3883d507a8b6c1f95f442df3fe commit r13-4712-g4ef521bbc63f8a3883d507a8b6c1f95f442df3fe Author: Jason Merrill Date: Wed Dec 14 17:42:52 2022 -0500 c++: fix initializer_list transformation [PR108071] In these testcases, we weren't adequately verifying that constructing the element type from an array element would have the same effect as constructing it from one of the initializers. PR c++/108071 PR c++/105838 gcc/cp/ChangeLog: * call.cc (struct conversion_obstack_sentinel): New. (maybe_init_list_as_array): Compare conversion of dummy argument. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist131.C: New test. * g++.dg/cpp0x/initlist132.C: New test. * g++.dg/cpp0x/initlist133.C: New test. Diff: --- gcc/cp/call.cc | 35 ++++++++++++++++++++++++++------ gcc/testsuite/g++.dg/cpp0x/initlist131.C | 14 +++++++++++++ gcc/testsuite/g++.dg/cpp0x/initlist132.C | 30 +++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/initlist133.C | 25 +++++++++++++++++++++++ 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 33b5e7f87f5..c25df174280 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -622,6 +622,15 @@ conversion_obstack_alloc (size_t n) return p; } +/* RAII class to discard anything added to conversion_obstack. */ + +struct conversion_obstack_sentinel +{ + void *p; + conversion_obstack_sentinel (): p (conversion_obstack_alloc (0)) {} + ~conversion_obstack_sentinel () { obstack_free (&conversion_obstack, p); } +}; + /* Allocate rejection reasons. */ static struct rejection_reason * @@ -4219,18 +4228,32 @@ static tree maybe_init_list_as_array (tree elttype, tree init) { /* Only do this if the array can go in rodata but not once converted. */ - if (!CLASS_TYPE_P (elttype)) + if (!TYPE_NON_AGGREGATE_CLASS (elttype)) return NULL_TREE; tree init_elttype = braced_init_element_type (init); if (!init_elttype || !SCALAR_TYPE_P (init_elttype) || !TREE_CONSTANT (init)) return NULL_TREE; + /* Check with a stub expression to weed out special cases, and check whether + we call the same function for direct-init as copy-list-init. */ + conversion_obstack_sentinel cos; + tree arg = build_stub_object (init_elttype); + conversion *c = implicit_conversion (elttype, init_elttype, arg, false, + LOOKUP_NORMAL, tf_none); + if (c && c->kind == ck_rvalue) + c = next_conversion (c); + if (!c || c->kind != ck_user) + return NULL_TREE; + tree first = CONSTRUCTOR_ELT (init, 0)->value; - if (TREE_CODE (init_elttype) == INTEGER_TYPE && null_ptr_cst_p (first)) - /* Avoid confusion from treating 0 as a null pointer constant. */ - first = build1 (UNARY_PLUS_EXPR, init_elttype, first); - first = (perform_implicit_conversion_flags - (elttype, first, tf_none, LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING)); + conversion *fc = implicit_conversion (elttype, init_elttype, first, false, + LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING, + tf_none); + if (fc && fc->kind == ck_rvalue) + fc = next_conversion (fc); + if (!fc || fc->kind != ck_user || fc->cand->fn != c->cand->fn) + return NULL_TREE; + first = convert_like (fc, first, tf_none); if (first == error_mark_node) /* Let the normal code give the error. */ return NULL_TREE; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist131.C b/gcc/testsuite/g++.dg/cpp0x/initlist131.C new file mode 100644 index 00000000000..a714215219a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist131.C @@ -0,0 +1,14 @@ +// PR c++/108071 +// { dg-do compile { target c++11 } } + +#include + +struct OptSpecifier { + explicit OptSpecifier(bool); + OptSpecifier(unsigned); +}; +void f (std::initializer_list); +int main() +{ + f({1}); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist132.C b/gcc/testsuite/g++.dg/cpp0x/initlist132.C new file mode 100644 index 00000000000..34e0307cbbc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist132.C @@ -0,0 +1,30 @@ +// PR c++/108071 +// { dg-do compile { target c++11 } } + +#include + +template< typename T1, typename T2 = void > +struct ConstCharArrayDetector +{ + static const bool ok = false; +}; +template< std::size_t N, typename T > +struct ConstCharArrayDetector< const char[ N ], T > +{ + typedef T Type; +}; + +struct Dummy { }; + +struct OUString +{ + template + OUString(T&, typename ConstCharArrayDetector::Type = Dummy()) + { } +}; + +struct Sequence { + Sequence(std::initializer_list); +}; + +Sequence s = {""}; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist133.C b/gcc/testsuite/g++.dg/cpp0x/initlist133.C new file mode 100644 index 00000000000..08da5bebd0b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist133.C @@ -0,0 +1,25 @@ +// PR c++/108071 +// { dg-do compile { target c++14 } } + +#include + +template struct enable_if { }; +template<> struct enable_if { using type = void; }; + +template constexpr bool is_array_v = false; +template constexpr bool is_array_v = true; + +struct OUString +{ + template>::type> + OUString(T&) { } +}; + +struct vector +{ + vector(std::initializer_list) { } + template + vector(Iter i, Iter j) { if (i != j) OUString(*i); } +}; + +vector v = { "" };