Bug 53469 - #pragma GCC diagnostic works, but using _Pragma doesn't for -Wunused-local-typedefs
#pragma GCC diagnostic works, but using _Pragma doesn't for -Wunused-local-t...
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: preprocessor
4.8.0
: P3 normal
: ---
Assigned To: Dodji Seketeli
: diagnostic
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-05-24 09:30 UTC by Tobias Burnus
Modified: 2012-08-27 15:45 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-05-25 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-05-24 09:30:53 UTC
Since GCC 4.7, the new warning -Wunused-local-typedefs is supported (PR c++/33255, 2011-09-08); since GCC 4.8 (2012-05-04) it is enabled by -Wall and -Wunused.


A typedef was used in a compile-time check whether an expression is constant (compile-time assert). To allow for the new check but selectively disable the warning for that line, I tried a pragma.


While using #pragma directly works, using _Pragma fails. The following example shows no warning for "foo" but for "bar" it fails with:

test.cc:19:14: error: typedef ‘myint’ locally defined but not used [-Werror=unused-local-typedefs]


Expected: _Pragma has the same result as writing #pragma.



#pragma GCC diagnostic error "-Wunused-local-typedefs"

// Works:

void foo ()
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
  typedef int myint;
#pragma GCC diagnostic pop
}


// Fails:

#define STRINGIFY(x) #x
#define TEST(x) \
 _Pragma(STRINGIFY(GCC diagnostic ignored "-Wunused-local-typedefs")) \
 typedef int myint;
// _Pragma(STRINGIFY(GCC diagnostic pop))
void bar ()
{
  TEST(myint)
}
Comment 1 Dodji Seketeli 2012-05-29 10:20:52 UTC
I candidate fix was proposed to http://gcc.gnu.org/ml/gcc-patches/2012-05/msg01899.html
Comment 2 Dodji Seketeli 2012-08-27 15:41:44 UTC
Author: dodji
Date: Mon Aug 27 15:41:38 2012
New Revision: 190714

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190714
Log:
PR preprocessor/53469 - argument tokens of _Pragma miss virtual location

Consider this short test snippet:

-------------------------8-------------------
    #define STRINGIFY(x) #x
    #define TEST(x) \
      _Pragma(STRINGIFY(GCC diagnostic ignored "-Wunused-local-typedefs")) \
      typedef int myint;

    void bar ()
    {
      TEST(myint)
    }
-------------------------8-------------------

The _Pragma is effectively ignored, and compiling with
-Wunused-local-typedefs warns on the local typedef, even though the
pragma should have prevented the warning to be emitted.

This is because when the preprocessor sees the _Pragma operator and
then goes to handle the first token ('GCC' here) that makes up its
operands, it retains the spelling location of that token, not its
virtual location.

Later when diagnostic_report_diagnostic is called to emit the warning
(or ignore it because of the pragma), it compares the location of the
first operand of the pragma with the location of the unused location,
(by calling linemap_location_before_p) and that comparison fails
because in this case, both locations should be virtual.

This patch fixes the issue by teaching the pragma handling to use
virtual locations.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

libcpp/

	PR preprocessor/53469
	* directives.c (do_pragma): Use the virtual location for the
	pragma token, instead of its spelling location.

gcc/testsuite/

	PR preprocessor/53469
	* gcc.dg/cpp/_Pragma7.c: New test case.

Added:
    trunk/gcc/testsuite/gcc.dg/cpp/_Pragma7.c
Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/libcpp/ChangeLog
    trunk/libcpp/directives.c
Comment 3 Dodji Seketeli 2012-08-27 15:45:33 UTC
Fixed in trunk (4.8).