With GCC, can I disable -Wframe-larger-than on a per-function basis? - c++

Using GCC, is it possible to specify a set of functions that are exempt from -Wframe-larger-than? (For example, main.)

GCC supplies you with pragmas for this purpose:
http://gcc.gnu.org/onlinedocs/gcc-4.5.2/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas
Currently it won't do exactly what you want, since it seems to do it on a file by file basis, but in the next version of gcc (4.6), it appears as though it is context aware:
http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas

This is a bit old, but I came across it looking for the same answer, so I thought I'd post my solution (found by trial and error):
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wframe-larger-than="
void func()
{ int x[2000] = {}; printf("%d",x[1]); }
#pragma GCC diagnostic pop
seems to work. For some reason, trying to use diagnostic warning did not work. It does not seem possible to change the stack size that generates the warning. Also, you need the = at the end. Maybe the next guy will find this and save themselves some time :). This is 4.6.2 (on an ARM cross compiler).
John

You can use the GCC diagnostic pragma.

Related

How to enable GCC compiler flags via preprocessor directives, rather than command line options?

I'm wondering how to activate GCC compiler flags in code, as opposed to including them in the compilation command on the command line.
Consider the following minimal example, which produces the warning -Wswitch-bool (I think by default but at least with -Wall enabled):
switch (true) {
default:
break;
}
This warning can be suppressed by providing the flag -Wno-switch-bool when compiling the program via the command line.
Is it possible to activate this flag in code? The following naive attempt doesn't work, since Wno-switch-bool is not a legal identifier (dashes are interpreted as minuses):
#define Wno-switch-bool
What is the appropriate command/syntax to use?
Note: This question is not specifically about warnings. I.e. I'm not asking about how to deactivate a specific class of warnings, which I know is best done via #pragma GCC diagnostic ignore, etc. This is a general question about how to enable GCC compiler flags in code. For instance, another example could be how I could activate -Werror, or -fno-implicit-templates via preprocessor directives (whether or not that would be ill-advised).
Is it possible to activate this flag in code?
Yes, you can use GCC's diagnostic pragmas to apply a specific pragma temporarily around a specific snippet of code, by remembering and subsequently restoring the state of the diagnostics prior to a source-local tweaking of it. E.g.:
#pragma GCC diagnostic push
// ^^^^^^^^^^^^^^^ remember the state of the diagnostics
#pragma GCC diagnostic ignored "-Wswitch-bool"
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ tweak diagnostics
switch (true) {
default:
break;
}
#pragma GCC diagnostic pop
// ^^^^^^^^^^^^^^^ restore the state of the diagnostics

Turn warnings into error only within supplied diff

