class.c (build_vtable): Do not set DECL_VISIBILITY here.
authorMark Mitchell <mark@codesourcery.com>
Wed, 4 Aug 2004 05:27:52 +0000 (05:27 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 4 Aug 2004 05:27:52 +0000 (05:27 +0000)
* class.c (build_vtable): Do not set DECL_VISIBILITY here.
(check_field_decls): Or here.
(check_methods): Or here.
(initialize_array): Don't mess with DECL_CONTEXT.
* cp-tree.h (start_decl): Adjust prototype.
(determine_visibility): New function.
* decl.c (duplicate_decls): Remove checks for hidden "operator
new".
(build_library_fn_1): Give all library functions default
visibility.
(start_decl): Add pop_scope_p parameter.  Tidy.
(cp_finish_decl): Do not pop scopes here.  Call
determine_visibility for variable definitions.
(start_preparsed_function): Call determine_visibility.
* decl2.c (determine_visibility): New function.
* method.c (use_thunk): Fix formatting.
* parser.c (cp_parser_condition): Adjust calls to start_decl.
(cp_parser_init_declarator): Likewise.
* pt.c (instantiate_decl): Always call pop_nested_class.
* rtti.c (get_tinfo_decl): Do not set DECL_VISIBILITY.
(tinfo_base_init): Likewise.

* g++.dg/ext/visibility/assign1.C: New test.
* g++.dg/ext/visibility/new1.C: Likewise.

From-SVN: r85543

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/method.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/testsuite/g++.dg/ext/visibility/assign1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/visibility/new1.C [new file with mode: 0644]

index d87b4827aee2fc5c695eecf84fa382be48404a5a..e82e5005d00b78885d31146115e61fc6b2148298 100644 (file)
@@ -1,3 +1,27 @@
+2004-08-03  Mark Mitchell  <mark@codesourcery.com>
+
+       * class.c (build_vtable): Do not set DECL_VISIBILITY here.
+       (check_field_decls): Or here.
+       (check_methods): Or here.
+       (initialize_array): Don't mess with DECL_CONTEXT.
+       * cp-tree.h (start_decl): Adjust prototype.
+       (determine_visibility): New function.
+       * decl.c (duplicate_decls): Remove checks for hidden "operator
+       new".
+       (build_library_fn_1): Give all library functions default
+       visibility.
+       (start_decl): Add pop_scope_p parameter.  Tidy.
+       (cp_finish_decl): Do not pop scopes here.  Call
+       determine_visibility for variable definitions.
+       (start_preparsed_function): Call determine_visibility.
+       * decl2.c (determine_visibility): New function.
+       * method.c (use_thunk): Fix formatting.
+       * parser.c (cp_parser_condition): Adjust calls to start_decl.
+       (cp_parser_init_declarator): Likewise.
+       * pt.c (instantiate_decl): Always call pop_nested_class.
+       * rtti.c (get_tinfo_decl): Do not set DECL_VISIBILITY.
+       (tinfo_base_init): Likewise.
+
 2004-08-02  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/16707
index 365febbb7040ecd9a8cecc7bb8f433d2d22da908..e0bae52179f65981a008d888804568085e69b076 100644 (file)
@@ -659,11 +659,6 @@ build_vtable (tree class_type, tree name, tree vtable_type)
        require more intrusive changes to the g++ front end.  */
     DECL_IGNORED_P (decl) = 1;
 
-  /* The vtable's visibility is the class visibility.  There is no way
-     to override the visibility for just the vtable. */
-  DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
-  DECL_VISIBILITY_SPECIFIED (decl) = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
-
   return decl;
 }
 
@@ -2971,25 +2966,7 @@ check_field_decls (tree t, tree *access_decls,
        continue;
          
       if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
-       {
-         /* Apply the class's visibility attribute to static members
-            which do not have a visibility attribute. */
-         if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x)))
-            {
-              if (visibility_options.inlines_hidden && DECL_INLINE (x))
-                {
-                  DECL_VISIBILITY (x) = VISIBILITY_HIDDEN;
-                  DECL_VISIBILITY_SPECIFIED (x) = 1;
-                }
-              else
-                {
-                  DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type);
-                  DECL_VISIBILITY_SPECIFIED (x) = CLASSTYPE_VISIBILITY_SPECIFIED (current_class_type);
-                }
-            }
-
-         continue;
-       }
+       continue;
 
       /* Now it can only be a FIELD_DECL.  */
 
