+2017-02-24 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <ebotcazou@adacore.com>
* c-ada-spec.c (dump_ada_function_declaration): Add comment about the
}
}
+/* 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. */
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;
if (warn_format)
check_function_sentinel (fntype, nargs, argarray);
+
+ if (warn_restrict)
+ check_function_restrict (fndecl, fntype, nargs, argarray);
return warned_p;
}
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),
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<tree, va_gc> *);
+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
restrict-qualified param, and it aliases with another argument. */
void
-warn_for_restrict (unsigned param_pos, vec<tree, va_gc> *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<int, 16> 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
+2017-02-24 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <rguenther@suse.de>
PR c/79684
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
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))
+2017-02-24 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <polacek@redhat.com>
PR translation/79705
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);
}
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);
/* 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);
+2017-02-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/79588
+ * g++.dg/warn/Wrestrict-1.C: New test.
+ * g++.dg/warn/Wrestrict-2.C: New test.
+
2017-02-24 David Edelsohn <dje.gcc@gmail.com>
* g++.dg/ext/complit15.C: Require LTO.
--- /dev/null
+// 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);
+}
--- /dev/null
+// PR c++/79588
+// { dg-do compile }
+// { dg-options "-Wrestrict" }
+
+void foo (char *__restrict, char *__restrict = __null);
+
+template <int N>
+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 <int N>
+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);
+}