Package: gcc Version: 4:4.7.2-1 The `_Pragma' keyword is handled badly by GCC's preprocessor. Consider the following program, which is a simplified version of a warning suppression framework and a test case.
#include <stdio.h> #define PRAGMA(x) _Pragma(#x) #define WARNING(warn) PRAGMA(GCC diagnostic ignored warn) #define SANDWICH(warns, filling) \ _Pragma("GCC diagnostic push") \ warns \ filling \ _Pragma("GCC diagnostic pop") #define CHECK(cond) __extension__ ({ \ SANDWICH(WARNING("-Waddress"), !!(cond); ) \ }) #define WRAP(x) x int main(void) { int y = 0; if (CHECK(&y)) puts("Hello, world!"); return (0); } This doesn't emit warnings. Unfortunately, doesn't have the intended effect, as the preprocessor output reveals: int main(void) { int y = 0; if (__extension__ ({ # 22 "<stdin>" #pragma GCC diagnostic ignored "-Waddress" # 22 "<stdin>" # 22 "<stdin>" #pragma GCC diagnostic push # 22 "<stdin>" !!(&y); # 22 "<stdin>" #pragma GCC diagnostic pop # 22 "<stdin>" })) puts("Hello, world!"); return (0); } Somehow the `GCC diagnostic ignored "-Waddress"' has escaped from its sandwich. What's going on? A plausible explanation is that the pragmata are being acted upon immediately they're encountered during macro expansion, and macro arguments are expanded before being substituted into the body. Let's try to fix this by making SANDWICH more complicated: in particular, we'll offset the WARNING calls to delay their expansion until the rescanning phase. #include <stdio.h> #define PRAGMA(x) _Pragma(#x) #define MUFFLE_t(warn) PRAGMA(GCC diagnostic ignored warn) #define MUFFLE_nil(warn) #define MUFFLE(emitp, warn) MUFFLE_##emitp(warn) #define WARNING(warn) (t, warn) MUFFLE #define SANDWICH(warns, filling) \ _Pragma("GCC diagnostic push") \ MUFFLE warns (nil, nil) \ filling \ _Pragma("GCC diagnostic pop") #define CHECK(cond) __extension__ ({ \ SANDWICH(WARNING("-Waddress"), !!(cond); ) \ }) #define WRAP(x) x int main(void) { int y = 0; if (CHECK(&y)) puts("Hello, world!"); return (0); } This now appears to have the correct effect. Unfortunately, it actually doesn't. [gibson /tmp/mdw]gcc -c -O2 -g -Wall -pedantic pragbug2.c pragbug2.c: In function ‘main’: pragbug2.c:26:1: warning: the address of ‘y’ will always evaluate as ‘true’ [-Waddress] [gibson /tmp/mdw] Interestingly, though, the preprocessor output looks fine, and, just for extra amusement, [gibson /tmp/mdw]gcc -c -O2 -g -Wall -pedantic -no-integrated-cpp pragbug2.c [gibson /tmp/mdw] My guess is that there's some kind of special channel directly from the integrated preprocessor into the main compiler's pragma-handling, so the whole pragma sandwich goes by during macro expansion, before the compiler proper sees any of the actual code. What's clear is that there's something rather wrong with the way _Pragma is handled by the preprocessor, which is causing out-of-order behaviour and inconsistency between the integrated and separate preprocessors. -- [mdw] -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org