aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-pretty-print.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-09-19 17:21:52 -0600
committerMartin Sebor <msebor@redhat.com>2020-09-19 17:34:31 -0600
commit6450f07388f9fe575a489c9309c36012b17b88b0 (patch)
tree929351afdf436f119f15a3d37da96d3a0e3ae27c /gcc/c-family/c-pretty-print.c
parent3696a50beeb73f4ded8a584e76ee16f0bde109b9 (diff)
downloadgcc-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.c61
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