https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70336
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 38172 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38172&action=edit gcc6-pr70336.patch IMNSHO -Wconversion is totally useless warning, and one where if you want to avoid "false positives", we'd need to implement full VRP in the FEs. Anyway, given say: void f1 (unsigned char * x, int y, int z) { x[z / 8] |= (unsigned char) (0x80 >> y); } unsigned char f2 (unsigned char x, int y) { x = x | (unsigned char) (0x80 >> y); return x; } unsigned char f3 (unsigned char x, int y) { x = x | (unsigned char) (y & 255); return x; } unsigned char f4 (unsigned char x, int y) { x = x | (unsigned char) (y & 127); return x; } unsigned char f5 (unsigned char x, unsigned char y) { x = x | (unsigned char) (y & 255); return x; } the attached patch disables the warning on f4, and on f5 we don't warn already before. Perhaps the match.pd change should be guarded with GIMPLE? The match.pd change is responsible for getting rid of the explicit unsigned char casts early. Though, if you in the above testcase remove all the explicit (unsigned char) casts, already gcc 4.9 and earlier warn. As for the 0x80 >> whatever case, we'd need to handle that in unsafe_conversion_p as another case (though, the question is if at least on some targets with negative or other out of bound shift counts we don't sometimes get (in UB code) values where conversion would alter the values). And the y & 255 case is also questionable, there it wants to warn that for negative y the value would change and unsafe_conversion_p for whatever reason handles unsigned vs. signed mask constant differently for that exact case.