Bug 91669 - #pragma's and _Pragma's work but _Pragma's used in an equivalent macro don't
Summary: #pragma's and _Pragma's work but _Pragma's used in an equivalent macro don't
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 5.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
: 85153 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-09-05 10:39 UTC by Petr Skocik
Modified: 2022-10-19 20:29 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Petr Skocik 2019-09-05 10:39:25 UTC
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(})
Comment 1 Eric Gallager 2019-09-05 15:14:54 UTC
I think there's other bugs open similar to this one, e.g. bug 90400, bug 69558, bug 91285, etc.
Comment 2 Tobias Burnus 2021-10-29 16:25:53 UTC
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.
Comment 3 Tobias Burnus 2021-10-29 17:40:33 UTC
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
Comment 4 Lewis Hyatt 2022-09-30 23:00:49 UTC
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.
Comment 5 GCC Commits 2022-10-04 01:29:28 UTC
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.
Comment 6 Lewis Hyatt 2022-10-04 01:34:20 UTC
Testcase has been added, resolving fixed.
Comment 7 Lewis Hyatt 2022-10-19 20:29:26 UTC
*** Bug 85153 has been marked as a duplicate of this bug. ***