Manuel López-Ibáñez <lopeziba...@gmail.com> writes:

> Currently, #pragma GCC diagnostic is handled entirely by the FE. This
> has several drawbacks:
>
> * PR c++/53431 - C++ preprocessor ignores #pragma GCC diagnostic: The
> C++ parser lexes (and preprocesses) before handling the pragmas.
>
> * PR 53920 - "gcc -E" does not honor #pragma GCC diagnostic ignored
> "-Wunused-macro": Because -E does not invoke the FE code that parses
> the FE pragmas.
>
> * PR 64698 - preprocessor ignores #pragma GCC diagnostic when using
> -save-temps. Same issue as above.
>
> The following patch moves the handling of #pragma GCC diagnostic to
> libcpp but keeps the interface with the diagnostic machinery in the FE
> by using a call-back function.
>
> One serious problem with this approach is that the preprocessor will
> delete the pragmas from the preprocessed output, thus '-E',
> '-save-temps'  will not contain the pragmas and compiling the
> preprocessed file will trigger the warnings that they were meant to
> suppress.  Any ideas how to prevent libcpp from deleting the #pragmas?

[...]

Joseph Myers <jos...@codesourcery.com> writes:

> On Sun, 20 Sep 2015, Manuel López-Ibáñez wrote:

>> > I don't see any other way to fix these PRs, but I don't know how to
>> > keep the pragmas from being deleted by the preprocessor.
>
> I'd suppose you want a new type of pragma, that acts like a combination of 
> a deferred one and one for which a handler is called immediately by 
> libcpp.  libcpp would call the handler but also create a CPP_PRAGMA token.  
> The front-end code calling pragma handlers would need to know to do 
> nothing with such pragmas; the token would only be for textual 
> preprocessor output.

Right.  I was thinking about something along those lines as well.

So in concrete terms, in libcpp, once do_pragma() has handled the
pragma, it does two things that are interesting to us:

  * If the pragma is an internal one -- one that is handled immediately by
    libcpp, then it keeps going, chewing away at more tokens.

  * If the pragma is a deffered one -- one that is to be handled later
    by the FE, it updates pfile->directive_result.type to CPP_PRAGMA
    (and sets up some ancillary state there too).

The caller of do_pragma(), which is destringize_and_run() then detects
that pfile->directive_result.type is set, and then puts the tokens of
the pragma back into the input stream again.  So next time the FE
requests more tokens, it's going to get the same pragma tokens.

So, maybe you could alter pragma_entry::is_deferred; change it into a
flag which type is an enum that says how the the pragma is to be
handled; either internally and its tokens shouldn't be visible to the FE
(this is what the current pragma_entry::is_internal means), internally
and the tokens would be visible to the FE, or deferred.

Then do do_pragma() would be adjusted to change the if (p->is_deferred)
clause to allow the third handling kind I just talked about.

I hope this helps.

Cheers,

-- 
                Dodji

Reply via email to