From patchwork Thu Apr 20 20:35:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 753000 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 3w89cY1CQSz9s7k for ; Fri, 21 Apr 2017 06:35:55 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="cgV65ovb"; 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:from :to:subject:date:message-id:content-type:mime-version; q=dns; s= default; b=xgenRu3Bq91eN0l0+i3DwTmVsGr5IJjwrIHKmhWnLpB85BxJAvlNv pnj83VdvADh3c7ifqyCjeg7sXbwOvizM0oM4jWd2VO5C5l5olr/FimrguikcuGgr nj/+hqPTp/qpi7GAi1tjGoJsZEFr52ZAnC+9UUtMk+4iupit7j2fHs= 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:from :to:subject:date:message-id:content-type:mime-version; s= default; bh=VhWCNl4693yH0vjQtqAPdotHtjc=; b=cgV65ovbOXu5MGSyEK7n /6Tp3rdcVqOriEka86JofPTTV5WKkrEPfsZq6PCWwEQisoybk69Pj+OANdIH+2rA O6F/A6XLBrJjruFxh91wSJ5Kf/v82lFxc0VKRZpN35sIeaLtpL/NeYUyrNgGfzDM e5XYLHqFl8sX0okiPbPVtIE= Received: (qmail 127177 invoked by alias); 20 Apr 2017 20:35:34 -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 127155 invoked by uid 89); 20 Apr 2017 20:35:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_MANYTO, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=uf, revealed, 6067, 726 X-HELO: EUR02-VE1-obe.outbound.protection.outlook.com Received: from mail-oln040092069076.outbound.protection.outlook.com (HELO EUR02-VE1-obe.outbound.protection.outlook.com) (40.92.69.76) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Apr 2017 20:35:28 +0000 Received: from AM5EUR02FT008.eop-EUR02.prod.protection.outlook.com (10.152.8.58) by AM5EUR02HT025.eop-EUR02.prod.protection.outlook.com (10.152.9.199) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.1019.14; Thu, 20 Apr 2017 20:35:27 +0000 Received: from AM4PR0701MB2162.eurprd07.prod.outlook.com (10.152.8.57) by AM5EUR02FT008.mail.protection.outlook.com (10.152.8.69) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1019.14 via Frontend Transport; Thu, 20 Apr 2017 20:35:27 +0000 Received: from AM4PR0701MB2162.eurprd07.prod.outlook.com ([fe80::a806:64f0:6377:f3ea]) by AM4PR0701MB2162.eurprd07.prod.outlook.com ([fe80::a806:64f0:6377:f3ea%19]) with mapi id 15.01.1047.008; Thu, 20 Apr 2017 20:35:27 +0000 From: Bernd Edlinger To: "gcc-patches@gcc.gnu.org" , Joseph Myers , Jason Merrill , Jeff Law , Richard Biener , Jakub Jelinek Subject: [PATCH] Implement a warning for bogus sizeof(pointer) / sizeof(pointer[0]) Date: Thu, 20 Apr 2017 20:35:26 +0000 Message-ID: authentication-results: gcc.gnu.org; dkim=none (message not signed) header.d=none; gcc.gnu.org; dmarc=none action=none header.from=hotmail.de; x-incomingtopheadermarker: OriginalChecksum:AE375B6CF73D7899E5DF6AF3DD987BF997F744EAE540C1C0A21B93FCB061194B; UpperCasedChecksum:E98A9E5CD42DC59A77C0B7AD4488F9A9EFA3765C192171728E5F4E0EACB84088; SizeAsReceived:8060; Count:37 x-ms-exchange-messagesentrepresentingtype: 1 x-microsoft-exchange-diagnostics: 1; AM5EUR02HT025; 5:SIZkLwf5BwpuGL5MPZh4LEOXD0nx4UHgKMRsbvMCb+0wqlu+KaEziA6R54BMYT74d0qxQStUfWCG6Q638Hv9Vm02LQckK//s/dUJqbtlMyflL7EgNxnNa0gDEPgAn6czfoErv4jhnioTYvWIcJzI7g==; 24:sxUa/jBoClYeLIn40puXOuYwADmLxSXpPoNXOyq9u/4jY9Lg03vq9Vf2SBn8R7Xcq6i7H723YNll5C0/0ePeKj6ZjF6iPEXf1AVaYVD6UGs=; 7:w2pdAZgPBcD3k0R6jKxpyHU0EF3Yv+JxLHif6m/h1A6PplTohwIryTPniTHzN37IV6Jqrw3kmgleA556IYjeuuN9gna3L9f3shYXGfN6Mf6lLWaBMXThoRBuY2WA9HbFxGdMGgUgVYFg/yO9T3Mje3nxZXARiPS2Bx2zrBzux1UyNN1rwPGCP0DPsxD5xhlFMsWi+5pVUQlhMWrsHzmGhchmr3muuPY3wPKNhs4cJ4dkrLIzh+hC5bs3/6f34UvP0PKa8X2QBlfEWHFopfIZBsk3gtr7VFW1szxsNddp2wNwo+pDtmQuujTKwR6+fuzU x-incomingheadercount: 37 x-eopattributedmessage: 0 x-forefront-antispam-report: EFV:NLI; SFV:NSPM; SFS:(7070007)(98901004); DIR:OUT; SFP:1901; SCL:1; SRVR:AM5EUR02HT025; H:AM4PR0701MB2162.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; x-ms-office365-filtering-correlation-id: 027637dc-89a3-4a03-3f71-08d4882cc68e x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201702061074)(5061506573)(5061507331)(1603103135)(2017031320274)(2017031324274)(2017031323274)(2017031322274)(1601125374)(1603101448)(1701031045); SRVR:AM5EUR02HT025; x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(444000031); SRVR:AM5EUR02HT025; BCL:0; PCL:0; RULEID:; SRVR:AM5EUR02HT025; x-forefront-prvs: 02830F0362 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-originalarrivaltime: 20 Apr 2017 20:35:26.9732 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5EUR02HT025 Hi! This implements a new -Wall enabled warning for a rather common, but completely wrong way to compute an array size by dividing the sizeof(pointer) / sizeof(pointer[0]) or sizeof(*pointer). It is often hard to find this kind of error by simple code inspection in real code, because using sizeof in this way is a quite common idiom to get the array size of an array variable. And furthermore this expression may be used in macros, which makes it even more important to have this warning. There is a similar warning -Wsizeof-pointer-memaccess which helped in implementing the infrastructure for the new warning in the C FE. However I noticed that the -Wsizeof-pointer-memaccess warning was missing in C, when the sizeof is used inside parentheses, which is different from C++, so I fixed that too. Of course, I added some test cases for that as well. To illustrate the usefulness of this warning, it revealed quite a few places where bogus sizeof divisions were used in our testsuite. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd. gcc: 2017-04-20 Bernd Edlinger * doc/invoke.texi: Document the -Wsizeof-pointer-div warning. gcc/c-family: 2017-04-20 Bernd Edlinger * c.opt (Wsizeof-pointer-div): New warning option. gcc/c: 2017-04-20 Bernd Edlinger * c-parser.c (c_parser_binary_expression): Implement the -Wsizeof_pointer_div warning. (c_parser_postfix_expression): Allow SIZEOF_EXPR as expr.original_code from a parenthesized expression. (c_parser_expr_list): Use c_last_sizeof_loc. * c-tree.h (c_last_sizeof_loc): New external. * c-typeck.c (c_last_sizeof_loc): New variable. (c_expr_sizeof_expr, c_expr_sizeof_type): Assign c_last_sizeof_loc. gcc/cp: 2017-04-20 Bernd Edlinger * cp-gimplify.c (cp_fold): Implement the -Wsizeof_pointer_div warning. gcc/testsuite: 2017-04-20 Bernd Edlinger * c-c++-common/Wsizeof-pointer-div.c: New test. * gcc.dg/Wsizeof-pointer-memaccess1.c: Add test cases with parens. * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Likewise. * gcc.target/i386/sse-init-v4hi-1.c: Fix test case. * gcc.target/i386/sse-init-v4sf-1.c: Likewise. * gcc.target/i386/sse-set-ps-1.c: Likewise. * gcc.target/i386/sse2-init-v16qi-1.c: Likewise. * gcc.target/i386/sse2-init-v2di-1.c: Likewise. * gcc.target/i386/sse2-init-v4si-1.c: Likewise. * gcc.target/i386/sse2-init-v8hi-1.c: Likewise. * gcc.target/i386/sse2-set-epi32-1.c: Likewise. * gcc.target/i386/sse2-set-epi64x-1.c: Likewise. * gcc.target/i386/sse4_1-init-v16qi-1.c: Likewise. * gcc.target/i386/sse4_1-init-v2di-1.c: Likewise. * gcc.target/i386/sse4_1-init-v4sf-1.c: Likewise. * gcc.target/i386/sse4_1-init-v4si-1.c: Likewise. * gcc.target/i386/sse4_1-set-epi32-1.c: Likewise. * gcc.target/i386/sse4_1-set-epi64x-1.c: Likewise. * gcc.target/i386/sse4_1-set-ps-1.c: Likewise. * libgomp.c/pr39591-2.c: Likewise. * libgomp.c/pr39591-3.c: Likewise. Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 246482) +++ gcc/c/c-parser.c (working copy) @@ -6652,6 +6652,8 @@ c_parser_binary_expression (c_parser *parser, stru enum tree_code op; /* The source location of this operation. */ location_t loc; + /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */ + tree sizeof_arg; } stack[NUM_PRECS]; int sp; /* Location of the binary operator. */ @@ -6668,6 +6670,22 @@ c_parser_binary_expression (c_parser *parser, stru c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \ == truthvalue_true_node); \ break; \ + case TRUNC_DIV_EXPR: \ + if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \ + && stack[sp].expr.original_code == SIZEOF_EXPR) \ + { \ + tree type0 = stack[sp - 1].sizeof_arg; \ + tree type1 = stack[sp].sizeof_arg; \ + if (!TYPE_P (type0)) \ + type0 = TREE_TYPE (type0); \ + if (!TYPE_P (type1)) \ + type1 = TREE_TYPE (type1); \ + if (POINTER_TYPE_P (type0) \ + && comptypes (TREE_TYPE (type0), type1)) \ + warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \ + "dividing the pointer size by the element size"); \ + } \ + break; \ default: \ break; \ } \ @@ -6701,6 +6719,7 @@ c_parser_binary_expression (c_parser *parser, stru stack[0].loc = c_parser_peek_token (parser)->location; stack[0].expr = c_parser_cast_expression (parser, after); stack[0].prec = PREC_NONE; + stack[0].sizeof_arg = c_last_sizeof_arg; sp = 0; while (true) { @@ -6824,6 +6843,7 @@ c_parser_binary_expression (c_parser *parser, stru stack[sp].expr = c_parser_cast_expression (parser, NULL); stack[sp].prec = oprec; stack[sp].op = ocode; + stack[sp].sizeof_arg = c_last_sizeof_arg; } out: while (sp > 0) @@ -7715,7 +7735,8 @@ c_parser_postfix_expression (c_parser *parser) expr = c_parser_expression (parser); if (TREE_CODE (expr.value) == MODIFY_EXPR) TREE_NO_WARNING (expr.value) = 1; - if (expr.original_code != C_MAYBE_CONST_EXPR) + if (expr.original_code != C_MAYBE_CONST_EXPR + && expr.original_code != SIZEOF_EXPR) expr.original_code = ERROR_MARK; /* Don't change EXPR.ORIGINAL_TYPE. */ location_t loc_close_paren = c_parser_peek_token (parser)->location; @@ -8674,7 +8695,6 @@ c_parser_expr_list (c_parser *parser, bool convert vec *orig_types; struct c_expr expr; location_t loc = c_parser_peek_token (parser)->location; - location_t cur_sizeof_arg_loc = UNKNOWN_LOCATION; unsigned int idx = 0; ret = make_tree_vector (); @@ -8683,9 +8703,6 @@ c_parser_expr_list (c_parser *parser, bool convert else orig_types = make_tree_vector (); - if (sizeof_arg != NULL - && c_parser_next_token_is_keyword (parser, RID_SIZEOF)) - cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location; if (literal_zero_mask) c_parser_check_literal_zero (parser, literal_zero_mask, 0); expr = c_parser_expr_no_commas (parser, NULL); @@ -8699,21 +8716,15 @@ c_parser_expr_list (c_parser *parser, bool convert if (locations) locations->safe_push (loc); if (sizeof_arg != NULL - && cur_sizeof_arg_loc != UNKNOWN_LOCATION && expr.original_code == SIZEOF_EXPR) { sizeof_arg[0] = c_last_sizeof_arg; - sizeof_arg_loc[0] = cur_sizeof_arg_loc; + sizeof_arg_loc[0] = c_last_sizeof_loc; } while (c_parser_next_token_is (parser, CPP_COMMA)) { c_parser_consume_token (parser); loc = c_parser_peek_token (parser)->location; - if (sizeof_arg != NULL - && c_parser_next_token_is_keyword (parser, RID_SIZEOF)) - cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location; - else - cur_sizeof_arg_loc = UNKNOWN_LOCATION; if (literal_zero_mask) c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1); expr = c_parser_expr_no_commas (parser, NULL); @@ -8728,11 +8739,10 @@ c_parser_expr_list (c_parser *parser, bool convert locations->safe_push (loc); if (++idx < 3 && sizeof_arg != NULL - && cur_sizeof_arg_loc != UNKNOWN_LOCATION && expr.original_code == SIZEOF_EXPR) { sizeof_arg[idx] = c_last_sizeof_arg; - sizeof_arg_loc[idx] = cur_sizeof_arg_loc; + sizeof_arg_loc[idx] = c_last_sizeof_loc; } } if (orig_types) Index: gcc/c/c-tree.h =================================================================== --- gcc/c/c-tree.h (revision 246482) +++ gcc/c/c-tree.h (working copy) @@ -606,6 +606,7 @@ extern int in_sizeof; extern int in_typeof; extern tree c_last_sizeof_arg; +extern location_t c_last_sizeof_loc; extern struct c_switch *c_switch_stack; Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 246482) +++ gcc/c/c-typeck.c (working copy) @@ -72,6 +72,7 @@ int in_typeof; /* The argument of last parsed sizeof expression, only to be tested if expr.original_code == SIZEOF_EXPR. */ tree c_last_sizeof_arg; +location_t c_last_sizeof_loc; /* Nonzero if we might need to print a "missing braces around initializer" message within this initializer. */ @@ -2909,6 +2910,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr &expr_const_operands); ret.value = c_sizeof (loc, TREE_TYPE (folded_expr)); c_last_sizeof_arg = expr.value; + c_last_sizeof_loc = loc; ret.original_code = SIZEOF_EXPR; ret.original_type = NULL; if (c_vla_type_p (TREE_TYPE (folded_expr))) @@ -2938,6 +2940,7 @@ c_expr_sizeof_type (location_t loc, struct c_type_ type = groktypename (t, &type_expr, &type_expr_const); ret.value = c_sizeof (loc, type); c_last_sizeof_arg = type; + c_last_sizeof_loc = loc; ret.original_code = SIZEOF_EXPR; ret.original_type = NULL; if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST) Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 246482) +++ gcc/c-family/c.opt (working copy) @@ -698,6 +698,10 @@ Wsized-deallocation C++ ObjC++ Var(warn_sized_deallocation) Warning EnabledBy(Wextra) Warn about missing sized deallocation functions. +Wsizeof-pointer-div +C ObjC C++ ObjC++ Var(warn_sizeof_pointer_div) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) +Warn about suspicious divisions of two sizeof expressions that don't work correctly with pointers. + Wsizeof-pointer-memaccess C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn about suspicious length parameters to certain string functions if the argument uses sizeof. Index: gcc/cp/cp-gimplify.c =================================================================== --- gcc/cp/cp-gimplify.c (revision 246482) +++ gcc/cp/cp-gimplify.c (working copy) @@ -2223,6 +2223,22 @@ cp_fold (tree x) else x = fold (x); + if (TREE_CODE (x) == INTEGER_CST && + TREE_CODE (org_x) == TRUNC_DIV_EXPR + && TREE_CODE (TREE_OPERAND (org_x, 0)) == SIZEOF_EXPR + && TREE_CODE (TREE_OPERAND (org_x, 1)) == SIZEOF_EXPR) + { + tree type0 = TREE_OPERAND (TREE_OPERAND (org_x, 0), 0); + tree type1 = TREE_OPERAND (TREE_OPERAND (org_x, 1), 0); + if (!TYPE_P (type0)) + type0 = TREE_TYPE (type0); + if (!TYPE_P (type1)) + type1 = TREE_TYPE (type1); + if (POINTER_TYPE_P (type0) && same_type_p (TREE_TYPE (type0), type1)) + warning_at (loc, OPT_Wsizeof_pointer_div, + "dividing the pointer size by the element size"); + } + if (TREE_NO_WARNING (org_x) && warn_nonnull_compare && COMPARISON_CLASS_P (org_x)) Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 246482) +++ gcc/doc/invoke.texi (working copy) @@ -304,7 +304,7 @@ Objective-C and Objective-C++ Dialects}. -Wshift-overflow -Wshift-overflow=@var{n} @gol -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol -Wsign-compare -Wsign-conversion -Wfloat-conversion @gol --Wno-scalar-storage-order @gol +-Wno-scalar-storage-order -Wsizeof-pointer-div @gol -Wsizeof-pointer-memaccess -Wsizeof-array-argument @gol -Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol @@ -3777,6 +3777,7 @@ Options} and @ref{Objective-C and Objective-C++ Di -Wreturn-type @gol -Wsequence-point @gol -Wsign-compare @r{(only in C++)} @gol +-Wsizeof-pointer-div @gol -Wsizeof-pointer-memaccess @gol -Wstrict-aliasing @gol -Wstrict-overflow=1 @gol @@ -6022,6 +6023,15 @@ void operator delete[] (void *, std::size_t) noexc or vice versa. Enabled by @option{-Wextra} along with @option{-fsized-deallocation}. +@item -Wsizeof-pointer-div +@opindex Wsizeof-pointer-div +@opindex Wno-sizeof-pointer-div +Warn for suspicious divisions of two sizeof expressions that divide +the pointer size by the element size, which is the usual way to compute +the array size but won't work out correctly with pointers. This warning +warns e.g.@: about @code{sizeof (ptr) / sizeof (ptr[0])} if @code{ptr} is +not an array, but a pointer. This warning is enabled by @option{-Wall}. + @item -Wsizeof-pointer-memaccess @opindex Wsizeof-pointer-memaccess @opindex Wno-sizeof-pointer-memaccess Index: gcc/testsuite/c-c++-common/Wsizeof-pointer-div.c =================================================================== --- gcc/testsuite/c-c++-common/Wsizeof-pointer-div.c (revision 0) +++ gcc/testsuite/c-c++-common/Wsizeof-pointer-div.c (working copy) @@ -0,0 +1,36 @@ +/* Test -Wsizeof-pointer-div warnings. */ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +int +f1 (int *array) +{ + int i; + i = sizeof array / sizeof *array; /* { dg-warning "dividing the pointer size by the element size" } */ + i += sizeof array / sizeof array[0]; /* { dg-warning "dividing the pointer size by the element size" } */ + i += sizeof(array) / sizeof(*array); /* { dg-warning "dividing the pointer size by the element size" } */ + i += sizeof(array) / sizeof(array[0]); /* { dg-warning "dividing the pointer size by the element size" } */ + i += (sizeof(array)) / (sizeof(array[0])); /* { dg-warning "dividing the pointer size by the element size" } */ + i += sizeof(array) / sizeof(int); /* { dg-warning "dividing the pointer size by the element size" } */ + i += sizeof(array) / sizeof(char); + i += sizeof(*array) / sizeof(char); + i += sizeof(array[0]) / sizeof(char); + return i; +} + +int +f2 (void) +{ + int array[10]; + int i; + i = sizeof array / sizeof *array; + i += sizeof array / sizeof array[0]; + i += sizeof(array) / sizeof(*array); + i += sizeof(array) / sizeof(array[0]); + i += (sizeof(array)) / (sizeof(array[0])); + i += sizeof(array) / sizeof(int); + i += sizeof(array) / sizeof(char); + i += sizeof(*array) / sizeof(char); + i += sizeof(array[0]) / sizeof(char); + return i; +} Index: gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c =================================================================== --- gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c (revision 246482) +++ gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c (working copy) @@ -73,6 +73,15 @@ f1 (void *x, int z) z += bcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ z += bcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, (&a), (sizeof (&a))); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += bcmp (x, (pa1), (sizeof (pa1))); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, (pa2), (sizeof pa2)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, (pa3), (sizeof (pa3))); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, (pa4), (sizeof pa4)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, (pa1), (sizeof (struct A *)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, (pa2), (sizeof (PTA))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, (pa3), (sizeof (PA))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + /* These are correct, no warning. */ bzero (&a, sizeof a); bzero (&a, sizeof (a)); Index: gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c =================================================================== --- gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c (revision 246482) +++ gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c (working copy) @@ -150,6 +150,15 @@ f1 (void *x, int z) z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, (&a), (sizeof (&a))); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += memcmp (x, (pa1), (sizeof (pa1))); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, (pa2), (sizeof pa2)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, (pa3), (sizeof (pa3))); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, (pa4), (sizeof pa4)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, (pa1), (sizeof (struct A *)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, (pa2), (sizeof (PTA))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, (pa3), (sizeof (PA))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + /* These are correct, no warning. */ memset (&a, 0, sizeof a); memset (&a, 0, sizeof (a)); Index: gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c (working copy) @@ -17,13 +17,13 @@ check (__m64 x, unsigned short *v, int j) union { __m64 x; - unsigned short i[8]; + unsigned short i[4]; } u; unsigned int i; u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128 x, float *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.f[i]) Index: gcc/testsuite/gcc.target/i386/sse-set-ps-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse-set-ps-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse-set-ps-1.c (working copy) @@ -23,7 +23,7 @@ test (float *v) u.x = _mm_set_ps (v[3], v[2], v[1], v[0]); - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (v[i] != u.f[i]) { #ifdef DEBUG Index: gcc/testsuite/gcc.target/i386/sse2-init-v16qi-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse2-init-v16qi-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse2-init-v16qi-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned char *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse2-init-v2di-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse2-init-v2di-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse2-init-v2di-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned long long *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse2-init-v4si-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse2-init-v4si-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse2-init-v4si-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned int *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse2-init-v8hi-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse2-init-v8hi-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse2-init-v8hi-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned short *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse2-set-epi32-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse2-set-epi32-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse2-set-epi32-1.c (working copy) @@ -23,7 +23,7 @@ test (unsigned int *v) u.x = _mm_set_epi32 (v[3], v[2], v[1], v[0]); - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (v[i] != u.i[i]) { #ifdef DEBUG Index: gcc/testsuite/gcc.target/i386/sse2-set-epi64x-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse2-set-epi64x-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse2-set-epi64x-1.c (working copy) @@ -23,7 +23,7 @@ test (unsigned long long *v) u.x = _mm_set_epi64x (v[1], v[0]); - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (v[i] != u.i[i]) { #ifdef DEBUG Index: gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned char *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned long long *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128 x, float *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.f[i]) Index: gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-1.c (working copy) @@ -23,7 +23,7 @@ check (__m128i x, unsigned int *v, int j) u.x = x; - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (i == j) { if (v[i] != u.i[i]) Index: gcc/testsuite/gcc.target/i386/sse4_1-set-epi32-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-set-epi32-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-set-epi32-1.c (working copy) @@ -23,7 +23,7 @@ test (unsigned int *v) u.x = _mm_set_epi32 (v[3], v[2], v[1], v[0]); - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (v[i] != u.i[i]) { #ifdef DEBUG Index: gcc/testsuite/gcc.target/i386/sse4_1-set-epi64x-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-set-epi64x-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-set-epi64x-1.c (working copy) @@ -23,7 +23,7 @@ test (unsigned long long *v) u.x = _mm_set_epi64x (v[1], v[0]); - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (v[i] != u.i[i]) { #ifdef DEBUG Index: gcc/testsuite/gcc.target/i386/sse4_1-set-ps-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/sse4_1-set-ps-1.c (revision 246482) +++ gcc/testsuite/gcc.target/i386/sse4_1-set-ps-1.c (working copy) @@ -23,7 +23,7 @@ test (float *v) u.x = _mm_set_ps (v[3], v[2], v[1], v[0]); - for (i = 0; i < sizeof (v) / sizeof (v[0]); i++) + for (i = 0; i < sizeof (u) / sizeof (v[0]); i++) if (v[i] != u.f[i]) { #ifdef DEBUG Index: libgomp/testsuite/libgomp.c/pr39591-2.c =================================================================== --- libgomp/testsuite/libgomp.c/pr39591-2.c (revision 246482) +++ libgomp/testsuite/libgomp.c/pr39591-2.c (working copy) @@ -11,7 +11,7 @@ foo (int *array) #pragma omp task { int j; - for (j = 0; j < sizeof array / sizeof array[0]; j++) + for (j = 0; j < 40; j++) if (array[j] != 0x55555555) #pragma omp atomic err++; Index: libgomp/testsuite/libgomp.c/pr39591-3.c =================================================================== --- libgomp/testsuite/libgomp.c/pr39591-3.c (revision 246482) +++ libgomp/testsuite/libgomp.c/pr39591-3.c (working copy) @@ -11,7 +11,7 @@ foo (int *array) #pragma omp task { int j; - for (j = 0; j < sizeof array / sizeof array[0]; j++) + for (j = 0; j < 40; j++) if (array[j] != 0x55555555) #pragma omp atomic err++;