At a company I used to work at, the build system was set up to turn warnings into errors only within changed code. It worked by supplying generating a diff (typically between the branch you were trying to merge and master and then supplying that diff to some compilation tool, and the tool would produce warnings only within the supplied diff.
This was great as it allowed you to e.g. deprecate some function, and have the build system prevent people from introducing new uses of that function, and then remove old usages of that function later.
Unfortunately, I didn't look at the setup closely enough before I left the company, and don't know how to replicate it. My question: How can I replicate this setup?
Question is tagged Clang but I would also be interested in answers that use tooling from other compilers.
If I had to implement that, my first idea would be:
Get merged file.
Analyze diff to figure out which regions were changed.
Generate a new file and inject #pragma directives1 that locally enable/disable warnings around the changed regions.
Also inject #line directives to make it look like warnings/errors are coming from the original file.
Compile modified file and save compiler warnings/errors.
Delete modified file.
Present compiler diagnostics to the user.
1 E.g. https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas for GCC.
Clang supports GCC's #pragma diagnostic.
For example:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
// ... changed code here ...
#pragma GCC diagnostic pop
MSVC also has something similar:
#pragma warning(push, 3)
// ... changed code here ...
#pragma warning(pop)

#pragma(* diagnostic) when mixing Clang analyzers with a GCC compiler

I'm compiling on with GCC on Linux, but CMake is kind enough to produce a Clang compatible compilation database. This means that I can run fancy, modern Clang based tools on my codebase and those tools have perfect knowledge of how each file is to be built (flags, defines, include paths, etc.) So far so good.
But today the Clang based static analysis in my IDE started showing a Clang specific warning. I don't think it particularly matters for my question which warning it is, but it was warning: disabled expansion of recursive macro, generated by -Wdisabled-macro-expansion. This particular macro is provided by a third party, so fixing the warning isn't an option, but I would like to suppress it as it occurs several times in the file in question.
What I'm struggling with is how to suppress the warning in Clang based analysis tools without causing new warnings in the GCC build.
Adding #pragma clang diagnostic ignored "-Wdisabled-macro-expansion" suppresses the warning for Clang tools, but causes GCC to issue warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas].
Similarly, adding #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion" suppresses the Clang warning (because Clang tries to be compatible with GCC diagnostics), but causes GCC to issue warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas].
Wrapping either of the above with #ifdef __clang__ makes GCC happy, but doesn't suppress the Clang warning because the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead.
Is there a way to make a diagnostic #pragma visible to Clang tooling, but not to GCC?
the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead
If it's reporting a clang-only warning, but does not think that __clang__ is defined, that sounds like a problem with the tooling. If it's trying to be that clever about misrepresenting itself, you may be up a creek... but also you should be complaining to the tool author for creating this situation in the first place.
That said, you could try:
#if defined(__has_warning)
# if __has_warning("-Wdisabled-macro-expansion")
# pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
# endif
#endif
I'm not sure if this will work... it depends on how hard the tooling is pretending to not be clang (__has_warning is a clang-only extension).

Why "pragma GCC diagnostic push" pop warning in GCC/C++?

#pragma GCC diagnostic push
it pop: warning: expected [error|warning|ignored] after â#pragma GCC diagnosticâ
Why? I use GCC in Linux.
I have one question, if I can't use pop/push, if the ignore only influence the compiled cpp, not influence other cpp? if some other include the cap, if influence it?
#pragma GCC diagnostic push and #pragma GCC diagnostic pop were added in gcc 4.6. You're using an older version.
These pragmas are typically used in conjunction with other #pragma GCC diagnostic directives to suppress, turn on, or turn into an error specific warnings for a small section of your code only. If they're ignored, the changes to warning levels will apply to the rest of the source file rather than just until the next #pragma GCC diagnostic pop. This may not be a problem, or it may be the end of the world; you'll need to understand your code to know for sure.
Either way, you should probably update your compiler. You wouldn't compile C99 with a C89 compiler; don't compile code containing pragmas for gcc 4.6 with gcc 4.4.

How to prevent `#warning` messages from being treated as an error?

I'm trying to compile introduce the -Werror flag in an existing codebase. One of the issues I'm encountering is that at some places #warning is used to display informational messages. These should not be treated as an error.
One solution would be to use #pragma message instead, but this does not seem to be supported by older versions of gcc. (Our build servers use gcc 4.1.2).
Can anyone help me fix this?
In gcc-4.6 and above, you can use -Wno-error=cpp. In at least the clang released with Lion and later, you can use -Wno-error=#warnings. But since your build servers use an ancient gcc, you're probably out of luck there.
In general, pass -fdiagnostics-show-option to have warnings show output like:
test.cc:1:2: warning: #warning hello [-Wcpp]
which tells you a warning flag that controls the warning. In gcc >=4.6 and clang, this is the default, so knowing to pass it may not be too useful anymore.
Locally disable effect of -Werror for #warning as follows:
#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wcpp"
#warning Informative message: everything is nice and good!!!
#pragma GCC diagnostic pop
The benefit with this approach is that you can still induce error with #warning elsewhere in the code.