re PR c++/61825 (g++.dg/cpp0x/static_assert9.C FAILs)
PR c++/61825 * c-family/c-common.c (handle_alias_ifunc_attribute): Check that visibility change is possible (handle_weakref_attribute): Likewise. * cgraph.h (symtab_node): Add method get_create and field refuse_visibility_changes. (symtab_node::get_create): New method. * fold-const.c (tree_single_nonzero_warnv_p): Use get_create. * varasm.c (mark_weak): Verify that visibility change is possible. * gcc.dg/tree-ssa/nonzero-1.c: Require error to be output. From-SVN: r215409
This commit is contained in:
parent
3f99b0612f
commit
f7217cde7f
@ -1,3 +1,16 @@
|
||||
2014-09-19 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR c++/61825
|
||||
* c-family/c-common.c (handle_alias_ifunc_attribute): Check
|
||||
that visibility change is possible
|
||||
(handle_weakref_attribute): Likewise.
|
||||
* cgraph.h (symtab_node): Add method get_create and
|
||||
field refuse_visibility_changes.
|
||||
(symtab_node::get_create): New method.
|
||||
* fold-const.c (tree_single_nonzero_warnv_p): Use get_create.
|
||||
* varasm.c (mark_weak): Verify that visibility change is
|
||||
possible.
|
||||
|
||||
2014-09-19 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* config/rs6000/predicates.md (fusion_gpr_mem_load): Move testing
|
||||
|
@ -7757,6 +7757,19 @@ handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args,
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
|
||||
if (decl_in_symtab_p (*node))
|
||||
{
|
||||
struct symtab_node *n = symtab_node::get (decl);
|
||||
if (n && n->refuse_visibility_changes)
|
||||
{
|
||||
if (is_alias)
|
||||
error ("%+D declared alias after being used", decl);
|
||||
else
|
||||
error ("%+D declared ifunc after being used", decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
@ -7833,6 +7846,13 @@ handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
|
||||
DECL_WEAK (*node) = 1;
|
||||
}
|
||||
|
||||
if (decl_in_symtab_p (*node))
|
||||
{
|
||||
struct symtab_node *n = symtab_node::get (*node);
|
||||
if (n && n->refuse_visibility_changes)
|
||||
error ("%+D declared weakref after being used", *node);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
16
gcc/cgraph.h
16
gcc/cgraph.h
@ -346,6 +346,10 @@ public:
|
||||
return decl->decl_with_vis.symtab_node;
|
||||
}
|
||||
|
||||
/* Try to find a symtab node for declaration DECL and if it does not
|
||||
exist or if it corresponds to an inline clone, create a new one. */
|
||||
static inline symtab_node * get_create (tree node);
|
||||
|
||||
/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
|
||||
Return NULL if there's no such node. */
|
||||
static symtab_node *get_for_asmname (const_tree asmname);
|
||||
@ -394,7 +398,9 @@ public:
|
||||
unsigned analyzed : 1;
|
||||
/* Set for write-only variables. */
|
||||
unsigned writeonly : 1;
|
||||
|
||||
/* Visibility of symbol was used for further optimization; do not
|
||||
permit further changes. */
|
||||
unsigned refuse_visibility_changes : 1;
|
||||
|
||||
/*** Visibility and linkage flags. ***/
|
||||
|
||||
@ -2519,4 +2525,12 @@ cgraph_node::mark_force_output (void)
|
||||
gcc_checking_assert (!global.inlined_to);
|
||||
}
|
||||
|
||||
inline symtab_node * symtab_node::get_create (tree node)
|
||||
{
|
||||
if (TREE_CODE (node) == VAR_DECL)
|
||||
return varpool_node::get_create (node);
|
||||
else
|
||||
return cgraph_node::get_create (node);
|
||||
}
|
||||
|
||||
#endif /* GCC_CGRAPH_H */
|
||||
|
@ -15850,7 +15850,7 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p)
|
||||
{
|
||||
struct symtab_node *symbol;
|
||||
|
||||
symbol = symtab_node::get (base);
|
||||
symbol = symtab_node::get_create (base);
|
||||
if (symbol)
|
||||
return symbol->nonzero_address ();
|
||||
else
|
||||
|
30
gcc/symtab.c
30
gcc/symtab.c
@ -1811,9 +1811,9 @@ bool
|
||||
symtab_node::nonzero_address ()
|
||||
{
|
||||
/* Weakrefs may be NULL when their target is not defined. */
|
||||
if (this->alias && this->weakref)
|
||||
if (alias && weakref)
|
||||
{
|
||||
if (this->analyzed)
|
||||
if (analyzed)
|
||||
{
|
||||
symtab_node *target = ultimate_alias_target ();
|
||||
|
||||
@ -1828,7 +1828,7 @@ symtab_node::nonzero_address ()
|
||||
could be useful to eliminate the NULL pointer checks in LTO
|
||||
programs. */
|
||||
if (target->definition && !DECL_EXTERNAL (target->decl))
|
||||
return true;
|
||||
return true;
|
||||
if (target->resolution != LDPR_UNKNOWN
|
||||
&& target->resolution != LDPR_UNDEF
|
||||
&& flag_delete_null_pointer_checks)
|
||||
@ -1847,22 +1847,28 @@ symtab_node::nonzero_address ()
|
||||
Those are handled by later check for definition.
|
||||
|
||||
When parsing, beware the cases when WEAK attribute is added later. */
|
||||
if (!DECL_WEAK (this->decl)
|
||||
&& flag_delete_null_pointer_checks
|
||||
&& symtab->state > PARSING)
|
||||
return true;
|
||||
if (!DECL_WEAK (decl)
|
||||
&& flag_delete_null_pointer_checks)
|
||||
{
|
||||
refuse_visibility_changes = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If target is defined and not extern, we know it will be output and thus
|
||||
it will bind to non-NULL.
|
||||
Play safe for flag_delete_null_pointer_checks where weak definition maye
|
||||
be re-defined by NULL. */
|
||||
if (this->definition && !DECL_EXTERNAL (this->decl)
|
||||
&& (flag_delete_null_pointer_checks || !DECL_WEAK (this->decl)))
|
||||
return true;
|
||||
if (definition && !DECL_EXTERNAL (decl)
|
||||
&& (flag_delete_null_pointer_checks || !DECL_WEAK (decl)))
|
||||
{
|
||||
if (!DECL_WEAK (decl))
|
||||
refuse_visibility_changes = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* As the last resort, check the resolution info. */
|
||||
if (this->resolution != LDPR_UNKNOWN
|
||||
&& this->resolution != LDPR_UNDEF
|
||||
if (resolution != LDPR_UNKNOWN
|
||||
&& resolution != LDPR_UNDEF
|
||||
&& flag_delete_null_pointer_checks)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-09-19 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR c++/61825
|
||||
* gcc.dg/tree-ssa/nonzero-1.c: Require error to be output.
|
||||
|
||||
2014-09-19 Andi Kleen <ak@linux.intel.com>
|
||||
|
||||
* gcc.dg/pg-override.c: Only run on x86 Linux.
|
||||
|
@ -1,11 +1,8 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||
extern int a;
|
||||
/* { dg-options "-O2" } */
|
||||
extern int a; /* { dg-error "declared weak after being used" } */
|
||||
t()
|
||||
{
|
||||
return &a!=0;
|
||||
}
|
||||
extern int a __attribute__ ((weak));
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "return 1" "optimized"} } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
@ -5230,6 +5230,12 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
|
||||
static void
|
||||
mark_weak (tree decl)
|
||||
{
|
||||
if (DECL_WEAK (decl))
|
||||
return;
|
||||
|
||||
struct symtab_node *n = symtab_node::get (decl);
|
||||
if (n && n->refuse_visibility_changes)
|
||||
error ("%+D declared weak after being used", decl);
|
||||
DECL_WEAK (decl) = 1;
|
||||
|
||||
if (DECL_RTL_SET_P (decl)
|
||||
|
Loading…
x
Reference in New Issue
Block a user