[Bug c++/69126] [6 regression] _Pragma does not apply if part of a macro

2016-01-14 Thread rguenth at gcc dot gnu.org
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

2016-01-08 Thread dmalcolm at gcc dot gnu.org
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

2016-01-08 Thread dmalcolm at gcc dot gnu.org
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

2016-01-08 Thread dmalcolm at gcc dot gnu.org
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

2016-01-08 Thread jakub at gcc dot gnu.org
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

2016-01-07 Thread paolo.carlini at oracle dot com
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

2016-01-07 Thread dmalcolm at gcc dot gnu.org
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

2016-01-07 Thread dmalcolm at gcc dot gnu.org
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

2016-01-05 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69126

Andrew Pinski  changed:

   What|Removed |Added

   Target Milestone|--- |6.0