On Fri, Mar 17, 2023 at 09:14:04AM +0100, Jakub Jelinek wrote: > Hi! > > On the following testcase, the C FE decides to shorten the division because > it has a guarantee that INT_MIN / -1 division won't be encountered, the > first operand is widened from narrower unsigned and/or the second operand is > a constant other than all ones (in this case both are true). > The problem is that the narrower type in this case is _Bool and > ubsan_instrument_division only instruments it if op0's type is INTEGER_TYPE > or REAL_TYPE. Strangely this doesn't happen in C++ FE.
I was curious. The difference is because C++ passes this (gdb) pge op0 (int) (short int) (VIEW_CONVERT_EXPR<int>(d) == 1 | VIEW_CONVERT_EXPR<int>(d) > 9) to shorten_binary_op while C passes: (gdb) pge op0 (int) (<<< Unknown tree: c_maybe_const_expr d >>> == 1 || <<< Unknown tree: c_maybe_const_expr d >>> > 9) so when we remove the '(int)' cast, we have different types underneath, either short or bool. In C, the BIT_IOR_EXPR -> TRUTH_OR_EXPR change is because we call c_convert -> convert_to_integer -> do_narrow. In C++, we never called do_narrow so shorten_binary_op gets the original tree. Anyway, thanks for the patch. Marek