re PR c++/55877 (Anon visibility issues)
authorJason Merrill <jason@redhat.com>
Fri, 4 Jan 2013 16:50:28 +0000 (11:50 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 4 Jan 2013 16:50:28 +0000 (11:50 -0500)
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
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/ext/visibility/anon11.C [new file with mode: 0644]

index 0aef08d..1aecad0 100644 (file)
@@ -1,3 +1,11 @@
+2013-01-04  Jason Merrill  <jason@redhat.com>
+
+       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  <paolo.carlini@oracle.com>
 
        PR c++/54526 (again)
index 5c268b1..9640824 100644 (file)
@@ -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.  */
index 87b1f51..754e830 100644 (file)
@@ -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];
index c658582..fcab1a4 100644 (file)
@@ -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 (file)
index 0000000..dfb4f12
--- /dev/null
@@ -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;