diff options
Diffstat (limited to 'gcc/c/c-decl.c')
-rw-r--r-- | gcc/c/c-decl.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 4da9fe994f3..ab3a5ed6e9e 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2352,13 +2352,33 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl) { tree remove = TREE_TYPE (newdecl); - for (tree t = TYPE_MAIN_VARIANT (remove); ; - t = TYPE_NEXT_VARIANT (t)) - if (TYPE_NEXT_VARIANT (t) == remove) - { - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); - break; - } + if (TYPE_MAIN_VARIANT (remove) == remove) + { + gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + /* If remove is the main variant, no need to remove that + from the list. One of the DECL_ORIGINAL_TYPE + variants, e.g. created for aligned attribute, might still + refer to the newdecl TYPE_DECL though, so remove that one + in that case. */ + if (DECL_ORIGINAL_TYPE (newdecl) + && DECL_ORIGINAL_TYPE (newdecl) != remove) + for (tree t = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (newdecl)); + t; t = TYPE_MAIN_VARIANT (t)) + if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl) + { + TYPE_NEXT_VARIANT (t) + = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t)); + break; + } + } + else + for (tree t = TYPE_MAIN_VARIANT (remove); ; + t = TYPE_NEXT_VARIANT (t)) + if (TYPE_NEXT_VARIANT (t) == remove) + { + TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); + break; + } } } @@ -6436,10 +6456,12 @@ grokdeclarator (const struct c_declarator *declarator, 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 @@ -6449,8 +6471,7 @@ grokdeclarator (const struct c_declarator *declarator, && (!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; @@ -9485,7 +9506,8 @@ finish_function (void) && !C_FUNCTION_IMPLICIT_INT (fndecl) /* Normally, with -Wreturn-type, flow will complain, but we might optimize out static functions. */ - && !TREE_PUBLIC (fndecl)) + && !TREE_PUBLIC (fndecl) + && targetm.warn_func_return (fndecl)) { warning (OPT_Wreturn_type, "no return statement in function returning non-void"); |