This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: GCC turns &~ into | due to undefined bit-shift without warning
On 13/03/2019 03:25, Vincent Lefevre wrote:
> On 2019-03-12 21:56:59 +0100, David Brown wrote:
>> I disagree. To generate an unconditional error (rejecting the program), the
>> compiler would need such proof - such as by tracing execution from main().
>> But to generate a warning activated specifically by the user, there is no
>> such requirement. It's fine to give a warning based on the code written,
>> rather than on code that the compiler knows without doubt will be executed.
>
> There's already a bug about spurious warnings on shift counts:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
>
You can divide code into three groups (with the exact divisions varying
by compiler switches and version):
1. Code that the compiler knows for sure will run in every execution of
the program, generally because it can track the code flow from main().
2. Code that the compiler knows will /not/ run, due to things like
constant propagation, inlining, etc.
3. Code that the compiler does not know if it will run or not.
Code in group 1 here is usually quite small. Code in group 2 can be
large, especially with C++ header libraries, templates, etc. The
compiler will often eliminate such code and avoid generating any object
code. gcc used to have a warning for when it found "group 2" code and
eliminated it - that warning was removed as gcc got smarter, and the
false positives were overwhelming.
Most code is in group 3.
I would say that if the compiler finds undefined behaviour in group 1
code, it should give an unconditional error message, almost regardless
of compiler switches. (Many people will disagree with me here - that's
okay. Fortunately for everyone else, I am not the one who decides these
things in gcc!). Certainly that is standards-condoned behaviour.
To be useful to the developer, warnings have to be applied to group 3
code. That does mean a risk of false positives - some code will be
group 2 (never run) though the compiler doesn't know it.
I am arguing here that a warning like this should be applied to group 3
code - you are suggesting it should only apply to group 1.
The bug report you linked was for code in group 2 - code that the
compiler can (or should be able to) see is never run. I can see it
makes sense to disable or hide warnings from such code, but it may be
useful to have them anyway. I expect people to have different
preferences here.
(I see in that bug report, solutions are complicated because C lets you
"disable" a block by writing "if (0)", and then lets you jump into it
from outside with labels and goto's. Perhaps that should automatically
trigger a warning saying "Your code is made of spaghetti. Any other
warnings may be unreliable with many false positives and false negatives".)