This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix expansion of constants with -fsection-anchors (PR middle-end/52074)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Eric Botcazou <ebotcazou at adacore dot com>, Richard Guenther <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 1 Feb 2012 17:43:55 +0100
- Subject: [PATCH] Fix expansion of constants with -fsection-anchors (PR middle-end/52074)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
For EXPAND_NORMAL we shouldn't be returning (plus (reg) (const_int)),
that should be limited to EXPAND_SUM and higher modifiers.
But with -fsection-anchors we sometimes do.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
tested with cross to powerpc64-linux on the testcase. Ok for trunk?
2012-02-01 Jakub Jelinek <jakub@redhat.com>
PR middle-end/52074
* expr.c (expand_expr_addr_expr_1): For CONSTANT_CLASS_P or CONST_DECL
if modifier < EXPAND_SUM call force_operand on the result.
* gcc.c-torture/compile/pr52074.c: New test.
--- gcc/expr.c.jj 2012-01-30 00:10:01.000000000 +0100
+++ gcc/expr.c 2012-02-01 13:00:03.468835769 +0100
@@ -7414,7 +7414,12 @@ expand_expr_addr_expr_1 (tree exp, rtx t
generating ADDR_EXPR of something that isn't an LVALUE. The only
exception here is STRING_CST. */
if (CONSTANT_CLASS_P (exp))
- return XEXP (expand_expr_constant (exp, 0, modifier), 0);
+ {
+ result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
+ if (modifier < EXPAND_SUM)
+ result = force_operand (result, target);
+ return result;
+ }
/* Everything must be something allowed by is_gimple_addressable. */
switch (TREE_CODE (exp))
@@ -7433,7 +7438,11 @@ expand_expr_addr_expr_1 (tree exp, rtx t
case CONST_DECL:
/* Expand the initializer like constants above. */
- return XEXP (expand_expr_constant (DECL_INITIAL (exp), 0, modifier), 0);
+ result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
+ 0, modifier), 0);
+ if (modifier < EXPAND_SUM)
+ result = force_operand (result, target);
+ return result;
case REALPART_EXPR:
/* The real part of the complex number is always first, therefore
--- gcc/testsuite/gcc.c-torture/compile/pr52074.c.jj 2012-02-01 13:03:26.236788697 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr52074.c 2012-02-01 13:03:07.000000000 +0100
@@ -0,0 +1,10 @@
+/* PR middle-end/52074 */
+
+struct S { const char *d, *e; } __attribute__((packed));
+
+void
+foo (const char **p, struct S *q)
+{
+ *p = "abcdef";
+ q->d = "ghijk";
+}
Jakub