PR c/19031
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Jan 2005 07:52:31 +0000 (07:52 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Jan 2005 07:52:31 +0000 (07:52 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92803 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-decl.c
gcc/c-lang.c
gcc/cgraph.c
gcc/cgraph.h
gcc/objc/objc-act.c
gcc/testsuite/gcc.dg/attr-alias-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/weak/weak-11.c [new file with mode: 0644]
gcc/varasm.c

index 50263c2..0ebb669 100644 (file)
@@ -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
index a0053ed..047ef59 100644 (file)
@@ -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 ();
 }
 
index 1552448..5217102 100644 (file)
@@ -89,7 +89,6 @@ const char *const tree_code_name[] = {
 void
 finish_file (void)
 {
-  maybe_apply_pending_pragma_weaks ();
 }
 
 #include "gtype-c.h"
index 8a570b3..1c06616 100644 (file)
@@ -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)
index 9156066..a30e548 100644 (file)
@@ -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);
index 0952500..e735d55 100644 (file)
@@ -603,8 +603,6 @@ objc_finish_file (void)
 
 #ifdef OBJCPLUS
   cp_finish_file ();
-#else
-  maybe_apply_pending_pragma_weaks ();
 #endif
 }
 \f
diff --git a/gcc/testsuite/gcc.dg/attr-alias-2.c b/gcc/testsuite/gcc.dg/attr-alias-2.c
new file mode 100644 (file)
index 0000000..8a21384
--- /dev/null
@@ -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 (file)
index 0000000..c20135a
--- /dev/null
@@ -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
index 362abaf..7c58b98 100644 (file)
@@ -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;