re PR c++/61825 (g++.dg/cpp0x/static_assert9.C FAILs)
authorJan Hubicka <hubicka@ucw.cz>
Fri, 19 Sep 2014 23:56:52 +0000 (01:56 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 19 Sep 2014 23:56:52 +0000 (23:56 +0000)
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

gcc/ChangeLog
gcc/c-family/c-common.c
gcc/cgraph.h
gcc/fold-const.c
gcc/symtab.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/nonzero-1.c
gcc/varasm.c

index 04db32adcce8f8c4dbacc994f0cb00e944ed863c..c345dc174dd16605997cdc2c7dc2fc943a808ddb 100644 (file)
@@ -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
index 39be9569395588996a147ccfc088a807726cb85e..818c32d68a0e0af558640954bd2bbd09a02598f3 100644 (file)
@@ -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;
 }
 
index 030a1c771b7c72741146ec7d3d6a2fa6c7289dcd..a316e406ce7af4e972846eefaffe278f09367f89 100644 (file)
@@ -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  */
index f7bf5254e1807291b2bc8ab3b5d1add73b9ed1aa..5cfc6461a4bf6b24dba870bdc742b879607f3f54 100644 (file)
@@ -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
index 792b3b50ea6a04bf1ea228a6201475df825c3c45..9590fc83dd2c320501e634361a9ddd4b658c386c 100644 (file)
@@ -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;
index 89c88ebe9a0ce2d3b8dc401c4f13d88d3be182f7..130c6a75b1d07efbb065a3d42a41f1d16836afb4 100644 (file)
@@ -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.
index c79811bccb894b19771529eac99da89e94415368..52e4a9a34747020cbcfa3d89c316503ab0b60c36 100644 (file)
@@ -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" } } */
index 111c6578c5f3a58f7282e4dde1a7935ffddd5b99..dd3211a2c5c37ae6a8de546e949decd921e90c24 100644 (file)
@@ -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)