This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/68052] No printf format warnings in C++ code for macro in system headers
- From: "gcc at blino dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 22 Oct 2015 22:13:12 +0000
- Subject: [Bug c++/68052] No printf format warnings in C++ code for macro in system headers
- Auto-submitted: auto-generated
- References: <bug-68052-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68052
--- Comment #3 from Olivier Blin <gcc at blino dot org> ---
Quoting Martin Sebor's answer from the gcc-help mailing list:
https://gcc.gnu.org/ml/gcc-help/2015-10/msg00128.html
> I'm inclined to say it's a bug. I recommend opening it in Bugzilla.
> The only way I was able to work around it is by changing MY_PRINTF
> from a function-like macro to an object macro like so:
>
> #define MY_PRINTF printf
>
> The problem isn't specific to -Wformat but can be reproduced with
> other warnings as well. For example, replacing the contents of
> the header in the test case with this:
>
> #pragma GCC system_header
>
> static inline void __attribute__ ((deprecated)) foobar (void) { }
>
> #define foo foobar
> #define bar() foobar()
>
> and the body of main with
>
> foo ();
> bar ();
>
> emits a warning for each of foo() and bar() in C but just one,
> for foo(), in C++.
>
> While stepping through the code that checks to see whether or not
> a diagnostic should be issued (diagnostic_issue_diagnostic) I see
> that the difference in the bar() case is in the return value of
> the linemap_macro_expansion_map_p() function which is documented
> to
>
> Return TRUE if MAP encodes locations coming from a macro
> replacement-list at macro expansion point.
>
> and implemented by testing the location MAP's REASON member for
> equality to the LC_ENTER_MACRO constant. In C, the REASON member
> is set to LC_LEAVE while in C++ to LC_ENTER_MACRO. In C, the
> call to bar is then treated as an ordinary token whose location
> (i.e., bar's invocation) determines whether or not to issue the
> diagnostic. In C++ the reference to bar is recognized as a macro
> expansion and the function proceeds to find the token it expands
> to and use that to determine whether or not to diagnose it. And
> since the token bar() expands to is defined in a system header,
> C++ doesn't issue the warning.
>
> In the case of foo(), the REASON is LC_LEAVE in both front-ends
> and so they both diagnose it.
>
> Martin