From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id E211F3858D32 for ; Mon, 20 Mar 2023 18:40:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E211F3858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1679337657; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xBW616Zs+G3YyblZkQ70ZMgyCAtkkEnCWkA7wHvy/Po=; b=gc+526pL4PQRdnw/XEfwhV2qocC/wkMNnRNSmXBiQ7G7XuBS1pWXF9zl2cJn5sw/ZJ7NdZ vOa/qPy8iXLVWTlgwTeXIKyOHZAp7uqDDX00LwFMHWWhXmoI7jrISB+HKTiAK+Xdcuvldr bxrkSCWMvJjfV+qOhjzugu8w0TWpz74= Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-32-HdehCiPaOly4F_rMSggjzw-1; Mon, 20 Mar 2023 14:40:56 -0400 X-MC-Unique: HdehCiPaOly4F_rMSggjzw-1 Received: by mail-qt1-f197.google.com with SMTP id ga17-20020a05622a591100b003bfdf586476so7448930qtb.7 for ; Mon, 20 Mar 2023 11:40:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679337656; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xBW616Zs+G3YyblZkQ70ZMgyCAtkkEnCWkA7wHvy/Po=; b=0YZyEkHZSwn8SaUZwW6v9P6qJ29Qgw/bb867VpeLumzzv2Dhm1ETAKn4YyEN9nCsRl /CCZXx8+1LLEtKKQYq7/jfqbVoQf6cMoUarjoMCFyrzjBKqJr3KS272zR9MgHUvvJe2t DYAlNoCQ/8qXIsZr1bk6dfl3nxeeicLDX/JYNvd4hlQddQ3PyLhEYskdF6ZPq0473I5K ZDuhMGMnFG8p1kVJ9PCuZdP8fHxCp4jvy9uJYFIuFPa3keXOLtm9vf/gfuvfOwsRViDU hArWwiNSflHS1i55Og0bZ0elUIwFC/HXaUvG3fYFgNICshw9tu4S5LzQzcWcQ4WPFtyj ZzPA== X-Gm-Message-State: AO0yUKUhOBvGsl5MVX1ifYTgV0ZSB8xEbbG2INdQ713CSoZ3B75X8Uph dvMOBQWP1HCp6o9TMQg4x5viF+phd9svyIMZ/pkBduLlL5KXxZg2h8+tjIUaHtY1zGu0mm9vwCr F6UWxJYVU6qtxpMQ/bQ== X-Received: by 2002:ac8:584a:0:b0:3dd:d7ca:535f with SMTP id h10-20020ac8584a000000b003ddd7ca535fmr175842qth.58.1679337655966; Mon, 20 Mar 2023 11:40:55 -0700 (PDT) X-Google-Smtp-Source: AK7set8d7wz9pXLbU+0vMfdUhCcEoNTPMzM0m7Q2C9sfwh1AJrouxAQgcyAVT3TKo4Q7Bv+X6G1YCg== X-Received: by 2002:ac8:584a:0:b0:3dd:d7ca:535f with SMTP id h10-20020ac8584a000000b003ddd7ca535fmr175805qth.58.1679337655540; Mon, 20 Mar 2023 11:40:55 -0700 (PDT) Received: from [192.168.1.108] (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id e1-20020ac84901000000b003d460ec242esm6887437qtq.81.2023.03.20.11.40.53 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 20 Mar 2023 11:40:54 -0700 (PDT) Message-ID: Date: Mon, 20 Mar 2023 14:40:53 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.9.0 Subject: Re: [PATCH] c++: explicit ctor and list-initialization [PR109159] To: Marek Polacek , GCC Patches References: <20230320155508.28497-1-polacek@redhat.com> From: Jason Merrill In-Reply-To: <20230320155508.28497-1-polacek@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 3/20/23 11:55, Marek Polacek wrote: > When I implemented explicit(bool) in r9-3735, I added this code to > add_template_candidate_real: > + /* Now the explicit specifier might have been deduced; check if this > + declaration is explicit. If it is and we're ignoring non-converting > + constructors, don't add this function to the set of candidates. */ > + if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn)) > + return NULL; > but as this test demonstrates, that's incorrect when we're initializing > from a {}: for list-initialization we consider explicit constructors and > complain if one is chosen. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/12? OK. > PR c++/109159 > > gcc/cp/ChangeLog: > > * call.cc (add_template_candidate_real): Add explicit decls to the > set of candidates when the initializer is a braced-init-list. > > libstdc++-v3/ChangeLog: > > * testsuite/20_util/pair/cons/explicit_construct.cc: Adjust dg-error. > * testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise. > * testsuite/23_containers/span/explicit.cc: Likewise. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/explicit16.C: New test. > --- > gcc/cp/call.cc | 4 +- > gcc/testsuite/g++.dg/cpp0x/explicit16.C | 18 ++++++ > .../20_util/pair/cons/explicit_construct.cc | 10 ++-- > .../20_util/tuple/cons/explicit_construct.cc | 58 +++++++++---------- > .../testsuite/23_containers/span/explicit.cc | 4 +- > 5 files changed, 57 insertions(+), 37 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/explicit16.C > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index c01e7b82457..c52a09b9be2 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -3612,7 +3612,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, > /* Now the explicit specifier might have been deduced; check if this > declaration is explicit. If it is and we're ignoring non-converting > constructors, don't add this function to the set of candidates. */ > - if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn)) > + if (((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR)) > + == LOOKUP_ONLYCONVERTING) > + && DECL_NONCONVERTING_P (fn)) > return NULL; > > if (DECL_CONSTRUCTOR_P (fn) && nargs == 2) > diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit16.C b/gcc/testsuite/g++.dg/cpp0x/explicit16.C > new file mode 100644 > index 00000000000..bb5a823aee6 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/explicit16.C > @@ -0,0 +1,18 @@ > +// PR c++/109159 > +// { dg-do compile { target c++11 } } > + > +struct A { > + A(float) {} > + template > + explicit A(U) {} > +}; > + > +void f(A t) > +{ > + t = {1}; // { dg-error "explicit constructor" } > + t = 1; > + A a1{1}; > + A a2 = {1}; // { dg-error "explicit constructor" } > + A a3 = 1; > + A a4(1); > +} > diff --git a/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc b/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc > index e875f0cbcd2..d550e9c604b 100644 > --- a/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc > +++ b/libstdc++-v3/testsuite/20_util/pair/cons/explicit_construct.cc > @@ -37,7 +37,7 @@ struct ExplicitDefaultDefault > > std::pair f1() {return {1,2};} > > -std::pair f2() {return {1,2};} // { dg-error "could not convert" } > +std::pair f2() {return {1,2};} // { dg-error "explicit constructor" } > > std::pair f3() {return std::pair{1,2};} > > @@ -52,7 +52,7 @@ std::pair v0{1,2}; > > std::pair v1{1,2}; > > -std::pair v2 = {1,2}; // { dg-error "could not convert" } > +std::pair v2 = {1,2}; // { dg-error "explicit constructor" } > > std::pair v3{std::pair{1,2}}; > > @@ -99,7 +99,7 @@ void test_arg_passing() > { > f6(v0); // { dg-error "could not convert" } > f6(v1); > - f6({1,2}); // { dg-error "could not convert" } > + f6({1,2}); // { dg-error "explicit constructor" } > f6(std::pair{}); > f6(std::pair{}); // { dg-error "could not convert" } > f7(v0); > @@ -130,6 +130,6 @@ std::pair v14{nullptr, MoveOnly{}}; > std::pair v15{MoveOnly{}, nullptr}; > > std::pair v16 = > - {nullptr, MoveOnly{}}; // { dg-error "could not convert" } > + {nullptr, MoveOnly{}}; // { dg-error "explicit constructor" } > std::pair v17 = > - {MoveOnly{}, nullptr}; // { dg-error "could not convert" } > + {MoveOnly{}, nullptr}; // { dg-error "explicit constructor" } > diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc > index 820ddef30b4..3352dd15f7d 100644 > --- a/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc > +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/explicit_construct.cc > @@ -45,11 +45,11 @@ std::tuple f1b() {return {1,2};} > std::tuple f1c() {return {1,2,3};} > > std::tuple f2_a() > -{return {1};} // { dg-error "could not convert" } > +{return {1};} // { dg-error "explicit constructor" } > std::tuple f2_b() > -{return {1,2};} // { dg-error "could not convert" } > +{return {1,2};} // { dg-error "explicit constructor" } > std::tuple f2_c() > -{return {1,2,3};} // { dg-error "could not convert" } > +{return {1,2,3};} // { dg-error "explicit constructor" } > > std::tuple f3_a() {return std::tuple{1};} > std::tuple f3_b() {return std::tuple{1,2};} > @@ -73,22 +73,22 @@ std::tuple f5_b() {return {1,2};} > std::tuple f5_c() {return {1,2,3};} > > std::tuple f6_a() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > std::tuple f6_b() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > std::tuple f6_c() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > std::tuple f6_d() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > > std::tuple f7_a() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > std::tuple f7_b() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > std::tuple ExplicitDefaultDefault, > ExplicitDefaultDefault> f7_c() > -{return {};} // { dg-error "could not convert" } > +{return {};} // { dg-error "explicit constructor" } > > std::tuple fp1() {return std::pair{1,2}; } > std::tuple fp2() {return std::pair{1,2}; } > @@ -103,9 +103,9 @@ std::tuple v1_a{1}; > std::tuple v1_b{1,2}; > std::tuple v1_c{1,2,3}; > > -std::tuple v2_a = {1}; // { dg-error "could not convert" } > -std::tuple v2_b = {1,2}; // { dg-error "could not convert" } > -std::tuple v2_c = {1,2,3}; // { dg-error "could not convert" } > +std::tuple v2_a = {1}; // { dg-error "explicit constructor" } > +std::tuple v2_b = {1,2}; // { dg-error "explicit constructor" } > +std::tuple v2_c = {1,2,3}; // { dg-error "explicit constructor" } > > std::tuple v3_a{std::tuple{1}}; > std::tuple v3_b{std::tuple{1,2}}; > @@ -196,11 +196,11 @@ std::tuple > v31_c{std::allocator_arg, std::allocator{}, 1,2,3}; > > std::tuple v32_a > - = {std::allocator_arg, std::allocator{ }, 1}; // { dg-error "could not convert" } > + = {std::allocator_arg, std::allocator{ }, 1}; // { dg-error "explicit constructor" } > std::tuple v32_b > - = {std::allocator_arg, std::allocator{}, 1, 2}; // { dg-error "could not convert" } > + = {std::allocator_arg, std::allocator{}, 1, 2}; // { dg-error "explicit constructor" } > std::tuple v32_c > - = {std::allocator_arg, std::allocator{}, 1,2,3}; // { dg-error "could not convert" } > + = {std::allocator_arg, std::allocator{}, 1,2,3}; // { dg-error "explicit constructor" } > > std::tuple v33{std::allocator_arg, std::allocator{}, > std::pair{1, 2}}; > @@ -218,7 +218,7 @@ std::tuple v37 = {std::allocator_arg, std::allocator{}, > std::pair{1, 2}}; > > std::tuple v38 > -= {std::allocator_arg, std::allocator{}, std::pair{1, 2}}; // { dg-error "could not convert" } > += {std::allocator_arg, std::allocator{}, std::pair{1, 2}}; // { dg-error "explicit constructor" } > > std::tuple v39{std::allocator_arg, std::allocator{}, v20}; > > @@ -232,18 +232,18 @@ std::tuple v42 = {std::allocator_arg, std::allocator{}, v20}; > std::tuple v43 = {std::allocator_arg, std::allocator{}, v20}; > > std::tuple v44 > -= {std::allocator_arg, std::allocator{ }, v20}; // { dg-error "could not convert" } > += {std::allocator_arg, std::allocator{ }, v20}; // { dg-error "explicit constructor" } > std::tuple v45_a{}; > std::tuple v45_b{}; > > -std::tuple v46_a = {}; // { dg-error "could not convert" } > -std::tuple v46_b = {}; // { dg-error "could not convert" } > +std::tuple v46_a = {}; // { dg-error "explicit constructor" } > +std::tuple v46_b = {}; // { dg-error "explicit constructor" } > > std::tuple v47_a{}; > std::tuple v47_b{}; > > -std::tuple v48_a = {}; // { dg-error "could not convert" } > -std::tuple v48_b = { }; // { dg-error "could not convert" } > +std::tuple v48_a = {}; // { dg-error "explicit constructor" } > +std::tuple v48_b = { }; // { dg-error "explicit constructor" } > > > struct DeletedCopy > @@ -295,9 +295,9 @@ void test_arg_passing() > f8_b(v1_b); > f8_c(v1_c); > > - f8_a({1}); // { dg-error "could not convert" } > - f8_b({1,2}); // { dg-error "could not convert" } > - f8_c({1,2,3}); // { dg-error "could not convert" } > + f8_a({1}); // { dg-error "explicit constructor" } > + f8_b({1,2}); // { dg-error "explicit constructor" } > + f8_c({1,2,3}); // { dg-error "explicit constructor" } > > f8_a(std::tuple{}); > f8_b(std::tuple{}); > @@ -330,10 +330,10 @@ void test_arg_passing() > f9_b(std::tuple{}); > f9_c(std::tuple{}); > > - f10_a({}); // { dg-error "could not convert" } > - f10_b({}); // { dg-error "could not convert" } > - f11_a({}); // { dg-error "could not convert" } > - f11_b({}); // { dg-error "could not convert" } > + f10_a({}); // { dg-error "explicit constructor" } > + f10_b({}); // { dg-error "explicit constructor" } > + f11_a({}); // { dg-error "explicit constructor" } > + f11_b({}); // { dg-error "explicit constructor" } > > f10_a(std::tuple{}); > f10_b(std::tuple{}); > diff --git a/libstdc++-v3/testsuite/23_containers/span/explicit.cc b/libstdc++-v3/testsuite/23_containers/span/explicit.cc > index 580d69e4f09..b0a1311f02c 100644 > --- a/libstdc++-v3/testsuite/23_containers/span/explicit.cc > +++ b/libstdc++-v3/testsuite/23_containers/span/explicit.cc > @@ -31,11 +31,11 @@ auto first = std::begin(r), last = std::end(r); > > // span(It, size_type) > std::span s1 = {first, 2}; > -std::span s2 = {first, 2}; // { dg-error "could not convert" } > +std::span s2 = {first, 2}; // { dg-error "explicit constructor" } > > // span(It, End) > std::span s3 = {first, last}; > -std::span s4 = {first, last}; // { dg-error "could not convert" } > +std::span s4 = {first, last}; // { dg-error "explicit constructor" } > > // span(R&&) > std::span s5 = r; > > base-commit: fbd50e867e6a782c7b56c9727bf7e1e74dae4b94