re PR c++/79588 (ICE in warn_for_restrict with -Wrestrict)
authorJakub Jelinek <jakub@redhat.com>
Fri, 24 Feb 2017 20:41:54 +0000 (21:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 24 Feb 2017 20:41:54 +0000 (21:41 +0100)
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

14 files changed:
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/c-warn.c
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/parser.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wrestrict-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wrestrict-2.C [new file with mode: 0644]

index c234c892e724bafb7167fa3da2687843691a869a..b2f2d08202c88d4bc3d1bd9b0aa1834c8953bc36 100644 (file)
@@ -1,3 +1,14 @@
+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
index 62b762bd388b9548acd642e73622213f4e0de265..fed7718507aef2d4f34c90c7c1c5e6d92a13ffcc 100644 (file)
@@ -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;
 }
 
index 9c288096cb4a37a9b7e5de5988e8d7e16ec0da9e..ac86712ceaf38a48a892b9aee30b5d4be0cb8f5b 100644 (file)
@@ -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<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
index 09c5760284932f324fea27e251784ff99b8a5747..cdfa10c792d13d5ae0d91933590bcb65cca2de7c 100644 (file)
@@ -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<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
index 70cfdc2098051c94bf5ac057189f37e24498d1ad..699def022f07497b53402aef0605a54a7442fa69 100644 (file)
@@ -1,3 +1,11 @@
+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
index 968c1dc7696946a0760f0ca10a2c5586d291f8cf..34585b912e6ccf5951f31fef52bbe1d74895e8b0 100644 (file)
@@ -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
index 8c2c561eb72e48d65d9fec653e32cd26770d55bd..b4f61b0a674e8f6f98abe96ec91c8aec3c752d46 100644 (file)
@@ -3110,7 +3110,8 @@ build_function_call_vec (location_t loc, vec<location_t> 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))
index 7bf24cd41a97ced39ca433b9605a40838eaeba16..990f066c854b4baf80f573fc82a8d77a9a99428c 100644 (file)
@@ -1,3 +1,13 @@
+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
index f7924f0f4cd078b54bc60e77d4e08abdae22a6d8..7ff98726c72cb3dae8e8fcf1be9c66d41c21decc 100644 (file)
@@ -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);
     }
 
index ffc0e88742a4fa94131def1573989db5ce2e10dc..65feca3ee994ad9bb9ed0307a405cef5a1b49512 100644 (file)
@@ -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);
index 9297a99add60763600bcb0c137acf28184858700..3216bc41edf47b5173990a4a5596d37038554d7a 100644 (file)
@@ -3667,7 +3667,7 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **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);
index 6f6719365fdc6025dd9c5c7aceadf3fbc5be65d7..0ecaa9610225ba96c1ecabeebe20a2c4f745765d 100644 (file)
@@ -1,3 +1,9 @@
+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.
diff --git a/gcc/testsuite/g++.dg/warn/Wrestrict-1.C b/gcc/testsuite/g++.dg/warn/Wrestrict-1.C
new file mode 100644 (file)
index 0000000..fe844f1
--- /dev/null
@@ -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 (file)
index 0000000..4bab03b
--- /dev/null
@@ -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);
+}