Here we are crashing because fold_binary_loc produced a BIT_IOR_EXPR with incompatible operands. Fixed by adding the missing conversion, similarly to <https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00551.html>.
Bootstrapped/regtested on x86_64-linux, ok for trunk? And 7.1? 2017-04-25 Marek Polacek <pola...@redhat.com> PR sanitizer/80349 * fold-const.c (fold_binary_loc) <case BIT_IOR_EXPR>: Convert arg0's first argument to type. * g++.dg/ubsan/pr80349-2.C: New test. diff --git gcc/fold-const.c gcc/fold-const.c index f0b8e7a..ce4b2df 100644 --- gcc/fold-const.c +++ gcc/fold-const.c @@ -9898,8 +9898,10 @@ fold_binary_loc (location_t loc, /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */ if (msk.and_not (c1 | c2) == 0) - return fold_build2_loc (loc, BIT_IOR_EXPR, type, - TREE_OPERAND (arg0, 0), arg1); + { + tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); + return fold_build2_loc (loc, BIT_IOR_EXPR, type, tem, arg1); + } /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2, unless (C1 & ~C2) | (C2 & C3) for some C3 is a mask of some diff --git gcc/testsuite/g++.dg/ubsan/pr80349-2.C gcc/testsuite/g++.dg/ubsan/pr80349-2.C index e69de29..ca5ea4a 100644 --- gcc/testsuite/g++.dg/ubsan/pr80349-2.C +++ gcc/testsuite/g++.dg/ubsan/pr80349-2.C @@ -0,0 +1,11 @@ +// PR sanitizer/80349 +// { dg-do compile } +// { dg-options "-fsanitize=undefined" } + +unsigned long int ll; + +int +foo () +{ + return (2036854775807 >> ll & char(207648476159223) | 502810590243120797UL) << 0; +} Marek