aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorAndrew Stubbs <ams@codesourcery.com>2012-05-15 10:53:04 +0100
committerAndrew Stubbs <ams@codesourcery.com>2012-05-15 10:53:04 +0100
commit2a576c06f3d410c3f1a50b35e77dd09df9737b0c (patch)
tree0fbb0d6fb9312d472a21f2223a70d9dc475972ed /gcc/varasm.c
parent371de70c3e1bcae5570733b47da9ac7d6914ee21 (diff)
Merge from FSF (GCC SVN branches/gcc-4_7-branch:187448)
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 1e58bd46b0a..bb835bcd4b6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1,7 +1,7 @@
/* Output variables, constants and external declarations, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011 Free Software Foundation, Inc.
+ 2010, 2011, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -315,11 +315,16 @@ get_section (const char *name, unsigned int flags, tree decl)
if (decl == 0)
decl = sect->named.decl;
gcc_assert (decl);
- error ("%+D causes a section type conflict with %D",
- decl, sect->named.decl);
- if (decl != sect->named.decl)
- inform (DECL_SOURCE_LOCATION (sect->named.decl),
- "%qD was declared here", sect->named.decl);
+ if (sect->named.decl == NULL)
+ error ("%+D causes a section type conflict", decl);
+ else
+ {
+ error ("%+D causes a section type conflict with %D",
+ decl, sect->named.decl);
+ if (decl != sect->named.decl)
+ inform (DECL_SOURCE_LOCATION (sect->named.decl),
+ "%qD was declared here", sect->named.decl);
+ }
/* Make sure we don't error about one section multiple times. */
sect->common.flags |= SECTION_OVERRIDE;
}
@@ -2108,6 +2113,11 @@ static GTY(()) tree pending_assemble_externals;
the entire pending_assemble_externals list. See assemble_external(). */
static struct pointer_set_t *pending_assemble_externals_set;
+/* Some targets delay some output to final using TARGET_ASM_FILE_END.
+ As a result, assemble_external can be called after the list of externals
+ is processed and the pointer set destroyed. */
+static bool pending_assemble_externals_processed;
+
#ifdef ASM_OUTPUT_EXTERNAL
/* True if DECL is a function decl for which no out-of-line copy exists.
It is assumed that DECL's assembler name has been set. */
@@ -2160,6 +2170,7 @@ process_pending_assemble_externals (void)
assemble_external_real (TREE_VALUE (list));
pending_assemble_externals = 0;
+ pending_assemble_externals_processed = true;
pointer_set_destroy (pending_assemble_externals_set);
#endif
}
@@ -2201,6 +2212,12 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
weak_decls = tree_cons (NULL, decl, weak_decls);
#ifdef ASM_OUTPUT_EXTERNAL
+ if (pending_assemble_externals_processed)
+ {
+ assemble_external_real (decl);
+ return;
+ }
+
if (! pointer_set_insert (pending_assemble_externals_set, decl))
pending_assemble_externals = tree_cons (NULL, decl,
pending_assemble_externals);
@@ -3936,6 +3953,13 @@ compute_reloc_for_constant (tree exp)
tem = TREE_OPERAND (tem, 0))
;
+ if (TREE_CODE (tem) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR)
+ {
+ reloc = compute_reloc_for_constant (TREE_OPERAND (tem, 0));
+ break;
+ }
+
if (TREE_PUBLIC (tem))
reloc |= 2;
else
@@ -4004,6 +4028,9 @@ output_addressed_constants (tree exp)
if (CONSTANT_CLASS_P (tem) || TREE_CODE (tem) == CONSTRUCTOR)
output_constant_def (tem, 0);
+
+ if (TREE_CODE (tem) == MEM_REF)
+ output_addressed_constants (TREE_OPERAND (tem, 0));
break;
case PLUS_EXPR: