Bug 53313 - Add warning levels
Summary: Add warning levels
Status: RESOLVED DUPLICATE of bug 31573
Alias: None
Product: gcc
Classification: Unclassified
Component: other (show other bugs)
Version: 4.8.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: diagnostic, easyhack
Depends on:
Reported: 2012-05-10 21:59 UTC by David Stone
Modified: 2024-01-11 23:41 UTC (History)
5 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

-Weverything (963 bytes, patch)
2012-12-08 17:59 UTC, Marc Glisse
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Stone 2012-05-10 21:59:05 UTC
The mailing list recently had this thread: http://gcc.gnu.org/ml/gcc/2012-04/msg00087.html

A separate, but I think possibly more important issue came up in that thread, starting at this post: http://gcc.gnu.org/ml/gcc/2012-04/msg00395.html

Vincent Lefevre mentioned the idea of "warnings levels". So instead of saying gcc -Wall -Wextra you would say gcc -W3 (or something). This is similar to what we do now for optimization levels and debug levels (-gn, -On), but there are a few things that I would like to do differently.

First of all, I would have these warnings be entirely meta-warnings. They would only turn on other warning flags. This means that unlike -02, where it turns on some optimizations not enabled by any flag, you could synthesize -W2 by selectively turning on every single warning contained by it.

In fact, I believe that all warnings should fall into one of two categories: either they warn for exactly one thing, or they are a collection of warnings. As an example of what I feel should be changed, consider this enhancement request: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7651 . -Wextra turns on a few options that are specified by other flags, but it also turns on a few warnings that don't seem to be part of any warning flag. As another example of where this might be helpful, C++ developers have the option Weffc++. It has 7 warnings, some of which appear to be turned on by other warnings (but not all). However, I personally do not use it because one of the 7 warnings it turns on has too many false positives for my code, so I cannot take advantage of the other 6 and still compile with Werror. If Weffc++ were entirely a meta-option, I could turn it on, and then disable that one warning.

However, I feel the best solution is the one mentioned in that thread: warning levels. Every warning level would include all of the warnings on the level below. I did a bit of research on the warning levels, and the results of it were posted here: http://stackoverflow.com/questions/5088460/flags-to-enable-thorough-and-verbose-g-warnings/9862800#9862800

This is a rough outline for what I feel the levels should be:

-W0: Absolutely no warnings at all.

-W1: Warnings that almost never false positive. The discussion on the mailing list seemed to suggest that this would be roughly equivalent to -Wall -Wno-unused -Wno-unitialized. This would likely be the default warning level.

-W2: I'm not exactly sure what the guiding principle would be for warnings higher than -W1. My guess would simply be making a judgment call on the ratio of real warnings : false positives, or else entirely based on the number of false positives. For W2 specifically, it would likely be equivalent to -Wall -Wextra. That's a pretty common set of warnings that I see people using, and has a low level of false-positive. I could see a strong argument for making this the default instead of -W1, but either would be a nice improvement. I would probably also add -Winvalid-pch because even though it's unlikely to trigger, if it does, it will generally indicate something is wrong (assuming the user is actually using a pre-compiled header).

-W3: A high level of warning. False positives are still tried to avoid, but we could allow style guidelines to be at this level. I suggest something roughly equivalent to: -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wuseless-cast -Wzero-as-null-pointer-constant. Some of the warnings in -Weffc++ could be added here if it were split into multiple warnings. This is the set of warnings that I actually recommend for everyone to add in my StackOverflow posting, with a few of the "questionable warnings that are present" removed from the list.

-W4: A paranoid level of warning. Likely equivalent to -W3 -Wdisabled-optimization -Wsign-conversion -Wsign-promo -Wstack-protector -Wswitch-default. This is every warning that I recommend turning on in my StackOverflow posting, plus a few that I didn't have just because they are likely to do nothing at all for most users and I didn't want them cluttering the command line even more, but if they are all hiding behind -W4, it won't matter.

-W5: I would define this one currently as all the warnings, but it does not necessarily need to always be this. False-positives are not considered for inclusion in this list. It would be (as far as I can tell) -W4 -Wabi -Waggregate-return -Wconversion -Weffc++ -Winline -Wpadded -Wswitch-enum -Wunsafe-loop-optimizations. Ideally, Weffc++ will be split into multiple warnings, some of which are safe to include at a lower level. -Wabi I could see moving down (I had no warnings triggered in my own code when I ran it), but I don't know how important support for multiple-compiler object code is. If we decide it is a bit more important than I rank it, I could see it dropping down to -W4 or -W3. -Wconversion is here because it has so many false-positives. If we get better support for range-propagation in variables to eliminate many of the obviously valid examples, I could see this going up to -W4. -Wunsafe-loop-optimizations is in the same category, it warns about situations that don't even contain user-visible loops currently, but it is useful enough (if the optimization is turned on) for it to merit -W4 if improved.

