OSDN Git Service

* tree.h (alias_diag_flags): New enum.
authorhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 20 Aug 2010 22:08:41 +0000 (22:08 +0000)
committerhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 20 Aug 2010 22:08:41 +0000 (22:08 +0000)
        (alias_pair): Add an 'emitted_diags' field.
        * varasm.c (finish_aliases_1): Honor and update
        * p->emitted_diags.
        (assemble_alias): Initialize emitted_diags of new pairs.

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

gcc/ChangeLog
gcc/tree.h
gcc/varasm.c

index 8a76347..7539067 100644 (file)
@@ -1,3 +1,10 @@
+2010-08-20  Olivier Hainque  <hainque@adacore.com>
+
+       * tree.h (alias_diag_flags): New enum.
+       (alias_pair): Add an 'emitted_diags' field.
+       * varasm.c (finish_aliases_1): Honor and update p->emitted_diags.
+       (assemble_alias): Initialize emitted_diags of new pairs.
+
 2010-08-20  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/rs6000/aix.h (STACK_CHECK_STATIC_BUILTIN): Define to 1.
index 4b0078a..907fc3e 100644 (file)
@@ -184,10 +184,21 @@ extern const char *const tree_code_name[];
    of an alias.  This requires that the decl have been defined.  Aliases
    that precede their definition have to be queued for later processing.  */
 
+/* The deferred processing proceeds in several passes.  We memorize the
+   diagnostics emitted for a pair to prevent repeating messages when the
+   queue gets re-scanned after possible updates.  */
+
+typedef enum {
+  ALIAS_DIAG_NONE      = 0x0,
+  ALIAS_DIAG_TO_UNDEF  = 0x1,
+  ALIAS_DIAG_TO_EXTERN = 0x2
+} alias_diag_flags;
+  
 typedef struct GTY(()) alias_pair
 {
   tree decl;
-  tree target;
+  tree target;  
+  int  emitted_diags;  /* alias_diags already emitted for this pair.  */
 } alias_pair;
 
 /* Define gc'd vector type.  */
index 597bac6..c509219 100644 (file)
@@ -5444,19 +5444,27 @@ finish_aliases_1 (void)
       target_decl = find_decl_and_mark_needed (p->decl, p->target);
       if (target_decl == NULL)
        {
-         if (! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
-           error ("%q+D aliased to undefined symbol %qE",
-                  p->decl, p->target);
+         if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF)
+             && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
+           {
+             error ("%q+D aliased to undefined symbol %qE",
+                    p->decl, p->target);
+             p->emitted_diags |= ALIAS_DIAG_TO_UNDEF;
+           }
        }
-      else if (DECL_EXTERNAL (target_decl)
-              /* We use local aliases for C++ thunks to force the tailcall
-                 to bind locally.  Of course this is a hack - to keep it
-                 working do the following (which is not strictly correct).  */
-              && (! TREE_CODE (target_decl) == FUNCTION_DECL
-                  || ! DECL_VIRTUAL_P (target_decl))
+      else if (! (p->emitted_diags & ALIAS_DIAG_TO_EXTERN)
+              && DECL_EXTERNAL (target_decl)
+              /* We use local aliases for C++ thunks to force the tailcall
+                 to bind locally.  This is a hack - to keep it working do
+                 the following (which is not strictly correct).  */
+              && (! TREE_CODE (target_decl) == FUNCTION_DECL
+                  || ! DECL_VIRTUAL_P (target_decl))
               && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
-       error ("%q+D aliased to external symbol %qE",
-              p->decl, p->target);
+       {
+         error ("%q+D aliased to external symbol %qE",
+                p->decl, p->target);     
+         p->emitted_diags |= ALIAS_DIAG_TO_EXTERN;
+       }
     }
 }
 
@@ -5549,6 +5557,7 @@ assemble_alias (tree decl, tree target)
       alias_pair *p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
       p->decl = decl;
       p->target = target;
+      p->emitted_diags = ALIAS_DIAG_NONE;
     }
 }