This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix c/19031
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 1 Jan 2005 23:53:53 -0800
- Subject: fix c/19031
The solution here is to let cgraph know (kinda) about the dependency
between the alias and its referant. C and ObjC needed a tweak so that
this would happen early enough; C++ already did this in the right place.
Tested on i686-linux.
r~
PR c/19031
* c-decl.c (pop_file_scope): Call maybe_apply_pending_pragma_weaks.
* c-lang.c (finish_file): Don't do it here.
* objc/objc-act.c (objc_finish_file): Likewise.
* cgraph.c (decl_assembler_name_equal): New.
(cgraph_node_for_asm, cgraph_varpool_node_for_asm): New.
(cgraph_varpool_node): Actually link up cgraph_varpool_nodes.
* cgraph.h (struct cgraph_varpool_node): Add next.
(cgraph_node_for_asm, cgraph_varpool_node_for_asm): Declare.
* varasm.c (assemble_alias): Mark the target as needed.
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.621
diff -c -p -d -r1.621 c-decl.c
*** gcc/c-decl.c 1 Jan 2005 16:15:10 -0000 1.621
--- gcc/c-decl.c 2 Jan 2005 07:47:28 -0000
*************** pop_file_scope (void)
*** 897,902 ****
--- 897,904 ----
/* Pop off the file scope and close this translation unit. */
pop_scope ();
file_scope = 0;
+
+ maybe_apply_pending_pragma_weaks ();
cgraph_finalize_compilation_unit ();
}
Index: gcc/c-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lang.c,v
retrieving revision 1.137
diff -c -p -d -r1.137 c-lang.c
*** gcc/c-lang.c 29 Nov 2004 18:53:53 -0000 1.137
--- gcc/c-lang.c 2 Jan 2005 07:47:28 -0000
*************** const char *const tree_code_name[] = {
*** 89,95 ****
void
finish_file (void)
{
- maybe_apply_pending_pragma_weaks ();
}
#include "gtype-c.h"
--- 89,94 ----
Index: gcc/cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.61
diff -c -p -d -r1.61 cgraph.c
*** gcc/cgraph.c 13 Nov 2004 21:11:04 -0000 1.61
--- gcc/cgraph.c 2 Jan 2005 07:47:28 -0000
*************** cgraph_node (tree decl)
*** 194,199 ****
--- 194,249 ----
return node;
}
+ /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
+
+ static bool
+ decl_assembler_name_equal (tree decl, tree asmname)
+ {
+ tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
+
+ if (decl_asmname == asmname)
+ return true;
+
+ /* If the target assembler name was set by the user, things are trickier.
+ We have a leading '*' to begin with. After that, it's arguable what
+ is the correct thing to do with -fleading-underscore. Arguably, we've
+ historically been doing the wrong thing in assemble_alias by always
+ printing the leading underscore. Since we're not changing that, make
+ sure user_label_prefix follows the '*' before matching. */
+ if (IDENTIFIER_POINTER (decl_asmname)[0] == '*')
+ {
+ const char *decl_str = IDENTIFIER_POINTER (decl_asmname) + 1;
+ size_t ulp_len = strlen (user_label_prefix);
+
+ if (ulp_len == 0)
+ ;
+ else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
+ decl_str += ulp_len;
+ else
+ return false;
+
+ return strcmp (decl_str, IDENTIFIER_POINTER (asmname)) == 0;
+ }
+
+ return false;
+ }
+
+
+ /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
+ Return NULL if there's no such node. */
+
+ struct cgraph_node *
+ cgraph_node_for_asm (tree asmname)
+ {
+ struct cgraph_node *node;
+
+ for (node = cgraph_nodes; node ; node = node->next)
+ if (decl_assembler_name_equal (node->decl, asmname))
+ return node;
+
+ return NULL;
+ }
+
/* Return callgraph edge representing CALL_EXPR. */
struct cgraph_edge *
cgraph_edge (struct cgraph_node *node, tree call_expr)
*************** cgraph_varpool_node (tree decl)
*** 533,544 ****
--- 583,607 ----
return *slot;
node = ggc_alloc_cleared (sizeof (*node));
node->decl = decl;
+ node->next = cgraph_varpool_nodes;
cgraph_varpool_n_nodes++;
cgraph_varpool_nodes = node;
*slot = node;
return node;
}
+ struct cgraph_varpool_node *
+ cgraph_varpool_node_for_asm (tree asmname)
+ {
+ struct cgraph_varpool_node *node;
+
+ for (node = cgraph_varpool_nodes; node ; node = node->next)
+ if (decl_assembler_name_equal (node->decl, asmname))
+ return node;
+
+ return NULL;
+ }
+
/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */
void
change_decl_assembler_name (tree decl, tree name)
Index: gcc/cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.41
diff -c -p -d -r1.41 cgraph.h
*** gcc/cgraph.h 18 Nov 2004 00:09:16 -0000 1.41
--- gcc/cgraph.h 2 Jan 2005 07:47:28 -0000
*************** struct cgraph_edge GTY((chain_next ("%h.
*** 138,143 ****
--- 138,145 ----
struct cgraph_varpool_node GTY(())
{
tree decl;
+ /* Pointer to the next function in cgraph_varpool_nodes. */
+ struct cgraph_varpool_node *next;
/* Pointer to the next function in cgraph_varpool_nodes_queue. */
struct cgraph_varpool_node *next_needed;
*************** struct cgraph_edge *cgraph_create_edge (
*** 168,173 ****
--- 170,176 ----
struct cgraph_node *,
tree);
struct cgraph_node *cgraph_node (tree decl);
+ struct cgraph_node *cgraph_node_for_asm (tree asmname);
struct cgraph_edge *cgraph_edge (struct cgraph_node *, tree call_expr);
struct cgraph_local_info *cgraph_local_info (tree);
struct cgraph_global_info *cgraph_global_info (tree);
*************** struct cgraph_edge * cgraph_clone_edge (
*** 177,182 ****
--- 180,186 ----
struct cgraph_node * cgraph_clone_node (struct cgraph_node *);
struct cgraph_varpool_node *cgraph_varpool_node (tree decl);
+ struct cgraph_varpool_node *cgraph_varpool_node_for_asm (tree asmname);
void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
void cgraph_varpool_finalize_decl (tree);
bool cgraph_varpool_assemble_pending_decls (void);
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.471
diff -c -p -d -r1.471 varasm.c
*** gcc/varasm.c 23 Dec 2004 07:13:05 -0000 1.471
--- gcc/varasm.c 2 Jan 2005 07:47:29 -0000
*************** globalize_decl (tree decl)
*** 4344,4350 ****
the symbol for TARGET. */
void
! assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED)
{
const char *name;
--- 4344,4350 ----
the symbol for TARGET. */
void
! assemble_alias (tree decl, tree target)
{
const char *name;
*************** assemble_alias (tree decl, tree target A
*** 4395,4400 ****
--- 4395,4438 ----
#endif
#endif
+ /* Tell cgraph that the aliased symbol is needed. We *could* be more
+ specific and tell cgraph about the relationship between the two
+ symbols, but given that aliases virtually always exist for a reason,
+ it doesn't seem worthwhile. */
+ if (flag_unit_at_a_time)
+ {
+ struct cgraph_node *fnode = NULL;
+ struct cgraph_varpool_node *vnode = NULL;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ fnode = cgraph_node_for_asm (target);
+ if (fnode != NULL)
+ cgraph_mark_needed_node (fnode);
+ else
+ {
+ vnode = cgraph_varpool_node_for_asm (target);
+ if (vnode != NULL)
+ cgraph_varpool_mark_needed_node (vnode);
+ }
+ }
+ else
+ {
+ vnode = cgraph_varpool_node_for_asm (target);
+ if (vnode != NULL)
+ cgraph_varpool_mark_needed_node (vnode);
+ else
+ {
+ fnode = cgraph_node_for_asm (target);
+ if (fnode != NULL)
+ cgraph_mark_needed_node (fnode);
+ }
+ }
+
+ if (fnode == NULL && vnode == NULL)
+ warning ("%qD aliased to undefined symbol %qE", decl, target);
+ }
+
TREE_USED (decl) = 1;
TREE_ASM_WRITTEN (decl) = 1;
TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1;
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.259
diff -c -p -d -r1.259 objc-act.c
*** gcc/objc/objc-act.c 30 Dec 2004 10:18:09 -0000 1.259
--- gcc/objc/objc-act.c 2 Jan 2005 07:47:30 -0000
*************** objc_finish_file (void)
*** 603,610 ****
#ifdef OBJCPLUS
cp_finish_file ();
- #else
- maybe_apply_pending_pragma_weaks ();
#endif
}
--- 603,608 ----
Index: gcc/testsuite/gcc.dg/attr-alias-2.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/attr-alias-2.c
diff -N gcc/testsuite/gcc.dg/attr-alias-2.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/gcc.dg/attr-alias-2.c 2 Jan 2005 07:47:30 -0000
***************
*** 0 ****
--- 1,20 ----
+ /* PR 19031 */
+ /* { dg-do link } */
+ /* { dg-require-alias } */
+ /* { dg-options "-funit-at-a-time" } */
+
+ static int f1 (void) { return 0; }
+ extern int g1 (void) __attribute__((__alias__("f1")));
+
+ #define STR(x) STR1(__USER_LABEL_PREFIX__, x)
+ #define STR1(x,y) STR2(x, y)
+ #define STR2(x,y) #x #y
+
+ static int f2 (void) __asm__(STR(a2));
+ static int f2 (void) { return 0; }
+ extern int g2 (void) __attribute__((__alias__("a2")));
+
+ int main ()
+ {
+ return g1() + g2();
+ }
Index: gcc/testsuite/gcc.dg/weak/weak-11.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/weak/weak-11.c
diff -N gcc/testsuite/gcc.dg/weak/weak-11.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/gcc.dg/weak/weak-11.c 2 Jan 2005 07:47:30 -0000
***************
*** 0 ****
--- 1,10 ----
+ /* PR 19031 */
+ /* { dg-do compile } */
+ /* { dg-require-weak "" } */
+ /* { dg-require-alias "" } */
+ /* { dg-options "-funit-at-a-time" } */
+
+ /* { dg-final { scan-assembler "xyzzy" } } */
+
+ static const int local = 1;
+ #pragma weak xyzzy = local