From patchwork Wed Nov 12 06:13:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Uecker X-Patchwork-Id: 409855 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 9C3B2140170 for ; Wed, 12 Nov 2014 17:13:38 +1100 (AEDT) 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:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=VSI987UU1xYKu9Ad CEhTHqh9aAtoxXC6JveDARt4jbRhxuwppVWFLt3PaZUrmM+KbENB1rFM1ojg15rt Ed4pu5wc4m1WjNeop9YwvccsbLN8ZEzm1tmgalOT2O+P8ZQ5Zv4avXyCk7aNNeSE //bQPj/XU0Q/lRQ9N4rop6a95rM= 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:mime-version:content-type :content-transfer-encoding; s=default; bh=7jH/7HOaOSZyLEV+370uQU 8OC6s=; b=jlKglIlnjr/yc9/2wLYWoyMsdQey3T7yS4o44UbUiC9JDiyJyHNcdz O9zS/BadYrL6Fc/mwqx7LrIfVOXX1rTup14DzKRrrFxDnQ4Iq5peHfC0FGnb/IOr qsuKL5iJ823ST/hLq186Cg1IPFscCSCc8J1uX5JOymhOHVy8mGPn0= Received: (qmail 3121 invoked by alias); 12 Nov 2014 06:13:31 -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 3108 invoked by uid 89); 12 Nov 2014 06:13:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f43.google.com Received: from mail-pa0-f43.google.com (HELO mail-pa0-f43.google.com) (209.85.220.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 12 Nov 2014 06:13:28 +0000 Received: by mail-pa0-f43.google.com with SMTP id eu11so12260391pac.30 for ; Tue, 11 Nov 2014 22:13:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-type:content-transfer-encoding; bh=wbiRdnB1MW6c4uyByTyqE8AknVEFKO4AoMYo87zzk7Y=; b=cFVpj+7tSBOIYILSdTwbCqudLLM2qaPenb//9LM5BQbvJzqEsdGqpWjcFIFbVQLfVp XHCxUrNXEwFm68P8YOmnhqt4+f4qxPySADNFLaRv8fhzYxUiidIrVdKhnW+nOO/Pqb2A Y0aBzphaft93r/KDqpcuOVBwX2iWimAQvXY3C/9Kbe52GCOHcSL8YEn04p6bJjjMuea4 zwqfLTzDjJY0L9MMrtGhEHTCXmqTemOb7CoDe94d82VM8upcsk7aDPniV31rzQHA3KXL 1Cc3N2xTGDrxt3aOZsYkre9YdtPqXM9/sqFvFXpH2+LX88AiJZVhXTcw2w+ATHTVtFUZ fIIw== X-Gm-Message-State: ALoCoQlFDcofzRDeoT09GsM2KR/WTv1j3QvgO59X1oufz0phk8p3JaxBwFKe1/A7zHeqfSvAWYSZ X-Received: by 10.68.213.101 with SMTP id nr5mr44446989pbc.81.1415772806021; Tue, 11 Nov 2014 22:13:26 -0800 (PST) Received: from lemur (c-24-130-240-105.hsd1.ca.comcast.net. [24.130.240.105]) by mx.google.com with ESMTPSA id ql6sm13754919pbb.39.2014.11.11.22.13.24 for (version=SSLv3 cipher=RC4-SHA bits=128/128); Tue, 11 Nov 2014 22:13:25 -0800 (PST) Date: Tue, 11 Nov 2014 22:13:20 -0800 From: Martin Uecker To: gcc Mailing List Cc: Jakub Jelinek , "Joseph S. Myers" Subject: [PATCH] add option to emit more array bounds warnigs Message-ID: <20141111221320.24113af4@lemur> MIME-Version: 1.0 Hi, this proposed patch adds an option "-Warray-bounds=" in addition to "-Warray-bound". "-Warray-bounds=1" corresponds to "-Warray-bound". For higher warning levels more warnings about optional accesses outside of arrays are emitted. For example, warnings for arrays accessed through pointers are now emitted: void foo(int (*a)[3]) { (*a)[4] = 1; } Also warnings for arrays which are the last element of a struct are emitted, if it is not a flexible array member or does not use the zero size extensions. Because there is the risk of false positives, the higher warning level is not used by default. Martin * gcc/tree-vrp.c (check_array_ref): Emit more warnings for warn_array_bounds >= 2. * gcc/testsuite/gcc.dg/Warray-bounds-11.c: New test-case. * gcc/c-family/c.opt: New option -Warray-bounds=. * gcc/common.opt: New option -Warray-bounds=. * gcc/doc/invoke.texi: Document new option. diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 66c62fb..0d5ecfd 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -279,6 +279,10 @@ Warray-bounds LangEnabledBy(C ObjC C++ ObjC++,Wall) ; in common.opt +Warray-bounds= +LangEnabledBy(C ObjC C++ ObjC++,Wall,1,0) +; in common.opt + Wassign-intercept ObjC ObjC++ Var(warn_assign_intercept) Warning Warn whenever an Objective-C assignment is being intercepted by the garbage collector diff --git a/gcc/common.opt b/gcc/common.opt index b400636..d65085a 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -525,6 +525,10 @@ Warray-bounds Common Var(warn_array_bounds) Warning Warn if an array is accessed out of bounds +Warray-bounds= +Common Joined RejectNegative UInteger Var(warn_array_bounds) Warning +Warn if an array is accessed out of bounds + Wattributes Common Var(warn_attributes) Init(1) Warning Warn about inappropriate attribute usage diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 57666db..afc4be8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -239,7 +239,7 @@ Objective-C and Objective-C++ Dialects}. @gccoptlist{-fsyntax-only -fmax-errors=@var{n} -Wpedantic @gol -pedantic-errors @gol -w -Wextra -Wall -Waddress -Waggregate-return @gol --Waggressive-loop-optimizations -Warray-bounds @gol +-Waggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol -Wbool-compare @gol -Wno-attributes -Wno-builtin-macro-redefined @gol -Wc90-c99-compat -Wc99-c11-compat @gol @@ -3344,7 +3344,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}. @option{-Wall} turns on the following warning flags: @gccoptlist{-Waddress @gol --Warray-bounds @r{(only with} @option{-O2}@r{)} @gol +-Warray-bounds=1 @r{(only with} @option{-O2}@r{)} @gol -Wc++11-compat @gol -Wchar-subscripts @gol -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol @@ -4239,12 +4239,26 @@ hiearchy graph is more complete. It is recommended to first consider suggestins of @option{-Wsuggest-final-types} and then rebuild with new annotations. @item -Warray-bounds +@itemx -Warray-bounds=@var{n} @opindex Wno-array-bounds @opindex Warray-bounds This option is only active when @option{-ftree-vrp} is active (default for @option{-O2} and above). It warns about subscripts to arrays that are always out of bounds. This warning is enabled by @option{-Wall}. +@table @gcctabopt +@item -Warray-bounds=1 +This is the warning level of @option{-Warray-bounds} and is enabled +by @option{-Wall}; higher levels are not, and must be explicitly requested. + +@item -Warray-bounds=2 +This warning level also warns about out of bounds access for +arrays at the end of a struct and for arrays accessed through +pointers. This warning level may give a larger number of +false positives and is deactivated by default. +@end table + + @item -Wbool-compare @opindex Wno-bool-compare @opindex Wbool-compare diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-11.c b/gcc/testsuite/gcc.dg/Warray-bounds-11.c new file mode 100644 index 0000000..2e68498 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-11.c @@ -0,0 +1,96 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Warray-bounds=2" } */ + +extern void* malloc(unsigned long x); + +int e[3]; + +struct f { int f[3]; }; + +extern void bar(int v[]); + +struct h { + + int i; + int j[]; +}; + +struct h0 { + + int i; + int j[0]; +}; + +struct h0b { + + int i; + int j[0]; + int k; +}; + +struct h1 { + + int i; + int j[1]; +}; + +struct h1b { + + int i; + int j[1]; + int k; +}; + +struct h3 { + + int i; + int j[3]; +}; + +struct h3b { + + int i; + int j[3]; + int k; +}; + +void foo(int (*a)[3]) +{ + (*a)[4] = 1; /* { dg-warning "subscript is above array bound" } */ + a[0][0] = 1; // ok + a[1][0] = 1; // ok + a[1][4] = 1; /* { dg-warning "subscript is above array bound" } */ + + int c[3] = { 0 }; + + c[4] = 1; /* { dg-warning "subscript is above array bound" } */ + + e[4] = 1; /* { dg-warning "subscript is above array bound" } */ + + struct f f; + f.f[4] = 1; /* { dg-warning "subscript is above array bound" } */ + + struct h* h = malloc(sizeof(struct h) + 3 * sizeof(int)); + struct h0* h0 = malloc(sizeof(struct h0) + 3 * sizeof(int)); + struct h1* h1 = malloc(sizeof(struct h1) + 3 * sizeof(int)); + struct h3* h3 = malloc(sizeof(struct h3)); + + h->j[4] = 1; // flexible array member + h0->j[4] = 1; // zero-sized array extension + h1->j[4] = 1; /* { dg-warning "subscript is above array bound" } */ + h3->j[4] = 1; /* { dg-warning "subscript is above array bound" } */ + + struct h0b* h0b = malloc(sizeof(struct h) + 3 * sizeof(int)); + struct h1b* h1b = malloc(sizeof(struct h1b) + 3 * sizeof(int)); + struct h3b* h3b = malloc(sizeof(struct h3b)); +// h0b->j[4] = 1; + h1b->j[4] = 1;; /* { dg-warning "subscript is above array bound" } */ + h3b->j[4] = 1;; /* { dg-warning "subscript is above array bound" } */ + + // make sure nothing gets optimized away + bar(*a); + bar(c); + bar(e); + bar(f.f); +} + diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 4e4ebe0..7a4bb9d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -6356,7 +6356,8 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one) /* Accesses to trailing arrays via pointers may access storage beyond the types array bounds. */ base = get_base_address (ref); - if (base && TREE_CODE (base) == MEM_REF) + if ((warn_array_bounds < 2) + && base && TREE_CODE (base) == MEM_REF) { tree cref, next = NULL_TREE;