re PR middle-end/87248 (Bad code for masked operations involving signed ints)

PR middle-end/87248
	* fold-const.c (fold_ternary_loc) <case COND_EXPR>: Verify also that
	BIT_AND_EXPR's second operand is a power of two.  Formatting fix.

	* c-c++-common/torture/pr87248.c: New test.

From-SVN: r264230
This commit is contained in:
Jakub Jelinek 2018-09-12 11:18:55 +02:00 committed by Jakub Jelinek
parent 03e992acea
commit 9095b53a8c
4 changed files with 56 additions and 3 deletions

View File

@ -1,3 +1,9 @@
2018-09-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/87248
* fold-const.c (fold_ternary_loc) <case COND_EXPR>: Verify also that
BIT_AND_EXPR's second operand is a power of two. Formatting fix.
2018-09-12 Tom de Vries <tdevries@suse.de>
* common.opt (gdescribe-dies): Add option.

View File

@ -11607,10 +11607,16 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
&& integer_pow2p (arg1)
&& TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
&& operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
arg1, OEP_ONLY_CONST))
arg1, OEP_ONLY_CONST)
/* operand_equal_p compares just value, not precision, so e.g.
arg1 could be 8-bit -128 and be power of two, but BIT_AND_EXPR
second operand 32-bit -128, which is not a power of two (or vice
versa. */
&& integer_pow2p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)))
return pedantic_non_lvalue_loc (loc,
fold_convert_loc (loc, type,
TREE_OPERAND (arg0, 0)));
fold_convert_loc (loc, type,
TREE_OPERAND (arg0,
0)));
/* Disable the transformations below for vectors, since
fold_binary_op_with_conditional_arg may undo them immediately,

View File

@ -1,3 +1,8 @@
2018-09-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/87248
* c-c++-common/torture/pr87248.c: New test.
2018-09-11 Janus Weil <janus@gcc.gnu.org>
PR fortran/87172

View File

@ -0,0 +1,36 @@
/* PR middle-end/87248 */
/* { dg-do run } */
void
foo (signed char *p, int q)
{
*p = q & (-__SCHAR_MAX__ - 1) ? (-__SCHAR_MAX__ - 1) : 0;
}
int
bar (long long x)
{
return x & (-__INT_MAX__ - 1) ? (-__INT_MAX__ - 1) : 0;
}
int
main ()
{
#if __INT_MAX__ > 4 * __SCHAR_MAX__
signed char a[4];
foo (a, __SCHAR_MAX__ + 1U);
foo (a + 1, 2 * (__SCHAR_MAX__ + 1U));
foo (a + 2, -__INT_MAX__ - 1);
foo (a + 3, (__SCHAR_MAX__ + 1U) / 2);
if (a[0] != (-__SCHAR_MAX__ - 1) || a[1] != a[0] || a[2] != a[0] || a[3] != 0)
__builtin_abort ();
#endif
#if __LONG_LONG_MAX__ > 4 * __INT_MAX__
if (bar (__INT_MAX__ + 1LL) != (-__INT_MAX__ - 1)
|| bar (2 * (__INT_MAX__ + 1LL)) != (-__INT_MAX__ - 1)
|| bar (-__LONG_LONG_MAX__ - 1) != (-__INT_MAX__ - 1)
|| bar ((__INT_MAX__ + 1LL) / 2) != 0)
__builtin_abort ();
#endif
return 0;
}