Without this change, finish_declspecs cannot tell that whether there was an erroneous type specified, or no type at all. This may result in additional diagnostics for implicit ints, or missing diagnostics for multiple types.
PR c/107805 gcc/c/ * c-decl.cc (declspecs_add_type): Propagate error_mark_bode from type to specs. gcc/testsuite/ * gcc.dg/pr107805-1.c: New test. * gcc.dg/pr107805-1.c: Likewise. --- Note regarding testing: I boostrap with c,c++,lto on x86-64 (non-multlib) and diffed these .sum files: gcc/testsuite/gcc/gcc.sum gcc/testsuite/g++/g++.sum x86_64-pc-linux-gnu/libgomp/testsuite/libgomp.sum x86_64-pc-linux-gnu/libstdc++-v3/testsuite/libstdc++.sum x86_64-pc-linux-gnu/libatomic/testsuite/libatomic.sum x86_64-pc-linux-gnu/libitm/testsuite/libitm.sum Apart from timestamps, the only differences I get is this change: --- ./gcc/testsuite/gcc/gcc.sum 2022-11-22 05:45:33.813264761 -0500 +++ /tmp/b/build/./gcc/testsuite/gcc/gcc.sum 2022-11-22 06:39:10.667590185 -0500 @@ -83303,6 +83303,11 @@ PASS: gcc.dg/pr107618.c (test for bogus messages, line 9) PASS: gcc.dg/pr107618.c (test for excess errors) PASS: gcc.dg/pr107686.c (test for excess errors) +PASS: gcc.dg/pr107805-1.c (test for errors, line 3) +PASS: gcc.dg/pr107805-1.c (test for excess errors) +PASS: gcc.dg/pr107805-2.c (test for errors, line 3) +PASS: gcc.dg/pr107805-2.c (test for errors, line 4) +PASS: gcc.dg/pr107805-2.c (test for excess errors) PASS: gcc.dg/pr11459-1.c (test for excess errors) PASS: gcc.dg/pr11492.c (test for bogus messages, line 8) PASS: gcc.dg/pr11492.c (test for excess errors) @@ -190486,7 +190491,7 @@ === gcc Summary === -# of expected passes 185932 +# of expected passes 185937 # of unexpected failures 99 # of unexpected successes 20 # of expected failures 1484 So I think this means there are no test suite regressions. Thanks, Florian gcc/c/c-decl.cc | 6 ++---- gcc/testsuite/gcc.dg/pr107805-1.c | 5 +++++ gcc/testsuite/gcc.dg/pr107805-2.c | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 098e475f65d..4adb89e4aaf 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -12243,11 +12243,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, error_at (loc, "two or more data types in declaration specifiers"); else if (TREE_CODE (type) == TYPE_DECL) { - if (TREE_TYPE (type) == error_mark_node) - ; /* Allow the type to default to int to avoid cascading errors. */ - else + specs->type = TREE_TYPE (type); + if (TREE_TYPE (type) != error_mark_node) { - specs->type = TREE_TYPE (type); specs->decl_attr = DECL_ATTRIBUTES (type); specs->typedef_p = true; specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type); diff --git a/gcc/testsuite/gcc.dg/pr107805-1.c b/gcc/testsuite/gcc.dg/pr107805-1.c new file mode 100644 index 00000000000..559b6a5586e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr107805-1.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +typedef int t; +typedef struct { double a; int b; } t; /* { dg-error "conflicting types" } */ +t x; /* No warning here. */ + diff --git a/gcc/testsuite/gcc.dg/pr107805-2.c b/gcc/testsuite/gcc.dg/pr107805-2.c new file mode 100644 index 00000000000..fa5fa4ce273 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr107805-2.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +typedef int t; +typedef struct { double a; int b; } t; /* { dg-error "conflicting types" } */ +t char x; /* { dg-error "two or more data types" } */ base-commit: e4faee8d02ec5d65bf418612f7181823eb08c078