aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2010-08-20 22:08:41 +0000
committerOlivier Hainque <hainque@gcc.gnu.org>2010-08-20 22:08:41 +0000
commitb4d456ffc0f749c78b1b53fb3e296a248ff700dd (patch)
tree25a265db39729efa8d868a101c02397e6e62df3f
parent39acb18f66f7b0ff8c36f5fa96e76168f959d2a1 (diff)
downloadgcc-b4d456ffc0f749c78b1b53fb3e296a248ff700dd.zip
gcc-b4d456ffc0f749c78b1b53fb3e296a248ff700dd.tar.gz
gcc-b4d456ffc0f749c78b1b53fb3e296a248ff700dd.tar.bz2
tree.h (alias_diag_flags): New enum.
* 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. From-SVN: r163425
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/tree.h13
-rw-r--r--gcc/varasm.c31
3 files changed, 39 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8a76347..7539067 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/tree.h b/gcc/tree.h
index 4b0078a..907fc3e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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. */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 597bac6..c509219 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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;
}
}