@@ -3744,23 +3721,6 @@ check_methods (tree t)
       check_for_override (x, t);
       if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
        cp_error_at ("initializer specified for non-virtual method `%D'", x);
-      /* Apply the class's visibility attribute to methods which do
-        not have a visibility attribute. */
-      if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x)))
-        {
-          if (visibility_options.inlines_hidden && DECL_INLINE (x))
-            {
-              DECL_VISIBILITY (x) = VISIBILITY_HIDDEN;
-              DECL_VISIBILITY_SPECIFIED (x) = 1;
-            }
-          else
-            {
-              DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type);
-              DECL_VISIBILITY_SPECIFIED (x) = CLASSTYPE_VISIBILITY_SPECIFIED (current_class_type);
-            }
-        }
-
       /* The name of the field is the original field name
         Save this in auxiliary field for later overloading.  */
       if (DECL_VINDEX (x))
@@ -6740,13 +6700,8 @@ initialize_vtable (tree binfo, tree inits)
 static void
 initialize_array (tree decl, tree inits)
 {
-  tree context;
-
-  context = DECL_CONTEXT (decl);
-  DECL_CONTEXT (decl) = NULL_TREE;
   DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
   cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
-  DECL_CONTEXT (decl) = context;
 }
 
 /* Build the VTT (virtual table table) for T.
index cdb67063f3ae773260f39d98b03d8fb077ce7c54..5b4992562386f34db78e7e4c3f8a824c68c6f0a0 100644 (file)
@@ -3740,7 +3740,7 @@ extern int init_type_desc                 (void);
 extern tree check_tag_decl                     (cp_decl_specifier_seq *);
 extern tree shadow_tag                         (cp_decl_specifier_seq *);
 extern tree groktypename                       (cp_decl_specifier_seq *, const cp_declarator *);
-extern tree start_decl                         (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree);
+extern tree start_decl                         (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, bool *);
 extern void start_decl_1                       (tree);
 extern void cp_finish_decl                     (tree, tree, tree, int);
 extern void finish_decl                                (tree, tree, tree);
@@ -3825,6 +3825,7 @@ extern tree finish_table (tree, tree, tree, int);
 extern tree coerce_new_type (tree);
 extern tree coerce_delete_type (tree);
 extern void comdat_linkage (tree);
+extern void determine_visibility (tree);
 extern void import_export_decl (tree);
 extern tree build_cleanup                      (tree);
 extern tree build_offset_ref_call_from_tree     (tree, tree);
index c4755c0c7b042efd919cc2f94699c2ca6eef8d5b..8c85e71003d24cb5298674f382d761aca2f84804 100644 (file)
@@ -1881,11 +1881,12 @@ duplicate_decls (tree newdecl, tree olddecl)
   COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
 
   /* Warn about conflicting visibility specifications.  */
-  if (DECL_VISIBILITY_SPECIFIED (olddecl) && DECL_VISIBILITY_SPECIFIED (newdecl)
+  if (DECL_VISIBILITY_SPECIFIED (olddecl) 
+      && DECL_VISIBILITY_SPECIFIED (newdecl)
       && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
     {
       warning ("%J'%D': visibility attribute ignored because it",
-        newdecl, newdecl);
+              newdecl, newdecl);
       warning ("%Jconflicts with previous declaration here", olddecl);
     }
   /* Choose the declaration which specified visibility.  */
@@ -1894,21 +1895,6 @@ duplicate_decls (tree newdecl, tree olddecl)
       DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
       DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
     }
