From patchwork Mon Aug 29 21:53:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 74927 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp1834570qga; Mon, 29 Aug 2016 14:53:53 -0700 (PDT) X-Received: by 10.66.191.234 with SMTP id hb10mr301631pac.149.1472507633368; Mon, 29 Aug 2016 14:53:53 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 9si41169585pfr.240.2016.08.29.14.53.52 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Aug 2016 14:53:53 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-434884-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-434884-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-434884-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; q=dns; s=default; b=QJ89jx9ABHlsRuY seTLp+LNWByv5svwJYDg2YVKrA4c3KsnGbtqbPM4jV0EFiZxfxyp0b66W2we4bdM vBy5aSmB6PovuwtyTPnm4qRJxOstiLwb1DAUvewSOk+RIzzxIc6h5sivwkxn4AiO FjG2CZtNOfF9hqe81kimvWj3c360= 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; s=default; bh=7kLe401ME6JGBrdm08Ldy 0EveUQ=; b=g63Mxgpebxa+0P73BTsbNd0xJmr0e5kztCV/waLExYIH1JF+nKI4M a3g2ZCsXk7px9xeE0VtjUhHEwKacOwScjDB6OLb9L0U2UIbsXUQld5VZyzcoPlRO 30wXccW5aJf5JeE3wAXRplNeuJr9jwes/OgKTeztR3FYLF2c8uTPxQ= Received: (qmail 65069 invoked by alias); 29 Aug 2016 21:53:29 -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 64987 invoked by uid 89); 29 Aug 2016 21:53:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=UD:length, sk:Wshift, sk:wshift, sk:wshift- X-HELO: mail-it0-f47.google.com Received: from mail-it0-f47.google.com (HELO mail-it0-f47.google.com) (209.85.214.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 29 Aug 2016 21:53:18 +0000 Received: by mail-it0-f47.google.com with SMTP id g62so7808925ith.1 for ; Mon, 29 Aug 2016 14:53:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=yiMpLIJN1rx9bW4H8bhJpIY860EEroom9XDvkvHMPG4=; b=B+IxTsrP1FFEs10Jz3k+IaY2IuvU/fhP2sDpreZTIsi38jCyqLkcBTQofRLih4RrtT 63/8rtQFgoZZCciZ+lbCgOB6xG367J4I+Q7+Fuka5iT1ypNC3zuLUy5v2Xyy1a2w1giy MvMpWhmLhnolCc+36JxY4IpGAt9To5ZJshUfu5d4uYAVdY4+O1Q8hENCMh5fF+NgMaej Qmkchl5vi1xD2hW9o2iIYDCAMq5fFzK0pCL3AZqPZNTcRHnsVxBNCs5PsVvdeLHZY4hy IAh2ByPj5j6DC2cN/frAti1CkFPy/qlxVlgD3Y5z9nqCOvHCrrLEdKmCetuB6QrOp73P 9/2A== X-Gm-Message-State: AE9vXwPLRTIEVsN1X1ubFpCXTTXqx75RN3KwYawFoFR2JIkOgUUtBJKE9YU2BJ5qNXRFaKLHUIiefZvN8qo1wkxK X-Received: by 10.36.13.203 with SMTP id 194mr18051727itx.79.1472507595877; Mon, 29 Aug 2016 14:53:15 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.65.232 with HTTP; Mon, 29 Aug 2016 14:53:15 -0700 (PDT) In-Reply-To: <20160829142925.GE11131@redhat.com> References: <20160829142525.GB9825@physik.fu-berlin.de> <20160829142925.GE11131@redhat.com> From: Prathamesh Kulkarni Date: Tue, 30 Aug 2016 03:23:15 +0530 Message-ID: Subject: Re: PR35503 - warn for restrict pointer To: Marek Polacek Cc: Tobias Burnus , gcc Patches , Jason Merrill , "Joseph S. Myers" , David Malcolm X-IsSubscribed: yes On 29 August 2016 at 19:59, Marek Polacek wrote: > On Mon, Aug 29, 2016 at 04:25:25PM +0200, Tobias Burnus wrote: >> Prathamesh Kulkarni wrote: >> > Attachment: pr35503-3.txt >> >> I tried the patch - and it found a bug in our code; nice! >> >> >> (a) Regarding the [-Werror] output: >> >> error: passing argument 24 to restrict qualified parameter aliases with argument 29 [-Werror] >> >> Shouldn't that output "[-Werror=restrict]" instead of a bare "[-Werror]? Namely, instead of >> >> + warning_at (loc, 0, >> + "passing argument %u to restrict qualified parameter aliases with " >> + "argument %u", param_pos + 1, i + 1); >> >> I think one gets this with >> warning_at (loc, OPT_Wrestrict, ... > > Yes, this needs to be fixed in the patch. Hi, Thanks for all the suggestions, I have tried to incorporate them in the attached version. To avoid duplicating the warnings for multiple aliased arguments, I am using TREE_VISITED to mark all the aliased arguments of the current arg, which makes diagnostic emitted only once per same set of aliases. Is using TREE_VISITED ok as in the patch ? eg: void f(int *__restrict x, int *y, int *__restrict z, int *w); void foo(int a, int b) { f (&a, &b, &a, &a); } Output: test-2.c: In function ‘foo’: test-2.c:5:6: warning: passing argument 1 to restrict-qualified parameter aliases with arguments 3, 4 [-Wrestrict] f (&a, &b, &a, &a); ^~ Using EXPR_LOCATION (arg), helps underline the argument for both C and C++ as in the example above. However in case of variadic functions, it appears C++FE doesn't set EXPR_LOCATION, so I am falling back to using input_location if EXPR_LOCATION is unknown. However it gives the location correctly for non-variadic functions. For setting locations correctly I will try the approach suggested by Jason in https://gcc.gnu.org/ml/gcc-patches/2016-08/msg01987.html I was wondering how to underline all the aliased arguments ? I would like to see the output for above eg as: test-2.c: In function ‘foo’: test-2.c:5:6: warning: passing argument 1 to restrict-qualified parameter aliases with arguments 3, 4 [-Wrestrict] f (&a, &b, &a, &a); ^~ ~~ ~~ I would be grateful for suggestions for the same. Bootstrap+test in progress on x86_64-unknown-linux-gnu. Thanks, Prathamesh > > Marek diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 3feb910..abb92b3 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -13057,4 +13057,76 @@ diagnose_mismatched_attributes (tree olddecl, tree newdecl) return warned; } +/* Warn if an argument at position param_pos is passed to a + restrict-qualified param, and it aliases with another argument. */ + +void +warn_for_restrict (unsigned param_pos, vec *args) +{ + tree arg = (*args)[param_pos]; + if (TREE_VISITED (arg)) + return; + + location_t loc = (EXPR_LOCATION (arg) != UNKNOWN_LOCATION) + ? EXPR_LOCATION (arg) + : input_location; + + if (operand_equal_p (arg, null_pointer_node, 0)) + return; + + unsigned i; + tree current_arg; + auto_vec arg_positions; + + FOR_EACH_VEC_ELT (*args, i, current_arg) + { + if (i == param_pos) + continue; + + tree current_arg = (*args)[i]; + if (operand_equal_p (arg, current_arg, 0)) + { + TREE_VISITED (current_arg) = 1; + arg_positions.safe_push (i); + } + } + + if (arg_positions.is_empty ()) + return; + + struct obstack fmt_obstack; + gcc_obstack_init (&fmt_obstack); + char *fmt = (char *) obstack_alloc (&fmt_obstack, 0); + + char num[32]; + sprintf (num, "%u", param_pos + 1); + + obstack_grow (&fmt_obstack, "passing argument ", + strlen ("passing argument ")); + obstack_grow (&fmt_obstack, num, strlen (num)); + obstack_grow (&fmt_obstack, + " to restrict-qualified parameter aliases with argument", + strlen (" to restrict-qualified parameter " + "aliases with argument")); + + /* make argument plural and append space. */ + if (arg_positions.length () > 1) + obstack_1grow (&fmt_obstack, 's'); + obstack_1grow (&fmt_obstack, ' '); + + unsigned pos; + FOR_EACH_VEC_ELT (arg_positions, i, pos) + { + sprintf (num, "%u", pos + 1); + obstack_grow (&fmt_obstack, num, strlen (num)); + + if (i < arg_positions.length () - 1) + obstack_grow (&fmt_obstack, ", ", strlen (", ")); + } + + obstack_1grow (&fmt_obstack, 0); + warning_at (loc, OPT_Wrestrict, fmt); + obstack_free (&fmt_obstack, fmt); +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index bc22baa..cdb762e 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -920,6 +920,7 @@ extern void c_parse_final_cleanups (void); extern void warn_for_omitted_condop (location_t, tree); extern void warn_for_memset (location_t, tree, tree, int); +extern void warn_for_restrict (unsigned, vec *); /* These macros provide convenient access to the various _STMT nodes. */ diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index a5358ed..a029a86 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1012,6 +1012,11 @@ Wduplicate-decl-specifier C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall) Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier. +Wrestrict +C C++ Var(warn_restrict) Warning LangEnabledBy(C C++,Wall) +Warn when an argument passed to a restrict-qualified parameter aliases with +another argument. + ansi C ObjC C++ ObjC++ A synonym for -std=c89 (for C) or -std=c++98 (for C++). diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index fe0c95f..7eaca04 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -8369,6 +8369,24 @@ 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_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)) + warn_for_restrict (param_pos, exprlist); + param_pos++; + } + } + start = expr.get_start (); finish = parser->tokens_buf[0].get_finish (); expr.value diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 690e928..5d0182f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6878,6 +6878,25 @@ 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_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)) + warn_for_restrict (param_pos, args); + } + } + if (TREE_CODE (postfix_expression) == COMPONENT_REF) { tree instance = TREE_OPERAND (postfix_expression, 0); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1f04501..3bd9612 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -288,7 +288,7 @@ Objective-C and Objective-C++ Dialects}. -Wparentheses -Wno-pedantic-ms-format @gol -Wplacement-new -Wplacement-new=@var{n} @gol -Wpointer-arith -Wno-pointer-to-int-cast @gol --Wno-pragmas -Wredundant-decls -Wno-return-local-addr @gol +-Wno-pragmas -Wredundant-decls -Wrestrict -Wno-return-local-addr @gol -Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol -Wshift-overflow -Wshift-overflow=@var{n} @gol -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol @@ -5274,6 +5274,12 @@ compilations. Warn when deleting a pointer to incomplete type, which may cause undefined behavior at runtime. This warning is enabled by default. +@item -Wrestrict @r{(C and C++ only)} +@opindex Wrestrict +@opindex Wno-restrict +Warn when an argument passed to a restrict-qualified parameter +aliases with another argument + @item -Wuseless-cast @r{(C++ and Objective-C++ only)} @opindex Wuseless-cast @opindex Wno-useless-cast diff --git a/gcc/testsuite/c-c++-common/pr35503-1.c b/gcc/testsuite/c-c++-common/pr35503-1.c new file mode 100644 index 0000000..b47fdda --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr35503-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-Wrestrict" } */ + +int foo (const char *__restrict buf, const char *__restrict fmt, ...); + +void f(void) +{ + char buf[100] = "hello"; + foo (buf, "%s-%s", buf, "world"); /* { dg-warning "passing argument 1 to restrict-qualified parameter aliases with argument 3" } */ +} diff --git a/gcc/testsuite/c-c++-common/pr35503-2.c b/gcc/testsuite/c-c++-common/pr35503-2.c new file mode 100644 index 0000000..c7828b8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr35503-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Wrestrict" } */ + +void f(int *__restrict x, int *__restrict y); + +void foo(int a) +{ + f (&a, &a); /* { dg-warning "passing argument 1 to restrict-qualified parameter aliases with argument 2" } */ +} diff --git a/gcc/testsuite/c-c++-common/pr35503-3.c b/gcc/testsuite/c-c++-common/pr35503-3.c new file mode 100644 index 0000000..8cbacab --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr35503-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Wrestrict" } */ + +void f(int *x, int *__restrict y); + +void foo(int a) +{ + f (&a, &a); /* { dg-warning "passing argument 2 to restrict-qualified parameter aliases with argument 1" } */ +}