Bug 90677 - [9 Regression] gcc-9.1.0 fails to build __gcc_diag__ souce: error: 'cgraph_node' is not defined as a type
Summary: [9 Regression] gcc-9.1.0 fails to build __gcc_diag__ souce: error: 'cgraph_no...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 9.1.0
: P2 normal
Target Milestone: 9.3
Assignee: Jakub Jelinek
URL:
Keywords: rejects-valid
: 93104 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-05-30 08:01 UTC by Sergei Trofimovich
Modified: 2020-01-02 17:37 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 8.3.1
Known to fail: 10.0, 9.1.0
Last reconfirmed: 2019-05-30 00:00:00


Attachments
tree-mudflap.i.gz (172.93 KB, application/gzip)
2019-05-30 11:48 UTC, Sergei Trofimovich
Details
gcc10-pr90677.patch (1.40 KB, patch)
2019-11-19 12:08 UTC, Jakub Jelinek
Details | Diff
Candidate patch (294 bytes, patch)
2019-11-22 13:04 UTC, Bernd Schmidt
Details | Diff
gcc10-pr90677-2.patch (644 bytes, patch)
2019-12-30 17:38 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2019-05-30 08:01:46 UTC
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.
Comment 1 Jonathan Wakely 2019-05-30 08:10:00 UTC
If the GCC 4.6.4 code is not valid C then it's not a bug to reject it.
Comment 2 Sergei Trofimovich 2019-05-30 11:41:58 UTC
(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.
Comment 3 Sergei Trofimovich 2019-05-30 11:48:22 UTC
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
Comment 4 Jonathan Wakely 2019-05-30 12:45:39 UTC
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.
Comment 5 Sergei Trofimovich 2019-05-31 21:59:40 UTC
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)
Comment 6 Jakub Jelinek 2019-08-12 08:55:10 UTC
GCC 9.2 has been released.
Comment 7 Jakub Jelinek 2019-11-19 11:09:56 UTC
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)));
Comment 8 Jakub Jelinek 2019-11-19 12:08:32 UTC
Created attachment 47297 [details]
gcc10-pr90677.patch

Untested fix.
Comment 9 Bernd Schmidt 2019-11-22 13:04:30 UTC
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.
Comment 10 Jakub Jelinek 2019-11-22 21:46:18 UTC
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
Comment 11 Jakub Jelinek 2019-11-22 21:50:16 UTC
Should be fixed on the trunk so far.
Comment 12 Jakub Jelinek 2019-12-20 16:57:01 UTC
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
Comment 13 Jakub Jelinek 2019-12-20 18:28:55 UTC
Fixed for 9.3 too.
Comment 14 Eric Botcazou 2019-12-23 08:37:32 UTC
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)));
      |
Comment 15 Jakub Jelinek 2019-12-30 17:38:10 UTC
Created attachment 47568 [details]
gcc10-pr90677-2.patch

Untested fix for that.
Comment 16 Jakub Jelinek 2019-12-30 18:12:47 UTC
*** Bug 93104 has been marked as a duplicate of this bug. ***
Comment 17 Jakub Jelinek 2020-01-02 17:30:41 UTC
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
Comment 18 Jakub Jelinek 2020-01-02 17:37:21 UTC
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
Comment 19 Jakub Jelinek 2020-01-02 17:37:49 UTC
Fixed for 9.3, 10.1 and later.