aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-11-14 08:56:54 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2002-11-14 08:56:54 +0100
commit7eca317a0fc20ba4032dc77daad321700a855f82 (patch)
tree93129dfbe6218445158cf46b67c5590976b31681
parent57751dd6cb0e941b9181e54edef85a795c108b8a (diff)
downloadgcc-7eca317a0fc20ba4032dc77daad321700a855f82.zip
gcc-7eca317a0fc20ba4032dc77daad321700a855f82.tar.gz
gcc-7eca317a0fc20ba4032dc77daad321700a855f82.tar.bz2
varasm.c (output_addressed_constants): Clear reloc if both operands contain local relocations.
* varasm.c (output_addressed_constants) [MINUS_EXPR]: Clear reloc if both operands contain local relocations. (categorize_decl_for_section): Don't use mergeable sections if initializer has any relocations. * gcc.dg/20021029-1.c: New test. * gcc.dg/20021029-2.c: New test. From-SVN: r59097
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/20021029-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/20021029-2.c14
-rw-r--r--gcc/varasm.c15
5 files changed, 54 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bdb0bd7..ae59f99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2002-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * varasm.c (output_addressed_constants) [MINUS_EXPR]: Clear reloc if
+ both operands contain local relocations.
+ (categorize_decl_for_section): Don't use mergeable sections if
+ initializer has any relocations.
+
2002-11-14 Kazu Hirata <kazu@cs.umass.edu>
* gthr-vxworks.h: Fix formatting.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa7a7da..968777c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2002-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/20021029-1.c: New test.
+ * gcc.dg/20021029-2.c: New test.
+
2002-11-13 John David Anglin <dave@hiauly1.hia.nrc.ca>
* g++.dg/abi/vague1.C (dg-final): Return if target is hppa*-*-hpux*.
diff --git a/gcc/testsuite/gcc.dg/20021029-1.c b/gcc/testsuite/gcc.dg/20021029-1.c
new file mode 100644
index 0000000..468f9c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20021029-1.c
@@ -0,0 +1,16 @@
+/* Test whether difference of local labels doesn't force
+ variables into writable sections. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-final { scan-assembler-not ".data.rel.ro.local" } } */
+
+int foo (int a)
+{
+ static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
+ void *p = &&l1 + ar[a];
+ goto *p;
+ l1:
+ return 1;
+ l2:
+ return 2;
+}
diff --git a/gcc/testsuite/gcc.dg/20021029-2.c b/gcc/testsuite/gcc.dg/20021029-2.c
new file mode 100644
index 0000000..e993424
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20021029-2.c
@@ -0,0 +1,14 @@
+/* Test whether variables with relocations aren't put into
+ mergeable sections even with -fmerge-all-constants. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fmerge-all-constants" } */
+/* { dg-final { scan-assembler-not ".rodata.cst" } } */
+
+int foo (int a)
+{
+ static void * const ar[] = { &&l2 };
+ void *p = ar[a];
+ goto *p;
+l2:
+ return 2;
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index d498b8f..b158b92 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3679,7 +3679,7 @@ static int
output_addressed_constants (exp)
tree exp;
{
- int reloc = 0;
+ int reloc = 0, reloc2;
tree tem;
/* Give the front-end a chance to convert VALUE to something that
@@ -3708,11 +3708,20 @@ output_addressed_constants (exp)
break;
case PLUS_EXPR:
- case MINUS_EXPR:
reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
break;
+ case MINUS_EXPR:
+ reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
+ reloc2 = output_addressed_constants (TREE_OPERAND (exp, 1));
+ /* The difference of two local labels is computable at link time. */
+ if (reloc == 1 && reloc2 == 1)
+ reloc = 0;
+ else
+ reloc |= reloc2;
+ break;
+
case NOP_EXPR:
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
@@ -5076,7 +5085,7 @@ categorize_decl_for_section (decl, reloc, shlib)
ret = SECCAT_DATA_REL_RO;
else if (shlib && reloc)
ret = SECCAT_DATA_REL_RO_LOCAL;
- else if (flag_merge_constants < 2)
+ else if (reloc || flag_merge_constants < 2)
/* C and C++ don't allow different variables to share the same
location. -fmerge-all-constants allows even that (at the
expense of not conforming). */