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 B73743850432 for ; Mon, 6 Jun 2022 21:48:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B73743850432 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-492-PXxLB5mQMoKPzC7Jl2LDsg-1; Mon, 06 Jun 2022 17:48:03 -0400 X-MC-Unique: PXxLB5mQMoKPzC7Jl2LDsg-1 Received: by mail-qv1-f70.google.com with SMTP id o99-20020a0c906c000000b00456332167ffso9612748qvo.13 for ; Mon, 06 Jun 2022 14:48:03 -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:references:from:in-reply-to :content-transfer-encoding; bh=5sN6LJayOD9d+GAbUad7lQZbFtA59o98fcUDPxAvOzE=; b=keyhEMAeXU48Oky1ff8wquvINYRJDwDBwjghzgVjw9pXn5qRKQiJsjvRQwKg0W7Ek3 r8US1C2VlnU1Jx5XHuI9n8ocXD3SCp3+nTsGBJvQ6D78KvOSIrggufT0MIrJZD+qyqHY j5RR7Ahg6qWcqlDYdN+lSOlslW5CzmHju2o2rgcHAAXTTCNBKlrVLwGhAsgMXVRPp7nY BMs8IbUg63haPjY8F3usHKxATJL7WgkgQj/O14Sv3PNo8WaaYaideNMHGJgeP0ezW3Fy dDEbiPS+4T2IZliyAZUHY4B1Ia5ca3tD1sikpBx2ECYHBivjtNDY0Q4zkt1BwkP5KohD tgRA== X-Gm-Message-State: AOAM533nSF7UxVgkz20d7WeDxcRWUNcKT4V5uyiu3kcDbyLw2jd5FIbb UTNcaV/5cb0CP05yfskYDsPFC9TNLq6UBAXJQKgwaW6SXSV1V8zs5Dco3nxD0LRQ0gnyesSkq3t nvUrJeIwuOWc2VJrPLA== X-Received: by 2002:a05:622a:f:b0:304:ea08:4227 with SMTP id x15-20020a05622a000f00b00304ea084227mr7428338qtw.620.1654552082598; Mon, 06 Jun 2022 14:48:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzivrjzVdr/pef69N3qn+bo/TcHjdQrvTrcir8TRB7+2FLIJPhkDdTx+Hh2NCVwPUOyEv3jAA== X-Received: by 2002:a05:622a:f:b0:304:ea08:4227 with SMTP id x15-20020a05622a000f00b00304ea084227mr7428321qtw.620.1654552082224; Mon, 06 Jun 2022 14:48:02 -0700 (PDT) Received: from [192.168.1.100] (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 y19-20020a05620a44d300b006a6a4b43c01sm8423753qkp.38.2022.06.06.14.48.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 06 Jun 2022 14:48:01 -0700 (PDT) Message-ID: <481d5c23-3983-3c89-9d48-e74c97096c72@redhat.com> Date: Mon, 6 Jun 2022 17:48:01 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0 Subject: Re: [PATCH] Fix behavior of using enum in dependent contexts [PR105787] To: Michael Colavita , gcc-patches@gcc.gnu.org References: <16F04525-9B51-404E-B13D-4BF80F9DF473@hudson-trading.com> From: Jason Merrill In-Reply-To: <16F04525-9B51-404E-B13D-4BF80F9DF473@hudson-trading.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=-14.4 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, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Mon, 06 Jun 2022 21:48:06 -0000 On 6/6/22 15:39, Michael Colavita via Gcc-patches wrote: > Per #105787, "using enum" in a dependent context leads to an ICE. This > is because the type substitution logic doesn't properly juggle the > context and abstract origin for CONST_DECLs introduced via using enum. > When we are performing type substitution on the CONST_DECL, we want to > do so in the context of the original enum type. When we return the > resulting value, we want to replace the context with the class in which > the CONST_DECL exists. This amounts to using the abstract origin for the > type substitution, and performing the same clone/abstract origin update > as we do for parsing "using enum" in non-dependent contexts. Thanks for the patch! It looks like you don't have a copyright assignment on file, so we need you to certify the DCO in the commit message of your patch; see https://gcc.gnu.org/contribute.html#legal for more details. Also, per the section on e-mail subject lines further down in that page, you need a "c++:" tag in your subject line. > PR c++/105787 - internal compiler error: tree check: expected enumeral_type, have record_type in tsubst_copy > > PR c++/105787 > > gcc/cp/ChangeLog: > > * pt.cc (tsubst_copy): Handle CONST_DECLs involving "using enum" > in dependent contexts. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/using-enum-10.C: New test. > * g++.dg/cpp2a/using-enum-11.C: New test. > --- > gcc/cp/pt.cc | 24 +++++++++++++- > gcc/testsuite/g++.dg/cpp2a/using-enum-10.C | 35 ++++++++++++++++++++ > gcc/testsuite/g++.dg/cpp2a/using-enum-11.C | 38 ++++++++++++++++++++++ > 3 files changed, 96 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/using-enum-10.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/using-enum-11.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 6de8e496859..c11c682ded7 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -16892,6 +16892,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) > { > tree enum_type; > tree v; > + tree original; Note that existing variable declarations at the beginning of the block are vestiges of when GCC was written in C; now that we can write C++11, it's better to declare variables at the point when they are first initialized. > if (DECL_TEMPLATE_PARM_P (t)) > return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); > @@ -16903,6 +16904,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) > if (args == NULL_TREE) > return scalar_constant_value (t); > > + /* When the CONST_DECL is a class-scope clone from using enum, we want > + to perform the type substitution in the context of the original enum > + (the abstract origin), but return a value in the context of the > + class. */ > + original = t; > + if (CONST_DECL_USING_P (original)) > + t = DECL_ABSTRACT_ORIGIN (original); > + > /* Unfortunately, we cannot just call lookup_name here. > Consider: > > @@ -16921,7 +16930,20 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) > v != NULL_TREE; > v = TREE_CHAIN (v)) > if (TREE_PURPOSE (v) == DECL_NAME (t)) > - return TREE_VALUE (v); > + { > + tree value = TREE_VALUE (v); > + if (!CONST_DECL_USING_P (original)) > + return value; > + else > + { > + value = copy_decl (value); > + DECL_ARTIFICIAL (value) = true; > + DECL_CONTEXT (value) = DECL_CONTEXT (original); > + DECL_IGNORED_P (value) = true; > + DECL_ABSTRACT_ORIGIN (value) = DECL_ABSTRACT_ORIGIN (original); > + return value; We shouldn't be creating new decls in tsubst_copy, which is called for uses of a decl in an expression; if instantiate_class_template (calling tsubst_decl) is doing something wrong when instantiating the clone, that's the place to fix it. > + } > + } > > /* We didn't find the name. That should never happen; if > name-lookup found it during preliminary parsing, we > diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-10.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-10.C > new file mode 100644 > index 00000000000..ab4cb648e03 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-10.C > @@ -0,0 +1,35 @@ > +// PR c++/105787 > +// { dg-do compile { target c++20 } } > + > +enum class fruit { orange, apple }; > + > +struct A { > +public: > + using enum fruit; > +private: > +}; > + > +struct B { > +protected: > + using enum fruit; > +public: > +}; > + > +struct C { > +private: > + using enum fruit; > +public: > +}; > + > +template struct D { > + char a1 = (char) A::orange; > + char a2 = (char) A::apple; > + char b1 = (char) B::orange; // { dg-error "protected" } > + char b2 = (char) B::apple; // { dg-error "protected" } > + char c1 = (char) C::orange; // { dg-error "private" } > + char c2 = (char) C::apple; // { dg-error "private" } > +}; > + > +int main() { > + D<0> d; > +} > diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-11.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-11.C > new file mode 100644 > index 00000000000..1899e05c68d > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-11.C > @@ -0,0 +1,38 @@ > +// PR c++/105787 > +// { dg-do compile { target c++20 } } > + > +enum class fruit { orange, apple }; > + > +struct A { > +public: > + using fruit::apple; > + using fruit::orange; > +private: > +}; > + > +struct B { > +protected: > + using fruit::apple; > + using fruit::orange; > +public: > +}; > + > +struct C { > +private: > + using fruit::apple; > + using fruit::orange; > +public: > +}; > + > +template struct D { > + char a1 = (char) A::orange; > + char a2 = (char) A::apple; > + char b1 = (char) B::orange; // { dg-error "protected" } > + char b2 = (char) B::apple; // { dg-error "protected" } > + char c1 = (char) C::orange; // { dg-error "private" } > + char c2 = (char) C::apple; // { dg-error "private" } > +}; > + > +int main() { > + D<0> d; > +}