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.
This commit is contained in:
parent
3f83845457
commit
47145e6916
3 changed files with 18 additions and 8 deletions
|
@ -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);
|
||||
|
|
9
gcc/testsuite/g++.dg/modules/pr99208_a.C
Normal file
9
gcc/testsuite/g++.dg/modules/pr99208_a.C
Normal file
|
@ -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;
|
4
gcc/testsuite/g++.dg/modules/pr99208_b.C
Normal file
4
gcc/testsuite/g++.dg/modules/pr99208_b.C
Normal file
|
@ -0,0 +1,4 @@
|
|||
// { dg-additional-options {-fmodules-ts} }
|
||||
export module hello;
|
||||
// { dg-module-cmi hello }
|
||||
export import :format;
|
Loading…
Add table
Reference in a new issue