From patchwork Mon Feb 20 20:35:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 730190 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vRwPj3swvz9s8G for ; Tue, 21 Feb 2017 07:35:52 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="crx/mzG7"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=JvwhKYTX+Dsxr8NI7YFkigxHCPn1u z8cymR5BwXh0lUgK9ZDYBrC8FRLUMz2tm2MFCt9+AWrPHksMK9TocTvpXFmftdlz CrKb5yoe0ubkcx/Q+cMuojzm1LUnsqwntTZqFynRRB/WjOj2yGmaWmi6iyynp9N5 wPIZuk+w5GGguk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=8umj9K/IIrmwA/f2wO1WW6RziHU=; b=crx /mzG7bPaQ5xK2C3UN/iwftTwu51eDj5IrApFG5BJnLABGmOxgKnjk+DVnuww7c6M Z9FPDrjrd1eYtSAHAFiSujCX1SJ9dX9nNYs5m6IkMenCerwlzVeSCVdko3t5r/n3 q3489mBK64Q/3H7XGXMTHYGq1eMNbl2wDChL6l0Q= Received: (qmail 125099 invoked by alias); 20 Feb 2017 20:35:44 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 125078 invoked by uid 89); 20 Feb 2017 20:35:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=12000000000, Places, 69336, inappropriately X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 20 Feb 2017 20:35:40 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7831781254; Mon, 20 Feb 2017 20:35:40 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-117-76.ams2.redhat.com [10.36.117.76]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1KKZcIk006145 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Feb 2017 15:35:39 -0500 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id v1KKZZ9L007996; Mon, 20 Feb 2017 21:35:36 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v1KKZYt5007995; Mon, 20 Feb 2017 21:35:34 +0100 Date: Mon, 20 Feb 2017 21:35:33 +0100 From: Jakub Jelinek To: Jason Merrill , "Joseph S. Myers" Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588) Message-ID: <20170220203533.GF1849@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) X-IsSubscribed: yes 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 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. Jakub --- 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 *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 --- 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 *); +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 +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); +}