The problem appears to exist on all gcc versions. Example Code: #define BX_gcc_push(Category,...) BX_pragma(GCC Category push ) BX_pragma(GCC Category __VA_ARGS__) #define BX_gcc_pop(Category) BX_pragma(GCC Category pop) #define BX_nodiag_push(DiagStr) BX_gcc_push(diagnostic, ignored DiagStr) #define BX_nodiag_pop() BX_gcc_pop(diagnostic) #define BX_pragma(...) _Pragma(#__VA_ARGS__) int foo(void) { //This silences -Wreturn-type on the closing curly as it should BX_nodiag_push("-Wreturn-type") } BX_nodiag_pop() #define BX_retundef(Rbr) /*{{{*/ \ BX_nodiag_push("-Wreturn-type") \ Rbr \ BX_nodiag_pop() /*}}}*/ int bar(void) { //This FAILS to silence -Wreturn on the closing curly //(works on clang and the code obtained from text-expanding the macro (gcc -E) //works on gcc too) BX_retundef(})
I think there's other bugs open similar to this one, e.g. bug 90400, bug 69558, bug 91285, etc.
I note that preprocessing itself is working. That is using -save-temps which first preprocesses the file and then runs the result on the compiler works but doing everything in one step doesn't.
Comparing the two inside handle_pragma_visibility: * the no-save-temps version has as 'loc' the line pointing to _Pragma(#__VA_ARGS__) * with -save-temps, 'loc' == 'input_location'. But: control_warning_option is called with input_location and not 'loc', thus that should not be the reason for the issue. * * * However, if one does a deep dive into update_effective_level_from_pragmas, the difference seems to be only the column number. There is: if (!linemap_location_before_p (line_table, pragloc, loc)) continue; Without -save-temps, there is (with warnings + notes added for debugging): foo.c:29:1: warning: update_effective_level_from_pragmas - pragloc 29 | BX_retundef(}) | ^~~~~~~~~~~ foo.c:29:13: note: loc is here 29 | BX_retundef(}) | ^ thus loc > pragloc But -save-temps, i.e. working on the preprocessed input, there is: foo.c:29:9: warning: update_effective_level_from_pragmas - pragloc 29 | BX_retundef(}) | ^~~ foo.c:29:2: note: loc is here 29 | BX_retundef(}) | ^ That is: loc < pragloc
This is already fixed on the latest GCC 10, 11, and 12 branches and on trunk for GCC 13. There were two separate issues contributing to this problem. The first one was common to both C and C++, and it was fixed by r10-325 for PR90382. (That PR was primarily about something else so was not focused on _Pragma locations, but the fix resolved this PR too.) The second issue made it stay broken longer for C only, not C++. In that sense it's partially a dupe of PR97498 and this aspect was fixed by r13-1596. (Issue was that in C, input_location used to be always the start of the line.) That fix has been backported to 10, 11, and 12 branches already. The testcase I added in r13-1596 provides partial coverage for this issue as well, but it does not quite cover the issue with adhoc locations addressed by r10-325. Here is a reduced testcase for this PR: ======================= #define ENDFUNC \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ } \ _Pragma("GCC diagnostic pop") int f () { ENDFUNC ======================= I will submit a patch to add this testcase and then close this one once that's applied.
The master branch has been updated by Lewis Hyatt <lhyatt@gcc.gnu.org>: https://gcc.gnu.org/g:70e3f71a279856eabf99bbc92c0345c3ad20b615 commit r13-3051-g70e3f71a279856eabf99bbc92c0345c3ad20b615 Author: Lewis Hyatt <lhyatt@gmail.com> Date: Sat Oct 1 12:05:13 2022 -0400 diagnostics: Add test for fixed _Pragma location issue [PR91669] This PR related to _Pragma locations and diagnostic pragmas was fixed by a combination of r10-325 and r13-1596. Add missing test coverage. gcc/testsuite/ChangeLog: PR c/91669 * c-c++-common/pr91669.c: New test.
Testcase has been added, resolving fixed.
*** Bug 85153 has been marked as a duplicate of this bug. ***