From c015ff8ccaf3ee8e4f6393679ed790ed0df92873 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 16 Mar 2020 22:58:41 +0100 Subject: [PATCH] c: Handle MEM_REF in c_fully_fold* [PR94179] The recent match.pd changes can generate a MEM_REF which can be seen by the C FE folding routines. Unlike the C++ FE, they weren't expected in the C FE yet. MEM_REF should be handled like INDIRECT_REF, except that it has two operands rather than just one and that we should preserve the type of the second operand. Given that it already has to be an INTEGER_CST with pointer type, I think we are fine, the recursive call should return the INTEGER_CST unmodified and STRIP_TYPE_NOPS will not strip anything. 2020-03-16 Jakub Jelinek PR c/94179 * c-fold.c (c_fully_fold_internal): Handle MEM_REF. * gcc.c-torture/compile/pr94179.c: New test. --- gcc/c/ChangeLog | 5 +++++ gcc/c/c-fold.c | 9 +++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/compile/pr94179.c | 9 +++++++++ 4 files changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr94179.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d3a3b2fc784..240859e9fed 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2020-03-16 Jakub Jelinek + + PR c/94179 + * c-fold.c (c_fully_fold_internal): Handle MEM_REF. + 2020-03-13 Martin Sebor PR c/94040 diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index fde2d55e579..63becfeaf2c 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -346,6 +346,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, case UNGT_EXPR: case UNGE_EXPR: case UNEQ_EXPR: + case MEM_REF: /* Binary operations evaluating both arguments (increment and decrement are binary internally in GCC). */ orig_op0 = op0 = TREE_OPERAND (expr, 0); @@ -435,6 +436,14 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE) warn_for_div_by_zero (loc, op1); + if (code == MEM_REF + && ret != expr + && TREE_CODE (ret) == MEM_REF) + { + TREE_READONLY (ret) = TREE_READONLY (expr); + TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); + TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); + } goto out; case ADDR_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b277cecac3..f0d703369a8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-16 Jakub Jelinek + + PR c/94179 + * gcc.c-torture/compile/pr94179.c: New test. + 2020-03-16 Vladimir Makarov PR target/94185 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr94179.c b/gcc/testsuite/gcc.c-torture/compile/pr94179.c new file mode 100644 index 00000000000..dfe27fe61d4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr94179.c @@ -0,0 +1,9 @@ +/* PR c/94179 */ + +struct S { char c, d, e[64]; } a; + +unsigned char * +foo (int b) +{ + return (unsigned char *)((char *)&a.e[b != 0] - (char *)&((struct S *)0)->d); +} -- 2.30.2