On Thu, Jan 12, 2023 at 02:37:13PM -0500, Jason Merrill wrote: > > But the C++ FE was checking if op0 is a NOP_EXPR from TYPE_UNSIGNED. > > First of all, not sure if the operand of NOP_EXPR couldn't be non-integral > > type where TYPE_UNSIGNED wouldn't be meaningful, but more importantly, > > even if it is a cast from unsigned integral type, we only know it can't be > > minimum signed value if it is a widening cast, if it is same precision or > > narrowing cast, we know nothing. > > Curious, this divergence goes back to 1994, when the C++ front-end was > merged and tege changed the condition in the C front-end.
And it was changed to match the modulo condition adjusted by rms in 1993. > > So, the following patch for the NOP_EXPR cases checks just in case that > > it is from integral type and more importantly checks it is a widening > > conversion, and then next to it also allows op0 to be just unsigned, > > promoted or not, as that is what the C FE will do for those cases too > > and I believe it must work - either the division/modulo common type > > will be that unsigned type, then we can shorten and don't need to worry > > about UB, or it will be some wider signed type but then it can't be most > > negative value of the wider type. > > Why not use the same condition in C and C++? I can test that. Do you mean change the C FE to match the patched C++ or change C++ FE to just test TYPE_UNSIGNED (orig_op0)? I think both should work, though what I wrote perhaps can shorten in more cases. Can try to construct testcases where it differs... Jakub