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 ECE0E3858D3C for ; Thu, 24 Mar 2022 17:11:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org ECE0E3858D3C Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-178-4QjdPOhqMHOy-Q_Fz90D1A-1; Thu, 24 Mar 2022 13:11:24 -0400 X-MC-Unique: 4QjdPOhqMHOy-Q_Fz90D1A-1 Received: by mail-qt1-f199.google.com with SMTP id a24-20020ac81098000000b002e1e06a72aeso4164101qtj.6 for ; Thu, 24 Mar 2022 10:11:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=O26e3tfWcwqytcIeGgvFr514H4rYsVpx+Di4Cr5pcI0=; b=DxpgUFFw4Zlpyj7lAsjHekwpm2pg5o5Sgzw9tchg9LJT7N5UBym7QEPgVFPlnJ7T9q rur5FKcufSB9CyZlUCiE5PZntkUSYeDl2X1JG2U5RQ+5GMq4POg7uC+PbaQlOWIQFkF7 DAT1vbE4GO+0WAOWqwqiRsiN+us1tY0A756RZhDwX3nkUbfyo5qi0apwusOyt3+A2Qmg Wvxg97YXomzSC1sSllyq6rdZ4jba/oXsdv95U9NtY4WyMX+A/3meZsatNnm74xIxUGwV 9LXiTdvKmSg8sM/ImByV0y9MWtl+S/1KfXSSC1HB1cROQ9AmTEHYFYJkrqYB3IJOM/yc /WnA== X-Gm-Message-State: AOAM530pnYxRWA01sCuXRq9MrUTVN8wdx+BslnDlXYqy0x9z5Uz9UWNb FPnrEZAL/xwHgCN9IA1Dn56frAu+TaNIApU4ELUx+WaNXUvmyQKLimK3No1AWP7/iz7zHMiAlsd 0P8bUOlX5dujUql+RuA== X-Received: by 2002:ad4:5bc7:0:b0:441:53a2:169c with SMTP id t7-20020ad45bc7000000b0044153a2169cmr5306954qvt.8.1648141883038; Thu, 24 Mar 2022 10:11:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyFzi6/yQtga10cYNjFf52lXQK73maHTQxXeaWQUo1dSKLbfgZ6ir8QqIslq0x4SJHNaQVs0w== X-Received: by 2002:ad4:5bc7:0:b0:441:53a2:169c with SMTP id t7-20020ad45bc7000000b0044153a2169cmr5306880qvt.8.1648141882258; Thu, 24 Mar 2022 10:11:22 -0700 (PDT) Received: from [192.168.1.149] (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 n131-20020a372789000000b0067bce1ac001sm1790395qkn.71.2022.03.24.10.11.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 24 Mar 2022 10:11:21 -0700 (PDT) Message-ID: <9d516056-174b-2a46-67f8-8e8a1172fd59@redhat.com> Date: Thu, 24 Mar 2022 13:11:20 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: [PATCH v2] c++: FIX_TRUNC_EXPR in tsubst [PR102990] To: Marek Polacek Cc: GCC Patches References: <20220322235557.836257-1-polacek@redhat.com> <9b400f63-5ac8-ebb2-4a8c-1981a744e50a@redhat.com> From: Jason Merrill In-Reply-To: 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=-13.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Mar 2022 17:11:27 -0000 On 3/24/22 13:03, Marek Polacek wrote: > On Thu, Mar 24, 2022 at 09:32:19AM -0400, Jason Merrill wrote: >> On 3/23/22 19:26, Marek Polacek wrote: >>> On Wed, Mar 23, 2022 at 04:35:32PM -0400, Jason Merrill wrote: >>>> On 3/22/22 19:55, Marek Polacek wrote: >>>>> This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build >>>>> where it hits gcc_unreachable (). >>>>> >>>>> The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it >>>>> was introduced in r181478, but it did the wrong thing, whereupon it >>>>> was turned into gcc_unreachable () in r258821 (see this thread: >>>>> ). >>>>> >>>>> In a template, we should never create a FIX_TRUNC_EXPR (that's what >>>>> conv_unsafe_in_template_p is for). But in this test we are NOT in >>>>> a template when we call digest_nsdmi_init which ends up calling >>>>> convert_like, converting 1.0e+0 to int, so convert_to_integer_1 >>>>> gives us a FIX_TRUNC_EXPR. >>>>> >>>>> But then when we get to parsing f's parameters, we are in a template >>>>> when processing decltype(Helpers{}), and since r268321, when the >>>>> compound literal isn't instantiation-dependent and the type isn't >>>>> type-dependent, finish_compound_literal falls back to the normal >>>>> processing, so it calls digest_init, which does fold_non_dependent_init >>>>> and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and >>>>> therefore crash in tsubst_copy_and_build. >>>> >>>> Hmm, we shouldn't be doing fold_non_dependent_init on the result of >>>> get_nsdmi. Why does that happen? >>> >>> OK, so we have decltype(Helpers{}), finish_compound_literal gets >>> Helpers{}, it's not type-dependent, so: >>> >>> - call digest_init (type=Helpers, init={}) >>> init is BRACE_ENCLOSED_INITIALIZER_P, type is !TYPE_NON_AGGREGATE_CLASS >>> so go down to... >>> - process_init_constructor_record (type=Helpers, init={}) >>> - we walk the fields of Helpers, there's 'inputs' of type knob_t >>> type_build_ctor_call (knob_t) is true, we want to default-init this >>> field >>> - create a {} as the init for default-initialization >>> - call massage_init_elt (type=knob_t, init={}) to adjust the init >>> - we do so by calling digest_init_r (type=knob_t, init={}) >>> - here we again call process_init_constructor_record, walk knob_t's >>> fields, see the field 'value', it has a DECL_INITIAL, so call >>> get_nsdmi, that returns the FIX_TRUNC_EXPR we've created before >>> - so digesting {} for knob_t produced >>> init = {.value=(int) NON_LVALUE_EXPR <1.0e+0>} >>> - then we call fold_non_dependent_init on this init, and die >> >> Maybe we shouldn't call fold_non_dependent_init on a CONSTRUCTOR here, since >> presumably we already called it on elements that needed it in the recursive >> digest_init_r. > > Ah, that works. It's still a bit weird that we don't treat FLOAT_EXPR and > FIX_TRUNC_EXPR the same. > > I've tried to remove the call to fold_non_dependent_init in massage_init_elt > to see what breaks...a lot. So it has to stay at least in this form. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? OK. > Thanks, > > -- >8 -- > This is a crash where a FIX_TRUNC_EXPR gets into tsubst_copy_and_build > where it hits gcc_unreachable (). > > The history of tsubst_copy_and_build/FIX_TRUNC_EXPR is such that it > was introduced in r181478, but it did the wrong thing, whereupon it > was turned into gcc_unreachable () in r258821 (see this thread: > ). > > In a template, we should never create a FIX_TRUNC_EXPR (that's what > conv_unsafe_in_template_p is for). But in this test we are NOT in > a template when we call digest_nsdmi_init which ends up calling > convert_like, converting 1.0e+0 to int, so convert_to_integer_1 > gives us a FIX_TRUNC_EXPR. > > But then when we get to parsing f's parameters, we are in a template > when processing decltype(Helpers{}), and since r268321, when the > compound literal isn't instantiation-dependent and the type isn't > type-dependent, finish_compound_literal falls back to the normal > processing, so it calls digest_init, which does fold_non_dependent_init > and since the FIX_TRUNC_EXPR isn't dependent, we instantiate and > therefore crash in tsubst_copy_and_build. > > The fateful call to fold_non_dependent_init comes from massage_init_elt, > We shouldn't be calling f_n_d_i on the result of get_nsdmi. This we can > avoid by eschewing calling f_n_d_i on CONSTRUCTORs; their elements have > already been folded. > > PR c++/102990 > > gcc/cp/ChangeLog: > > * typeck2.cc (massage_init_elt): Avoid folding CONSTRUCTORs. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/nsdmi-template22.C: New test. > * g++.dg/cpp0x/nsdmi-template23.C: New test. > --- > gcc/cp/typeck2.cc | 13 +++++++++---- > gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C | 13 +++++++++++++ > gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C | 13 +++++++++++++ > 3 files changed, 35 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C > create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C > > diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc > index a4c825fc34d..cebe6acf487 100644 > --- a/gcc/cp/typeck2.cc > +++ b/gcc/cp/typeck2.cc > @@ -1433,10 +1433,15 @@ massage_init_elt (tree type, tree init, int nested, int flags, > new_flags |= LOOKUP_AGGREGATE_PAREN_INIT; > init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain); > /* When we defer constant folding within a statement, we may want to > - defer this folding as well. */ > - tree t = fold_non_dependent_init (init, complain); > - if (TREE_CONSTANT (t)) > - init = t; > + defer this folding as well. Don't call this on CONSTRUCTORs because > + their elements have already been folded, and we must avoid folding > + the result of get_nsdmi. */ > + if (TREE_CODE (init) != CONSTRUCTOR) > + { > + tree t = fold_non_dependent_init (init, complain); > + if (TREE_CONSTANT (t)) > + init = t; > + } > return init; > } > > diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C > new file mode 100644 > index 00000000000..4ed2501035c > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template22.C > @@ -0,0 +1,13 @@ > +// PR c++/102990 > +// { dg-do compile { target c++11 } } > + > +struct knob_t { > + /* Let's create a FIX_TRUNC_EXPR. */ > + int value = 1.0; > +}; > + > +struct Helpers { > + knob_t inputs; > +}; > + > +template void f(decltype(Helpers{})); > diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C > new file mode 100644 > index 00000000000..240cab4347a > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template23.C > @@ -0,0 +1,13 @@ > +// PR c++/102990 > +// { dg-do compile { target c++11 } } > + > +struct knob_t { > + /* Let's create a FLOAT_EXPR. */ > + double value = 1UL; > +}; > + > +struct Helpers { > + knob_t inputs; > +}; > + > +template void f(decltype(Helpers{})); > > base-commit: fb488cba571539b6644e8f99f1dd997cdb4c82c1