Hi! The following patch (the second hunk in particular) should fix following testcase. c_build_qualified_type used to be called unconditionally at that spot, it was just the changes to use quals_used instead of type_quals there that made it conditional, but it needs to be done even if quals_used is 0, when TYPE_QUALS is non-zero and we need to remove quals.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-03-18 Jakub Jelinek <ja...@redhat.com> PR c/89734 * c-decl.c (grokdeclarator): Call c_build_qualified_type on function return type even if quals_used is 0. Formatting fixes. * gcc.dg/pr89734.c: New test. --- gcc/c/c-decl.c.jj 2019-03-11 22:56:44.000000000 +0100 +++ gcc/c/c-decl.c 2019-03-18 13:55:17.679750733 +0100 @@ -6611,10 +6611,12 @@ grokdeclarator (const struct c_declarato quals_used &= TYPE_QUAL_ATOMIC; if (quals_used && VOID_TYPE_P (type) && really_funcdef) pedwarn (specs_loc, 0, - "function definition has qualified void return type"); + "function definition has qualified void " + "return type"); else warning_at (specs_loc, OPT_Wignored_qualifiers, - "type qualifiers ignored on function return type"); + "type qualifiers ignored on function " + "return type"); /* Ensure an error for restrict on invalid types; the DR#423 resolution is not entirely clear about @@ -6624,8 +6626,7 @@ grokdeclarator (const struct c_declarato && (!POINTER_TYPE_P (type) || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))) error_at (loc, "invalid use of %<restrict%>"); - if (quals_used) - type = c_build_qualified_type (type, quals_used); + type = c_build_qualified_type (type, quals_used); } type_quals = TYPE_UNQUALIFIED; --- gcc/testsuite/gcc.dg/pr89734.c.jj 2019-03-18 13:59:14.916942573 +0100 +++ gcc/testsuite/gcc.dg/pr89734.c 2019-03-18 14:02:28.801814072 +0100 @@ -0,0 +1,12 @@ +/* PR c/89734 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef const int CI; +typedef _Atomic int AI; + +CI foo (void); +const int foo (void); + +AI baz (void); +_Atomic int baz (void); Jakub