From: Jan Hubicka Date: Fri, 19 Sep 2014 23:56:52 +0000 (+0200) Subject: re PR c++/61825 (g++.dg/cpp0x/static_assert9.C FAILs) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f7217cde7f382aeb19dd3e80bc8f7ffae798315f;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04db32adcce..c345dc174dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-09-19 Jan Hubicka + + 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 * config/rs6000/predicates.md (fusion_gpr_mem_load): Move testing diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 39be9569395..818c32d68a0 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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; } diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 030a1c771b7..a316e406ce7 100644 --- a/gcc/cgraph.h +++ b/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 */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index f7bf5254e18..5cfc6461a4b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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 diff --git a/gcc/symtab.c b/gcc/symtab.c index 792b3b50ea6..9590fc83dd2 100644 --- a/gcc/symtab.c +++ b/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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 89c88ebe9a0..130c6a75b1d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-09-19 Jan Hubicka + + PR c++/61825 + * gcc.dg/tree-ssa/nonzero-1.c: Require error to be output. + 2014-09-19 Andi Kleen * gcc.dg/pg-override.c: Only run on x86 Linux. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/nonzero-1.c b/gcc/testsuite/gcc.dg/tree-ssa/nonzero-1.c index c79811bccb8..52e4a9a3474 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/nonzero-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/nonzero-1.c @@ -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" } } */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 111c6578c5f..dd3211a2c5c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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)