-Winf: Every single warning. This should always be equal to some specified W(number). In this proposal, -Winf and -W5 would be the same thing. However, if we ever decide to expand our warning set, then -Winf would become that new level instead. -Winf has no concerns of maintaining the warning list between releases, it is always defined as every single warning you can possibly turn on, at the max level that the warning supports.

I'm not exactly sure where a few warnings should fit in. For instance, -Wpedantic vs. -Wmissing-format-attribute, -Wsuggest-attribute, and some others. My understanding of -Wpedantic is that it will warn if I do use GNU extensions, whereas the others will warn if I don't. Perhaps disable the GNU-extension warnings if -pedantic is explicitly listed (and only enable them at the highest warning level). -Wstrict-aliasing is also a questionable one. It seems that -Wall turns on -Wstrict-aliasing=3, which claims to be the most accurate, but it seems that the loss in accuracy from lower numbers is only an increase in false-positives. If this also means that there is an increase in real-positives (and not just that it takes slightly more analysis time), it may be worth adding -Wstrict-aliasing=1 to higher warning levels. I'm not sure what the internals on this warning are, however.

I could also see a case for moving many of the warnings I list at -W3 down to -W2, but my code has been warning free for so long at a level somewhere between -W3 and -W4 (currently I use what I described as -W4 -pedantic -Werror -Wno-unused) that I don't quite know how often those other warnings really trigger.
Comment 1 David Stone 2012-05-10 22:00:17 UTC
We could also consider deprecating -Wall and -Wextra in favor of the numbered warnings, but that obviously is not required.
Comment 2 David Stone 2012-08-16 03:49:07 UTC
Naming the meta-warning that turns on all warnings '-Weverything' would match with clang's syntax, so that's probably what we should name it, too.
Comment 3 Jan Kratochvil 2012-09-30 07:24:30 UTC
For example PR 35173 would not be filed and also I would find -Wconversion without Google if there was -Weverything.
Comment 4 Manuel López-Ibáñez 2012-09-30 13:16:16 UTC
I don't have a strong opinion on whether numeric levels or Weverything are a good idea or not. However, the issues you mention with -Wextra and -Weffc++ (PR16166) are clear-cut: if you propose a patch fixing them, they will be accepted.

There is also the problem that the infrastructure for defining flags that enable other flags is quite rudimentary PR53063. If done properly, the documentation about which warnings enable other warnings could be automatically generated.

If you really really want to implement a -Weverything, I would start by submitting a patch that makes -Weverything = -Wall + -Wextra + -Wconversion + a bunch of generally useful warnings not included in -Wall or -Wextra and see what happens. Probably you will need to negotiate the specific list of warnings (or the name of -Weverything, e.g., -Wparanoid) with the maintainers, but I think that it should be possible to find a set of "very noisy but sometimes useful" warnings.

But the key point is that very likely nobody is going to implement any of this for you.

Clang introduced the concept of categories for diagnostics, which seems much more interesting to me than numeric levels. But I don't really know what is the consensus about this in GCC.
Comment 5 Marc Glisse 2012-12-08 17:59:31 UTC
Created attachment 28901 [details]

