From 47145e6916f58e1cd4f562c06fa7289da49f690c Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 23 Feb 2021 07:08:55 -0800 Subject: [PATCH] c++: typedef for linkage [PR 99208] Unnamed types with a typedef name for linkage were always troublesome in modules. This is the underlying cause of that trouble -- we were creating incorrect type structures. Classes have an implicit self-reference, and we created that for unnamed classes too. It turns out we make use of this member, so just not generating it turned into a rathole. This member is created using the anonymous name -- because we've not yet met the typedef name. When we retrofit the typedef name we were checking identifier matching and changing all type variants with that identifier. Which meant we ended up with a strange typedef for the self reference. This fixes things to check for DECL identity of the variants, so we don't smash the self-reference -- that continues to have the anonymous name. PR c++/99208 gcc/cp/ * decl.c (name_unnamed_type): Check DECL identity, not IDENTIFIER identity. gcc/testsuite/ * g++.dg/modules/pr99208_a.C: New. * g++.dg/modules/pr99208_b.C: New. --- gcc/cp/decl.c | 13 +++++-------- gcc/testsuite/g++.dg/modules/pr99208_a.C | 9 +++++++++ gcc/testsuite/g++.dg/modules/pr99208_b.C | 4 ++++ 3 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/pr99208_a.C create mode 100644 gcc/testsuite/g++.dg/modules/pr99208_b.C diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7fa8f52..1742e28 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11081,21 +11081,18 @@ name_unnamed_type (tree type, tree decl) { gcc_assert (TYPE_UNNAMED_P (type)); - /* Replace the anonymous name with the real name everywhere. */ + /* Replace the anonymous decl with the real decl. Be careful not to + rename other typedefs (such as the self-reference) of type. */ + tree orig = TYPE_NAME (type); for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - if (IDENTIFIER_ANON_P (TYPE_IDENTIFIER (t))) - /* We do not rename the debug info representing the unnamed - tagged type because the standard says in [dcl.typedef] that - the naming applies only for linkage purposes. */ - /*debug_hooks->set_name (t, decl);*/ + if (TYPE_NAME (t) == orig) TYPE_NAME (t) = decl; /* If this is a typedef within a template class, the nested type is a (non-primary) template. The name for the template needs updating as well. */ if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type)) - DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) - = TYPE_IDENTIFIER (type); + DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) = DECL_NAME (decl); /* Adjust linkage now that we aren't unnamed anymore. */ reset_type_linkage (type); diff --git a/gcc/testsuite/g++.dg/modules/pr99208_a.C b/gcc/testsuite/g++.dg/modules/pr99208_a.C new file mode 100644 index 0000000..427c7f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99208_a.C @@ -0,0 +1,9 @@ +// PR 99208 typedef anonymous class +// { dg-additional-options {-Wno-pedantic -fmodules-ts} } +module; +# 5 "pr99208_a.C" 1 +typedef struct {} __mbstate_t; +# 7 "" 2 +export module hello:format; +// { dg-module-cmi {hello:format} } +export __mbstate_t v; diff --git a/gcc/testsuite/g++.dg/modules/pr99208_b.C b/gcc/testsuite/g++.dg/modules/pr99208_b.C new file mode 100644 index 0000000..0ed68d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr99208_b.C @@ -0,0 +1,4 @@ +// { dg-additional-options {-fmodules-ts} } +export module hello; +// { dg-module-cmi hello } +export import :format; -- 2.7.4