http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53476



--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> 2012-12-13 
13:49:47 UTC ---

Reduced testcase:



static int Wv10a __attribute__((weakref ("Wv10b")));

static int Wv10b __attribute__((weakref ("wv10")));

extern int wv10;



extern void abort (void);



int main ()

{

  if (!!&Wv10a)

    abort ();

  return 0;

}



fails to link at -O1 works with -O0.



>From .000i.cgraph:



Reclaiming functions:

Reclaiming variables:

Clearing address taken flags:

Trivially needed variables:

Removing variables: Wv10a



Final Symbol table:



...



Breakpoint 5, varpool_remove_unreferenced_decls ()

    at /space/rguenther/src/svn/trunk/gcc/varpool.c:405

405               varpool_remove_node (node);

(gdb) call debug_symtab_node((symtab_node)node)

Wv10a/0 (Wv10a) @0x7ffff68fa068

  Type: variable

  Visibility: external weak

  References: Wv10b/1 (alias)

  Referring: main/2 (addr)

  Availability: available

  Varpool flags: analyzed finalized



so it's still refered to.



  if (cgraph_dump_file)

    fprintf (cgraph_dump_file, "Trivially needed variables:");

  FOR_EACH_DEFINED_VARIABLE (node)

    {

      if (node->analyzed

          && (!varpool_can_remove_if_no_refs (node)

              /* We just expanded all function bodies.  See if any of

                 them needed the variable.  */

              || (!DECL_EXTERNAL (node->symbol.decl)

                  && DECL_RTL_SET_P (node->symbol.decl))))



doesn't catch it because



(gdb) call debug_tree (node->symbol.decl)

 <var_decl 0x7ffff68045f0 Wv10a

    type <integer_type 0x7ffff67f75e8 int public SI

        size <integer_cst 0x7ffff67fa0c0 constant 32>

        unit size <integer_cst 0x7ffff67fa0e0 constant 4>

        align 32 symtab 0 alias set -1 canonical type 0x7ffff67f75e8 precision

32 min <integer_cst 0x7ffff67fa060 -2147483648> max <integer_cst 0x7ffff67fa080

2147483647>

        pointer_to_this <pointer_type 0x7ffff67ff2a0>>

    addressable used static external weak SI file t.c line 1 col 12 size

<integer_cst 0x7ffff67fa0c0 32> unit size <integer_cst 0x7ffff67fa0e0 4>

    align 32 context <translation_unit_decl 0x7ffff6918000 D.1721> attributes

<tree_list 0x7ffff68f3c08>

    (mem:SI (symbol_ref/i:DI ("Wv10a") <var_decl 0x7ffff68045f0 Wv10a>) [0

Wv10a+0 S4 A32]) chain <var_decl 0x7ffff6804688 Wv10b>>



it has DECL_EXTERNAL set (but it also is TREE_STATIC and has RTL!).

On the 4.7 branch we simply checked whether the DECL had RTL but didn't bother

to check whether it does not have DECL_EXTERNAL set.



I'd say either revert to 4.7 behavior here or do



Index: varpool.c

===================================================================

--- varpool.c   (revision 194472)

+++ varpool.c   (working copy)

@@ -358,7 +358,8 @@ varpool_remove_unreferenced_decls (void)

          && (!varpool_can_remove_if_no_refs (node)

              /* We just expanded all function bodies.  See if any of

                 them needed the variable.  */

-             || (!DECL_EXTERNAL (node->symbol.decl)

+             || (!(DECL_EXTERNAL (node->symbol.decl)

+                   && !TREE_STATIC (node->symbol.decl))

                  && DECL_RTL_SET_P (node->symbol.decl))))

        {

          enqueue_node (node, &first);



testing reversal to 4.7 behavior.

Reply via email to