From 82f2836c6e0eab99dc2ed4d761fbc611408902a1 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 4 Jan 2013 11:50:28 -0500 Subject: [PATCH] re PR c++/55877 (Anon visibility issues) PR c++/55877 * decl.c (reset_type_linkage, bt_reset_linkage): New. (grokdeclarator): Use reset_type_linkage. * name-lookup.c (binding_table_foreach): Handle null table. * tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME. From-SVN: r194910 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/decl.c | 20 ++++++++++++++++++-- gcc/cp/name-lookup.c | 6 +++++- gcc/cp/tree.c | 2 +- gcc/testsuite/g++.dg/ext/visibility/anon11.C | 13 +++++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/visibility/anon11.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0aef08d..1aecad0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2013-01-04 Jason Merrill + + PR c++/55877 + * decl.c (reset_type_linkage, bt_reset_linkage): New. + (grokdeclarator): Use reset_type_linkage. + * name-lookup.c (binding_table_foreach): Handle null table. + * tree.c (decl_anon_ns_mem_p): Check TYPE_MAIN_DECL, not TYPE_NAME. + 2013-01-04 Paolo Carlini PR c++/54526 (again) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5c268b1..9640824 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8513,6 +8513,23 @@ check_var_type (tree identifier, tree type) return type; } +/* Functions for adjusting the visibility of a tagged type and its nested + types when it gets a name for linkage purposes from a typedef. */ + +static void bt_reset_linkage (binding_entry, void *); +static void +reset_type_linkage (tree type) +{ + set_linkage_according_to_type (type, TYPE_MAIN_DECL (type)); + if (CLASS_TYPE_P (type)) + binding_table_foreach (CLASSTYPE_NESTED_UTDS (type), bt_reset_linkage, NULL); +} +static void +bt_reset_linkage (binding_entry b, void */*data*/) +{ + reset_type_linkage (b->type); +} + /* Given declspecs and a declarator (abstract or otherwise), determine the name and type of the object declared and construct a DECL node for it. @@ -10053,8 +10070,7 @@ grokdeclarator (const cp_declarator *declarator, = TYPE_IDENTIFIER (type); /* Adjust linkage now that we aren't anonymous anymore. */ - set_linkage_according_to_type (type, TYPE_MAIN_DECL (type)); - determine_visibility (TYPE_MAIN_DECL (type)); + reset_type_linkage (type); /* FIXME remangle member functions; member functions of a type with external linkage have external linkage. */ diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 87b1f51..754e830 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -251,9 +251,13 @@ binding_table_find (binding_table table, tree name) void binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data) { - const size_t chain_count = table->chain_count; + size_t chain_count; size_t i; + if (!table) + return; + + chain_count = table->chain_count; for (i = 0; i < chain_count; ++i) { binding_entry entry = table->chain[i]; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index c658582..fcab1a4 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2404,7 +2404,7 @@ decl_anon_ns_mem_p (const_tree decl) /* Classes and namespaces inside anonymous namespaces have TREE_PUBLIC == 0, so we can shortcut the search. */ else if (TYPE_P (decl)) - return (TREE_PUBLIC (TYPE_NAME (decl)) == 0); + return (TREE_PUBLIC (TYPE_MAIN_DECL (decl)) == 0); else if (TREE_CODE (decl) == NAMESPACE_DECL) return (TREE_PUBLIC (decl) == 0); else diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon11.C b/gcc/testsuite/g++.dg/ext/visibility/anon11.C new file mode 100644 index 0000000..dfb4f12 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/anon11.C @@ -0,0 +1,13 @@ +// PR c++/55877 +// { dg-final { scan-assembler-not "\\.local" } } + +typedef struct { + typedef enum { X, Y } A; + typedef struct { } B; + struct C { }; +} D; + +D d; +D::A a; +D::B b; +D::C c; -- 2.7.4