diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 15 | ||||
-rw-r--r-- | gcc/output.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr65780-1.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr65780-2.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr32219-1.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr32219-9.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr64317.c | 2 | ||||
-rw-r--r-- | gcc/varasm.c | 35 |
10 files changed, 105 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 008e36a..71c692e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-04-17 H.J. Lu <hongjiu.lu@intel.com> + + PR target/65780 + * output.h (default_binds_local_p_3): New. + * varasm.c (default_binds_local_p_3): Make it public. Take an + argument to indicate if common symbol may be local. If common + symbol may be local, treat non-external variable as defined + locally. + (default_binds_local_p_2): Pass !flag_pic to default_binds_local_p_3. + (default_binds_local_p_1): Pass false to default_binds_local_p_3. + * config/i386/i386.c (ix86_binds_local_p): New. + (TARGET_BINDS_LOCAL_P): Replace default_binds_local_p_2 with + ix86_binds_local_p. + 2015-04-17 Jakub Jelinek <jakub@redhat.com> PR debug/65771 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 1f20ff3..72e6bc2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -51793,6 +51793,19 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts) return 2; } +/* For i386, common symbol is local only for non-PIE binaries. For + x86-64, common symbol is local only for non-PIE binaries or linker + supports copy reloc in PIE binaries. */ + +static bool +ix86_binds_local_p (const_tree exp) +{ + return default_binds_local_p_3 (exp, flag_shlib != 0, true, true, + (!flag_pic + || (TARGET_64BIT + && HAVE_LD_PIE_COPYRELOC != 0))); +} + /* Initialize the GCC target structure. */ #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory @@ -51927,7 +51940,7 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts) #define TARGET_BINDS_LOCAL_P darwin_binds_local_p #else #undef TARGET_BINDS_LOCAL_P -#define TARGET_BINDS_LOCAL_P default_binds_local_p_2 +#define TARGET_BINDS_LOCAL_P ix86_binds_local_p #endif #if TARGET_DLLIMPORT_DECL_ATTRIBUTES #undef TARGET_BINDS_LOCAL_P diff --git a/gcc/output.h b/gcc/output.h index 53e47d0..81d2ad2 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -587,6 +587,7 @@ extern bool default_use_anchors_for_symbol_p (const_rtx); extern bool default_binds_local_p (const_tree); extern bool default_binds_local_p_1 (const_tree, int); extern bool default_binds_local_p_2 (const_tree); +extern bool default_binds_local_p_3 (const_tree, bool, bool, bool, bool); extern void default_globalize_label (FILE *, const char *); extern void default_globalize_decl_name (FILE *, tree); extern void default_emit_unwind_label (FILE *, tree, int, int); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7b3048..c6bd2ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,15 @@ 2015-04-17 H.J. Lu <hongjiu.lu@intel.com> + PR target/65780 + * gcc.dg/pr65780-1.c: New test. + * gcc.dg/pr65780-2.c: Likewise. + * gcc.target/i386/pr32219-9.c: Likewise. + * gcc.target/i386/pr32219-1.c (xxx): Make it initialized common + symbol. + * gcc.target/i386/pr64317.c (c): Initialize. + +2015-04-17 H.J. Lu <hongjiu.lu@intel.com> + PR target/65612 * g++.dg/ext/mv18.C: New test. * g++.dg/ext/mv19.C: Likewise. diff --git a/gcc/testsuite/gcc.dg/pr65780-1.c b/gcc/testsuite/gcc.dg/pr65780-1.c new file mode 100644 index 0000000..b586211 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr65780-1.c @@ -0,0 +1,12 @@ +/* PR target/65780 */ +/* { dg-do link { target *-*-linux* *-*-gnu* } } */ +/* { dg-options "-O2" } */ + +int optopt; + +int +main () +{ + optopt = 4; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr65780-2.c b/gcc/testsuite/gcc.dg/pr65780-2.c new file mode 100644 index 0000000..bff3323 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr65780-2.c @@ -0,0 +1,13 @@ +/* PR target/65780 */ +/* { dg-do link { target *-*-linux* *-*-gnu* } } */ +/* { dg-require-effective-target pie } */ +/* { dg-options "-O2 -fpie" } */ + +int optopt; + +int +main () +{ + optopt = 4; + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr32219-1.c b/gcc/testsuite/gcc.target/i386/pr32219-1.c index 5bd80a0..2622f66 100644 --- a/gcc/testsuite/gcc.target/i386/pr32219-1.c +++ b/gcc/testsuite/gcc.target/i386/pr32219-1.c @@ -1,7 +1,8 @@ /* { dg-do compile { target *-*-linux* } } */ /* { dg-options "-O2 -fpie" } */ -/* Common symbol with -fpie. */ +/* Initialized common symbol with -fpie. */ +int xxx = 5; int xxx; int diff --git a/gcc/testsuite/gcc.target/i386/pr32219-9.c b/gcc/testsuite/gcc.target/i386/pr32219-9.c new file mode 100644 index 0000000..8c21826 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr32219-9.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target pie_copyreloc } */ +/* { dg-options "-O2 -fpie" } */ + +/* Uninitialized common symbol with -fpie. */ +int xxx; + +int +foo () +{ + return xxx; +} + +/* { dg-final { scan-assembler "movl\[ \t\]xxx\\(%rip\\), %eax" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "xxx@GOTPCREL" { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr64317.c b/gcc/testsuite/gcc.target/i386/pr64317.c index 32969fc..8cac6dd 100644 --- a/gcc/testsuite/gcc.target/i386/pr64317.c +++ b/gcc/testsuite/gcc.target/i386/pr64317.c @@ -3,7 +3,7 @@ /* { dg-final { scan-assembler "addl\[ \\t\]+\[$\]_GLOBAL_OFFSET_TABLE_, %ebx" } } */ /* { dg-final { scan-assembler "movl\[ \\t\]+c@GOTOFF\[(\]%ebx\[)\]" } } */ /* { dg-final { scan-assembler-not "movl\[ \\t\]+\[0-9]+\[(\]%esp\[)\], %ebx" } } */ -long c; +long c = 1; int bar(); diff --git a/gcc/varasm.c b/gcc/varasm.c index e644b1d..e8d996c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -6809,9 +6809,13 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution) || resolution == LDPR_RESOLVED_EXEC); } -static bool +/* COMMON_LOCAL_P is true means that the linker can guarantee that an + uninitialized common symbol in the executable will still be defined + (through COPY relocation) in the executable. */ + +bool default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, - bool extern_protected_data) + bool extern_protected_data, bool common_local_p) { /* A non-decl is an entry in the constant pool. */ if (!DECL_P (exp)) @@ -6836,7 +6840,16 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, because dynamic linking might overwrite symbols in shared libraries. */ bool resolved_locally = false; - bool defined_locally = !DECL_EXTERNAL (exp); + + bool uninited_common = (DECL_COMMON (exp) + && (DECL_INITIAL (exp) == NULL + || (!in_lto_p + && DECL_INITIAL (exp) == error_mark_node))); + + /* A non-external variable is defined locally only if it isn't + uninitialized COMMON variable or common_local_p is true. */ + bool defined_locally = (!DECL_EXTERNAL (exp) + && (!uninited_common || common_local_p)); if (symtab_node *node = symtab_node::get (exp)) { if (node->in_other_partition) @@ -6878,10 +6891,7 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, /* Uninitialized COMMON variable may be unified with symbols resolved from other modules. */ - if (DECL_COMMON (exp) - && !resolved_locally - && (DECL_INITIAL (exp) == NULL - || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node))) + if (uninited_common && !resolved_locally) return false; /* Otherwise we're left with initialized (or non-common) global data @@ -6895,21 +6905,22 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, bool default_binds_local_p (const_tree exp) { - return default_binds_local_p_3 (exp, flag_shlib != 0, true, false); + return default_binds_local_p_3 (exp, flag_shlib != 0, true, false, false); } -/* Similar to default_binds_local_p, but protected data may be - external. */ +/* Similar to default_binds_local_p, but common symbol may be local. */ + bool default_binds_local_p_2 (const_tree exp) { - return default_binds_local_p_3 (exp, flag_shlib != 0, true, true); + return default_binds_local_p_3 (exp, flag_shlib != 0, true, false, + !flag_pic); } bool default_binds_local_p_1 (const_tree exp, int shlib) { - return default_binds_local_p_3 (exp, shlib != 0, false, false); + return default_binds_local_p_3 (exp, shlib != 0, false, false, false); } /* Return true when references to DECL must bind to current definition in |