Yet another missing converts caused that BIT_XOR_EXPRs with incompatible arguments have gotten into the gimplifier. Fixed thus. This patch also improves readability by using a temporary, the current style wasn't very readable especially because of the wrong formatting caused by adding the *_loc variants...
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2017-04-27 Marek Polacek <pola...@redhat.com> PR sanitizer/80349 * fold-const.c (fold_binary_loc) <case EQ_EXPR, NE_EXPR>: Convert arg10 and arg11 to itype. * c-c++-common/ubsan/pr80349.c: New test. diff --git gcc/fold-const.c gcc/fold-const.c index ce4b2df..f6d5af4 100644 --- gcc/fold-const.c +++ gcc/fold-const.c @@ -10797,40 +10797,37 @@ fold_binary_loc (location_t loc, tree itype = TREE_TYPE (arg0); if (operand_equal_p (arg01, arg11, 0)) - return fold_build2_loc (loc, code, type, - fold_build2_loc (loc, BIT_AND_EXPR, itype, - fold_build2_loc (loc, - BIT_XOR_EXPR, itype, - arg00, arg10), - arg01), - build_zero_cst (itype)); - + { + tem = fold_convert_loc (loc, itype, arg10); + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem); + tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg01); + return fold_build2_loc (loc, code, type, tem, + build_zero_cst (itype)); + } if (operand_equal_p (arg01, arg10, 0)) - return fold_build2_loc (loc, code, type, - fold_build2_loc (loc, BIT_AND_EXPR, itype, - fold_build2_loc (loc, - BIT_XOR_EXPR, itype, - arg00, arg11), - arg01), - build_zero_cst (itype)); - + { + tem = fold_convert_loc (loc, itype, arg11); + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem); + tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg01); + return fold_build2_loc (loc, code, type, tem, + build_zero_cst (itype)); + } if (operand_equal_p (arg00, arg11, 0)) - return fold_build2_loc (loc, code, type, - fold_build2_loc (loc, BIT_AND_EXPR, itype, - fold_build2_loc (loc, - BIT_XOR_EXPR, itype, - arg01, arg10), - arg00), - build_zero_cst (itype)); - + { + tem = fold_convert_loc (loc, itype, arg10); + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01, tem); + tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg00); + return fold_build2_loc (loc, code, type, tem, + build_zero_cst (itype)); + } if (operand_equal_p (arg00, arg10, 0)) - return fold_build2_loc (loc, code, type, - fold_build2_loc (loc, BIT_AND_EXPR, itype, - fold_build2_loc (loc, - BIT_XOR_EXPR, itype, - arg01, arg11), - arg00), - build_zero_cst (itype)); + { + tem = fold_convert_loc (loc, itype, arg11); + tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01, tem); + tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, tem, arg00); + return fold_build2_loc (loc, code, type, tem, + build_zero_cst (itype)); + } } if (TREE_CODE (arg0) == BIT_XOR_EXPR diff --git gcc/testsuite/c-c++-common/ubsan/pr80349.c gcc/testsuite/c-c++-common/ubsan/pr80349.c index e69de29..eb2e3da 100644 --- gcc/testsuite/c-c++-common/ubsan/pr80349.c +++ gcc/testsuite/c-c++-common/ubsan/pr80349.c @@ -0,0 +1,30 @@ +/* PR sanitizer/80349 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined" } */ + +int var; +long a; + +long +fn1 () +{ + return 0 % ((a & 1) == (7UL & 1)); +} + +long +fn2 () +{ + return 0 % ((a & 1) == (1 & 7UL)); +} + +long +fn3 () +{ + return 0 % ((1 & a) == (7UL & 1)); +} + +long +fn4 () +{ + return 0 % ((1 & a) == (1 & 7UL)); +} Marek