[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 Richard Biener changed: What|Removed |Added Priority|P3 |P1
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #8 from David Malcolm --- Looking at calls to linemap_compare_locations, the crucial comparison is the comparison of the location of the 2nd diagnostic with that of the "ignore" pragma: Breakpoint 2, linemap_compare_locations (set=0x77ffb000, pre=226930, post=post@entry=2147483645) at ../../src/libcpp/line-map.c:1311 (gdb) call inform (226930, "pre, the location of the ignore") /tmp/test.cc:17:24: note: pre, the location of the ignore MACRO; ^ (gdb) call inform (2147483645, "post, the location of the diagnostic") /tmp/test.cc:13:9: note: post, the location of the diagnostic int x; ^ /tmp/test.cc:17:5: note: in expansion of macro ‘MACRO’ MACRO; ^ The initial value of l1 == post (location of the diagnostic): (gdb) p /x l1 $15 = 0x7ffd linemap_compare_locations expands macro locations at LRK_MACRO_EXPANSION_POINT and obtains: (gdb) p l1 $19 = 226308 (gdb) call inform (226308, "") /tmp/test.cc:17:5: note: MACRO; ^ and hence treats the location of "post" (the diagnostic) as the "M" of the macro expansion point. However, the location of the "ignore" within the macro definition is 226930, which is *after* that "M": (gdb) call inform (226930, "pre, the location of the ignore") /tmp/test.cc:17:24: note: pre, the location of the ignore MACRO; ^ Hence that strange-looking synthesized location of the "ignore" directive within the tokens synthesized by _cpp_do__Pragma is effectively *after* that of the macro expansion point. Hence the "ignore" is treated as occurring after the diagnostic, hence the "ignore" doesn't affect the diagnostic, and the warning is emitted. FWIW, there's also some logic in linemap_compare_locations for handling locations in the same macro expansion, but this isn't the case here as the location of the pragma has been recorded as an ordinary location.
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #9 from David Malcolm --- Running with gcc-4.8.3, it appears that the strange-looking location of the "ignore" is pre-existing behavior, and that the change in r226234 of where the diagnostic occurs has simply exposed it. Breakpoint 18, linemap_compare_locations (set=0x77ffb000, pre=7092, post=post@entry=7209) at ../../libcpp/line-map.c:1023 (gdb) call inform (7092, "pre, the location of the ignore") /tmp/test.cc: In function ‘int g()’: /tmp/test.cc:17:24: note: pre, the location of the ignore MACRO; ^ (gdb) call inform (7209, "post, the location of the diagnostic") /tmp/test.cc:18:13: note: post, the location of the diagnostic return 0; ^
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #10 from David Malcolm --- Hence I *think* the issue here is that the locations of the tokens within libcpp/directives.c:destringize_and_run don't respect macro expansions, leading to the strange location for the ignore directive that is slightly after the relevant macro expansion. However, that function is full of comments like /* Ugh; an awful kludge. We are really not set up to be lexing and: /* ??? Antique Disgusting Hack. What does this do? */ and the like, so am not sure I want to touch it... Perhaps this could be papered over by reverting r226234, but that would regress the removal of %q+D mentioned in comment #7, and there are presumably other ways to combine _Pragma and macros that would show up issues this way (though these behaviors are presumably already present in earlier gcc releases).
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #11 from Jakub Jelinek --- Perhaps it would be possible to arrange for the lexing of _Pragma string to get the right locations for the simple case where _Pragma argument is a single string literal without escapes etc., but as soon as escapes are there, or say stringified arguments are added, and string literals concatenated, it is going to be really difficult. But if we at least could let the easiest cases work fine, it would be really nice.
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #2 from Paolo Carlini --- Hi Jakub. I thought it was simply matter of using location_of instead of DECL_SOURCE_LOCATION as I did in other places in that patch set, but in fact it doesn't work, in order to avoid the spurious warning a warning and '+' instead of a locally computed location + warning_at seems really necessary. Certainly I can revert the specific change of mine (would be line #633 and #634 in the current decl.c) and align the C++ FE with the C FE, that fixes the regression and I'm pretty sure would not introduce other wrt the status pre-r226234, but I don't fully understand why that is necessary, there are interactions with the handling of macros which I don't fully understand, at the moment. Let me know if you want me to do that for now.
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #6 from David Malcolm --- (In reply to David Malcolm from comment #5) [...snip...] > That said, the location of the token from _Pragma looks wrong; note the > underlines here: > > Breakpoint 2, handle_pragma_diagnostic (dummy=) at > ../../src/gcc/c-family/c-pragma.c:760 > 760 kind = DK_IGNORED; > (gdb) call inform (loc, "1st ignore") > /tmp/test.cc: In function ‘int f()’: > /tmp/test.cc:4:16: note: 1st ignore > _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") > ^~~ > (gdb) cont > Continuing. > > Breakpoint 2, handle_pragma_diagnostic (dummy=) at > ../../src/gcc/c-family/c-pragma.c:760 > 760 kind = DK_IGNORED; > (gdb) call inform (loc, "2nd ignore") > /tmp/test.cc: In function ‘int g()’: > /tmp/test.cc:17:16: note: 2nd ignore > MACRO; > ^ I got this slightly wrong, the locations passed to control_warning_option (and thus put in the classification_history) are these: (gdb) p loc $1 = 173682 (gdb) call inform (loc, "1st ignore") /tmp/test.cc: In function ‘int f()’: /tmp/test.cc:4:24: note: 1st ignore _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") ^~~ (gdb) p loc $2 = 226930 (gdb) call inform (loc, "2nd ignore") /tmp/test.cc: In function ‘int g()’: /tmp/test.cc:17:24: note: 2nd ignore MACRO; ^ (the above is trunk). That said gcc 4.8.3 appears to generate similarly strange locations for these tokens: (gdb) p loc $15 = 5428 (gdb) call inform (loc, "1st ignore") /tmp/test.cc:4:24: note: 1st ignore _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") ^ (gdb) p loc $16 = 7092 (gdb) call inform (loc, "2nd ignore") /tmp/test.cc: In function ‘int g()’: /tmp/test.cc:17:24: note: 2nd ignore MACRO; ^
[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 --- Comment #5 from David Malcolm --- As far as I can tell: * _Pragma is handled by _cpp_do__Pragma which injects pragma tokens into the token stream * the resulting "ignore" pragmas are handled by gcc/c-family/c-pragma.c:handle_pragma_diagnostic which calls: * control_warning_option, which calls * diagnostic_classify_diagnostic, which leads to an element being pushed onto context->classification_history with location as the location of the token. When handling the warning/warning_at, diagnostic_report_diagnostic has this logic: 695 /* This tests for #pragma diagnostic changes. */ 696 if (context->n_classification_history > 0) 697 { 698 int i; 699 /* FIXME: Stupid search. Optimize later. */ 700 for (i = context->n_classification_history - 1; i >= 0; i --) 701 { 702 if (linemap_location_before_p 703 (line_table, 704context->classification_history[i].location, 705location)) Note the call to linemap_location_before_p, which calls linemap_compare_locations. That said, the location of the token from _Pragma looks wrong; note the underlines here: Breakpoint 2, handle_pragma_diagnostic (dummy=) at ../../src/gcc/c-family/c-pragma.c:760 760 kind = DK_IGNORED; (gdb) call inform (loc, "1st ignore") /tmp/test.cc: In function ‘int f()’: /tmp/test.cc:4:16: note: 1st ignore _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") ^~~ (gdb) cont Continuing. Breakpoint 2, handle_pragma_diagnostic (dummy=) at ../../src/gcc/c-family/c-pragma.c:760 760 kind = DK_IGNORED; (gdb) call inform (loc, "2nd ignore") /tmp/test.cc: In function ‘int g()’: /tmp/test.cc:17:16: note: 2nd ignore MACRO; ^
[Bug c/69126] [6 regression] _Pragma does not apply if part of a macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126 Andrew Pinski changed: What|Removed |Added Target Milestone|--- |6.0