-  /* If it's a definition of a global operator new or operator
-     delete, it must be default visibility.  */
-  if (NEW_DELETE_OPNAME_P (DECL_NAME (newdecl)) && DECL_INITIAL (newdecl) != NULL_TREE)
-    {
-      if (!DECL_FUNCTION_MEMBER_P (newdecl) && VISIBILITY_DEFAULT != DECL_VISIBILITY (newdecl))
-        {
-          warning ("%J`%D': ignoring non-default symbol",
-            newdecl, newdecl);
-          warning ("%Jvisibility on global operator new or delete", newdecl);
-          DECL_VISIBILITY (olddecl) = VISIBILITY_DEFAULT;
-          DECL_VISIBILITY_SPECIFIED (olddecl) = 1;
-          DECL_VISIBILITY (newdecl) = VISIBILITY_DEFAULT;
-          DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
-        }
-    }
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
@@ -3276,6 +3262,10 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
   TREE_NOTHROW (fn) = 1;
   SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);
   SET_DECL_LANGUAGE (fn, lang_c);
+  /* Runtime library routines are, by definition, available in an
+     external shared object.  */
+  DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
+  DECL_VISIBILITY_SPECIFIED (fn) = 1;
   return fn;
 }
 
@@ -3607,7 +3597,8 @@ start_decl (const cp_declarator *declarator,
            cp_decl_specifier_seq *declspecs,
             int initialized,
             tree attributes,
-            tree prefix_attributes)
+            tree prefix_attributes, 
+           bool *pop_scope_p)
 {
   tree decl;
   tree type, tem;
@@ -3642,14 +3633,11 @@ start_decl (const cp_declarator *declarator,
 
   context = DECL_CONTEXT (decl);
 
-  if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL
-      && context != current_namespace && TREE_CODE (decl) == VAR_DECL)
-    {
-      /* When parsing the initializer, lookup should use the object's
-        namespace.  */
-      push_decl_namespace (context);
-    }
-
+  if (context)
+    *pop_scope_p = push_scope (context);
+  else
+    *pop_scope_p = false;
+  
   /* We are only interested in class contexts, later.  */
   if (context && TREE_CODE (context) == NAMESPACE_DECL)
     context = NULL_TREE;
@@ -3705,8 +3693,6 @@ start_decl (const cp_declarator *declarator,
 
   if (context && COMPLETE_TYPE_P (complete_type (context)))
     {
-      push_nested_class (context);
-
       if (TREE_CODE (decl) == VAR_DECL)
        {
          tree field = lookup_field (context, DECL_NAME (decl), 0, false);
@@ -4715,20 +4701,10 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
       && (DECL_INITIAL (decl) || init))
     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
 
-  if (TREE_CODE (decl) == VAR_DECL
-      && DECL_CONTEXT (decl)
-      && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL
-      && DECL_CONTEXT (decl) != current_namespace
-      && init)
-    {
-      /* Leave the namespace of the object.  */
-      pop_decl_namespace ();
-    }
-
   type = TREE_TYPE (decl);
 
   if (type == error_mark_node)
-    goto finish_end0;
+    goto finish_end;
 
   if (TYPE_HAS_MUTABLE_P (type))
     TREE_READONLY (decl) = 0;
@@ -4745,7 +4721,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          && !DECL_PRETTY_FUNCTION_P (decl)
          && !dependent_type_p (TREE_TYPE (decl)))
        maybe_deduce_size_from_array_init (decl, init);
-      goto finish_end0;
+      goto finish_end;
     }
 
   /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
@@ -4833,6 +4809,9 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          /* Remember that the initialization for this variable has
             taken place.  */
          DECL_INITIALIZED_P (decl) = 1;
+         /* The variable is being defined, so determine its
+            visibility.  */
+         determine_visibility (decl);
        }
       /* If the variable has an array type, lay out the type, even if
         there is no initializer.  It is valid to index through the
@@ -4899,26 +4878,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          if (TREE_STATIC (decl))
            expand_static_init (decl, init);
        }
-    finish_end0:
-
-      /* Undo call to `pushclass' that was done in `start_decl'
-        due to initialization of qualified member variable.
-        I.e., Foo::x = 10;  */
-      {
-       tree context = CP_DECL_CONTEXT (decl);
-       if (context
-           && TYPE_P (context)
-           && (TREE_CODE (decl) == VAR_DECL
-               /* We also have a pushclass done that we need to undo here
-                  if we're at top level and declare a method.  */
-               || TREE_CODE (decl) == FUNCTION_DECL)
-           /* If size hasn't been set, we're still defining it,
-              and therefore inside the class body; don't pop
-              the binding level..  */
-           && COMPLETE_TYPE_P (context)
-           && context == current_class_type)
-         pop_nested_class ();
-      }
     }
 
   /* If a CLEANUP_STMT was created to destroy a temporary bound to a
@@ -9663,6 +9622,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       && lookup_attribute ("noinline", attrs))
     warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
 
+  /* Determine the ELF visibility attribute for the function.  */
+  determine_visibility (decl1);
+
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
     /* This is a constructor, we must ensure that any default args
        introduced by this definition are propagated to the clones
index 40322ab31cc4e5362a5a6c60a73b380db33b94db..53060dd16faff1e9e3a1f3f2c14091b3eb1920e5 100644 (file)
@@ -1616,6 +1616,59 @@ maybe_emit_vtables (tree ctype)
   return true;
 }
 
+/* Determine the ELF symbol visibility for DECL.  */
+
+void
+determine_visibility (tree decl)
+{
+  tree class_type;
+
+  /* Cloned constructors and destructors get the same visibility as
+     the underlying function.  That should be set up in
+     maybe_clone_body.  */
+  if (DECL_CLONED_FUNCTION_P (decl))
+    return;
+
+  if (DECL_CLASS_SCOPE_P (decl))
+    class_type = DECL_CONTEXT (decl);
+  else if (TREE_CODE (decl) == VAR_DECL
+          && DECL_TINFO_P (decl)
+          && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl))))
+    class_type = TREE_TYPE (DECL_NAME (decl));
+  else
+    {
+      /* Virtual tables have DECL_CONTEXT set to their associated class,
+        so they are automatically handled above.  */
+      my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL
+                           && DECL_VTABLE_OR_VTT_P (decl)), 20040803);
+      /* Entities not associated with any class just get the
+        visibility specified by their attributes.  */
+      return;
+    }
+
+  /* By default, static data members and function members receive
+     the visibility of their containing class.  */
+  if (class_type
+      && (TREE_CODE (decl) == VAR_DECL 
+         || TREE_CODE (decl) == FUNCTION_DECL)
+      && !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
+    {
+      if (TREE_CODE (decl) == FUNCTION_DECL
+         && DECL_DECLARED_INLINE_P (decl)
+         && visibility_options.inlines_hidden)
+       {
+         DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+         DECL_VISIBILITY_SPECIFIED (decl) = 1;
+       }
+      else
+       {
+         DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+         DECL_VISIBILITY_SPECIFIED (decl)
+           = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
+       }
+    }
+}
+
 /* DECL is a FUNCTION_DECL or VAR_DECL.  If the object file linkage
    for DECL has not already been determined, do so now by setting
    DECL_EXTERNAL, DECL_COMDAT and other related flags.  Until this
index d741d3d3cd1e3b719d21cda2a62b020e1467dded..7a2a7624fd809d6616d6230d4229f38b9c213dac 100644 (file)
@@ -368,7 +368,8 @@ use_thunk (tree thunk_fndecl, bool emit_p)
      rewrite.  */
   TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
   DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
