Minimal reproducer: $ cat tree-mudflap.i int cgraph_node; void a() __attribute__((__format__(__gcc_diag__, 2, 3))); $ LANG=C gcc-8.3.0 -fsyntax-only -c tree-mudflap.i $ LANG=C gcc-9.1.0 -fsyntax-only -c tree-mudflap.i tree-mudflap.i:2:1: error: 'cgraph_node' is not defined as a type 2 | void a() __attribute__((__format__(__gcc_diag__, 2, 3))); | ^~~~ The original build failure was observed on gcc-4.6.4. gcc-9.1.0 failed to to build gcc-4.6.4 while gcc-8.3.0 succeeded. I was not able to produce a reasonable workaround to make 4.6.4 compile again. gcc-4.6.4 failure looks like that: In file included from /tmp/portage/sys-devel/gcc-4.6.4-r1/work/gcc-4.6.4/gcc/diagnostic.h:25, from /tmp/portage/sys-devel/gcc-4.6.4-r1/work/gcc-4.6.4/gcc/tree-mudflap.c:41: /tmp/portage/sys-devel/gcc-4.6.4-r1/work/gcc-4.6.4/gcc/pretty-print.h:322:6: error: 'cgraph_node' is not defined as a type 322 | ATTRIBUTE_GCC_PPDIAG(2,3); | ^~~~~~~~~~~~~ /tmp/portage/sys-devel/gcc-4.6.4-r1/work/gcc-4.6.4/gcc/pretty-print.h:325:6: error: 'cgraph_node' is not defined as a type 325 | ATTRIBUTE_GCC_PPDIAG(2,3); | ^~~~~~~~~~~~~ I think there are two bugs here: - (major) gcc-9.1.0 fails to build the code that used to compile - (minor) diagnostic complains about 'cgraph_node' but does not mention it in warning text.
If the GCC 4.6.4 code is not valid C then it's not a bug to reject it.
(In reply to Jonathan Wakely from comment #1) > If the GCC 4.6.4 code is not valid C then it's not a bug to reject it. Can you clarify what specifically here is not valid C? Should gcc-8 also reject it? From what I see gcc-9 has the same code in gcc/pretty-print.h as it used to be in gcc-4.6.4. I don't understand what requrements __gcc_diag__ imposes on the source to be "valid C". I can re-reduce tree-mudflap.i again to maintain the property.
Created attachment 46432 [details] tree-mudflap.i.gz If it helps here is complete tree-mudflap.i from gcc-4.6.4 as is: // fails: // $ x86_64-pc-linux-gnu-gcc-9.1.0 -c tree-mudflap.i -o tree-mudflap.o // works: // $ x86_64-pc-linux-gnu-gcc-8.3.0 -c tree-mudflap.i -o tree-mudflap.o
Sorry, I misunderstood the report and the reduced example. I agree that your reduced code should compile. The regression started with r265918. It seems that after this change the identifier 'cgraph_node' can only be used for types, not variables. Since it's not a reserved name and could occur in user code, that's a bug. dump_printf: add "%C" for dumping cgraph_node * This patch implements support for %C in dump_printf for dumping cgraph_node *. (I would have preferred to have a code for printing symtab_node * and both subclasses, but there doesn't seem to be a good way for -Wformat to handle inheritance, so, failing that, I went with this approach). gcc/c-family/ChangeLog: * c-format.c (local_cgraph_node_ptr_node): New variable. (gcc_dump_printf_char_table): Add entry for %C. (get_pointer_to_named_type): New function, taken from the handling code for "gimple *" from... (init_dynamic_diag_info): ...here. Add handling for "cgraph_node *". * c-format.h (T_CGRAPH_NODE): New. gcc/ChangeLog: * dump-context.h (ASSERT_IS_CGRAPH_NODE): New macro. * dumpfile.c (make_item_for_dump_cgraph_node): Move to before... (dump_pretty_printer::decode_format): Implement "%C" for cgraph_node *. (selftest::test_capture_of_dump_calls): Rename "where" to "stmt_loc". Convert test_decl to a function decl and set its location. Add a symbol_table_test RAII instance and a cgraph_node, using it to test "%C" and dump_symtab_node. gcc/testsuite/ChangeLog: * gcc.dg/format/gcc_diag-10.c (cgraph_node): New typedef. (test_dump): Add testing of %C.
No problem! Thank you for the very detailed explanation! Name stealing makes sense. I managed to craft a workaround for old gcc-4.6.4 source code locally [1] and not blocked by proper fix. [1] the workaround: --- a/gcc/pretty-print.h +++ b/gcc/pretty-print.h @@ -305,7 +305,7 @@ extern void pp_base_append_text (pretty_printer *, const char *, const char *); /* This header may be included before diagnostics-core.h, hence the duplicate definitions to allow for GCC-specific formats. */ -#if GCC_VERSION >= 3005 +#if (GCC_VERSION >= 3005) && (GCC_VERSION != 9001) /* 9.1.0 is buggy: https://gcc.gnu.org/PR90677 */ #define ATTRIBUTE_GCC_PPDIAG(m, n) __attribute__ ((__format__ (__gcc_diag__, m ,n))) ATTRIBUTE_NONNULL(m) #else #define ATTRIBUTE_GCC_PPDIAG(m, n) ATTRIBUTE_NONNULL(m)
GCC 9.2 has been released.
Better reduced testcase that shows what actually is happening in the older GCCs: struct cgraph_node; struct tree_node; typedef struct tree_node *tree; struct cgraph_node *cgraph_node (tree); void foo (int, const char *, ...) __attribute__((__format__(__gcc_diag__, 2, 3)));
Created attachment 47297 [details] gcc10-pr90677.patch Untested fix.
Created attachment 47333 [details] Candidate patch I was actually using the following during testing recently. I can't see a reason to emit an error in that function. This was bootstrapped and tested on the gcc135 machine.
Author: jakub Date: Fri Nov 22 21:45:27 2019 New Revision: 278634 URL: https://gcc.gnu.org/viewcvs?rev=278634&root=gcc&view=rev Log: PR c/90677 * c-common.h (identifier_global_tag): Declare. * c-format.c (get_pointer_to_named_type): Renamed to ... (get_named_type): ... this. Use identifier_global_tag instead of identifier_global_value, handle the return value being a TYPE_P. (init_dynamic_diag_info): Adjust get_pointer_to_named_type callers to call get_named_type instead. Formatting fixes. c/ * c-decl.c (identifier_global_tag): Define. cp/ * cp-objcp-common.c (identifier_global_tag): Define. testsuite/ * c-c++-common/pr90677.c: New test. Added: trunk/gcc/testsuite/c-c++-common/pr90677.c Modified: trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.h trunk/gcc/c-family/c-format.c trunk/gcc/c/ChangeLog trunk/gcc/c/c-decl.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-objcp-common.c trunk/gcc/testsuite/ChangeLog
Should be fixed on the trunk so far.
Author: jakub Date: Fri Dec 20 16:56:30 2019 New Revision: 279650 URL: https://gcc.gnu.org/viewcvs?rev=279650&root=gcc&view=rev Log: Backported from mainline 2019-11-22 Jakub Jelinek <jakub@redhat.com> PR c/90677 * c-common.h (identifier_global_tag): Declare. * c-format.c (get_pointer_to_named_type): Renamed to ... (get_named_type): ... this. Use identifier_global_tag instead of identifier_global_value, handle the return value being a TYPE_P. (init_dynamic_diag_info): Adjust get_pointer_to_named_type callers to call get_named_type instead. Formatting fixes. * c-decl.c (identifier_global_tag): Define. * cp-objcp-common.c (identifier_global_tag): Define. * c-c++-common/pr90677.c: New test. Added: branches/gcc-9-branch/gcc/testsuite/c-c++-common/pr90677.c Modified: branches/gcc-9-branch/gcc/c-family/ChangeLog branches/gcc-9-branch/gcc/c-family/c-common.h branches/gcc-9-branch/gcc/c-family/c-format.c branches/gcc-9-branch/gcc/c/ChangeLog branches/gcc-9-branch/gcc/c/c-decl.c branches/gcc-9-branch/gcc/cp/ChangeLog branches/gcc-9-branch/gcc/cp/cp-objcp-common.c branches/gcc-9-branch/gcc/testsuite/ChangeLog
Fixed for 9.3 too.
The fix breaks the build of earlier GCCs with the C++ compiler: extern void foo (int, int, const char *, ...) __attribute__ ((__format__ (__gcc_tdiag__, 3, 4))); struct cgraph_node; extern void bar (struct cgraph_node *); t.cpp:2:52: error: 'cgraph_node' is not defined as a type 2 | __attribute__ ((__format__ (__gcc_tdiag__, 3, 4))); |
Created attachment 47568 [details] gcc10-pr90677-2.patch Untested fix for that.
*** Bug 93104 has been marked as a duplicate of this bug. ***
Author: jakub Date: Thu Jan 2 17:29:59 2020 New Revision: 279840 URL: https://gcc.gnu.org/viewcvs?rev=279840&root=gcc&view=rev Log: PR c/90677 * cp-objcp-common.c (identifier_global_tag): Return NULL_TREE if name has not been found, rather than error_mark_node. * c-c++-common/pr90677-2.c: New test. Added: trunk/gcc/testsuite/c-c++-common/pr90677-2.c Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-objcp-common.c trunk/gcc/testsuite/ChangeLog
Author: jakub Date: Thu Jan 2 17:36:50 2020 New Revision: 279841 URL: https://gcc.gnu.org/viewcvs?rev=279841&root=gcc&view=rev Log: PR c/90677 * cp-objcp-common.c (identifier_global_tag): Return NULL_TREE if name has not been found, rather than error_mark_node. * c-c++-common/pr90677-2.c: New test. Added: branches/gcc-9-branch/gcc/testsuite/c-c++-common/pr90677-2.c Modified: branches/gcc-9-branch/gcc/cp/ChangeLog branches/gcc-9-branch/gcc/cp/cp-objcp-common.c branches/gcc-9-branch/gcc/testsuite/ChangeLog
Fixed for 9.3, 10.1 and later.