Created attachment 42777 [details]
test case using _Pragma(GCC diagnostic push/pop)
I tried using _Pragma("GCC diagnostic push") and _Pragma("GCC diagnostic pop") inside of a multi-line macro to turn a particular warning off inside code in that macro. This worked in some cases but not others. From what I can tell, the differences are:
- If I first preprocess the file with "gcc -E", and then compile the preprocessed source, it works as expected.
- In case of the "-Wattribute-alias" warning (added in gcc-8), I get the expected behavior only if I declare a structure before the _Pragma("GCC diagnostic pop"); removing the 'struct s;' line from the attached example leads to a warning for the incompatible alias.
- With the -Wuninitialized warning, I could find no way to disabled it just inside of the macro expansion
The same thing seems to happen with multi-line statements that I join with '\' line ends even without macros, but of course there is little use in that. I did not try what happens with other. Support for _Pragma("GCC diagnostic ...") was first added in gcc-4.2. This did not yet support push/pop, but the behavior of multi-line macros was already the same as with gcc-8: preprocessing the file makes it work as expected, but the integrated preprocessor seems to evaluate the _Pragma() early.
I was investigating a similar gcc bug, and was pointed at this one. I note that the test case attached to this bug seems to be (according to the godbolt compilers) broken in gcc 7.3 but fixed by 8.1.
8.1 didn't fix everything in this area, though -- I have a rather similar kind of test case (which I'll attach), which seems to be still broken in 8.3 but fixed in gcc trunk.
Created attachment 44817 [details]
repro for similar bug, apparently broken up to 8.3 but fixed in trunk?
Unless someone can identify a commit that deliberately fixed the bug *and
added appropriate tests to the testsuite*, I'd strongly advise adding
tests to the testsuite before marking FIXED on the basis of those tests
now passing (if they are passing incidentally as a result of some other
change that didn't add tests directly related to this bug).
I tried to achieve something very similar to temporarily enable -Wswitch-enum just for a single switch:
#define SWITCH_ENUM(x) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic warning \"-Wswitch-enum\"") \
_Pragma("GCC diagnostic pop")
which doesn't work as expected in gcc7.4 and gcc8.4 (it works however in 9.1, 9.2 and trunk). Manually expanding the macro (as well as compiling the preprocessor output) leads to the expected result.
It seems that the evaluation of _Pragma in macros happens after the 'real' source code of the macro, so
#define _Pragma("X") my_code_here
seems to be interpreted as
#define my_code_here _Pragma("X")
When omitting _Pragma("GCC diagnostic pop") in the macro, -Wswitch-enum is enabled within the switch body, but disabled for the switch itself.