On Thu, Feb 23, 2017 at 03:09:47PM -0700, Jeff Law wrote:
> Please  refactor the restrict warning bits into their own function, then
> calling that from check_function_arguments.  That's the style already used
> there.
> 
> OK with that change.

Here is what I've committed after another bootstrap/regtest:

2017-02-24  Jakub Jelinek  <ja...@redhat.com>

        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.

--- gcc/c-family/c-common.c.jj  2017-02-20 13:43:15.169555324 +0100
+++ gcc/c-family/c-common.c     2017-02-24 19:44:47.239427073 +0100
@@ -5364,6 +5364,49 @@ check_function_sentinel (const_tree fnty
     }
 }
 
+/* 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
 
   if (warn_format)
     check_function_sentinel (fntype, nargs, argarray);
+
+  if (warn_restrict)
+    check_function_restrict (fndecl, fntype, nargs, argarray);
   return warned_p;
 }
 
--- gcc/c-family/c-warn.c.jj    2017-02-20 13:43:15.126555893 +0100
+++ gcc/c-family/c-warn.c       2017-02-24 19:39:43.621454404 +0100
@@ -2170,55 +2170,49 @@ maybe_warn_bool_compare (location_t loc,
    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
--- gcc/c-family/c-common.h.jj  2017-02-20 13:43:15.200554914 +0100
+++ gcc/c-family/c-common.h     2017-02-24 19:39:43.622454390 +0100
@@ -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_che
 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
--- gcc/c/c-parser.c.jj 2017-02-20 13:43:15.041557018 +0100
+++ gcc/c/c-parser.c    2017-02-24 19:39:43.626454337 +0100
@@ -8418,28 +8418,6 @@ c_parser_postfix_expression_after_primar
              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
--- gcc/c/c-typeck.c.jj 2017-02-22 22:32:35.477710734 +0100
+++ gcc/c/c-typeck.c    2017-02-24 19:39:43.629454298 +0100
@@ -3110,7 +3110,8 @@ build_function_call_vec (location_t 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))
--- gcc/cp/call.c.jj    2017-02-24 15:31:49.041955772 +0100
+++ gcc/cp/call.c       2017-02-24 19:39:43.631454271 +0100
@@ -7903,14 +7903,17 @@ build_over_call (struct z_candidate *can
      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);
     }
 
--- gcc/cp/parser.c.jj  2017-02-22 23:00:21.472093702 +0100
+++ gcc/cp/parser.c     2017-02-24 19:39:43.638454178 +0100
@@ -6934,29 +6934,6 @@ cp_parser_postfix_expression (cp_parser
                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);
--- gcc/cp/typeck.c.jj  2017-02-20 13:43:21.485471769 +0100
+++ gcc/cp/typeck.c     2017-02-24 19:39:43.640454152 +0100
@@ -3667,7 +3667,7 @@ cp_build_function_call_vec (tree functio
 
   /* 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);
--- gcc/testsuite/g++.dg/warn/Wrestrict-1.C.jj  2017-02-24 19:39:43.640454152 
+0100
+++ gcc/testsuite/g++.dg/warn/Wrestrict-1.C     2017-02-24 19:39:43.640454152 
+0100
@@ -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);
+}
--- gcc/testsuite/g++.dg/warn/Wrestrict-2.C.jj  2017-02-24 19:39:43.640454152 
+0100
+++ gcc/testsuite/g++.dg/warn/Wrestrict-2.C     2017-02-24 19:39:43.640454152 
+0100
@@ -0,0 +1,30 @@
+// 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);
+}


        Jakub

Reply via email to