diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 31 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 22 | ||||
-rw-r--r-- | gcc/c/c-lang.h | 12 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 51 |
4 files changed, 96 insertions, 20 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 351eb4e..47f828f 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,34 @@ +2025-06-12 Jakub Jelinek <jakub@redhat.com> + + * c-lang.h (union lang_type::maybe_objc_info): New type. + (struct lang_type): Use union maybe_objc_info info member + instead of tree objc_info. + * c-decl.cc (finish_struct): Allocate struct lang_type using + ggc_internal_cleared_alloc instead of ggc_cleared_alloc, + and use sizeof (struct lang_type) for ObjC and otherwise + offsetof (struct lang_type, info) as size. + (finish_enum): Likewise. + +2025-06-11 Martin Uecker <uecker@tugraz.at> + + PR c/120510 + * c-typeck.cc (composite_type_internal): Activate checking + assertions for all types and also inputs. + (comptypes_for_composite_check): New helper function. + (function_types_compatible_p): Add exception. + +2025-06-11 Martin Uecker <uecker@tugraz.at> + + * c-typeck.cc (function_types_compatible_p): Remove unused + variables and return true/false instead of 1/0. + (type_lists_compatible_p): Return false instead of 0. + +2025-06-11 Martin Uecker <uecker@tugraz.at> + + PR c/120303 + * c-parser.cc (c_parser_generic_selection): Handle error + condition. + 2025-06-09 Martin Uecker <uecker@tugraz.at> PR c/120510 diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 2b0bd66..8bbd6eb 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9790,12 +9790,17 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, len += list_length (x); /* Use the same allocation policy here that make_node uses, to - ensure that this lives as long as the rest of the struct decl. - All decls in an inline function need to be saved. */ - - space = ggc_cleared_alloc<struct lang_type> (); - space2 = (sorted_fields_type *) ggc_internal_alloc - (sizeof (struct sorted_fields_type) + len * sizeof (tree)); + ensure that this lives as long as the rest of the struct decl. + All decls in an inline function need to be saved. */ + + space = ((struct lang_type *) + ggc_internal_cleared_alloc (c_dialect_objc () + ? sizeof (struct lang_type) + : offsetof (struct lang_type, + info))); + space2 = ((sorted_fields_type *) + ggc_internal_alloc (sizeof (struct sorted_fields_type) + + len * sizeof (tree))); len = 0; space->s = space2; @@ -10269,7 +10274,10 @@ finish_enum (tree enumtype, tree values, tree attributes) /* Record the min/max values so that we can warn about bit-field enumerations that are too small for the values. */ - lt = ggc_cleared_alloc<struct lang_type> (); + lt = ((struct lang_type *) + ggc_internal_cleared_alloc (c_dialect_objc () + ? sizeof (struct lang_type) + : offsetof (struct lang_type, info))); lt->enum_min = minnode; lt->enum_max = maxnode; TYPE_LANG_SPECIFIC (enumtype) = lt; diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 4b93d18..2e99b4d 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -35,10 +35,14 @@ struct GTY(()) lang_type { /* In an ENUMERAL_TYPE, the min and max values. */ tree enum_min; tree enum_max; - /* In a RECORD_TYPE, information specific to Objective-C, such - as a list of adopted protocols or a pointer to a corresponding - @interface. See objc/objc-act.h for details. */ - tree objc_info; + union maybe_objc_info { + /* If not c_dialect_objc, this part is not even allocated. */ + char GTY((tag ("0"))) non_objc; + /* In a RECORD_TYPE, information specific to Objective-C, such + as a list of adopted protocols or a pointer to a corresponding + @interface. See objc/objc-act.h for details. */ + tree GTY((tag ("1"))) objc_info; + } GTY ((desc ("c_dialect_objc ()"))) info; }; struct GTY(()) lang_decl { diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index ae3e706..e24629b 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -136,6 +136,7 @@ static int lvalue_or_else (location_t, const_tree, enum lvalue_use); static void record_maybe_used_decl (tree); static bool comptypes_internal (const_tree, const_tree, struct comptypes_data *data); +static bool comptypes_check_for_composite (tree t1, tree t2); /* Return true if EXP is a null pointer constant, false otherwise. */ @@ -1002,15 +1003,13 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) tree composite_type (tree t1, tree t2) { + gcc_checking_assert (comptypes_check_for_composite (t1, t2)); + struct composite_cache cache = { }; tree n = composite_type_internal (t1, t2, &cache); - /* For function types there are some cases where qualifiers do - not match. See PR120510. */ - if (FUNCTION_TYPE != TREE_CODE (n)) - { - gcc_checking_assert (comptypes (n, t1)); - gcc_checking_assert (comptypes (n, t2)); - } + + gcc_checking_assert (comptypes_check_for_composite (n, t1)); + gcc_checking_assert (comptypes_check_for_composite (n, t2)); return n; } @@ -1454,16 +1453,39 @@ comptypes_verify (tree type1, tree type2) } struct comptypes_data { + + /* output */ bool enum_and_int_p; bool different_types_p; bool warning_needed; + + /* context */ bool anon_field; bool pointedto; + + /* configuration */ bool equiv; + bool ignore_promoting_args; const struct tagged_tu_seen_cache* cache; }; + +/* Helper function for composite_type. This function ignores when the + function type of an old-style declaration is incompatible with a type + of a declaration with prototype because some are arguments are not + self-promoting. This is ignored only for function types but not + ignored in a nested context. */ + +static bool +comptypes_check_for_composite (tree t1, tree t2) +{ + struct comptypes_data data = { }; + data.ignore_promoting_args = FUNCTION_TYPE == TREE_CODE (t1); + return comptypes_internal (t1, t2, &data); +} + + /* C implementation of compatible_types_for_indirection_note_p. */ bool @@ -1593,6 +1615,10 @@ comptypes_equiv_p (tree type1, tree type2) permitted in C11 typedef redeclarations, then this sets 'different_types_p' in DATA to true; it is never set to false, but may or may not be set if the types are incompatible. + If two functions types are not compatible only because one is + an old-style definition that does not have self-promoting arguments, + then this can be ignored by setting 'ignore_promoting_args_p'. + For 'equiv' we can compute equivalency classes (see above). This differs from comptypes, in that we don't free the seen types. */ @@ -2030,9 +2056,14 @@ function_types_compatible_p (const_tree f1, const_tree f2, ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2), TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE); + bool ignore_pargs = data->ignore_promoting_args; + data->ignore_promoting_args = false; + if (!comptypes_internal (ret1, ret2, data)) return false; + data->ignore_promoting_args = ignore_pargs; + tree args1 = TYPE_ARG_TYPES (f1); tree args2 = TYPE_ARG_TYPES (f2); @@ -2046,8 +2077,9 @@ function_types_compatible_p (const_tree f1, const_tree f2, { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2)) return false; - if (!self_promoting_args_p (args2)) + if (!(data->ignore_promoting_args || self_promoting_args_p (args2))) return false; + data->ignore_promoting_args = false; /* If one of these types comes from a non-prototype fn definition, compare that with the other type's arglist. If they don't match, ask for a warning (but no error). */ @@ -2060,8 +2092,9 @@ function_types_compatible_p (const_tree f1, const_tree f2, { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2)) return false; - if (!self_promoting_args_p (args1)) + if (!(data->ignore_promoting_args || self_promoting_args_p (args1))) return false; + data->ignore_promoting_args = false; if (TYPE_ACTUAL_ARG_TYPES (f2) && !type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), data)) data->warning_needed = true; |