diff mbox

prevent doubled diagnostics on symbol alias pairs

Message ID 20100820165926.GA22223@cardhu.act-europe.fr
State New
Headers show

Commit Message

Olivier Hainque Aug. 20, 2010, 4:59 p.m. UTC
Hello,

Compiling this code:

    /* au.c */
    extern int var __attribute__ ((alias ("undef")));

on e.g. x86-linux, the current mainline compiler emits the "aliased to
undefined" diagnostic twice:

 << au.c:1:12: error: 'var' aliased to undefined symbol 'undef'
    au.c:1:12: error: 'var' aliased to undefined symbol 'undef'
 >>

This is caused by the compiler going through finish_aliases_1
from several places for different or iterative purposes.

The attached patch is a suggestion to address this by teaching the
circuitry to remember which diags it has emitted for alias_pairs already.

Bootstrapped and regression tested on x86_64-suse-linux.

OK ?

Thanks in advance,

With Kind Regards,

Olivier

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.

Comments

Richard Henderson Aug. 20, 2010, 5:39 p.m. UTC | #1
On 08/20/2010 09:59 AM, Olivier Hainque wrote:
> 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.

Ok.


r~
Olivier Hainque Aug. 20, 2010, 10:07 p.m. UTC | #2
Richard Henderson wrote:
> >         * 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.
> 
> Ok.

 About to commit. Thanks for your prompt review :)

 Olivier
diff mbox

Patch

Index: tree.h
===================================================================
--- tree.h	(revision 163326)
+++ tree.h	(working copy)
@@ -184,10 +184,21 @@ 
    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: varasm.c
===================================================================
--- varasm.c	(revision 163326)
+++ varasm.c	(working copy)
@@ -5444,19 +5444,27 @@ 
       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 @@ 
       alias_pair *p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
       p->decl = decl;
       p->target = target;
+      p->emitted_diags = ALIAS_DIAG_NONE;
     }
 }