From: Jakub Jelinek Date: Fri, 24 Feb 2017 20:41:54 +0000 (+0100) Subject: re PR c++/79588 (ICE in warn_for_restrict with -Wrestrict) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4227c9adf01d5ada5eb7c868aa104167c2a01983;p=gcc.git re PR c++/79588 (ICE in warn_for_restrict with -Wrestrict) PR c++/79588 c-family/ * c-common.c (check_function_restrict): New function. (check_function_arguments): Add FNDECL argument. Call check_function_restrict if -Wrestrict. * c-warn.c (warn_for_restrict): Remove ARGS argument, add ARGARRAY and NARGS. Use auto_vec for ARG_POSITIONS, simplify. * c-common.h (check_function_arguments): Add FNDECL argument. (warn_for_restrict): Remove ARGS argument, add ARGARRAY and NARGS. c/ * c-parser.c (c_parser_postfix_expression_after_primary): Don't handle -Wrestrict here. * c-typeck.c (build_function_call_vec): Adjust check_function_arguments caller. cp/ * call.c (build_over_call): Call check_function_arguments even for -Wrestrict, adjust check_function_arguments caller. * parser.c (cp_parser_postfix_expression): Don't handle -Wrestrict here. * typeck.c (cp_build_function_call_vec): Adjust check_function_arguments caller. testsuite/ * g++.dg/warn/Wrestrict-1.C: New test. * g++.dg/warn/Wrestrict-2.C: New test. From-SVN: r245719 --- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c234c892e72..b2f2d08202c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,14 @@ +2017-02-24 Jakub Jelinek + + PR c++/79588 + * c-common.c (check_function_restrict): New function. + (check_function_arguments): Add FNDECL argument. Call + check_function_restrict if -Wrestrict. + * c-warn.c (warn_for_restrict): Remove ARGS argument, add ARGARRAY + and NARGS. Use auto_vec for ARG_POSITIONS, simplify. + * c-common.h (check_function_arguments): Add FNDECL argument. + (warn_for_restrict): Remove ARGS argument, add ARGARRAY and NARGS. + 2017-02-24 Eric Botcazou * c-ada-spec.c (dump_ada_function_declaration): Add comment about the diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 62b762bd388..fed7718507a 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -5364,6 +5364,49 @@ check_function_sentinel (const_tree fntype, int nargs, tree *argarray) } } +/* Check that the same argument isn't passed to restrict arguments + and other arguments. */ + +static void +check_function_restrict (const_tree fndecl, const_tree fntype, + int nargs, tree *argarray) +{ + int i; + tree parms; + + if (fndecl + && TREE_CODE (fndecl) == FUNCTION_DECL + && DECL_ARGUMENTS (fndecl)) + parms = DECL_ARGUMENTS (fndecl); + else + parms = TYPE_ARG_TYPES (fntype); + + for (i = 0; i < nargs; i++) + TREE_VISITED (argarray[i]) = 0; + + for (i = 0; i < nargs && parms && parms != void_list_node; i++) + { + tree type; + if (TREE_CODE (parms) == PARM_DECL) + { + type = TREE_TYPE (parms); + parms = DECL_CHAIN (parms); + } + else + { + type = TREE_VALUE (parms); + parms = TREE_CHAIN (parms); + } + if (POINTER_TYPE_P (type) + && TYPE_RESTRICT (type) + && !TYPE_READONLY (TREE_TYPE (type))) + warn_for_restrict (i, argarray, nargs); + } + + for (i = 0; i < nargs; i++) + TREE_VISITED (argarray[i]) = 0; +} + /* Helper for check_function_nonnull; given a list of operands which must be non-null in ARGS, determine if operand PARAM_NUM should be checked. */ @@ -5605,8 +5648,8 @@ attribute_fallthrough_p (tree attr) There are NARGS arguments in the array ARGARRAY. LOC should be used for diagnostics. Return true if -Wnonnull warning has been diagnosed. */ bool -check_function_arguments (location_t loc, const_tree fntype, int nargs, - tree *argarray) +check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, + int nargs, tree *argarray) { bool warned_p = false; @@ -5624,6 +5667,9 @@ check_function_arguments (location_t loc, const_tree fntype, int nargs, if (warn_format) check_function_sentinel (fntype, nargs, argarray); + + if (warn_restrict) + check_function_restrict (fndecl, fntype, nargs, argarray); return warned_p; } diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 9c288096cb4..ac86712ceaf 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -807,7 +807,8 @@ extern const char *fname_as_string (int); extern tree fname_decl (location_t, unsigned, tree); extern int check_user_alignment (const_tree, bool); -extern bool check_function_arguments (location_t loc, const_tree, int, tree *); +extern bool check_function_arguments (location_t loc, const_tree, const_tree, + int, tree *); extern void check_function_arguments_recurse (void (*) (void *, tree, unsigned HOST_WIDE_INT), @@ -1501,7 +1502,7 @@ extern void warnings_for_convert_and_check (location_t, tree, tree, tree); extern void c_do_switch_warnings (splay_tree, location_t, tree, tree, bool, bool); extern void warn_for_omitted_condop (location_t, tree); -extern void warn_for_restrict (unsigned, vec *); +extern void warn_for_restrict (unsigned, tree *, unsigned); /* Places where an lvalue, or modifiable lvalue, may be required. Used to select diagnostic messages in lvalue_error and diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 09c57602849..cdfa10c792d 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -2170,55 +2170,49 @@ maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0, restrict-qualified param, and it aliases with another argument. */ void -warn_for_restrict (unsigned param_pos, vec *args) +warn_for_restrict (unsigned param_pos, tree *argarray, unsigned nargs) { - tree arg = (*args)[param_pos]; - if (TREE_VISITED (arg) || operand_equal_p (arg, null_pointer_node, 0)) + tree arg = argarray[param_pos]; + if (TREE_VISITED (arg) || integer_zerop (arg)) return; location_t loc = EXPR_LOC_OR_LOC (arg, input_location); gcc_rich_location richloc (loc); unsigned i; - tree current_arg; - int *arg_positions = XNEWVEC (int, args->length ()); - unsigned arg_positions_len = 0; + auto_vec arg_positions; - FOR_EACH_VEC_ELT (*args, i, current_arg) + for (i = 0; i < nargs; i++) { if (i == param_pos) continue; - tree current_arg = (*args)[i]; + tree current_arg = argarray[i]; if (operand_equal_p (arg, current_arg, 0)) { TREE_VISITED (current_arg) = 1; - arg_positions[arg_positions_len++] = (i + 1); + arg_positions.safe_push (i + 1); } } - if (arg_positions_len == 0) - { - free (arg_positions); - return; - } + if (arg_positions.is_empty ()) + return; - for (unsigned i = 0; i < arg_positions_len; i++) + int pos; + FOR_EACH_VEC_ELT (arg_positions, i, pos) { - unsigned pos = arg_positions[i]; - tree arg = (*args)[pos - 1]; + arg = argarray[pos - 1]; if (EXPR_HAS_LOCATION (arg)) richloc.add_range (EXPR_LOCATION (arg), false); } - warning_at_rich_loc_n (&richloc, OPT_Wrestrict, arg_positions_len, + warning_at_rich_loc_n (&richloc, OPT_Wrestrict, arg_positions.length (), "passing argument %i to restrict-qualified parameter" " aliases with argument %Z", "passing argument %i to restrict-qualified parameter" " aliases with arguments %Z", - param_pos + 1, arg_positions, arg_positions_len); - - free (arg_positions); + param_pos + 1, arg_positions.address (), + arg_positions.length ()); } /* Callback function to determine whether an expression TP or one of its diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 70cfdc20980..699def022f0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,11 @@ +2017-02-24 Jakub Jelinek + + PR c++/79588 + * c-parser.c (c_parser_postfix_expression_after_primary): Don't + handle -Wrestrict here. + * c-typeck.c (build_function_call_vec): Adjust + check_function_arguments caller. + 2017-02-23 Richard Biener PR c/79684 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 968c1dc7696..34585b912e6 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -8418,28 +8418,6 @@ c_parser_postfix_expression_after_primary (c_parser *parser, warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask); } - if (TREE_CODE (expr.value) == FUNCTION_DECL && warn_restrict) - { - unsigned i; - tree arg; - FOR_EACH_VEC_SAFE_ELT (exprlist, i, arg) - TREE_VISITED (arg) = 0; - - unsigned param_pos = 0; - function_args_iterator iter; - tree t; - FOREACH_FUNCTION_ARGS (TREE_TYPE (expr.value), t, iter) - { - if (POINTER_TYPE_P (t) && TYPE_RESTRICT (t) - && !TYPE_READONLY (TREE_TYPE (t))) - warn_for_restrict (param_pos, exprlist); - param_pos++; - } - - FOR_EACH_VEC_SAFE_ELT (exprlist, i, arg) - TREE_VISITED (arg) = 0; - } - start = expr.get_start (); finish = parser->tokens_buf[0].get_finish (); expr.value diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 8c2c561eb72..b4f61b0a674 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3110,7 +3110,8 @@ build_function_call_vec (location_t loc, vec arg_loc, return error_mark_node; /* Check that the arguments to the function are valid. */ - bool warned_p = check_function_arguments (loc, fntype, nargs, argarray); + bool warned_p = check_function_arguments (loc, fundecl, fntype, + nargs, argarray); if (name != NULL_TREE && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10)) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7bf24cd41a9..990f066c854 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2017-02-24 Jakub Jelinek + + PR c++/79588 + * call.c (build_over_call): Call check_function_arguments even for + -Wrestrict, adjust check_function_arguments caller. + * parser.c (cp_parser_postfix_expression): Don't handle -Wrestrict + here. + * typeck.c (cp_build_function_call_vec): Adjust + check_function_arguments caller. + 2017-02-24 Marek Polacek PR translation/79705 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f7924f0f4cd..7ff98726c72 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7903,14 +7903,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) the check_function_arguments function might warn about something. */ bool warned_p = false; - if (warn_nonnull || warn_format || warn_suggest_attribute_format) + if (warn_nonnull + || warn_format + || warn_suggest_attribute_format + || warn_restrict) { tree *fargs = (!nargs ? argarray : (tree *) alloca (nargs * sizeof (tree))); for (j = 0; j < nargs; j++) fargs[j] = maybe_constant_value (argarray[j]); - warned_p = check_function_arguments (input_location, TREE_TYPE (fn), + warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn), nargs, fargs); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ffc0e88742a..65feca3ee99 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6934,29 +6934,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, warn_for_memset (input_location, arg0, arg2, literal_mask); } - if (TREE_CODE (postfix_expression) == FUNCTION_DECL - && warn_restrict) - { - unsigned i; - tree arg; - FOR_EACH_VEC_SAFE_ELT (args, i, arg) - TREE_VISITED (arg) = 0; - - unsigned param_pos = 0; - for (tree decl = DECL_ARGUMENTS (postfix_expression); - decl != NULL_TREE; - decl = DECL_CHAIN (decl), param_pos++) - { - tree type = TREE_TYPE (decl); - if (POINTER_TYPE_P (type) && TYPE_RESTRICT (type) - && !TYPE_READONLY (TREE_TYPE (type))) - warn_for_restrict (param_pos, args); - } - - FOR_EACH_VEC_SAFE_ELT (args, i, arg) - TREE_VISITED (arg) = 0; - } - if (TREE_CODE (postfix_expression) == COMPONENT_REF) { tree instance = TREE_OPERAND (postfix_expression, 0); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9297a99add6..3216bc41edf 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3667,7 +3667,7 @@ cp_build_function_call_vec (tree function, vec **params, /* Check for errors in format strings and inappropriately null parameters. */ - bool warned_p = check_function_arguments (input_location, fntype, + bool warned_p = check_function_arguments (input_location, fndecl, fntype, nargs, argarray); ret = build_cxx_call (function, nargs, argarray, complain); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6f6719365fd..0ecaa961022 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-02-24 Jakub Jelinek + + PR c++/79588 + * g++.dg/warn/Wrestrict-1.C: New test. + * g++.dg/warn/Wrestrict-2.C: New test. + 2017-02-24 David Edelsohn * g++.dg/ext/complit15.C: Require LTO. diff --git a/gcc/testsuite/g++.dg/warn/Wrestrict-1.C b/gcc/testsuite/g++.dg/warn/Wrestrict-1.C new file mode 100644 index 00000000000..fe844f18c43 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wrestrict-1.C @@ -0,0 +1,12 @@ +// PR c++/79588 +// { dg-do compile } +// { dg-options "-Wrestrict" } + +void foo (char *__restrict, char *__restrict = __null); + +void +bar (char *p) +{ + foo (p, p); // { dg-warning "to restrict-qualified parameter aliases with" } + foo (p); +} diff --git a/gcc/testsuite/g++.dg/warn/Wrestrict-2.C b/gcc/testsuite/g++.dg/warn/Wrestrict-2.C new file mode 100644 index 00000000000..4bab03bc850 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wrestrict-2.C @@ -0,0 +1,30 @@ +// PR c++/79588 +// { dg-do compile } +// { dg-options "-Wrestrict" } + +void foo (char *__restrict, char *__restrict = __null); + +template +void +bar (char **p) +{ + foo (p[0], p[0]); // { dg-warning "to restrict-qualified parameter aliases with" } + foo (p[0], p[N]); // { dg-warning "to restrict-qualified parameter aliases with" } + foo (p[0]); +} + +template +void +bar2 (char **p) +{ + foo (p[0], p[0]); // { dg-warning "to restrict-qualified parameter aliases with" } + foo (p[0], p[N]); // { dg-bogus "to restrict-qualified parameter aliases with" } + foo (p[0]); +} + +void +baz (char **p) +{ + bar<0> (p); + bar2<1> (p); +}