OK if Joseph doesn't object in the next couple of days.

On Mon, Feb 20, 2017 at 12:35 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> As mentioned in the PR, -Wrestrict warning is done way too early, where
> e.g. default arguments aren't filled up yet (reason for ICE on first
> testcase) or where arguments in templates aren't instantiated yet (reason
> why we don't diagnose anything on the second testcase).
>
> This patch moves it later where e.g. -Wformat is diagnosed and fixes
> some issues I found while looking at the code.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2017-02-20  Jakub Jelinek  <ja...@redhat.com>
>
>         PR c++/79588
> c-family/
>         * c-common.c (check_function_arguments): Add FNDECL argument.
>         Handle -Wrestrict here.
>         * 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-01-24 23:29:05.000000000 +0100
> +++ gcc/c-family/c-common.c     2017-02-20 13:17:06.601211847 +0100
> @@ -5605,8 +5605,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 +5624,44 @@ check_function_arguments (location_t loc
>
>    if (warn_format)
>      check_function_sentinel (fntype, nargs, argarray);
> +
> +  if (warn_restrict)
> +    {
> +      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;
> +    }
>    return warned_p;
>  }
>
> --- gcc/c-family/c-warn.c.jj    2017-02-15 18:06:19.000000000 +0100
> +++ gcc/c-family/c-warn.c       2017-02-20 12:36:29.008455672 +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-01-24 23:29:05.000000000 +0100
> +++ gcc/c-family/c-common.h     2017-02-20 13:00:55.540080276 +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-16 13:01:31.000000000 +0100
> +++ gcc/c/c-parser.c    2017-02-20 12:22:55.610210942 +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-01-21 02:25:57.000000000 +0100
> +++ gcc/c/c-typeck.c    2017-02-20 13:01:36.829532979 +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-17 18:29:21.000000000 +0100
> +++ gcc/cp/call.c       2017-02-20 13:03:21.874140599 +0100
> @@ -7900,14 +7900,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-18 14:12:36.000000000 +0100
> +++ gcc/cp/parser.c     2017-02-20 12:21:32.257313679 +0100
> @@ -6933,29 +6933,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-13 20:30:33.000000000 +0100
> +++ gcc/cp/typeck.c     2017-02-20 13:04:10.994489395 +0100
> @@ -3661,7 +3661,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-18 18:07:19.535116220 
> +0100
> +++ gcc/testsuite/g++.dg/warn/Wrestrict-1.C     2017-02-18 18:05:52.000000000 
> +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-20 13:07:34.635789299 
> +0100
> +++ gcc/testsuite/g++.dg/warn/Wrestrict-2.C     2017-02-20 12:55:12.000000000 
> +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