diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 94 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 306 | ||||
-rw-r--r-- | gcc/c/c-errors.cc | 63 | ||||
-rw-r--r-- | gcc/c/c-objc-common.cc | 2 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 55 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 10 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 155 |
7 files changed, 337 insertions, 348 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index cb69b8c..464e5a1 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,97 @@ +2025-08-02 Martin Uecker <uecker@tugraz.at> + + * c-decl.cc (get_parm_array_spec): Remove. + (push_parm_decl): Do not add `arg spec` attribute. + (build_arg_spec_attribute): New function. + (grokdeklarator): Add `arg spec` attribute. + +2025-07-25 David Malcolm <dmalcolm@redhat.com> + + * c-errors.cc: Update usage of "diagnostic_info" to explicitly + refer to "diagnostics::diagnostic_info". + +2025-07-25 David Malcolm <dmalcolm@redhat.com> + + * c-errors.cc: Update for diagnostic_t becoming + enum class diagnostics::kind. + * c-parser.cc: Likewise. + * c-typeck.cc: Likewise. + +2025-07-25 David Malcolm <dmalcolm@redhat.com> + + * c-decl.cc: Update for renaming of diagnostic_option_id to + diagnostics::option_id. + * c-errors.cc: Likewise. + * c-tree.h: Likewise. + +2025-07-25 David Malcolm <dmalcolm@redhat.com> + + * c-objc-common.cc: Update for diagnostic_context becoming + diagnostics::context. + * c-tree.h: Likewise. + +2025-07-25 David Malcolm <dmalcolm@redhat.com> + + * c-errors.cc: Update to add "m_" prefix to fields of + diagnostic_info throughout. + +2025-07-21 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * c-typeck.cc (build_asm_expr): Pass null pointer to + parse_{input,output}_constraint(). + +2025-07-16 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * c-typeck.cc (handle_omp_array_sections): Use OMP_ITERATOR_DECL_P. + (c_finish_omp_clauses): Likewise. + +2025-07-15 Jakub Jelinek <jakub@redhat.com> + Jason Merrill <jason@redhat.com> + + PR c/44677 + * c-parser.cc (c_parser_unary_expression): Clear DECL_READ_P + after default_function_array_read_conversion for + -Wunused-but-set-{parameter,variable}={2,3} on + PRE{IN,DE}CREMENT_EXPR argument. + (c_parser_postfix_expression_after_primary): Similarly for + POST{IN,DE}CREMENT_EXPR. + * c-decl.cc (pop_scope): Use OPT_Wunused_but_set_variable_ + instead of OPT_Wunused_but_set_variable. + (finish_function): Use OPT_Wunused_but_set_parameter_ + instead of OPT_Wunused_but_set_parameter. + * c-typeck.cc (mark_exp_read): Handle {PRE,POST}{IN,DE}CREMENT_EXPR + and don't handle it when cast to void. + (build_modify_expr): Clear DECL_READ_P after build_binary_op + for -Wunused-but-set-{parameter,variable}=3. + +2025-07-10 Qing Zhao <qing.zhao@oracle.com> + + * c-typeck.cc (build_access_with_size_for_counted_by): Update comments. + Adjust the arguments per the new design. + +2025-07-10 Qing Zhao <qing.zhao@oracle.com> + + PR middle-end/121000 + * c-typeck.cc (build_access_with_size_for_counted_by): Update comments. + Pass TYPE_SIZE_UNIT of the element as the 6th argument. + +2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + Revert: + 2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument + to a vector of fields with counted_by attribute. Verify all fields + in this vector. + (finish_struct): Collect all the fields with counted_by attribute + to a vector and pass this vector to verify_counted_by_attribute. + * c-typeck.cc (build_counted_by_ref): Handle pointers with counted_by. + Add one more argument, issue error when the pointee type is a structure + or union including a flexible array member. + (build_access_with_size_for_counted_by): Handle pointers with counted_by. + (handle_counted_by_for_component_ref): Call build_counted_by_ref + with the new prototype. + 2025-07-01 Qing Zhao <qing.zhao@oracle.com> * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 7e1c197..7850365 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -1363,7 +1363,7 @@ pop_scope (void) case VAR_DECL: /* Warnings for unused variables. */ if ((!TREE_USED (p) || !DECL_READ_P (p)) - && !warning_suppressed_p (p, OPT_Wunused_but_set_variable) + && !warning_suppressed_p (p, OPT_Wunused_but_set_variable_) && !DECL_IN_SYSTEM_HEADER (p) && DECL_NAME (p) && !DECL_ARTIFICIAL (p) @@ -1377,7 +1377,7 @@ pop_scope (void) } else if (DECL_CONTEXT (p) == current_function_decl) warning_at (DECL_SOURCE_LOCATION (p), - OPT_Wunused_but_set_variable, + OPT_Wunused_but_set_variable_, "variable %qD set but not used", p); } @@ -4556,7 +4556,7 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc) /* Next, look for exact matches for builtin defines that would have been defined if the user had passed a command-line option (e.g. -fopenmp for "_OPENMP"). */ - diagnostic_option_id option_id + diagnostics::option_id option_id = get_option_for_builtin_define (IDENTIFIER_POINTER (name)); if (option_id.m_idx > 0) return name_hint @@ -6208,184 +6208,7 @@ grokparm (const struct c_parm *parm, tree *expr) return decl; } -/* Return attribute "arg spec" corresponding to an array/VLA parameter - described by PARM, concatenated onto attributes ATTRS. - The spec consists of one dollar symbol for each specified variable - bound, one asterisk for each unspecified variable bound, followed - by at most one specification of the most significant bound of - an ordinary array parameter. For ordinary arrays the specification - is either the constant bound itself, or the space character for - an array with an unspecified bound (the [] form). Finally, a chain - of specified variable bounds is appended to the spec, starting with - the most significant bound. For example, the PARM T a[2][m][3][n] - will produce __attribute__((arg spec ("[$$2]", m, n)). - For T a typedef for an array with variable bounds, the bounds are - included in the specification in the expected order. - No "arg spec" is created for parameters of pointer types, making - a distinction between T(*)[N] (or, equivalently, T[][N]) and - the T[M][N] form, all of which have the same type and are represented - the same, but only the last of which gets an "arg spec" describing - the most significant bound M. */ -static tree -get_parm_array_spec (const struct c_parm *parm, tree attrs) -{ - /* The attribute specification string, minor bound first. */ - std::string spec; - - /* A list of VLA variable bounds, major first, or null if unspecified - or not a VLA. */ - tree vbchain = NULL_TREE; - /* True for a pointer parameter. */ - bool pointer = false; - /* True for an ordinary array with an unpecified bound. */ - bool nobound = false; - - /* Create a string representation for the bounds of the array/VLA. */ - for (c_declarator *pd = parm->declarator, *next; pd; pd = next) - { - next = pd->declarator; - while (next && next->kind == cdk_attrs) - next = next->declarator; - - /* Remember if a pointer has been seen to avoid storing the constant - bound. */ - if (pd->kind == cdk_pointer) - pointer = true; - - if ((pd->kind == cdk_pointer || pd->kind == cdk_function) - && (!next || next->kind == cdk_id)) - { - /* Do nothing for the common case of a pointer. The fact that - the parameter is one can be deduced from the absence of - an arg spec for it. */ - return attrs; - } - - if (pd->kind == cdk_id) - { - if (pointer - || !parm->specs->type - || TREE_CODE (parm->specs->type) != ARRAY_TYPE - || !TYPE_DOMAIN (parm->specs->type) - || !TYPE_MAX_VALUE (TYPE_DOMAIN (parm->specs->type))) - continue; - - tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm->specs->type)); - if (!vbchain - && TREE_CODE (max) == INTEGER_CST) - { - /* Extract the upper bound from a parameter of an array type - unless the parameter is an ordinary array of unspecified - bound in which case a next iteration of the loop will - exit. */ - if (spec.empty () || spec.end ()[-1] != ' ') - { - if (!tree_fits_shwi_p (max)) - continue; - - /* The upper bound is the value of the largest valid - index. */ - HOST_WIDE_INT n = tree_to_shwi (max) + 1; - char buf[40]; - sprintf (buf, HOST_WIDE_INT_PRINT_UNSIGNED, n); - spec += buf; - } - continue; - } - - /* For a VLA typedef, create a list of its variable bounds and - append it in the expected order to VBCHAIN. */ - tree tpbnds = NULL_TREE; - for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE; - type = TREE_TYPE (type)) - { - tree nelts_minus_one = array_type_nelts_minus_one (type); - if (error_operand_p (nelts_minus_one)) - return attrs; - if (TREE_CODE (nelts_minus_one) != INTEGER_CST) - { - /* Each variable VLA bound is represented by the dollar - sign. */ - spec += "$"; - tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds); - } - } - tpbnds = nreverse (tpbnds); - vbchain = chainon (vbchain, tpbnds); - continue; - } - - if (pd->kind != cdk_array) - continue; - - if (pd->u.array.vla_unspec_p) - { - /* Each unspecified bound is represented by a star. There - can be any number of these in a declaration (but none in - a definition). */ - spec += '*'; - continue; - } - - tree nelts = pd->u.array.dimen; - if (!nelts) - { - /* Ordinary array of unspecified size. There can be at most - one for the most significant bound. Exit on the next - iteration which determines whether or not PARM is declared - as a pointer or an array. */ - nobound = true; - continue; - } - - if (pd->u.array.static_p) - spec += 's'; - - if (!INTEGRAL_TYPE_P (TREE_TYPE (nelts))) - /* Avoid invalid NELTS. */ - return attrs; - - STRIP_NOPS (nelts); - nelts = c_fully_fold (nelts, false, nullptr); - if (TREE_CODE (nelts) == INTEGER_CST) - { - /* Skip all constant bounds except the most significant one. - The interior ones are included in the array type. */ - if (next && (next->kind == cdk_array || next->kind == cdk_pointer)) - continue; - - if (!tree_fits_uhwi_p (nelts)) - /* Bail completely on invalid bounds. */ - return attrs; - - char buf[40]; - unsigned HOST_WIDE_INT n = tree_to_uhwi (nelts); - sprintf (buf, HOST_WIDE_INT_PRINT_UNSIGNED, n); - spec += buf; - break; - } - - /* Each variable VLA bound is represented by a dollar sign. */ - spec += "$"; - vbchain = tree_cons (NULL_TREE, nelts, vbchain); - } - - if (spec.empty () && !nobound) - return attrs; - - spec.insert (0, "["); - if (nobound) - /* Ordinary array of unspecified bound is represented by a space. - It must be last in the spec. */ - spec += ' '; - spec += ']'; - - tree acsstr = build_string (spec.length () + 1, spec.c_str ()); - tree args = tree_cons (NULL_TREE, acsstr, vbchain); - tree name = get_identifier ("arg spec"); - return tree_cons (name, args, attrs); -} /* Given a parsed parameter declaration, decode it into a PARM_DECL and push that on the current scope. EXPR is a pointer to an @@ -6401,7 +6224,6 @@ push_parm_decl (const struct c_parm *parm, tree *expr) if (decl && DECL_P (decl)) DECL_SOURCE_LOCATION (decl) = parm->loc; - attrs = get_parm_array_spec (parm, attrs); decl_attributes (&decl, attrs, 0); decl = pushdecl (decl); @@ -6775,6 +6597,25 @@ add_decl_expr (location_t loc, tree type, tree *expr, bool set_name_p) } } + +/* Add attribute "arg spec" to ATTRS corresponding to an array/VLA parameter + declared with type TYPE. The attribute has two arguments. The first is + a string that encodes the presence of the static keyword. The second is + the declared type of the array before adjustment, i.e. as an array type + including the outermost bound. */ + +static tree +build_arg_spec_attribute (tree type, bool static_p, tree attrs) +{ + tree vbchain = tree_cons (NULL_TREE, type, NULL_TREE); + tree acsstr = static_p ? build_string (7, "static") : + build_string (1, ""); + tree args = tree_cons (NULL_TREE, acsstr, vbchain); + tree name = get_identifier ("arg spec"); + return tree_cons (name, args, attrs); +} + + /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. @@ -6834,6 +6675,7 @@ grokdeclarator (const struct c_declarator *declarator, bool funcdef_flag = false; bool funcdef_syntax = false; bool size_varies = false; + bool size_error = false; tree decl_attr = declspecs->decl_attr; int array_ptr_quals = TYPE_UNQUALIFIED; tree array_ptr_attrs = NULL_TREE; @@ -7326,6 +7168,7 @@ grokdeclarator (const struct c_declarator *declarator, "size of unnamed array has non-integer type"); size = integer_one_node; size_int_const = true; + size_error = true; } /* This can happen with enum forward declaration. */ else if (!COMPLETE_TYPE_P (TREE_TYPE (size))) @@ -7338,6 +7181,7 @@ grokdeclarator (const struct c_declarator *declarator, "type"); size = integer_one_node; size_int_const = true; + size_error = true; } size = c_fully_fold (size, false, &size_maybe_const); @@ -7363,6 +7207,7 @@ grokdeclarator (const struct c_declarator *declarator, error_at (loc, "size of unnamed array is negative"); size = integer_one_node; size_int_const = true; + size_error = true; } /* Handle a size folded to an integer constant but not an integer constant expression. */ @@ -7978,6 +7823,10 @@ grokdeclarator (const struct c_declarator *declarator, if (TREE_CODE (type) == ARRAY_TYPE) { + if (!size_error) + *decl_attrs = build_arg_spec_attribute (type, array_parm_static, + *decl_attrs); + /* Transfer const-ness of array into that of type pointed to. */ type = TREE_TYPE (type); if (orig_qual_type != NULL_TREE) @@ -9432,62 +9281,56 @@ c_update_type_canonical (tree t) } } -/* Verify the argument of the counted_by attribute of each of the - FIELDS_WITH_COUNTED_BY is a valid field of the containing structure, - STRUCT_TYPE, Report error and remove the corresponding attribute - when it's not. */ +/* Verify the argument of the counted_by attribute of the flexible array + member FIELD_DECL is a valid field of the containing structure, + STRUCT_TYPE, Report error and remove this attribute when it's not. */ static void -verify_counted_by_attribute (tree struct_type, - auto_vec<tree> *fields_with_counted_by) +verify_counted_by_attribute (tree struct_type, tree field_decl) { - for (tree field_decl : *fields_with_counted_by) - { - tree attr_counted_by = lookup_attribute ("counted_by", - DECL_ATTRIBUTES (field_decl)); + tree attr_counted_by = lookup_attribute ("counted_by", + DECL_ATTRIBUTES (field_decl)); - if (!attr_counted_by) - continue; + if (!attr_counted_by) + return; - /* If there is an counted_by attribute attached to the field, - verify it. */ + /* If there is an counted_by attribute attached to the field, + verify it. */ - tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by)); + tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by)); - /* Verify the argument of the attrbute is a valid field of the - containing structure. */ + /* Verify the argument of the attrbute is a valid field of the + containing structure. */ - tree counted_by_field = lookup_field (struct_type, fieldname); + tree counted_by_field = lookup_field (struct_type, fieldname); - /* Error when the field is not found in the containing structure and - remove the corresponding counted_by attribute from the field_decl. */ - if (!counted_by_field) + /* Error when the field is not found in the containing structure and + remove the corresponding counted_by attribute from the field_decl. */ + if (!counted_by_field) + { + error_at (DECL_SOURCE_LOCATION (field_decl), + "argument %qE to the %<counted_by%> attribute" + " is not a field declaration in the same structure" + " as %qD", fieldname, field_decl); + DECL_ATTRIBUTES (field_decl) + = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl)); + } + else + /* Error when the field is not with an integer type. */ + { + while (TREE_CHAIN (counted_by_field)) + counted_by_field = TREE_CHAIN (counted_by_field); + tree real_field = TREE_VALUE (counted_by_field); + + if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field))) { error_at (DECL_SOURCE_LOCATION (field_decl), "argument %qE to the %<counted_by%> attribute" - " is not a field declaration in the same structure" - " as %qD", fieldname, field_decl); + " is not a field declaration with an integer type", + fieldname); DECL_ATTRIBUTES (field_decl) = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl)); } - else - /* Error when the field is not with an integer type. */ - { - while (TREE_CHAIN (counted_by_field)) - counted_by_field = TREE_CHAIN (counted_by_field); - tree real_field = TREE_VALUE (counted_by_field); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field))) - { - error_at (DECL_SOURCE_LOCATION (field_decl), - "argument %qE to the %<counted_by%> attribute" - " is not a field declaration with an integer type", - fieldname); - DECL_ATTRIBUTES (field_decl) - = remove_attribute ("counted_by", - DECL_ATTRIBUTES (field_decl)); - } - } } } @@ -9562,7 +9405,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, until now.) */ bool saw_named_field = false; - auto_vec<tree> fields_with_counted_by; + tree counted_by_fam_field = NULL_TREE; for (x = fieldlist; x; x = DECL_CHAIN (x)) { /* Whether this field is the last field of the structure or union. @@ -9643,16 +9486,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, record it here and do more verification later after the whole structure is complete. */ if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x))) - fields_with_counted_by.safe_push (x); + counted_by_fam_field = x; } - if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE) - /* If there is a counted_by attribute attached to this field, - record it here and do more verification later after the - whole structure is complete. */ - if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x))) - fields_with_counted_by.safe_push (x); - if (pedantic && TREE_CODE (t) == RECORD_TYPE && flexible_array_type_p (TREE_TYPE (x))) pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic, @@ -9951,8 +9787,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, struct_parse_info->struct_types.safe_push (t); } - if (fields_with_counted_by.length () > 0) - verify_counted_by_attribute (t, &fields_with_counted_by); + if (counted_by_fam_field) + verify_counted_by_attribute (t, counted_by_fam_field); return t; } @@ -11478,9 +11314,9 @@ finish_function (location_t end_loc) && !DECL_READ_P (decl) && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl) - && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter)) + && !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter_)) warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_but_set_parameter, + OPT_Wunused_but_set_parameter_, "parameter %qD set but not used", decl); } diff --git a/gcc/c/c-errors.cc b/gcc/c/c-errors.cc index 4682dca..e2c74fe 100644 --- a/gcc/c/c-errors.cc +++ b/gcc/c/c-errors.cc @@ -33,10 +33,10 @@ along with GCC; see the file COPYING3. If not see bool pedwarn_c23 (location_t location, - diagnostic_option_id option_id, + diagnostics::option_id option_id, const char *gmsgid, ...) { - diagnostic_info diagnostic; + diagnostics::diagnostic_info diagnostic; va_list ap; bool warned = false; rich_location richloc (line_table, location); @@ -48,8 +48,9 @@ pedwarn_c23 (location_t location, { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc2y) - ? DK_PEDWARN : DK_WARNING); - diagnostic.option_id = OPT_Wc23_c2y_compat; + ? diagnostics::kind::pedwarn + : diagnostics::kind::warning); + diagnostic.m_option_id = OPT_Wc23_c2y_compat; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } /* -Wno-c23-c2y-compat suppresses even the pedwarns. */ @@ -58,8 +59,9 @@ pedwarn_c23 (location_t location, /* For -pedantic outside C2Y, issue a pedwarn. */ else if (pedantic && !flag_isoc2y) { - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); - diagnostic.option_id = option_id; + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, + diagnostics::kind::pedwarn); + diagnostic.m_option_id = option_id; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } va_end (ap); @@ -77,10 +79,10 @@ pedwarn_c23 (location_t location, bool pedwarn_c11 (location_t location, - diagnostic_option_id option_id, + diagnostics::option_id option_id, const char *gmsgid, ...) { - diagnostic_info diagnostic; + diagnostics::diagnostic_info diagnostic; va_list ap; bool warned = false; rich_location richloc (line_table, location); @@ -93,11 +95,12 @@ pedwarn_c11 (location_t location, { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc23) - ? DK_PEDWARN : DK_WARNING); + ? diagnostics::kind::pedwarn + : diagnostics::kind::warning); if (option_id == OPT_Wpedantic) - diagnostic.option_id = OPT_Wc11_c23_compat; + diagnostic.m_option_id = OPT_Wc11_c23_compat; else - diagnostic.option_id = option_id; + diagnostic.m_option_id = option_id; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } /* -Wno-c11-c23-compat suppresses even the pedwarns. */ @@ -106,8 +109,9 @@ pedwarn_c11 (location_t location, /* For -pedantic outside C23, issue a pedwarn. */ else if (pedantic && !flag_isoc23) { - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); - diagnostic.option_id = option_id; + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, + diagnostics::kind::pedwarn); + diagnostic.m_option_id = option_id; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } va_end (ap); @@ -122,10 +126,10 @@ pedwarn_c11 (location_t location, bool pedwarn_c99 (location_t location, - diagnostic_option_id option_id, + diagnostics::option_id option_id, const char *gmsgid, ...) { - diagnostic_info diagnostic; + diagnostics::diagnostic_info diagnostic; va_list ap; bool warned = false; rich_location richloc (line_table, location); @@ -137,8 +141,9 @@ pedwarn_c99 (location_t location, { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc11) - ? DK_PEDWARN : DK_WARNING); - diagnostic.option_id = OPT_Wc99_c11_compat; + ? diagnostics::kind::pedwarn + : diagnostics::kind::warning); + diagnostic.m_option_id = OPT_Wc99_c11_compat; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } /* -Wno-c99-c11-compat suppresses even the pedwarns. */ @@ -147,8 +152,9 @@ pedwarn_c99 (location_t location, /* For -pedantic outside C11, issue a pedwarn. */ else if (pedantic && !flag_isoc11) { - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); - diagnostic.option_id = option_id; + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, + diagnostics::kind::pedwarn); + diagnostic.m_option_id = option_id; warned = diagnostic_report_diagnostic (global_dc, &diagnostic); } va_end (ap); @@ -164,10 +170,10 @@ pedwarn_c99 (location_t location, bool pedwarn_c90 (location_t location, - diagnostic_option_id option_id, + diagnostics::option_id option_id, const char *gmsgid, ...) { - diagnostic_info diagnostic; + diagnostics::diagnostic_info diagnostic; va_list ap; bool warned = false; rich_location richloc (line_table, location); @@ -183,8 +189,9 @@ pedwarn_c90 (location_t location, { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc99) - ? DK_PEDWARN : DK_WARNING); - diagnostic.option_id = option_id; + ? diagnostics::kind::pedwarn + : diagnostics::kind::warning); + diagnostic.m_option_id = option_id; diagnostic_report_diagnostic (global_dc, &diagnostic); warned = true; goto out; @@ -196,8 +203,9 @@ pedwarn_c90 (location_t location, { diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, (pedantic && !flag_isoc99) - ? DK_PEDWARN : DK_WARNING); - diagnostic.option_id = OPT_Wc90_c99_compat; + ? diagnostics::kind::pedwarn + : diagnostics::kind::warning); + diagnostic.m_option_id = OPT_Wc90_c99_compat; diagnostic_report_diagnostic (global_dc, &diagnostic); } /* -Wno-c90-c99-compat suppresses the pedwarns. */ @@ -206,8 +214,9 @@ pedwarn_c90 (location_t location, /* For -pedantic outside C99, issue a pedwarn. */ else if (pedantic && !flag_isoc99) { - diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); - diagnostic.option_id = option_id; + diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, + diagnostics::kind::pedwarn); + diagnostic.m_option_id = option_id; diagnostic_report_diagnostic (global_dc, &diagnostic); warned = true; } diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc index d574bc7..5c50983 100644 --- a/gcc/c/c-objc-common.cc +++ b/gcc/c/c-objc-common.cc @@ -414,7 +414,7 @@ has_c_linkage (const_tree decl ATTRIBUTE_UNUSED) } void -c_initialize_diagnostics (diagnostic_context *context) +c_initialize_diagnostics (diagnostics::context *context) { context->set_pretty_printer (std::make_unique<c_pretty_printer> ()); c_common_diagnostics_set_defaults (context); diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 0c3e3e2..4a13fc0 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -10547,15 +10547,31 @@ c_parser_unary_expression (c_parser *parser) c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - - op = default_function_array_read_conversion (exp_loc, op); + if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL) + && !DECL_READ_P (op.value) + && (VAR_P (op.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1) + { + op = default_function_array_read_conversion (exp_loc, op); + DECL_READ_P (op.value) = 0; + } + else + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); case CPP_MINUS_MINUS: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); - - op = default_function_array_read_conversion (exp_loc, op); + if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL) + && !DECL_READ_P (op.value) + && (VAR_P (op.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1) + { + op = default_function_array_read_conversion (exp_loc, op); + DECL_READ_P (op.value) = 0; + } + else + op = default_function_array_read_conversion (exp_loc, op); return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); case CPP_AND: c_parser_consume_token (parser); @@ -13933,7 +13949,17 @@ c_parser_postfix_expression_after_primary (c_parser *parser, start = expr.get_start (); finish = c_parser_peek_token (parser)->get_finish (); c_parser_consume_token (parser); - expr = default_function_array_read_conversion (expr_loc, expr); + if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL) + && !DECL_READ_P (expr.value) + && (VAR_P (expr.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1 + && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE) + { + expr = default_function_array_read_conversion (expr_loc, expr); + DECL_READ_P (expr.value) = 0; + } + else + expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR, expr.value, false); set_c_expr_source_range (&expr, start, finish); @@ -13945,7 +13971,17 @@ c_parser_postfix_expression_after_primary (c_parser *parser, start = expr.get_start (); finish = c_parser_peek_token (parser)->get_finish (); c_parser_consume_token (parser); - expr = default_function_array_read_conversion (expr_loc, expr); + if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL) + && !DECL_READ_P (expr.value) + && (VAR_P (expr.value) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 1 + && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE) + { + expr = default_function_array_read_conversion (expr_loc, expr); + DECL_READ_P (expr.value) = 0; + } + else + expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR, expr.value, false); set_c_expr_source_range (&expr, start, finish); @@ -29126,11 +29162,14 @@ c_parser_omp_error (c_parser *parser, enum pragma_context context) if (msg == NULL) msg = _("<message unknown at compile time>"); } + const enum diagnostics::kind diag_kind = (severity_fatal + ? diagnostics::kind::error + : diagnostics::kind::warning); if (msg) - emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0, + emit_diagnostic (diag_kind, loc, 0, "%<pragma omp error%> encountered: %s", msg); else - emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0, + emit_diagnostic (diag_kind, loc, 0, "%<pragma omp error%> encountered"); return false; } diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 364f51d..bb0b113 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -757,7 +757,7 @@ extern tree c_finish_bc_name (location_t, tree, bool); extern bool c_objc_common_init (void); extern bool c_missing_noreturn_ok_p (tree); extern bool c_warn_unused_global_decl (const_tree); -extern void c_initialize_diagnostics (diagnostic_context *); +extern void c_initialize_diagnostics (diagnostics::context *); extern bool c_var_mod_p (tree x, tree fn); extern alias_set_type c_get_alias_set (tree); extern int c_type_dwarf_attribute (const_tree, int); @@ -960,13 +960,13 @@ extern void c_bind (location_t, tree, bool); extern bool tag_exists_p (enum tree_code, tree); /* In c-errors.cc */ -extern bool pedwarn_c90 (location_t, diagnostic_option_id, const char *, ...) +extern bool pedwarn_c90 (location_t, diagnostics::option_id, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -extern bool pedwarn_c99 (location_t, diagnostic_option_id, const char *, ...) +extern bool pedwarn_c99 (location_t, diagnostics::option_id, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -extern bool pedwarn_c11 (location_t, diagnostic_option_id, const char *, ...) +extern bool pedwarn_c11 (location_t, diagnostics::option_id, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -extern bool pedwarn_c23 (location_t, diagnostic_option_id, const char *, ...) +extern bool pedwarn_c23 (location_t, diagnostics::option_id, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern void add_note_about_new_keyword (location_t loc, tree keyword_id); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 7948106..ed6e56e 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -2310,14 +2310,30 @@ mark_exp_read (tree exp) case PARM_DECL: DECL_READ_P (exp) = 1; break; + CASE_CONVERT: + if (VOID_TYPE_P (TREE_TYPE (exp))) + switch (TREE_CODE (TREE_OPERAND (exp, 0))) + { + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: + return; + default: + break; + } + /* FALLTHRU */ case ARRAY_REF: case COMPONENT_REF: case MODIFY_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: - CASE_CONVERT: case ADDR_EXPR: case VIEW_CONVERT_EXPR: + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + case POSTINCREMENT_EXPR: + case POSTDECREMENT_EXPR: mark_exp_read (TREE_OPERAND (exp, 0)); break; case COMPOUND_EXPR: @@ -2922,8 +2938,8 @@ should_suggest_deref_p (tree datum_type) /* For a SUBDATUM field of a structure or union DATUM, generate a REF to the object that represents its counted_by per the attribute counted_by - attached to this field if it's a flexible array member or a pointer - field, otherwise return NULL_TREE. + attached to this field if it's a flexible array member field, otherwise + return NULL_TREE. Set COUNTED_BY_TYPE to the TYPE of the counted_by field. For example, if: @@ -2941,34 +2957,18 @@ should_suggest_deref_p (tree datum_type) */ static tree -build_counted_by_ref (location_t loc, tree datum, tree subdatum, - tree *counted_by_type) +build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) { tree type = TREE_TYPE (datum); - tree sub_type = TREE_TYPE (subdatum); - if (!c_flexible_array_member_type_p (sub_type) - && TREE_CODE (sub_type) != POINTER_TYPE) + if (!c_flexible_array_member_type_p (TREE_TYPE (subdatum))) return NULL_TREE; - tree element_type = TREE_TYPE (sub_type); - tree attr_counted_by = lookup_attribute ("counted_by", DECL_ATTRIBUTES (subdatum)); tree counted_by_ref = NULL_TREE; *counted_by_type = NULL_TREE; if (attr_counted_by) { - /* Issue error when the element_type is a structure or - union including a flexible array member. */ - if (RECORD_OR_UNION_TYPE_P (element_type) - && TYPE_INCLUDES_FLEXARRAY (element_type)) - { - error_at (loc, - "%<counted_by%> attribute is not allowed for a pointer to" - " structure or union with flexible array member"); - return error_mark_node; - } - tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by)); counted_by_ref = build_component_ref (UNKNOWN_LOCATION, @@ -2991,29 +2991,28 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum, } /* Given a COMPONENT_REF REF with the location LOC, the corresponding - COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate the corresponding - call to the internal function .ACCESS_WITH_SIZE. - - Generate an INDIRECT_REF to a call to the internal function - .ACCESS_WITH_SIZE. + COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate an INDIRECT_REF + to a call to the internal function .ACCESS_WITH_SIZE. REF to: - (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, (TYPE_OF_SIZE)0, -1, - (TYPE_OF_ARRAY *)0)) + (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, (* TYPE_OF_SIZE)0, + TYPE_SIZE_UNIT for element) NOTE: The return type of this function is the POINTER type pointing - to the original flexible array type or the original pointer type. - Then the type of the INDIRECT_REF is the original flexible array type - or the original pointer type. + to the original flexible array type. + Then the type of the INDIRECT_REF is the original flexible array type. + + The type of the first argument of this function is a POINTER type + to the original flexible array type. - The 4th argument of the call is a constant 0 with the TYPE of the - object pointed by COUNTED_BY_REF. + The 3rd argument of the call is a constant 0 with the pointer TYPE whose + pointee type is the TYPE of the object pointed by COUNTED_BY_REF. - The 6th argument of the call is a constant 0 of the same TYPE as - the return type of the call. + The 4th argument of the call is the TYPE_SIZE_UNIT of the element TYPE + of the array. */ static tree @@ -3021,29 +3020,26 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, tree counted_by_ref, tree counted_by_type) { - gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)) - || TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE); - bool is_fam = c_flexible_array_member_type_p (TREE_TYPE (ref)); - tree first_param = is_fam ? array_to_pointer_conversion (loc, ref) - : build_unary_op (loc, ADDR_EXPR, ref, false); - - /* The result type of the call is a pointer to the original type - of the ref. */ + gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))); + /* The result type of the call is a pointer to the flexible array type. */ tree result_type = c_build_pointer_type (TREE_TYPE (ref)); - first_param = c_fully_fold (first_param, false, NULL); + tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref))); + + tree first_param + = c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL); tree second_param = c_fully_fold (counted_by_ref, false, NULL); + tree third_param = build_int_cst (build_pointer_type (counted_by_type), 0); tree call = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE, - result_type, 6, + result_type, 4, first_param, second_param, - build_int_cst (integer_type_node, 1), - build_int_cst (counted_by_type, 0), - build_int_cst (integer_type_node, -1), - build_int_cst (result_type, 0)); - /* Wrap the call with an INDIRECT_REF with the original type of the ref. */ + third_param, + element_size); + + /* Wrap the call with an INDIRECT_REF with the flexible array type. */ call = build1 (INDIRECT_REF, TREE_TYPE (ref), call); SET_EXPR_LOCATION (call, loc); return call; @@ -3061,7 +3057,7 @@ handle_counted_by_for_component_ref (location_t loc, tree ref) tree datum = TREE_OPERAND (ref, 0); tree subdatum = TREE_OPERAND (ref, 1); tree counted_by_type = NULL_TREE; - tree counted_by_ref = build_counted_by_ref (loc, datum, subdatum, + tree counted_by_ref = build_counted_by_ref (datum, subdatum, &counted_by_type); if (counted_by_ref) ref = build_access_with_size_for_counted_by (loc, ref, @@ -6437,14 +6433,16 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, else { int qual = ENCODE_QUAL_ADDR_SPACE (as_common); - diagnostic_t kind = DK_PERMERROR; + enum diagnostics::kind kind = diagnostics::kind::permerror; if (!flag_isoc99) /* This downgrade to a warning ensures that -std=gnu89 -pedantic-errors does not flag these mismatches between - builtins as errors (as DK_PERMERROR would). ISO C99 - and later do not have implicit function declarations, + builtins as errors (as diagnostics::kind::permerror would) + ISO C99 and later do not have implicit function declarations, so the mismatch cannot occur naturally there. */ - kind = bltin1 && bltin2 ? DK_WARNING : DK_PEDWARN; + kind = (bltin1 && bltin2 + ? diagnostics::kind::warning + : diagnostics::kind::pedwarn); if (emit_diagnostic (kind, colon_loc, OPT_Wincompatible_pointer_types, "pointer type mismatch " "in conditional expression")) @@ -7328,8 +7326,21 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype, newrhs = build1 (EXCESS_PRECISION_EXPR, TREE_TYPE (rhs), newrhs); } + bool clear_decl_read = false; + if ((VAR_P (lhs) || TREE_CODE (lhs) == PARM_DECL) + && !DECL_READ_P (lhs) + && (VAR_P (lhs) ? warn_unused_but_set_variable + : warn_unused_but_set_parameter) > 2) + { + mark_exp_read (newrhs); + if (!DECL_READ_P (lhs)) + clear_decl_read = true; + } + newrhs = build_binary_op (location, modifycode, lhs, newrhs, true); + if (clear_decl_read) + DECL_READ_P (lhs) = 0; /* The original type of the right hand side is no longer meaningful. */ @@ -7589,7 +7600,8 @@ error_init (location_t loc, const char *gmsgid, ...) /* The gmsgid may be a format string with %< and %>. */ va_list ap; va_start (ap, gmsgid); - bool warned = emit_diagnostic_valist (DK_ERROR, loc, -1, gmsgid, &ap); + bool warned = emit_diagnostic_valist (diagnostics::kind::error, + loc, -1, gmsgid, &ap); va_end (ap); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); @@ -7601,7 +7613,7 @@ error_init (location_t loc, const char *gmsgid, ...) static bool ATTRIBUTE_GCC_DIAG (3,0) pedwarn_permerror_init (location_t loc, int opt, const char *gmsgid, - va_list *ap, diagnostic_t kind) + va_list *ap, enum diagnostics::kind kind) { /* Use the location where a macro was expanded rather than where it was defined to make sure macros defined in system headers @@ -7628,7 +7640,8 @@ pedwarn_init (location_t loc, int opt, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); - bool warned = pedwarn_permerror_init (loc, opt, gmsgid, &ap, DK_PEDWARN); + bool warned = pedwarn_permerror_init (loc, opt, gmsgid, &ap, + diagnostics::kind::pedwarn); va_end (ap); return warned; } @@ -7640,7 +7653,8 @@ permerror_init (location_t loc, int opt, const char *gmsgid, ...) { va_list ap; va_start (ap, gmsgid); - bool warned = pedwarn_permerror_init (loc, opt, gmsgid, &ap, DK_PERMERROR); + bool warned = pedwarn_permerror_init (loc, opt, gmsgid, &ap, + diagnostics::kind::permerror); va_end (ap); return warned; } @@ -12637,7 +12651,8 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, oconstraints[i] = constraint; if (parse_output_constraint (&constraint, i, ninputs, noutputs, - &allows_mem, &allows_reg, &is_inout)) + &allows_mem, &allows_reg, &is_inout, + nullptr)) { /* If the operand is going to end up in memory, mark it addressable. */ @@ -12698,7 +12713,8 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, input = TREE_VALUE (tail); if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0, - oconstraints, &allows_mem, &allows_reg)) + oconstraints, &allows_mem, &allows_reg, + nullptr)) { /* If the operand is going to end up in memory, mark it addressable. */ @@ -12880,7 +12896,9 @@ c_finish_return (location_t loc, tree retval, tree origtype, bool musttail_p) && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE) { no_warning = true; - if (emit_diagnostic (flag_isoc99 ? DK_PERMERROR : DK_WARNING, + if (emit_diagnostic (flag_isoc99 + ? diagnostics::kind::permerror + : diagnostics::kind::warning, loc, OPT_Wreturn_mismatch, "%<return%> with no value," " in function returning non-void")) @@ -15628,9 +15646,7 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort) tree *tp = &OMP_CLAUSE_DECL (c); if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) - && TREE_CODE (*tp) == TREE_LIST - && TREE_PURPOSE (*tp) - && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC) + && OMP_ITERATOR_DECL_P (*tp)) tp = &TREE_VALUE (*tp); tree first = handle_omp_array_sections_1 (c, *tp, types, maybe_zero_len, first_non_one, @@ -16827,9 +16843,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* FALLTHRU */ case OMP_CLAUSE_AFFINITY: t = OMP_CLAUSE_DECL (c); - if (TREE_CODE (t) == TREE_LIST - && TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + if (OMP_ITERATOR_DECL_P (t)) { if (TREE_PURPOSE (t) != last_iterators) last_iterators_remove @@ -16929,10 +16943,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; } } - if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST - && TREE_PURPOSE (OMP_CLAUSE_DECL (c)) - && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c))) - == TREE_VEC)) + if (OMP_ITERATOR_DECL_P (OMP_CLAUSE_DECL (c))) TREE_VALUE (OMP_CLAUSE_DECL (c)) = t; else OMP_CLAUSE_DECL (c) = t; |