-  DECL_VISIBILITY_SPECIFIED (thunk_fndecl) = DECL_VISIBILITY_SPECIFIED (function);
+  DECL_VISIBILITY_SPECIFIED (thunk_fndecl) 
+    = DECL_VISIBILITY_SPECIFIED (function);
   if (flag_weak && TREE_PUBLIC (thunk_fndecl))
     comdat_linkage (thunk_fndecl);
 
index f19ab252e27d28924a3c2a667646b59761643bb2..d6aadb37cd783afcb8a15ab51e383c88bfa4ef38 100644 (file)
@@ -6312,10 +6312,13 @@ cp_parser_condition (cp_parser* parser)
         for sure.  */
       if (cp_parser_parse_definitely (parser))
        {
+         bool pop_p;
+
          /* Create the declaration.  */
          decl = start_decl (declarator, &type_specifiers,
                             /*initialized_p=*/true,
-                            attributes, /*prefix_attributes=*/NULL_TREE);
+                            attributes, /*prefix_attributes=*/NULL_TREE,
+                            &pop_p);
          /* Parse the assignment-expression.  */
          initializer = cp_parser_assignment_expression (parser);
 
@@ -6324,6 +6327,8 @@ cp_parser_condition (cp_parser* parser)
                          initializer,
                          asm_specification,
                          LOOKUP_ONLYCONVERTING);
+         if (pop_p)
+           pop_scope (DECL_CONTEXT (decl));
 
          return convert_from_reference (decl);
        }
@@ -10630,12 +10635,12 @@ cp_parser_init_declarator (cp_parser* parser,
          have_extern_spec = false;
        }
       decl = start_decl (declarator, decl_specifiers,
-                        is_initialized, attributes, prefix_attributes);
+                        is_initialized, attributes, prefix_attributes,
+                        &pop_p);
     }
-
-  /* Enter the SCOPE.  That way unqualified names appearing in the
-     initializer will be looked up in SCOPE.  */
-  if (scope)
+  else if (scope)
+    /* Enter the SCOPE.  That way unqualified names appearing in the
+       initializer will be looked up in SCOPE.  */
     pop_p = push_scope (scope);
 
   /* Perform deferred access control checks, now that we know in which
@@ -10682,17 +10687,12 @@ cp_parser_init_declarator (cp_parser* parser,
     if (cp_parser_attributes_opt (parser))
       warning ("attributes after parenthesized initializer ignored");
 
-  /* Leave the SCOPE, now that we have processed the initializer.  It
-     is important to do this before calling cp_finish_decl because it
-     makes decisions about whether to create DECL_EXPRs or not based
-     on the current scope.  */
-  if (pop_p)
-    pop_scope (scope);
-
   /* For an in-class declaration, use `grokfield' to create the
      declaration.  */
   if (member_p)
     {
+      if (pop_p)
+       pop_scope (scope);
       decl = grokfield (declarator, decl_specifiers,
                        initializer, /*asmspec=*/NULL_TREE,
                        /*attributes=*/NULL_TREE);
@@ -10703,15 +10703,19 @@ cp_parser_init_declarator (cp_parser* parser,
   /* Finish processing the declaration.  But, skip friend
      declarations.  */
   if (!friend_p && decl)
-    cp_finish_decl (decl,
-                   initializer,
-                   asm_specification,
-                   /* If the initializer is in parentheses, then this is
-                      a direct-initialization, which means that an
-                      `explicit' constructor is OK.  Otherwise, an
-                      `explicit' constructor cannot be used.  */
-                   ((is_parenthesized_init || !is_initialized)
+    {
+      cp_finish_decl (decl,
+                     initializer,
+                     asm_specification,
+                     /* If the initializer is in parentheses, then this is
+                        a direct-initialization, which means that an
+                        `explicit' constructor is OK.  Otherwise, an
+                        `explicit' constructor cannot be used.  */
+                     ((is_parenthesized_init || !is_initialized)
                     ? 0 : LOOKUP_ONLYCONVERTING));
+      if (pop_p)
+       pop_scope (DECL_CONTEXT (decl));
+    }
 
   /* Remember whether or not variables were initialized by
      constant-expressions.  */
index 1e9bbb131227989f6fa93ca5c9c0d69c301e40a2..14b0c837cf24a9bea4a21a25c20a5015b5d1bdba 100644 (file)
@@ -11162,20 +11162,13 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
         we have a chance to determine linkage.  */
       DECL_EXTERNAL (d) = 0;
 
-      /* This is done in analogous to `start_decl'.  It is required
-        for correct access checking.  */
+      /* Enter the scope of D so that access-checking works correctly.  */
       push_nested_class (DECL_CONTEXT (d));
       cp_finish_decl (d, 
                      (!DECL_INITIALIZED_IN_CLASS_P (d) 
                       ? DECL_INITIAL (d) : NULL_TREE),
                      NULL_TREE, 0);
-      /* Normally, pop_nested_class is called by cp_finish_decl above.
-        But when instantiate_decl is triggered during
-        instantiate_class_template processing, its DECL_CONTEXT is
-        still not completed yet, and pop_nested_class isn't
-        called.  */
-      if (!COMPLETE_TYPE_P (DECL_CONTEXT (d)))
-       pop_nested_class ();
+      pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
     {
index 83e24c4e21c28aec70e87eaf17464ea5a3f72bb1..a59af79460b1f10c9bade3ffeaaa15932dd02906 100644 (file)
@@ -346,6 +346,8 @@ get_tinfo_decl (tree type)
 
       d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
       SET_DECL_ASSEMBLER_NAME (d, name);
+      /* Remember the type it is for.  */
+      TREE_TYPE (name) = type;
       DECL_TINFO_P (d) = 1;
       DECL_ARTIFICIAL (d) = 1;
       TREE_READONLY (d) = 1;
@@ -354,20 +356,11 @@ get_tinfo_decl (tree type)
         define it later if we need to do so.  */
       DECL_EXTERNAL (d) = 1;
       DECL_NOT_REALLY_EXTERN (d) = 1;
+      if (CLASS_TYPE_P (type))
+       CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
       set_linkage_according_to_type (type, d);
-
       pushdecl_top_level_and_finish (d, NULL_TREE);
 
-      if (CLASS_TYPE_P (type))
-       {
-         CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
-         DECL_VISIBILITY (d) = CLASSTYPE_VISIBILITY (type);
-         DECL_VISIBILITY_SPECIFIED (d) = CLASSTYPE_VISIBILITY_SPECIFIED (type);
-       }
-
-      /* Remember the type it is for.  */
-      TREE_TYPE (name) = type;
-
       /* Add decl to the global array of tinfo decls.  */
       my_friendly_assert (unemitted_tinfo_decls != 0, 20030312);
       VARRAY_PUSH_TREE (unemitted_tinfo_decls, d);
@@ -791,18 +784,12 @@ tinfo_base_init (tree desc, tree target)
     TREE_TYPE (name_name) = target;
 
     name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
-    
+    SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
     DECL_ARTIFICIAL (name_decl) = 1;
     TREE_READONLY (name_decl) = 1;
     TREE_STATIC (name_decl) = 1;
     DECL_EXTERNAL (name_decl) = 0;
     DECL_TINFO_P (name_decl) = 1;
-    if (CLASS_TYPE_P (target))
-      {
-        DECL_VISIBILITY (name_decl) = CLASSTYPE_VISIBILITY (target);
-        DECL_VISIBILITY_SPECIFIED (name_decl) 
-         = CLASSTYPE_VISIBILITY_SPECIFIED (target);
-      }
     if (involves_incomplete_p (target))
       {
        TREE_PUBLIC (name_decl) = 0;
@@ -811,10 +798,6 @@ tinfo_base_init (tree desc, tree target)
     else
       set_linkage_according_to_type (target, name_decl);
     import_export_decl (name_decl);
-    /* External name of the string containing the type's name has a
-       special name.  */
-    SET_DECL_ASSEMBLER_NAME (name_decl,
-                            mangle_typeinfo_string_for_type (target));
     DECL_INITIAL (name_decl) = name_string;
     mark_used (name_decl);
     pushdecl_top_level_and_finish (name_decl, name_string);
diff --git a/gcc/testsuite/g++.dg/ext/visibility/assign1.C b/gcc/testsuite/g++.dg/ext/visibility/assign1.C
new file mode 100644 (file)
index 0000000..6d7392f
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-visibility "" } */
+/* { dg-final { scan-assembler "\\.hidden.*_ZN1DaSERKS_" } } */
+
+struct B {
+  B& operator=(const B&);
+};
+
+struct D : public B {
+  // The implicit assignment operator should be hidden.
+} __attribute__((visibility("hidden")));
+
+D d1, d2;
+
+void f() {
+  d1 = d2;
+}
diff --git a/gcc/testsuite/g++.dg/ext/visibility/new1.C b/gcc/testsuite/g++.dg/ext/visibility/new1.C
new file mode 100644 (file)
index 0000000..0f0be51
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-require-visibility }
+// { dg-do compile }
+// { dg-options "-fvisibility=hidden" }
+// { dg-final { scan-assembler-not "\\.hidden\[^\n\]*_Znwj" } }
+
+void f() {
+  new int;
+}
+
+void *g();
+
+void *operator new(__SIZE_TYPE__) {
+  return g();
+}