Commit 73a8adb6 by Mark Mitchell Committed by Mark Mitchell

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
parent aed6152d
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> 2004-08-02 Mark Mitchell <mark@codesourcery.com>
PR c++/16707 PR c++/16707
......
...@@ -659,11 +659,6 @@ build_vtable (tree class_type, tree name, tree vtable_type) ...@@ -659,11 +659,6 @@ build_vtable (tree class_type, tree name, tree vtable_type)
require more intrusive changes to the g++ front end. */ require more intrusive changes to the g++ front end. */
DECL_IGNORED_P (decl) = 1; 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; return decl;
} }
...@@ -2971,25 +2966,7 @@ check_field_decls (tree t, tree *access_decls, ...@@ -2971,25 +2966,7 @@ check_field_decls (tree t, tree *access_decls,
continue; continue;
if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL) if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
{ continue;
/* 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;
}
/* Now it can only be a FIELD_DECL. */ /* Now it can only be a FIELD_DECL. */
...@@ -3744,23 +3721,6 @@ check_methods (tree t) ...@@ -3744,23 +3721,6 @@ check_methods (tree t)
check_for_override (x, t); check_for_override (x, t);
if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x)) if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
cp_error_at ("initializer specified for non-virtual method `%D'", 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 /* The name of the field is the original field name
Save this in auxiliary field for later overloading. */ Save this in auxiliary field for later overloading. */
if (DECL_VINDEX (x)) if (DECL_VINDEX (x))
...@@ -6740,13 +6700,8 @@ initialize_vtable (tree binfo, tree inits) ...@@ -6740,13 +6700,8 @@ initialize_vtable (tree binfo, tree inits)
static void static void
initialize_array (tree decl, tree inits) 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); DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context;
} }
/* Build the VTT (virtual table table) for T. /* Build the VTT (virtual table table) for T.
......
...@@ -3740,7 +3740,7 @@ extern int init_type_desc (void); ...@@ -3740,7 +3740,7 @@ extern int init_type_desc (void);
extern tree check_tag_decl (cp_decl_specifier_seq *); extern tree check_tag_decl (cp_decl_specifier_seq *);
extern tree shadow_tag (cp_decl_specifier_seq *); extern tree shadow_tag (cp_decl_specifier_seq *);
extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *); 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 start_decl_1 (tree);
extern void cp_finish_decl (tree, tree, tree, int); extern void cp_finish_decl (tree, tree, tree, int);
extern void finish_decl (tree, tree, tree); extern void finish_decl (tree, tree, tree);
...@@ -3825,6 +3825,7 @@ extern tree finish_table (tree, tree, tree, int); ...@@ -3825,6 +3825,7 @@ extern tree finish_table (tree, tree, tree, int);
extern tree coerce_new_type (tree); extern tree coerce_new_type (tree);
extern tree coerce_delete_type (tree); extern tree coerce_delete_type (tree);
extern void comdat_linkage (tree); extern void comdat_linkage (tree);
extern void determine_visibility (tree);
extern void import_export_decl (tree); extern void import_export_decl (tree);
extern tree build_cleanup (tree); extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, tree); extern tree build_offset_ref_call_from_tree (tree, tree);
......
...@@ -1881,11 +1881,12 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1881,11 +1881,12 @@ duplicate_decls (tree newdecl, tree olddecl)
COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
/* Warn about conflicting visibility specifications. */ /* 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)) && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
{ {
warning ("%J'%D': visibility attribute ignored because it", warning ("%J'%D': visibility attribute ignored because it",
newdecl, newdecl); newdecl, newdecl);
warning ("%Jconflicts with previous declaration here", olddecl); warning ("%Jconflicts with previous declaration here", olddecl);
} }
/* Choose the declaration which specified visibility. */ /* Choose the declaration which specified visibility. */
...@@ -1894,21 +1895,6 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1894,21 +1895,6 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
DECL_VISIBILITY_SPECIFIED (newdecl) = 1; 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) if (TREE_CODE (newdecl) == FUNCTION_DECL)
{ {
...@@ -3276,6 +3262,10 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type) ...@@ -3276,6 +3262,10 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
TREE_NOTHROW (fn) = 1; TREE_NOTHROW (fn) = 1;
SET_OVERLOADED_OPERATOR_CODE (fn, operator_code); SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);
SET_DECL_LANGUAGE (fn, lang_c); 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; return fn;
} }
...@@ -3607,7 +3597,8 @@ start_decl (const cp_declarator *declarator, ...@@ -3607,7 +3597,8 @@ start_decl (const cp_declarator *declarator,
cp_decl_specifier_seq *declspecs, cp_decl_specifier_seq *declspecs,
int initialized, int initialized,
tree attributes, tree attributes,
tree prefix_attributes) tree prefix_attributes,
bool *pop_scope_p)
{ {
tree decl; tree decl;
tree type, tem; tree type, tem;
...@@ -3642,14 +3633,11 @@ start_decl (const cp_declarator *declarator, ...@@ -3642,14 +3633,11 @@ start_decl (const cp_declarator *declarator,
context = DECL_CONTEXT (decl); context = DECL_CONTEXT (decl);
if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL if (context)
&& context != current_namespace && TREE_CODE (decl) == VAR_DECL) *pop_scope_p = push_scope (context);
{ else
/* When parsing the initializer, lookup should use the object's *pop_scope_p = false;
namespace. */
push_decl_namespace (context);
}
/* We are only interested in class contexts, later. */ /* We are only interested in class contexts, later. */
if (context && TREE_CODE (context) == NAMESPACE_DECL) if (context && TREE_CODE (context) == NAMESPACE_DECL)
context = NULL_TREE; context = NULL_TREE;
...@@ -3705,8 +3693,6 @@ start_decl (const cp_declarator *declarator, ...@@ -3705,8 +3693,6 @@ start_decl (const cp_declarator *declarator,
if (context && COMPLETE_TYPE_P (complete_type (context))) if (context && COMPLETE_TYPE_P (complete_type (context)))
{ {
push_nested_class (context);
if (TREE_CODE (decl) == VAR_DECL) if (TREE_CODE (decl) == VAR_DECL)
{ {
tree field = lookup_field (context, DECL_NAME (decl), 0, false); 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) ...@@ -4715,20 +4701,10 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
&& (DECL_INITIAL (decl) || init)) && (DECL_INITIAL (decl) || init))
DECL_INITIALIZED_IN_CLASS_P (decl) = 1; 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); type = TREE_TYPE (decl);
if (type == error_mark_node) if (type == error_mark_node)
goto finish_end0; goto finish_end;
if (TYPE_HAS_MUTABLE_P (type)) if (TYPE_HAS_MUTABLE_P (type))
TREE_READONLY (decl) = 0; TREE_READONLY (decl) = 0;
...@@ -4745,7 +4721,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ...@@ -4745,7 +4721,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
&& !DECL_PRETTY_FUNCTION_P (decl) && !DECL_PRETTY_FUNCTION_P (decl)
&& !dependent_type_p (TREE_TYPE (decl))) && !dependent_type_p (TREE_TYPE (decl)))
maybe_deduce_size_from_array_init (decl, init); 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. */ /* 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) ...@@ -4833,6 +4809,9 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
/* Remember that the initialization for this variable has /* Remember that the initialization for this variable has
taken place. */ taken place. */
DECL_INITIALIZED_P (decl) = 1; 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 /* If the variable has an array type, lay out the type, even if
there is no initializer. It is valid to index through the 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) ...@@ -4899,26 +4878,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
if (TREE_STATIC (decl)) if (TREE_STATIC (decl))
expand_static_init (decl, init); 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 /* 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) ...@@ -9663,6 +9622,9 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
&& lookup_attribute ("noinline", attrs)) && lookup_attribute ("noinline", attrs))
warning ("%Jinline function '%D' given attribute noinline", decl1, decl1); 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)) if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
/* This is a constructor, we must ensure that any default args /* This is a constructor, we must ensure that any default args
introduced by this definition are propagated to the clones introduced by this definition are propagated to the clones
......
...@@ -1616,6 +1616,59 @@ maybe_emit_vtables (tree ctype) ...@@ -1616,6 +1616,59 @@ maybe_emit_vtables (tree ctype)
return true; 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 /* 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 for DECL has not already been determined, do so now by setting
DECL_EXTERNAL, DECL_COMDAT and other related flags. Until this DECL_EXTERNAL, DECL_COMDAT and other related flags. Until this
......
...@@ -368,7 +368,8 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -368,7 +368,8 @@ use_thunk (tree thunk_fndecl, bool emit_p)
rewrite. */ rewrite. */
TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function); TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (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)) if (flag_weak && TREE_PUBLIC (thunk_fndecl))
comdat_linkage (thunk_fndecl); comdat_linkage (thunk_fndecl);
......
...@@ -6312,10 +6312,13 @@ cp_parser_condition (cp_parser* parser) ...@@ -6312,10 +6312,13 @@ cp_parser_condition (cp_parser* parser)
for sure. */ for sure. */
if (cp_parser_parse_definitely (parser)) if (cp_parser_parse_definitely (parser))
{ {
bool pop_p;
/* Create the declaration. */ /* Create the declaration. */
decl = start_decl (declarator, &type_specifiers, decl = start_decl (declarator, &type_specifiers,
/*initialized_p=*/true, /*initialized_p=*/true,
attributes, /*prefix_attributes=*/NULL_TREE); attributes, /*prefix_attributes=*/NULL_TREE,
&pop_p);
/* Parse the assignment-expression. */ /* Parse the assignment-expression. */
initializer = cp_parser_assignment_expression (parser); initializer = cp_parser_assignment_expression (parser);
...@@ -6324,6 +6327,8 @@ cp_parser_condition (cp_parser* parser) ...@@ -6324,6 +6327,8 @@ cp_parser_condition (cp_parser* parser)
initializer, initializer,
asm_specification, asm_specification,
LOOKUP_ONLYCONVERTING); LOOKUP_ONLYCONVERTING);
if (pop_p)
pop_scope (DECL_CONTEXT (decl));
return convert_from_reference (decl); return convert_from_reference (decl);
} }
...@@ -10630,12 +10635,12 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -10630,12 +10635,12 @@ cp_parser_init_declarator (cp_parser* parser,
have_extern_spec = false; have_extern_spec = false;
} }
decl = start_decl (declarator, decl_specifiers, decl = start_decl (declarator, decl_specifiers,
is_initialized, attributes, prefix_attributes); is_initialized, attributes, prefix_attributes,
&pop_p);
} }
else if (scope)
/* Enter the SCOPE. That way unqualified names appearing in the /* Enter the SCOPE. That way unqualified names appearing in the
initializer will be looked up in SCOPE. */ initializer will be looked up in SCOPE. */
if (scope)
pop_p = push_scope (scope); pop_p = push_scope (scope);
/* Perform deferred access control checks, now that we know in which /* Perform deferred access control checks, now that we know in which
...@@ -10682,17 +10687,12 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -10682,17 +10687,12 @@ cp_parser_init_declarator (cp_parser* parser,
if (cp_parser_attributes_opt (parser)) if (cp_parser_attributes_opt (parser))
warning ("attributes after parenthesized initializer ignored"); 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 /* For an in-class declaration, use `grokfield' to create the
declaration. */ declaration. */
if (member_p) if (member_p)
{ {
if (pop_p)
pop_scope (scope);
decl = grokfield (declarator, decl_specifiers, decl = grokfield (declarator, decl_specifiers,
initializer, /*asmspec=*/NULL_TREE, initializer, /*asmspec=*/NULL_TREE,
/*attributes=*/NULL_TREE); /*attributes=*/NULL_TREE);
...@@ -10703,15 +10703,19 @@ cp_parser_init_declarator (cp_parser* parser, ...@@ -10703,15 +10703,19 @@ cp_parser_init_declarator (cp_parser* parser,
/* Finish processing the declaration. But, skip friend /* Finish processing the declaration. But, skip friend
declarations. */ declarations. */
if (!friend_p && decl) if (!friend_p && decl)
cp_finish_decl (decl, {
initializer, cp_finish_decl (decl,
asm_specification, initializer,
/* If the initializer is in parentheses, then this is asm_specification,
a direct-initialization, which means that an /* If the initializer is in parentheses, then this is
`explicit' constructor is OK. Otherwise, an a direct-initialization, which means that an
`explicit' constructor cannot be used. */ `explicit' constructor is OK. Otherwise, an
((is_parenthesized_init || !is_initialized) `explicit' constructor cannot be used. */
((is_parenthesized_init || !is_initialized)
? 0 : LOOKUP_ONLYCONVERTING)); ? 0 : LOOKUP_ONLYCONVERTING));
if (pop_p)
pop_scope (DECL_CONTEXT (decl));
}
/* Remember whether or not variables were initialized by /* Remember whether or not variables were initialized by
constant-expressions. */ constant-expressions. */
......
...@@ -11162,20 +11162,13 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok) ...@@ -11162,20 +11162,13 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
we have a chance to determine linkage. */ we have a chance to determine linkage. */
DECL_EXTERNAL (d) = 0; DECL_EXTERNAL (d) = 0;
/* This is done in analogous to `start_decl'. It is required /* Enter the scope of D so that access-checking works correctly. */
for correct access checking. */
push_nested_class (DECL_CONTEXT (d)); push_nested_class (DECL_CONTEXT (d));
cp_finish_decl (d, cp_finish_decl (d,
(!DECL_INITIALIZED_IN_CLASS_P (d) (!DECL_INITIALIZED_IN_CLASS_P (d)
? DECL_INITIAL (d) : NULL_TREE), ? DECL_INITIAL (d) : NULL_TREE),
NULL_TREE, 0); NULL_TREE, 0);
/* Normally, pop_nested_class is called by cp_finish_decl above. pop_nested_class ();
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 ();
} }
else if (TREE_CODE (d) == FUNCTION_DECL) else if (TREE_CODE (d) == FUNCTION_DECL)
{ {
......
...@@ -346,6 +346,8 @@ get_tinfo_decl (tree type) ...@@ -346,6 +346,8 @@ get_tinfo_decl (tree type)
d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc)); d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
SET_DECL_ASSEMBLER_NAME (d, name); SET_DECL_ASSEMBLER_NAME (d, name);
/* Remember the type it is for. */
TREE_TYPE (name) = type;
DECL_TINFO_P (d) = 1; DECL_TINFO_P (d) = 1;
DECL_ARTIFICIAL (d) = 1; DECL_ARTIFICIAL (d) = 1;
TREE_READONLY (d) = 1; TREE_READONLY (d) = 1;
...@@ -354,20 +356,11 @@ get_tinfo_decl (tree type) ...@@ -354,20 +356,11 @@ get_tinfo_decl (tree type)
define it later if we need to do so. */ define it later if we need to do so. */
DECL_EXTERNAL (d) = 1; DECL_EXTERNAL (d) = 1;
DECL_NOT_REALLY_EXTERN (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); set_linkage_according_to_type (type, d);
pushdecl_top_level_and_finish (d, NULL_TREE); 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. */ /* Add decl to the global array of tinfo decls. */
my_friendly_assert (unemitted_tinfo_decls != 0, 20030312); my_friendly_assert (unemitted_tinfo_decls != 0, 20030312);
VARRAY_PUSH_TREE (unemitted_tinfo_decls, d); VARRAY_PUSH_TREE (unemitted_tinfo_decls, d);
...@@ -791,18 +784,12 @@ tinfo_base_init (tree desc, tree target) ...@@ -791,18 +784,12 @@ tinfo_base_init (tree desc, tree target)
TREE_TYPE (name_name) = target; TREE_TYPE (name_name) = target;
name_decl = build_lang_decl (VAR_DECL, name_name, name_type); name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
DECL_ARTIFICIAL (name_decl) = 1; DECL_ARTIFICIAL (name_decl) = 1;
TREE_READONLY (name_decl) = 1; TREE_READONLY (name_decl) = 1;
TREE_STATIC (name_decl) = 1; TREE_STATIC (name_decl) = 1;
DECL_EXTERNAL (name_decl) = 0; DECL_EXTERNAL (name_decl) = 0;
DECL_TINFO_P (name_decl) = 1; 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)) if (involves_incomplete_p (target))
{ {
TREE_PUBLIC (name_decl) = 0; TREE_PUBLIC (name_decl) = 0;
...@@ -811,10 +798,6 @@ tinfo_base_init (tree desc, tree target) ...@@ -811,10 +798,6 @@ tinfo_base_init (tree desc, tree target)
else else
set_linkage_according_to_type (target, name_decl); set_linkage_according_to_type (target, name_decl);
import_export_decl (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; DECL_INITIAL (name_decl) = name_string;
mark_used (name_decl); mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string); pushdecl_top_level_and_finish (name_decl, name_string);
......
/* { 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;
}
// { 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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment