aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-05-20 23:09:11 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2009-05-20 23:09:11 +0200
commit776248b87e53e18386405561ca260c665ca6bdb7 (patch)
treebefe401eb3201bc82589618ec4f366a7daa6ced7
parent6dea8e99a9430efa08176dfa5beb94fa9996480b (diff)
downloadgcc-776248b87e53e18386405561ca260c665ca6bdb7.zip
gcc-776248b87e53e18386405561ca260c665ca6bdb7.tar.gz
gcc-776248b87e53e18386405561ca260c665ca6bdb7.tar.bz2
re PR middle-end/40204 (segfault with bitfields in structs)
PR middle-end/40204 * fold-const.c (fold_binary) <case BIT_AND_EXPR>: Avoid infinite recursion if build_int_cst_type returns the same INTEGER_CST as arg1. * gcc.c-torture/compile/pr40204.c: New test. From-SVN: r147749
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40204.c14
4 files changed, 31 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 25d73d9..8770426 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2009-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40204
+ * fold-const.c (fold_binary) <case BIT_AND_EXPR>: Avoid infinite
+ recursion if build_int_cst_type returns the same INTEGER_CST as
+ arg1.
+
2009-05-20 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (build_fold_addr_expr_with_type): Take the address of
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0ac9e29..e322ecb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -11382,6 +11382,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (prec < HOST_BITS_PER_WIDE_INT
|| newmask == ~(unsigned HOST_WIDE_INT) 0)
{
+ tree newmaskt;
+
if (shift_type != TREE_TYPE (arg0))
{
tem = fold_build2 (TREE_CODE (arg0), shift_type,
@@ -11392,9 +11394,9 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
}
else
tem = op0;
- return fold_build2 (BIT_AND_EXPR, type, tem,
- build_int_cst_type (TREE_TYPE (op1),
- newmask));
+ newmaskt = build_int_cst_type (TREE_TYPE (op1), newmask);
+ if (!tree_int_cst_equal (newmaskt, arg1))
+ return fold_build2 (BIT_AND_EXPR, type, tem, newmaskt);
}
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cca56e5..465ae00 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40204
+ * gcc.c-torture/compile/pr40204.c: New test.
+
2009-05-20 Richard Guenther <rguenther@suse.de>
* gcc.c-torture/compile/20090518-1.c: New testcase.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40204.c b/gcc/testsuite/gcc.c-torture/compile/pr40204.c
new file mode 100644
index 0000000..3193284
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40204.c
@@ -0,0 +1,14 @@
+/* PR middle-end/40204 */
+
+struct S
+{
+ unsigned int a : 4;
+ unsigned int b : 28;
+} s;
+char c;
+
+void
+f (void)
+{
+ s.a = (c >> 4) & ~(1 << 4);
+}