On Wed, Jun 05, 2013 at 09:35:08PM +0200, Jakub Jelinek wrote: > On Wed, Jun 05, 2013 at 09:19:10PM +0200, Jakub Jelinek wrote: > > On Wed, Jun 05, 2013 at 07:57:28PM +0200, Marek Polacek wrote: > > > + tree t, tt; > > > + tree orig = build2 (code, TREE_TYPE (op0), op0, op1); > > > + tree prec = build_int_cst (TREE_TYPE (op0), > > > + TYPE_PRECISION (TREE_TYPE (op0))); > > BTW, also, to check that the shift count is not < 0 or >= prec, you can > just test that fold_convert_loc (loc, unsigned_type_for (TREE_TYPE (op1)), > op1) > is LE_EXPR than precm1 (also using the unsigned type). > While optimizers often fold it to that, you might very well just create > fewer trees from the start. > > The C99 undefined behavior of left signed shift can be tested by > testing if ((unsigned type for op0's type) op0) >> (precm1 - y) is > non-zero.
The C++11/C++14 undefined behavior of left signed shift can be tested similarly, if ((unsigned type for op0's type) op0) >> (precm1 - y) is greater than one, then it is undefined behavior. Jason, does http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3675.html#1457 apply just to C++11/C++14, or to C++03 too? In C++03 I see in [expr.shift]/2 "The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise." Is that the same case as C90 then, the wording seems to be pretty much the same? As for controlling the C99 (or even C++11?) warning individually, either it can be a separate suboption of -fsanitize=, like -fsanitize=shift,lshiftc99 (but then, would lshiftc99 be included in undefined and similar option groups), or IMHO better we just convince ubsan upstream to have env var for controlling the lshift diagnostics, gcc emits always checks for precisely what the current -std= makes as undefined behavior (though, because of DRs that is somewhat fuzzy, pre-DR1457 C++11 vs. post-DR1457 C++11), and users would through env var just choose, ok, please ignore left shift warnings of the 1 << 31 style, or ignore those and also 2 << 31 style. Jakub