public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Nathan Sidwell <nathan@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-6954] c++: header unit template alias merging [PR 98770] Date: Thu, 28 Jan 2021 12:57:43 +0000 (GMT) [thread overview] Message-ID: <20210128125743.BAFB8385B805@sourceware.org> (raw) https://gcc.gnu.org/g:af66f4f1b06f5e0c099dfced2fcf7b1b23fa53e7 commit r11-6954-gaf66f4f1b06f5e0c099dfced2fcf7b1b23fa53e7 Author: Nathan Sidwell <nathan@acm.org> Date: Thu Jan 28 04:48:33 2021 -0800 c++: header unit template alias merging [PR 98770] Typedefs are streamed by streaming the underlying type, and then recreating the typedef. But this breaks checking a duplicate is the same as the original when it is a template alias -- we end up checking a template alias (eg __void_t) against the underlying type (void). And those are not the same template alias. This stops pretendig that the underlying type is the typedef for that checking and tells is_matching_decl 'you have a typedef', so it knows what to do. (We do not want to recreate the typedef of the duplicate, because that whole set of nodes is going to go away.) PR c++/98770 gcc/cp/ * module.cc (trees_out::decl_value): Swap is_typedef & TYPE_NAME check order. (trees_in::decl_value): Do typedef frobbing only when installing a new typedef, adjust is_matching_decl call. Swap is_typedef & TYPE_NAME check. (trees_in::is_matching_decl): Add is_typedef parm. Adjust variable names and deal with typedef checking. gcc/testsuite/ * g++.dg/modules/pr98770_a.C: New. * g++.dg/modules/pr98770_b.C: New. Diff: --- gcc/cp/module.cc | 67 +++++++++++++++++--------------- gcc/testsuite/g++.dg/modules/pr98770_a.C | 10 +++++ gcc/testsuite/g++.dg/modules/pr98770_b.C | 12 ++++++ 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 18f5de8724b..daf75b16007 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -3029,7 +3029,7 @@ public: bool read_definition (tree decl); private: - bool is_matching_decl (tree existing, tree decl); + bool is_matching_decl (tree existing, tree decl, bool is_typedef); static bool install_implicit_member (tree decl); bool read_function_def (tree decl, tree maybe_template); bool read_var_def (tree decl, tree maybe_template); @@ -7864,8 +7864,8 @@ trees_out::decl_value (tree decl, depset *dep) || !dep == (VAR_OR_FUNCTION_DECL_P (inner) && DECL_LOCAL_DECL_P (inner))); else if ((TREE_CODE (inner) == TYPE_DECL - && TYPE_NAME (TREE_TYPE (inner)) == inner - && !is_typedef) + && !is_typedef + && TYPE_NAME (TREE_TYPE (inner)) == inner) || TREE_CODE (inner) == FUNCTION_DECL) { bool write_defn = !dep && has_definition (decl); @@ -8088,12 +8088,6 @@ trees_in::decl_value () && TREE_CODE (inner) == TYPE_DECL && DECL_ORIGINAL_TYPE (inner) && !TREE_TYPE (inner)); - if (is_typedef) - { - /* Frob it to be ready for cloning. */ - TREE_TYPE (inner) = DECL_ORIGINAL_TYPE (inner); - DECL_ORIGINAL_TYPE (inner) = NULL_TREE; - } existing = back_refs[~tag]; bool installed = install_entity (existing); @@ -8156,7 +8150,12 @@ trees_in::decl_value () } if (is_typedef) - set_underlying_type (inner); + { + /* Frob it to be ready for cloning. */ + TREE_TYPE (inner) = DECL_ORIGINAL_TYPE (inner); + DECL_ORIGINAL_TYPE (inner) = NULL_TREE; + set_underlying_type (inner); + } if (inner_tag) /* Set the TEMPLATE_DECL's type. */ @@ -8218,7 +8217,7 @@ trees_in::decl_value () /* Set the TEMPLATE_DECL's type. */ TREE_TYPE (decl) = TREE_TYPE (inner); - if (!is_matching_decl (existing, decl)) + if (!is_matching_decl (existing, decl, is_typedef)) unmatched_duplicate (existing); /* And our result is the existing node. */ @@ -8257,8 +8256,8 @@ trees_in::decl_value () if (inner && !NAMESPACE_SCOPE_P (inner) && ((TREE_CODE (inner) == TYPE_DECL - && TYPE_NAME (TREE_TYPE (inner)) == inner - && !is_typedef) + && !is_typedef + && TYPE_NAME (TREE_TYPE (inner)) == inner) || TREE_CODE (inner) == FUNCTION_DECL) && u ()) read_definition (decl); @@ -11088,7 +11087,7 @@ trees_in::binfo_mergeable (tree *type) decls_match because it can cause instantiations of constraints. */ bool -trees_in::is_matching_decl (tree existing, tree decl) +trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef) { // FIXME: We should probably do some duplicate decl-like stuff here // (beware, default parms should be the same?) Can we just call @@ -11099,35 +11098,36 @@ trees_in::is_matching_decl (tree existing, tree decl) // can elide some of the checking gcc_checking_assert (TREE_CODE (existing) == TREE_CODE (decl)); - tree inner = decl; + tree d_inner = decl; + tree e_inner = existing; if (TREE_CODE (decl) == TEMPLATE_DECL) { - inner = DECL_TEMPLATE_RESULT (decl); - gcc_checking_assert (TREE_CODE (DECL_TEMPLATE_RESULT (existing)) - == TREE_CODE (inner)); + d_inner = DECL_TEMPLATE_RESULT (d_inner); + e_inner = DECL_TEMPLATE_RESULT (e_inner); + gcc_checking_assert (TREE_CODE (e_inner) == TREE_CODE (d_inner)); } gcc_checking_assert (!map_context_from); /* This mapping requres the new decl on the lhs and the existing entity on the rhs of the comparitors below. */ - map_context_from = inner; - map_context_to = STRIP_TEMPLATE (existing); + map_context_from = d_inner; + map_context_to = e_inner; - if (TREE_CODE (inner) == FUNCTION_DECL) + if (TREE_CODE (d_inner) == FUNCTION_DECL) { tree e_ret = fndecl_declared_return_type (existing); tree d_ret = fndecl_declared_return_type (decl); - if (decl != inner && DECL_NAME (inner) == fun_identifier - && LAMBDA_TYPE_P (DECL_CONTEXT (inner))) + if (decl != d_inner && DECL_NAME (d_inner) == fun_identifier + && LAMBDA_TYPE_P (DECL_CONTEXT (d_inner))) /* This has a recursive type that will compare different. */; else if (!same_type_p (d_ret, e_ret)) goto mismatch; - tree e_type = TREE_TYPE (existing); - tree d_type = TREE_TYPE (decl); + tree e_type = TREE_TYPE (e_inner); + tree d_type = TREE_TYPE (d_inner); - if (DECL_EXTERN_C_P (decl) != DECL_EXTERN_C_P (existing)) + if (DECL_EXTERN_C_P (d_inner) != DECL_EXTERN_C_P (e_inner)) goto mismatch; for (tree e_args = TYPE_ARG_TYPES (e_type), @@ -11176,6 +11176,13 @@ trees_in::is_matching_decl (tree existing, tree decl) && !comp_except_specs (d_spec, e_spec, ce_type)) goto mismatch; } + else if (is_typedef) + { + if (!DECL_ORIGINAL_TYPE (e_inner) + || !same_type_p (DECL_ORIGINAL_TYPE (d_inner), + DECL_ORIGINAL_TYPE (e_inner))) + goto mismatch; + } /* Using cp_tree_equal because we can meet TYPE_ARGUMENT_PACKs here. I suspect the entities that directly do that are things that shouldn't go to duplicate_decls (FIELD_DECLs etc). */ @@ -11255,12 +11262,10 @@ trees_in::is_matching_decl (tree existing, tree decl) /* Don't instantiate again! */ DECL_TEMPLATE_INSTANTIATED (existing) = true; - tree e_inner = inner == decl ? existing : DECL_TEMPLATE_RESULT (existing); - - if (TREE_CODE (inner) == FUNCTION_DECL - && DECL_DECLARED_INLINE_P (inner)) + if (TREE_CODE (d_inner) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (d_inner)) DECL_DECLARED_INLINE_P (e_inner) = true; - if (!DECL_EXTERNAL (inner)) + if (!DECL_EXTERNAL (d_inner)) DECL_EXTERNAL (e_inner) = false; // FIXME: Check default tmpl and fn parms here diff --git a/gcc/testsuite/g++.dg/modules/pr98770_a.C b/gcc/testsuite/g++.dg/modules/pr98770_a.C new file mode 100644 index 00000000000..668ff2891ca --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr98770_a.C @@ -0,0 +1,10 @@ +// PR 98770 confused about duplicate template type aliases +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +module ; +# 6 __FILE__ 1 +template<typename> using __void_t = void; +# 8 "" 2 +export module Foo; + +export using B = __void_t<int>; diff --git a/gcc/testsuite/g++.dg/modules/pr98770_b.C b/gcc/testsuite/g++.dg/modules/pr98770_b.C new file mode 100644 index 00000000000..a4ab2376815 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr98770_b.C @@ -0,0 +1,12 @@ +// PR 98770 confused about duplicate template type aliases +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } + +module ; +# 6 __FILE__ 1 +template<typename> using __void_t = void; +# 8 "" 2 +export module Bar; + +import Foo; + +export B *b;
reply other threads:[~2021-01-28 12:57 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210128125743.BAFB8385B805@sourceware.org \ --to=nathan@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).