A very basic implementation of -Weverything (I don't really understand that code, but it compiles and shows many warnings :-)
Comment 6 Sergei Trofimovich 2014-03-17 10:37:11 UTC
I was about to fill the bug about -Weverything to enable all the warnings
you have.

All those things I've got from 'gcc --help=warnings':
    ... (+around of 20 of this kind)

But I'd like to see them (and new cool ones!) just with gcc upgrade
and a run on -Weverything on a project (as I do with clang).

Comment 7 Manuel López-Ibáñez 2015-04-22 16:12:57 UTC
It doesn't make sense to really enable every -Wx option, some of them are too specialized (-Wdouble-promotion, -Wtraditional, -Wlarger-than=, -Wc++-compat, etc.)

However, if someone goes through the trouble of compiling a list of potential candidates, it should be trivial to implement using EnabledBy() in common.opt, c.opt, etc.

Now I think the original proposal of having warnings levels is not what GCC wants. In fact, we now have -Ofast, -Os, and -Og and the consensus seems to be that we do not want to have -O4. According to https://gcc.gnu.org/wiki/DiagnosticsGuidelines

* enabled by default if it has (almost) no false positives (e.g., -Woverflow);

* added to -Wall if it is generally useful with low number of false positives that are easy to work-around;

* added to -Wextra if it has quite a lot of false positives but they are still easy to work-around; 

Warning options should move up in this list when bugfixes reduce the number of false positives. These cases are not meant to be exhaustive: some options should never be enabled by other option if the warning is too specific (-Wdouble-promotion); other options are already controlled by options such as -Wpedantic and -Wformat and do not need to move up in this list (but they might if deemed useful).

We could add:

* always added to -Weverything unless the warning was never meant to be generally useful even if it were perfect (-Wdouble-promotion, -Wtraditional, -Wlarger-than=, -Wc++-compat, etc.).
Comment 8 David Stone 2015-04-24 01:16:19 UTC
I have changed my opinion on this and agree that warning levels are probably not the way to go. The two things from this that I do still want are


All warnings either warn for exactly one type of thing or they turn on other warnings that themselves can be individually turned on or off.
Comment 9 Manuel López-Ibáñez 2015-04-24 10:29:39 UTC
(In reply to David Stone from comment #8)
> I have changed my opinion on this and agree that warning levels are probably
> not the way to go. The two things from this that I do still want are
> -Weverything-and-I-really-mean-it-this-time

Do you really want -Wdouble-promotion:

          float area(float radius)
             return 3.14159 * radius * radius; // warns!

And -Wtraditional? It warns for example for:
* The unary plus operator.
* A switch statement has an operand of type long. 

And what should happen for -Wc90-c99-compat -Wc99-c11-compat and -Wc++-compat? They will warn for bool, long long, etc, even if you use '-std=c11'.

As an exercise, you can take the list given by:

wget https://gcc.gnu.org/svn/gcc/trunk/gcc/doc/invoke.texi
grep '@item -W[^ ]\+' -o invoke.texi | grep -v '@item -Wno-\|-Werror\|-Wfatal-'

and try to build any large piece of software with it and see if you still want -Weverything-and-I-really-mean-it-this-time.
Comment 10 Marc Glisse 2015-04-24 11:59:39 UTC
Manuel, you seem to want a -Wsuper-extra that you can use everyday (maybe with a couple -Wno-*). What some other people want with -Weverything is a way to discover what warnings are available in the compiler. For instance, they discover a bug or a performance issue in their code, extract a small reproducer, and want to find if there exists a flag that would help them narrow down the places they need to review in the rest of their code base for similar issues. So yes, it should warn all over the place and give contradictory advice, it should even include the warning that just tells you how large your function is. As a bonus, this makes it obvious to users that they are not supposed to make their code -Weverything clean. Maybe the name -Wrant would make it more acceptable?
Comment 11 David Stone 2015-04-24 13:53:03 UTC
If the warnings are so ridiculous that no one could possibly want them on, then maybe we should remove them. Otherwise, I would want -Weverything and I can use -Wno-warnings-I-do-not-want
Comment 12 Jonathan Wakely 2015-04-24 14:22:01 UTC
(In reply to David Stone from comment #11)
> If the warnings are so ridiculous that no one could possibly want them on,
> then maybe we should remove them.

No because there's a difference between something that is only useful in very specialized cases and not useful at all.

Having spoken to core LLVM developers about -Weverything it was *not* added for users, it was added for internal reasons, and is seen by some as a bad idea.
Comment 13 David Stone 2015-04-25 15:10:04 UTC
I understand the difference between the two. I just prefer an opt-out system of warnings instead of opt-in. If absolutely no one could possibly want a warning, it shouldn't exist. If some users would want the warning, I may be one of those users at some point and I'd like to see it.
Comment 14 Manuel López-Ibáñez 2016-02-15 22:51:59 UTC
(In reply to David Stone from comment #8)
> I have changed my opinion on this and agree that warning levels are probably
> not the way to go. The two things from this that I do still want are
> -Weverything-and-I-really-mean-it-this-time

Then, this is a dup.

> All warnings either warn for exactly one type of thing or they turn on other
> warnings that themselves can be individually turned on or off.

Unfortunately, fixing Wextra (PR7651), for example, is a tedious and long process.

*** This bug has been marked as a duplicate of bug 31573 ***