This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.8, 4.9] fold-const.c fix (PR middle-end/63608)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 12 Jun 2015 13:17:14 +0200
- Subject: [4.8, 4.9] fold-const.c fix (PR middle-end/63608)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcase ICEs in 4.8/4.9. The problem is that we don't fold
NON_LVALUE_EXPR of INTEGER_CST into the INTEGER_CST, but it seems huge
amount of fold-const.c code has the assumption that if
argN = opN;
...
STRIP_NOPS (argN);
...
if (TREE_CODE (argN) == INTEGER_CST)
then argN == opN, so passes e.g. argN instead of opN, assuming that
argN must have type already. Eric has fixed this for 5+ already
by dropping the NON_LVALUE_EXPR if the argument is isn't a possible lvalue.
Bootstrapped/regtested on x86_64-linux and i686-linux on both 4.9 and 4.8
branches with --enable-checking=yes,rtl, ok for those branches?
Is the testcase alone ok for 5.2/trunk?
A safer alternative would be just to fold NON_LVALUE_EXPR of INTEGER_CST
into the INTEGER_CST.
2015-06-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/63608
* gcc.c-torture/compile/pr63608.c: New test.
Backported from mainline
2014-05-16 Eric Botcazou <ebotcazou@adacore.com>
* fold-const (fold_unary_loc) <NON_LVALUE_EXPR>: New case.
<CASE_CONVERT>: Pass arg0 instead of op0 to fold_convert_const.
--- gcc/fold-const.c (revision 210517)
+++ gcc/fold-const.c (revision 210518)
@@ -7850,6 +7850,11 @@ fold_unary_loc (location_t loc, enum tre
return fold_convert_loc (loc, type, op0);
return NULL_TREE;
+ case NON_LVALUE_EXPR:
+ if (!maybe_lvalue_p (op0))
+ return fold_convert_loc (loc, type, op0);
+ return NULL_TREE;
+
CASE_CONVERT:
case FLOAT_EXPR:
case FIX_TRUNC_EXPR:
@@ -8113,7 +8118,7 @@ fold_unary_loc (location_t loc, enum tre
}
}
- tem = fold_convert_const (code, type, op0);
+ tem = fold_convert_const (code, type, arg0);
return tem ? tem : NULL_TREE;
case ADDR_SPACE_CONVERT_EXPR:
--- gcc/testsuite/gcc.c-torture/compile/pr63608.c.jj 2015-06-12 10:55:16.484746890 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr63608.c 2015-06-12 10:53:58.000000000 +0200
@@ -0,0 +1,14 @@
+/* PR middle-end/63608 */
+
+typedef long T;
+typedef unsigned long U;
+unsigned long a;
+
+unsigned long
+foo (int b)
+{
+ T c = 0;
+ const U d = 2248593032UL;
+ a = (c = +d) | (~4L & ~b);
+ return c;
+}
Jakub