Bug 53469 - #pragma GCC diagnostic works, but using _Pragma doesn't for -Wunused-local-typedefs
Summary: #pragma GCC diagnostic works, but using _Pragma doesn't for -Wunused-local-t...
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Dodji Seketeli
Keywords: diagnostic
Depends on:
Reported: 2012-05-24 09:30 UTC by Tobias Burnus
Modified: 2016-09-08 03:32 UTC (History)
2 users (show)

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


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 ()
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
PR preprocessor/53469 - argument tokens of _Pragma miss virtual location

Consider this short test snippet:

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

    void bar ()

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.


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


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

Comment 3 Dodji Seketeli 2012-08-27 15:45:33 UTC
Fixed in trunk (4.8).
Comment 4 j8spencer 2016-09-08 03:32:18 UTC
I'm still seeing this behavior in 4.8.4.  #pragma can ignore unused-local-typedefs, _Pragma cannot.  This is on Ubuntu 16.04.  Options are -fPIE -O3 -NDEBUG -Wall -Wextra -Werror.  Because of -Werror, I also tried putting in _Pragma ("GCC diagnostic warning \"-Wunused-local-typedefs\"") before the ignored.  But regular #pragma works just fine.