diff options
author | Martin Sebor <msebor@redhat.com> | 2020-09-19 17:21:52 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-09-19 17:34:31 -0600 |
commit | 6450f07388f9fe575a489c9309c36012b17b88b0 (patch) | |
tree | 929351afdf436f119f15a3d37da96d3a0e3ae27c /gcc/c-family/c-pretty-print.c | |
parent | 3696a50beeb73f4ded8a584e76ee16f0bde109b9 (diff) | |
download | gcc-6450f07388f9fe575a489c9309c36012b17b88b0.zip gcc-6450f07388f9fe575a489c9309c36012b17b88b0.tar.gz gcc-6450f07388f9fe575a489c9309c36012b17b88b0.tar.bz2 |
Infrastructure & C front end changes for array parameter checking (PR c/50584).
gcc/ChangeLog:
PR c/50584
* attribs.c (decl_attributes): Also pass decl along with type
attributes to handlers.
(init_attr_rdwr_indices): Change second argument to attribute chain.
Handle internal attribute representation in addition to external.
(get_parm_access): New function.
(attr_access::to_internal_string): Define new member function.
(attr_access::to_external_string): Define new member function.
(attr_access::vla_bounds): Define new member function.
* attribs.h (struct attr_access): Declare new members.
(attr_access::from_mode_char): Define new member function.
(get_parm_access): Declare new function.
* calls.c (initialize_argument_information): Pass function type
attributes to init_attr_rdwr_indices.
* doc/invoke.texi (-Warray-parameter, -Wvla-parameter): Document.
* tree-pretty-print.c (dump_generic_node): Correct handling of
qualifiers.
* tree-ssa-uninit.c (maybe_warn_pass_by_reference): Same.
* tree.h (access_mode): Add new enumerator.
gcc/c-family/ChangeLog:
PR c/50584
* c-attribs.c (c_common_attribute_table): Add "arg spec" attribute.
(handle_argspec_attribute): New function.
(get_argument, get_argument_type): New functions.
(append_access_attrs): Add overload. Handle internal attribute
representation in addition to external.
(handle_access_attribute): Handle internal attribute representation
in addition to external.
(build_attr_access_from_parms): New function.
gcc/c-family/ChangeLog:
PR c/50584
* c-common.h (warn_parm_array_mismatch): Declare new function.
(has_attribute): Move declaration of an existing function.
(build_attr_access_from_parms): Declare new function.
* c-warn.c (parm_array_as_string): Define new function.
(plus_one): Define new function.
(warn_parm_ptrarray_mismatch): Define new function.
(warn_parm_array_mismatch): Define new function.
(vla_bound_parm_decl): New function.
* c.opt (-Warray-parameter, -Wvla-parameter): New options.
* c-pretty-print.c (pp_c_type_qualifier_list): Don't print array type
qualifiers here...
(c_pretty_printer::direct_abstract_declarator): ...but instead print
them in brackets here. Also print [static]. Strip extraneous
expressions from VLA bounds.
gcc/c/ChangeLog:
PR c/50584
* c-decl.c (lookup_last_decl): Define new function.
(c_decl_attributes): Call it.
(start_decl): Add argument and use it.
(finish_decl): Call build_attr_access_from_parms and decl_attributes.
(get_parm_array_spec): Define new function.
(push_parm_decl): Call get_parm_array_spec.
(start_function): Call warn_parm_array_mismatch. Build attribute
access and add it to current function.
* c-parser.c (c_parser_declaration_or_fndef): Diagnose mismatches
in forms of array parameters.
* c-tree.h (start_decl): Add argument.
gcc/testsuite/ChangeLog:
PR c/50584
* gcc.dg/attr-access-read-write-2.c: Adjust text of expected message.
* c-c++-common/Warray-bounds-6.c: Correct C++ declaration, adjust
text of expected diagnostics.
* gcc.dg/Wbuiltin-declaration-mismatch-9.c: Prune expected warning.
* gcc.dg/Warray-parameter-2.c: New test.
* gcc.dg/Warray-parameter-3.c: New test.
* gcc.dg/Warray-parameter-4.c: New test.
* gcc.dg/Warray-parameter-5.c: New test.
* gcc.dg/Warray-parameter.c: New test.
* gcc.dg/Wvla-parameter-2.c: New test.
* gcc.dg/Wvla-parameter-3.c: New test.
* gcc.dg/Wvla-parameter.c: New test.
Diffstat (limited to 'gcc/c-family/c-pretty-print.c')
-rw-r--r-- | gcc/c-family/c-pretty-print.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index c364e1c..acffd7b 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -248,9 +248,12 @@ pp_c_type_qualifier_list (c_pretty_printer *pp, tree t) if (!TYPE_P (t)) t = TREE_TYPE (t); - qualifiers = TYPE_QUALS (t); - pp_c_cv_qualifiers (pp, qualifiers, - TREE_CODE (t) == FUNCTION_TYPE); + if (TREE_CODE (t) != ARRAY_TYPE) + { + qualifiers = TYPE_QUALS (t); + pp_c_cv_qualifiers (pp, qualifiers, + TREE_CODE (t) == FUNCTION_TYPE); + } if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t))) { @@ -572,6 +575,8 @@ c_pretty_printer::abstract_declarator (tree t) void c_pretty_printer::direct_abstract_declarator (tree t) { + bool add_space = false; + switch (TREE_CODE (t)) { case POINTER_TYPE: @@ -585,17 +590,65 @@ c_pretty_printer::direct_abstract_declarator (tree t) case ARRAY_TYPE: pp_c_left_bracket (this); + + if (int quals = TYPE_QUALS (t)) + { + /* Print the array qualifiers such as in "T[const restrict 3]". */ + pp_c_cv_qualifiers (this, quals, false); + add_space = true; + } + + if (tree arr = lookup_attribute ("array", TYPE_ATTRIBUTES (t))) + { + if (TREE_VALUE (arr)) + { + /* Print the specifier as in "T[static 3]" that's not actually + part of the type but may be added by the front end. */ + pp_c_ws_string (this, "static"); + add_space = true; + } + else if (!TYPE_DOMAIN (t)) + /* For arrays of unspecified bound using the [*] notation. */ + pp_character (this, '*'); + } + if (tree dom = TYPE_DOMAIN (t)) { if (tree maxval = TYPE_MAX_VALUE (dom)) { + if (add_space) + pp_space (this); + tree type = TREE_TYPE (maxval); if (tree_fits_shwi_p (maxval)) pp_wide_integer (this, tree_to_shwi (maxval) + 1); - else + else if (TREE_CODE (maxval) == INTEGER_CST) expression (fold_build2 (PLUS_EXPR, type, maxval, build_int_cst (type, 1))); + else + { + /* Strip the expressions from around a VLA bound added + internally to make it fit the domain mold, including + any casts. */ + if (TREE_CODE (maxval) == NOP_EXPR) + maxval = TREE_OPERAND (maxval, 0); + if (TREE_CODE (maxval) == PLUS_EXPR + && integer_all_onesp (TREE_OPERAND (maxval, 1))) + { + maxval = TREE_OPERAND (maxval, 0); + if (TREE_CODE (maxval) == NOP_EXPR) + maxval = TREE_OPERAND (maxval, 0); + } + if (TREE_CODE (maxval) == SAVE_EXPR) + { + maxval = TREE_OPERAND (maxval, 0); + if (TREE_CODE (maxval) == NOP_EXPR) + maxval = TREE_OPERAND (maxval, 0); + } + + expression (maxval); + } } else if (TYPE_SIZE (t)) /* Print zero for zero-length arrays but not for flexible |