From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk1-x733.google.com (mail-qk1-x733.google.com [IPv6:2607:f8b0:4864:20::733]) by sourceware.org (Postfix) with ESMTPS id 8FACD3834E7A for ; Mon, 6 Jun 2022 19:39:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8FACD3834E7A Received: by mail-qk1-x733.google.com with SMTP id d128so3821065qkg.8 for ; Mon, 06 Jun 2022 12:39:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:content-transfer-encoding:mime-version :subject:message-id:date:to; bh=a/dI8NGMiS9k4WxPI4Qhdf91DNtUAjQwuVJwfAJFeCc=; b=5gVrqP9jRTIc34g8aKK9/pbkpfaObPLIRu1ulRWZmiTmy+jCIfOi+cJw3FrFeQu8Ft ZF5Jh3674AXi3ki757zCCxlFoAVaAdTx3do/RGyaw/rdWfbqpWlNCenyfthGTctmpDVP t5+pzLyj9x1EAfbC+auNx9eSGXgYd1FEWSutelD7d9GKk6xuXZokzeUVwYpjeFuWalHo b3j7zJtXzA50hhQKZ0uz21E5hcM209oDzUUhe/QMrzrCxZ45yVrR7k4mgCX+JUNUgBsZ 0//lQFdEdgc3mvla1mi++eI995tammsPK5zq78L2+8y9WBZpR/5zNjkCihLtC2a+MAtm DIxQ== X-Gm-Message-State: AOAM531p985NJgwSSy/Q3iGtPL/RhCxYaR+QKNqli4fl7Epa+IA79epl 875nMV7O+l+hgo6tlViLJlWy3zeIGrVqW3hL6HwEmgBMYtiwXul9PiwWPacgrT3XqCLcPBhK70+ T76YnR3OjbKXnpBUBUaKP/CjR17RK0wcSFC+jHudNf7ORj1e0MTMWOs83EGyDO5hL7aK8a/HElf JcTAZ2eAA= X-Google-Smtp-Source: ABdhPJxVElffv369+rM4wGSpt5bQYdQsmEYpRt0ceMVU9LTZlM9LEUqwfo0S21SNto1S5rRpnfiPvQ== X-Received: by 2002:a37:a285:0:b0:6a6:bdbb:5b30 with SMTP id l127-20020a37a285000000b006a6bdbb5b30mr4732727qke.414.1654544394592; Mon, 06 Jun 2022 12:39:54 -0700 (PDT) Received: from smtpclient.apple ([209.249.190.124]) by smtp.gmail.com with ESMTPSA id y14-20020a05622a164e00b00304c13ec6c8sm11300809qtj.30.2022.06.06.12.39.54 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Jun 2022 12:39:54 -0700 (PDT) From: Michael Colavita Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.120.0.1.13\)) Subject: [PATCH] Fix behavior of using enum in dependent contexts [PR105787] Message-Id: <16F04525-9B51-404E-B13D-4BF80F9DF473@hudson-trading.com> Date: Mon, 6 Jun 2022 15:39:53 -0400 To: gcc-patches@gcc.gnu.org X-Mailer: Apple Mail (2.3654.120.0.1.13) X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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 19:39:58 -0000 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. 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; =20 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 =3D=3D NULL_TREE) return scalar_constant_value (t); =20 + /* 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 =3D t; + if (CONST_DECL_USING_P (original)) + t =3D DECL_ABSTRACT_ORIGIN (original); + /* Unfortunately, we cannot just call lookup_name here. Consider: =20 @@ -16921,7 +16930,20 @@ tsubst_copy (tree t, tree args, tsubst_flags_t = complain, tree in_decl) v !=3D NULL_TREE; v =3D TREE_CHAIN (v)) if (TREE_PURPOSE (v) =3D=3D DECL_NAME (t)) - return TREE_VALUE (v); + { + tree value =3D TREE_VALUE (v); + if (!CONST_DECL_USING_P (original)) + return value; + else + { + value =3D copy_decl (value); + DECL_ARTIFICIAL (value) =3D true; + DECL_CONTEXT (value) =3D DECL_CONTEXT (original); + DECL_IGNORED_P (value) =3D true; + DECL_ABSTRACT_ORIGIN (value) =3D DECL_ABSTRACT_ORIGIN = (original); + return value; + } + } =20 /* 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 =3D (char) A::orange; + char a2 =3D (char) A::apple; + char b1 =3D (char) B::orange; // { dg-error "protected" } + char b2 =3D (char) B::apple; // { dg-error "protected" } + char c1 =3D (char) C::orange; // { dg-error "private" } + char c2 =3D (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 =3D (char) A::orange; + char a2 =3D (char) A::apple; + char b1 =3D (char) B::orange; // { dg-error "protected" } + char b2 =3D (char) B::apple; // { dg-error "protected" } + char c1 =3D (char) C::orange; // { dg-error "private" } + char c2 =3D (char) C::apple; // { dg-error "private" } +}; + +int main() { + D<0> d; +} --=20 2.23.0