===================================================================
@@ -7576,13 +7576,7 @@ handle_alias_ifunc_attribute (bool is_al
if (TREE_CODE (decl) == FUNCTION_DECL)
DECL_INITIAL (decl) = error_mark_node;
else
- {
- if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
- DECL_EXTERNAL (decl) = 1;
- else
- DECL_EXTERNAL (decl) = 0;
- TREE_STATIC (decl) = 1;
- }
+ TREE_STATIC (decl) = 1;
if (!is_alias)
/* ifuncs are also aliases, so set that attribute too. */
===================================================================
@@ -367,7 +367,12 @@ handle_pragma_weak (cpp_reader * ARG_UNU
{
apply_pragma_weak (decl, value);
if (value)
- assemble_alias (decl, value);
+ {
+ DECL_EXTERNAL (decl) = 0;
+ if (TREE_CODE (decl) == VAR_DECL)
+ TREE_STATIC (decl) = 1;
+ assemble_alias (decl, value);
+ }
}
else
{
===================================================================
@@ -568,6 +568,8 @@ cgraph_create_function_alias (tree alias
alias_node->symbol.alias_target = target;
alias_node->symbol.definition = true;
alias_node->symbol.alias = true;
+ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
+ alias_node->symbol.weakref = true;
return alias_node;
}
===================================================================
@@ -56,6 +56,8 @@ struct GTY(()) symtab_node_base
/* True when symbol is an alias.
Set by assemble_alias. */
unsigned alias : 1;
+ /* True when alias is a weakref. */
+ unsigned weakref : 1;
/* C++ frontend produce same body aliases and extra name aliases for
virutal functions and vtables that are obviously equivalent.
Those aliases are bit special, especially because C++ frontend
===================================================================
@@ -379,6 +379,7 @@ cgraph_reset_node (struct cgraph_node *n
node->symbol.analyzed = false;
node->symbol.definition = false;
node->symbol.alias = false;
+ node->symbol.weakref = false;
node->symbol.cpp_implicit_alias = false;
cgraph_node_remove_callees (node);
@@ -1021,9 +1022,9 @@ handle_alias_pairs (void)
if (node)
{
node->symbol.alias_target = p->target;
+ node->symbol.weakref = true;
node->symbol.alias = true;
}
- DECL_EXTERNAL (p->decl) = 1;
alias_pairs->unordered_remove (i);
continue;
}
@@ -1034,16 +1035,6 @@ handle_alias_pairs (void)
continue;
}
- /* Normally EXTERNAL flag is used to mark external inlines,
- however for aliases it seems to be allowed to use it w/o
- any meaning. See gcc.dg/attr-alias-3.c
- However for weakref we insist on EXTERNAL flag being set.
- See gcc.dg/attr-alias-5.c */
- if (DECL_EXTERNAL (p->decl))
- DECL_EXTERNAL (p->decl)
- = lookup_attribute ("weakref",
- DECL_ATTRIBUTES (p->decl)) != NULL;
-
if (DECL_EXTERNAL (target_node->symbol.decl)
/* We use local aliases for C++ thunks to force the tailcall
to bind locally. This is a hack - to keep it working do
@@ -1885,9 +1876,9 @@ output_weakrefs (void)
{
symtab_node node;
FOR_EACH_SYMBOL (node)
- if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl)
+ if (node->symbol.alias
&& !TREE_ASM_WRITTEN (node->symbol.decl)
- && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ && node->symbol.weakref)
{
tree target;
===================================================================
@@ -3755,6 +3755,10 @@ simple_operand_p (const_tree exp)
#pragma weak, etc). */
&& ! TREE_PUBLIC (exp)
&& ! DECL_EXTERNAL (exp)
+ /* Weakrefs are not safe to be read, since they can be NULL.
+ They are !TREE_PUBLIC && !DECL_EXTERNAL but still
+ have DECL_WEAK flag set. */
+ && (! VAR_OR_FUNCTION_DECL_P (exp) || ! DECL_WEAK (exp))
/* Loading a static variable is unduly expensive, but global
registers aren't expensive. */
&& (! TREE_STATIC (exp) || DECL_REGISTER (exp))));
===================================================================
@@ -73,11 +73,6 @@ can_refer_decl_in_current_unit_p (tree d
if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
|| (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL))
return true;
- /* Weakrefs have somewhat confusing DECL_EXTERNAL flag set; they
- are always safe. */
- if (DECL_EXTERNAL (decl)
- && lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
- return true;
/* We are folding reference from external vtable. The vtable may reffer
to a symbol keyed to other compilation unit. The other compilation
unit may be in separate DSO and the symbol may be hidden. */
===================================================================
@@ -664,12 +664,6 @@ cgraph_externally_visible_p (struct cgra
bool
varpool_externally_visible_p (struct varpool_node *vnode)
{
- /* Do not touch weakrefs; while they are not externally visible,
- dropping their DECL_EXTERNAL flags confuse most
- of code handling them. */
- if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl))
- return true;
-
if (DECL_EXTERNAL (vnode->symbol.decl))
return true;
@@ -784,9 +778,9 @@ function_and_variable_visibility (bool w
happy. Clear the flag here to avoid confusion in middle-end. */
if (DECL_COMDAT (node->symbol.decl) && !TREE_PUBLIC (node->symbol.decl))
DECL_COMDAT (node->symbol.decl) = 0;
- /* For external decls stop tracking same_comdat_group, it doesn't matter
- what comdat group they are in when they won't be emitted in this TU,
- and simplifies later passes. */
+
+ /* For external decls stop tracking same_comdat_group. It doesn't matter
+ what comdat group they are in when they won't be emitted in this TU. */
if (node->symbol.same_comdat_group && DECL_EXTERNAL (node->symbol.decl))
{
#ifdef ENABLE_CHECKING
@@ -804,6 +798,7 @@ function_and_variable_visibility (bool w
gcc_assert ((!DECL_WEAK (node->symbol.decl)
&& !DECL_COMDAT (node->symbol.decl))
|| TREE_PUBLIC (node->symbol.decl)
+ || node->symbol.weakref
|| DECL_EXTERNAL (node->symbol.decl));
if (cgraph_externally_visible_p (node, whole_program))
{
@@ -815,7 +810,8 @@ function_and_variable_visibility (bool w
node->symbol.externally_visible = false;
node->symbol.forced_by_abi = false;
}
- if (!node->symbol.externally_visible && node->symbol.definition
+ if (!node->symbol.externally_visible
+ && node->symbol.definition && !node->symbol.weakref
&& !DECL_EXTERNAL (node->symbol.decl))
{
gcc_assert (whole_program || in_lto_p
@@ -860,6 +856,7 @@ function_and_variable_visibility (bool w
{
/* weak flag makes no sense on local variables. */
gcc_assert (!DECL_WEAK (vnode->symbol.decl)
+ || vnode->symbol.weakref
|| TREE_PUBLIC (vnode->symbol.decl)
|| DECL_EXTERNAL (vnode->symbol.decl));
/* In several cases declarations can not be common:
@@ -897,7 +894,8 @@ function_and_variable_visibility (bool w
vnode->symbol.externally_visible = false;
vnode->symbol.forced_by_abi = false;
}
- if (!vnode->symbol.externally_visible)
+ if (!vnode->symbol.externally_visible
+ && !vnode->symbol.weakref)
{
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
symtab_make_decl_local (vnode->symbol.decl);
===================================================================
@@ -60,7 +60,7 @@ get_symbol_class (symtab_node node)
return SYMBOL_DUPLICATE;
/* Weakref aliases are always duplicated. */
- if (lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ if (node->symbol.weakref)
return SYMBOL_DUPLICATE;
/* External declarations are external. */
@@ -218,10 +218,7 @@ add_symbol_to_partition_1 (ltrans_partit
/* Add all aliases associated with the symbol. */
for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref); i++)
- if (ref->use == IPA_REF_ALIAS
- && !lookup_attribute ("weakref",
- DECL_ATTRIBUTES
- (ref->referring->symbol.decl)))
+ if (ref->use == IPA_REF_ALIAS && !node->symbol.weakref)
add_symbol_to_partition_1 (part, ref->referring);
/* Ensure that SAME_COMDAT_GROUP lists all allways added in a group. */
@@ -243,8 +240,7 @@ static symtab_node
contained_in_symbol (symtab_node node)
{
/* Weakrefs are never contained in anything. */
- if (lookup_attribute ("weakref",
- DECL_ATTRIBUTES (node->symbol.decl)))
+ if (node->symbol.weakref)
return node;
if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
{
@@ -561,8 +557,7 @@ lto_balanced_map (void)
last_visited_node++;
- gcc_assert (node->symbol.definition
- || lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)));
+ gcc_assert (node->symbol.definition || node->symbol.weakref);
/* Compute boundary cost of callgraph edges. */
for (edge = node->callees; edge; edge = edge->next_callee)
@@ -871,8 +866,7 @@ rename_statics (lto_symtab_encoder_t enc
once this is fixed. */
|| DECL_EXTERNAL (node->symbol.decl)
|| !symtab_real_symbol_p (node))
- && !may_need_named_section_p (encoder, node)
- && !lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ && !may_need_named_section_p (encoder, node))
return;
/* Now walk symbols sharing the same name and see if there are any conflicts.
@@ -897,11 +891,9 @@ rename_statics (lto_symtab_encoder_t enc
/* Assign every symbol in the set that shares the same ASM name an unique
mangled name. */
for (s = symtab_node_for_asm (name); s;)
- if ((!s->symbol.externally_visible
- || lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ if (!s->symbol.externally_visible
&& ((symtab_real_symbol_p (s)
- && (!DECL_EXTERNAL (node->symbol.decl)
- || lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ && !DECL_EXTERNAL (node->symbol.decl)
&& !TREE_PUBLIC (node->symbol.decl))
|| may_need_named_section_p (encoder, s))
&& (!encoder
===================================================================
@@ -487,8 +487,9 @@ lto_output_node (struct lto_simple_outpu
defined in other unit, we may use the info on aliases to resolve
symbol1 != symbol2 type tests that we can do only for locally defined objects
otherwise. */
- alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
+ alias_p = node->symbol.alias && (!boundary_p || node->symbol.weakref);
bp_pack_value (&bp, alias_p, 1);
+ bp_pack_value (&bp, node->symbol.weakref, 1);
bp_pack_value (&bp, node->frequency, 2);
bp_pack_value (&bp, node->only_called_at_startup, 1);
bp_pack_value (&bp, node->only_called_at_exit, 1);
@@ -531,8 +532,9 @@ lto_output_varpool_node (struct lto_simp
bp_pack_value (&bp, node->symbol.forced_by_abi, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1);
bp_pack_value (&bp, node->symbol.definition, 1);
- alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
+ alias_p = node->symbol.alias && (!boundary_p || node->symbol.weakref);
bp_pack_value (&bp, alias_p, 1);
+ bp_pack_value (&bp, node->symbol.weakref, 1);
bp_pack_value (&bp, node->symbol.analyzed && !boundary_p, 1);
gcc_assert (node->symbol.definition || !node->symbol.analyzed);
/* Constant pool initializers can be de-unified into individual ltrans units.
@@ -906,6 +908,7 @@ input_overwrite_node (struct lto_file_de
TREE_STATIC (node->symbol.decl) = 0;
}
node->symbol.alias = bp_unpack_value (bp, 1);
+ node->symbol.weakref = bp_unpack_value (bp, 1);
node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
node->only_called_at_startup = bp_unpack_value (bp, 1);
node->only_called_at_exit = bp_unpack_value (bp, 1);
@@ -1010,8 +1013,7 @@ input_node (struct lto_file_decl_data *f
node->thunk.virtual_value = virtual_value;
node->thunk.virtual_offset_p = (type & 4);
}
- if (node->symbol.alias && !node->symbol.analyzed
- && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ if (node->symbol.alias && !node->symbol.analyzed && node->symbol.weakref)
node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
return node;
}
@@ -1046,6 +1048,7 @@ input_varpool_node (struct lto_file_decl
node->symbol.unique_name = bp_unpack_value (&bp, 1);
node->symbol.definition = bp_unpack_value (&bp, 1);
node->symbol.alias = bp_unpack_value (&bp, 1);
+ node->symbol.weakref = bp_unpack_value (&bp, 1);
node->symbol.analyzed = bp_unpack_value (&bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (&bp, 1);
node->symbol.in_other_partition = bp_unpack_value (&bp, 1);
@@ -1054,8 +1057,7 @@ input_varpool_node (struct lto_file_decl
DECL_EXTERNAL (node->symbol.decl) = 1;
TREE_STATIC (node->symbol.decl) = 0;
}
- if (node->symbol.alias && !node->symbol.analyzed
- && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ if (node->symbol.alias && !node->symbol.analyzed && node->symbol.weakref)
node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
ref = streamer_read_hwi (ib);
/* Store a reference for now, and fix up later to be a pointer. */
===================================================================
@@ -235,9 +235,6 @@ lto_symtab_symbol_p (symtab_node e)
{
if (!TREE_PUBLIC (e->symbol.decl) && !DECL_EXTERNAL (e->symbol.decl))
return false;
- /* weakrefs are really static variables that are made external by a hack. */
- if (lookup_attribute ("weakref", DECL_ATTRIBUTES (e->symbol.decl)))
- return false;
return symtab_real_symbol_p (e);
}
@@ -589,6 +586,7 @@ lto_symtab_merge_symbols (void)
if (!node->symbol.analyzed && node->symbol.alias_target)
{
symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target);
+ gcc_assert (node->symbol.weakref);
if (tgt)
symtab_resolve_alias (node, tgt);
}
@@ -617,11 +615,6 @@ lto_symtab_prevailing_decl (tree decl)
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
return decl;
- /* As an anoying special cases weakrefs are really static variables with
- EXTERNAL flag. */
- if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
- return decl;
-
/* Ensure DECL_ASSEMBLER_NAME will not set assembler name. */
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
===================================================================
@@ -136,8 +136,8 @@ rest_of_decl_compilation (tree decl,
/* A quirk of the initial implementation of aliases required that the
user add "extern" to all of them. Which is silly, but now
historical. Do note that the symbol is in fact locally defined. */
- if (!lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
- DECL_EXTERNAL (decl) = 0;
+ DECL_EXTERNAL (decl) = 0;
+ TREE_STATIC (decl) = 1;
assemble_alias (decl, alias);
}
}
===================================================================
@@ -481,6 +481,8 @@ dump_symtab_base (FILE *f, symtab_node n
fprintf (f, " analyzed");
if (node->symbol.alias)
fprintf (f, " alias");
+ if (node->symbol.weakref)
+ fprintf (f, " weakref");
if (node->symbol.cpp_implicit_alias)
fprintf (f, " cpp_implicit_alias");
if (node->symbol.alias_target)
@@ -682,11 +684,16 @@ verify_symtab_base (symtab_node node)
error_found = true;
}
if (node->symbol.alias && !node->symbol.definition
- && !lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+ && !node->symbol.weakref)
{
error ("node is alias but not definition");
error_found = true;
}
+ if (node->symbol.weakref && !node->symbol.alias)
+ {
+ error ("node is weakref but not an alias");
+ error_found = true;
+ }
if (node->symbol.same_comdat_group)
{
symtab_node n = node->symbol.same_comdat_group;
@@ -799,8 +806,6 @@ symtab_make_decl_local (tree decl)
DECL_VISIBILITY_SPECIFIED (decl) = 0;
DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
TREE_PUBLIC (decl) = 0;
- DECL_VISIBILITY_SPECIFIED (decl) = 0;
- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
if (!DECL_RTL_SET_P (decl))
return;
@@ -861,7 +866,7 @@ symtab_alias_ultimate_target (symtab_nod
if (availability)
{
- weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
+ weakref_p = node->symbol.weakref;
if (!weakref_p)
*availability = symtab_node_availability (node);
else
@@ -893,7 +898,7 @@ symtab_alias_ultimate_target (symtab_nod
enum availability a = symtab_node_availability (node);
if (a < *availability)
*availability = a;
- weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
+ weakref_p = node->symbol.weakref;
}
}
if (availability)
===================================================================
@@ -452,6 +452,8 @@ varpool_create_variable_alias (tree alia
alias_node->symbol.alias = true;
alias_node->symbol.definition = true;
alias_node->symbol.alias_target = decl;
+ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
+ alias_node->symbol.weakref = true;
return alias_node;
}