aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-08-04 05:27:52 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-08-04 05:27:52 +0000
commit73a8adb62e1609c94e21903fe9c261b6d30a8415 (patch)
treedc4c187d7c4a64c15aab2950413405f2b750eaf1 /gcc
parentaed6152d8c55eb6e756b7459733a8bfda3dd00a3 (diff)
downloadgcc-73a8adb62e1609c94e21903fe9c261b6d30a8415.zip
gcc-73a8adb62e1609c94e21903fe9c261b6d30a8415.tar.gz
gcc-73a8adb62e1609c94e21903fe9c261b6d30a8415.tar.bz2
class.c (build_vtable): Do not set DECL_VISIBILITY here.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog24
-rw-r--r--gcc/cp/class.c47
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c82
-rw-r--r--gcc/cp/decl2.c53
-rw-r--r--gcc/cp/method.c3
-rw-r--r--gcc/cp/parser.c46
-rw-r--r--gcc/cp/pt.c11
-rw-r--r--gcc/cp/rtti.c27
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/assign1.C17
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/new1.C14
11 files changed, 167 insertions, 160 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d87b4827..e82e500 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 365febb..e0bae52 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cdb6706..5b49925 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c4755c0c..8c85e71 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 40322ab..53060dd 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index d741d3d..7a2a762 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f19ab25..d6aadb3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1e9bbb1..14b0c83 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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)
{
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 83e24c4..a59af79 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -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
index 0000000..6d7392f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/assign1.C
@@ -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
index 0000000..0f0be51
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/new1.C
@@ -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();
+}