https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60304

--- Comment #31 from Harald van Dijk <harald at gigawatt dot nl> ---
(In reply to Jonathan Wakely from comment #30)
> I'm curious why the preprocessed code in comment 28 doesn't warn,

This was still bugging me, so I looked into it a little bit, and since I had
trouble finding this written down somewhere I thought it would be worth
including here. The line "# 2 "b.C" 3 4" means that what follows is line 2 of
b.C, and b.C is a C system header. The relevant bits of GCC code to see this
are

 
https://github.com/gcc-mirror/gcc/blob/releases/gcc-10.2.0/libcpp/directives.c#L1061
 
https://github.com/gcc-mirror/gcc/blob/releases/gcc-10.2.0/libcpp/internal.h#L358

So this means that "false" is coming from a system header. It is: it is coming
from the macro expansion of "false", and the macro definition was in a system
header. So far, so good.

However, during normal operation, with the integrated preprocessor, when a
warning would be emitted in a system header, that
get_location_for_expr_unwinding_for_system_header function added by the commit
you were asking about,
https://github.com/gcc-mirror/gcc/blob/releases/gcc-10.2.0/gcc/cp/call.c#L7146,
would change the warning location to that of the macro expansion point, if the
warning location was actually inside a macro definition from a system header.
Such macro unwinding is not possible when the preprocessor is invoked
separately, as this information is missing in the -E output. A
non-system-header effect of this can be seen in this test:

test.h:

  #define FALSE false

test.cc:

  #include "test.h"
  void *p = FALSE;

g++ -std=c++03 -c test.cc:

In file included from test.cc:1:
test.h:1:15: warning: converting ‘false’ to pointer type ‘void*’
[-Wconversion-null]
    1 | #define FALSE false
      |               ^~~~~
test.cc:2:11: note: in expansion of macro ‘FALSE’
    2 | void *p = FALSE;
      |           ^~~~~

g++ -std=c++03 -c test.cc -save-temps
test.cc:2:11: warning: converting ‘false’ to pointer type ‘void*’
[-Wconversion-null]
    2 | void *p = FALSE;
      |           ^~~~~

The addition of -save-temps causes the "note: in expansion of macro ‘FALSE’" to
go missing, because the information needed to produce that note is gone by the
time the warning is emitted: the macro expansion tracking is only available at
preprocessing time. It was that macro expansion tracking functionality that GCC
needs to determine that really, the warning should be treated as *not* coming
from a system header, even though it really was.

In short: I think there is no lingering bug here, this is just an unfortunate
result of the current design. However, if you disagree, if you think the macro
expansion tracking state should be included somehow in the preprocessor output
so that the compiler always has access to it, I can report that as a new bug if
you like.

Reply via email to