diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/c-decl.c | 2 | ||||
-rw-r--r-- | gcc/c-lang.c | 1 | ||||
-rw-r--r-- | gcc/cgraph.c | 63 | ||||
-rw-r--r-- | gcc/cgraph.h | 4 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-alias-2.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/weak/weak-11.c | 10 | ||||
-rw-r--r-- | gcc/varasm.c | 40 |
9 files changed, 152 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50263c2..0ebb669 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-01-01 Richard Henderson <rth@redhat.com> + + 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. + 2005-01-01 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/19221 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index a0053ed..047ef59 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -897,6 +897,8 @@ pop_file_scope (void) /* Pop off the file scope and close this translation unit. */ pop_scope (); file_scope = 0; + + maybe_apply_pending_pragma_weaks (); cgraph_finalize_compilation_unit (); } diff --git a/gcc/c-lang.c b/gcc/c-lang.c index 1552448..5217102 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -89,7 +89,6 @@ const char *const tree_code_name[] = { void finish_file (void) { - maybe_apply_pending_pragma_weaks (); } #include "gtype-c.h" diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 8a570b3..1c06616 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -194,6 +194,56 @@ cgraph_node (tree decl) 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) @@ -533,12 +583,25 @@ cgraph_varpool_node (tree decl) 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) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 9156066..a30e548 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -138,6 +138,8 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"))) 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; @@ -168,6 +170,7 @@ struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, 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); @@ -177,6 +180,7 @@ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *, struct cgraph_node 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); diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 0952500..e735d55 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -603,8 +603,6 @@ objc_finish_file (void) #ifdef OBJCPLUS cp_finish_file (); -#else - maybe_apply_pending_pragma_weaks (); #endif } diff --git a/gcc/testsuite/gcc.dg/attr-alias-2.c b/gcc/testsuite/gcc.dg/attr-alias-2.c new file mode 100644 index 0000000..8a21384 --- /dev/null +++ b/gcc/testsuite/gcc.dg/attr-alias-2.c @@ -0,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(); +} diff --git a/gcc/testsuite/gcc.dg/weak/weak-11.c b/gcc/testsuite/gcc.dg/weak/weak-11.c new file mode 100644 index 0000000..c20135a --- /dev/null +++ b/gcc/testsuite/gcc.dg/weak/weak-11.c @@ -0,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 diff --git a/gcc/varasm.c b/gcc/varasm.c index 362abaf..7c58b98 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4344,7 +4344,7 @@ globalize_decl (tree decl) the symbol for TARGET. */ void -assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED) +assemble_alias (tree decl, tree target) { const char *name; @@ -4395,6 +4395,44 @@ assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED) #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; |