From patchwork Thu Feb 7 01:13:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1037811 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-495419-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="gY+NIG7v"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="iuobKKtR"; dkim-atps=neutral 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 43w0j31d0Wz9sLw for ; Thu, 7 Feb 2019 12:14:40 +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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=RPj/lFm2JVBmRI4VjFnPJjSzSPN+7coVZk4qxL0vOpWbyBw5bL N3uzUNBMyE8F1QXbKGbCuNRx2R5zbWYhKC+X7O7J0f5gDkEMURnmgFP1cxHhlYz8 KE8otLXiJQOYoZnnKdm6zR0KfAVV5i6c1XykJENNrj0l6uTehG8yGiScM= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=HVbiRtavYrJF3RSnWusf7o1fUmA=; b=gY+NIG7vjxXuEw6eyDlJ JzQZRIvs2C8InQHegc9vUgp/YuXfrQfjYhMJ8T6tsR2ZfZ+2B/LoXI50rZkFfKU0 NxRr6aQFuy6dqGPPOwa2kvATZqtd8rRt0/XHqMv58oYmzComVv4DXmVxmON0vC9d KN7/MN9Mx88Kr5bJQhF71EM= Received: (qmail 108023 invoked by alias); 7 Feb 2019 01:14:12 -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 107935 invoked by uid 89); 7 Feb 2019 01:14:08 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=REF, *fun, exceeds, sk:Wstring X-HELO: mail-qk1-f171.google.com Received: from mail-qk1-f171.google.com (HELO mail-qk1-f171.google.com) (209.85.222.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Feb 2019 01:14:03 +0000 Received: by mail-qk1-f171.google.com with SMTP id z18so5528926qkj.10 for ; Wed, 06 Feb 2019 17:14:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=WUzYmnbxZsR9sdM30zH0SmdM2VjAWttyunO28nmCt3U=; b=iuobKKtRclvVtma9/bjVcbZGac+JiP7vQkPd+L8pdeg3bguPv4OfkE1xa1ag1Cx1Ru 1qmsjHp0sKYo6GsL+DXwLr4ImisEW3g4wU9HcLtM5dnJpTbH2kcAw/v8+EqiRw2o4Sgv 4jTFN+fz0PUW77R87Ear8Utv5yNtsvf8ZFYK1VQaaY8S7aaz1m3keM+WD0OQ9dSIkqdW KCy3WZ2FSFg/yemt1QwWQXXCHqvRdf6EPFU5uMVqqtQhKEiJYTcNhG4rzoUNS3fRKmOk RBFQL1Q4l0xE9W4ZrAtKm4N840RXeNeMVpeMJr8Wt4wUhO8BQnx3MAw8aqrqPT6h5aW/ pjfA== Received: from [192.168.0.106] (97-118-121-10.hlrn.qwest.net. [97.118.121.10]) by smtp.gmail.com with ESMTPSA id j189sm13354476qkc.77.2019.02.06.17.14.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Feb 2019 17:14:00 -0800 (PST) To: "gcc-patches@gcc.gnu.org" , Richard Biener From: Martin Sebor Subject: [PATCH] improve out-of-bounds pointer warning (PR 88771) Message-ID: <8e2d2236-7958-3def-7bb9-f8b1b30fdcb2@gmail.com> Date: Wed, 6 Feb 2019 18:13:59 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 X-IsSubscribed: yes The attached patch doesn't avoid the false positive but only improves the warning to make it more readable (as suggested in the PR by Richard for GCC 9). With the patch, for a call like: memcpy (d, s, -1); where d and s are pointers with unknown provenances the patch has GCC in LP32 issue warning: ‘memcpy’ specified bound 4294967295 exceeds maximum object size 2147483647 [-Wstringop-overflow=] instead of the somewhat mystifying ‘memcpy’ pointer overflow between offset 0 and size [4294967295, 2147483647] [-Warray-bounds] There are a few places the warning is issued from and it would make sense to consolidate them into the same utility function. Since that will require some not entirely trivial changes to the warning code I defer it until GCC 10 as well, along with a fix for the false positive. Tested on x86_64-linux. Martin PR tree-optimization/88771 - Misleading -Werror=array-bounds error gcc/ChangeLog: PR tree-optimization/88771 * gimple-ssa-warn-restrict.c (pass_wrestrict::gate): Also enable when -Wstringop-overflow is set. (builtin_memref::builtin_memref): Adjust excessive upper bound only when lower bound is not excessive. (maybe_diag_overlap): Detect and diagnose excessive bounds via -Wstringop-ovefflow. (maybe_diag_offset_bounds): Rename... (maybe_diag_access_bounds): ...to this. (check_bounds_or_overlap): Adjust for name change above. gcc/testsuite/ChangeLog: PR tree-optimization/88771 * gcc.dg/Wstringop-overflow-8.c: New test. * gcc.dg/Wstringop-overflow-9.c: New test. * gcc.dg/Warray-bounds-40.c: New test. * gcc.dg/builtin-stpncpy.c: Adjust. * gcc.dg/builtin-stringop-chk-4.c: Adjust. * g++.dg/opt/memcpy1.C: Adjust. Index: gcc/gimple-ssa-warn-restrict.c =================================================================== --- gcc/gimple-ssa-warn-restrict.c (revision 268583) +++ gcc/gimple-ssa-warn-restrict.c (working copy) @@ -75,7 +75,7 @@ class pass_wrestrict : public gimple_opt_pass bool pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED) { - return warn_array_bounds != 0 || warn_restrict != 0; + return warn_array_bounds || warn_restrict || warn_stringop_overflow; } /* Class to walk the basic blocks of a function in dominator order. */ @@ -256,7 +256,7 @@ builtin_memref::builtin_memref (tree expr, tree si sizrange[1] = wi::to_offset (range[1]); /* get_size_range returns SIZE_MAX for the maximum size. Constrain it to the real maximum of PTRDIFF_MAX. */ - if (sizrange[1] > maxobjsize) + if (sizrange[0] <= maxobjsize && sizrange[1] > maxobjsize) sizrange[1] = maxobjsize; } else @@ -1567,18 +1567,56 @@ maybe_diag_overlap (location_t loc, gimple *call, return true; } -/* Validate REF offsets in an expression passed as an argument to a CALL - to a built-in function FUNC to make sure they are within the bounds - of the referenced object if its size is known, or PTRDIFF_MAX otherwise. - Both initial values of the offsets and their final value computed by - the function by incrementing the initial value by the size are +/* Validate REF size and offsets in an expression passed as an argument + to a CALL to a built-in function FUNC to make sure they are within + the bounds of the referenced object if its size is known, or + PTRDIFF_MAX otherwise. DO_WARN is true when a diagnostic should + be issued, false otherwise. + Both initial values of the offsets and their final value computed + by the function by incrementing the initial value by the size are validated. Return true if the offsets are not valid and a diagnostic - has been issued. */ + has been issued, or would have been issued if DO_WARN had been true. */ static bool -maybe_diag_offset_bounds (location_t loc, gimple *call, tree func, int strict, +maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict, const builtin_memref &ref, bool do_warn) { + const offset_int maxobjsize = tree_to_shwi (max_object_size ()); + + /* Check for excessive size first and regardless of warning options + since the result is used to make codegen decisions. */ + if (ref.sizrange[0] > maxobjsize) + { + /* Return true without issuing a warning. */ + if (!do_warn) + return true; + + if (ref.ref && TREE_NO_WARNING (ref.ref)) + return false; + + if (warn_stringop_overflow) + { + if (EXPR_HAS_LOCATION (ref.ptr)) + loc = EXPR_LOCATION (ref.ptr); + + loc = expansion_point_location_if_in_system_header (loc); + + if (ref.sizrange[0] == ref.sizrange[1]) + return warning_at (loc, OPT_Wstringop_overflow_, + "%G%qD specified bound %wu " + "exceeds maximum object size %wu", + call, func, ref.sizrange[0].to_uhwi (), + maxobjsize.to_uhwi ()); + + return warning_at (loc, OPT_Wstringop_overflow_, + "%G%qD specified bound between %wu and %wu " + "exceeds maximum object size %wu", + call, func, ref.sizrange[0].to_uhwi (), + ref.sizrange[1].to_uhwi (), + maxobjsize.to_uhwi ()); + } + } + /* Check for out-bounds pointers regardless of warning options since the result is used to make codegen decisions. */ offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] }; @@ -1616,11 +1654,12 @@ static bool if (oobref == error_mark_node) { if (ref.sizrange[0] == ref.sizrange[1]) - sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ()); + sprintf (rangestr[1], "%llu", + (unsigned long long) ref.sizrange[0].to_shwi ()); else sprintf (rangestr[1], "[%lli, %lli]", - (long long) ref.sizrange[0].to_shwi (), - (long long) ref.sizrange[1].to_shwi ()); + (unsigned long long) ref.sizrange[0].to_uhwi (), + (unsigned long long) ref.sizrange[1].to_uhwi ()); tree type; @@ -1854,8 +1893,8 @@ check_bounds_or_overlap (gimple *call, tree dst, t /* Validate offsets first to make sure they are within the bounds of the destination object if its size is known, or PTRDIFF_MAX otherwise. */ - if (maybe_diag_offset_bounds (loc, call, func, strict, dstref, do_warn) - || maybe_diag_offset_bounds (loc, call, func, strict, srcref, do_warn)) + if (maybe_diag_access_bounds (loc, call, func, strict, dstref, do_warn) + || maybe_diag_access_bounds (loc, call, func, strict, srcref, do_warn)) { if (do_warn) gimple_set_no_warning (call, true); Index: gcc/testsuite/gcc.dg/Wstringop-overflow-8.c =================================================================== --- gcc/testsuite/gcc.dg/Wstringop-overflow-8.c (nonexistent) +++ gcc/testsuite/gcc.dg/Wstringop-overflow-8.c (working copy) @@ -0,0 +1,62 @@ +/* PR tree-optimization/79220 - missing -Wstringop-overflow= on a memcpy + overflow with a small power-of-2 size + { dg-do compile } + { dg-options "-O2 -Wno-array-bounds -Wstringop-overflow" } */ + +extern void* memcpy (void*, const void*, __SIZE_TYPE__); +extern void* memmove (void*, const void*, __SIZE_TYPE__); +extern void* memset (void*, int, __SIZE_TYPE__); + +char d[1]; + +void test_memcpy_lit_2 (void) +{ + memcpy (d, "01", 2); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memcpy_lit_4 (void) +{ + memcpy (d, "0123", 4); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memmove_lit_8 (void) +{ + memmove (d, "01234567", 8); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + + +void test_memcpy_ptr_2 (const void *s) +{ + memcpy (d, s, 2); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memcpy_ptr_4 (const void *s) +{ + memcpy (d, s, 4); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memcpy_ptr_8 (const void *s) +{ + memcpy (d, s, 8); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + + +void test_memmove_ptr (const void *s) +{ + memmove (d, s, 8); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memset_2 (void) +{ + memset (d, 0, 2); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memset_4 (void) +{ + memset (d, 0, 4); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} + +void test_memset_8 (void) +{ + memset (d, 0, 8); /* { dg-warning "\\\[-Wstringop-overflow" } */ +} Index: gcc/testsuite/gcc.dg/Wstringop-overflow-9.c =================================================================== --- gcc/testsuite/gcc.dg/Wstringop-overflow-9.c (nonexistent) +++ gcc/testsuite/gcc.dg/Wstringop-overflow-9.c (working copy) @@ -0,0 +1,72 @@ +/* PR middle-end/88771 - Misleading -Werror=array-bounds error + Verify that the warning issued for calls to "bounded" string + functions is -Wstringop-overflow with the right wording. + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +#define PTRDIFF_MAX __PTRDIFF_MAX__ +#define SIZE_MAX __SIZE_MAX__ + +typedef __SIZE_TYPE__ size_t; + +extern void* memcpy (void*, const void*, size_t); +extern void* memmove (void*, const void*, size_t); +extern void* memset (void*, int, size_t); + +extern char* stpncpy (char*, const char*, size_t); + +extern char* strncat (char*, const char*, size_t); +extern char* strncpy (char*, const char*, size_t); + +extern char* strndup (const char*, size_t); + +extern int strncmp (const char*, const char*, size_t); +extern int strncasecmp (const char*, const char*, size_t); + +extern size_t strnlen (const char*, size_t); + +extern char *d; +extern const char *s; + + +void test_memcpy (void) +{ + memcpy (d, s, SIZE_MAX); /* { dg-warning ".memcpy. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + +void test_memmove (void) +{ + memmove (d, s, SIZE_MAX - 1); /* { dg-warning ".memmove. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + +void test_memset (void) +{ + memset (d, 0, SIZE_MAX - 2); /* { dg-warning ".memset. specified \(bound|size\) \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + + +char* test_stpncpy (void) +{ + return stpncpy (d, s, SIZE_MAX - 4); /* { dg-warning ".stpncpy. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + + +void test_strncat (void) +{ + strncat (d, s, SIZE_MAX - 3); /* { dg-warning ".strncat. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + +void test_strncpy (void) +{ + strncpy (d, s, SIZE_MAX - 4); /* { dg-warning ".strncpy. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + +char* test_strndup (void) +{ + return strndup (s, SIZE_MAX - 5); /* { dg-warning ".strndup. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} + +size_t test_strnlen (void) +{ + return strnlen (s, SIZE_MAX - 6); /* { dg-warning ".strnlen. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */ +} Index: gcc/testsuite/gcc.dg/Warray-bounds-40.c =================================================================== --- gcc/testsuite/gcc.dg/Warray-bounds-40.c (nonexistent) +++ gcc/testsuite/gcc.dg/Warray-bounds-40.c (working copy) @@ -0,0 +1,73 @@ +/* PR middle-end/88771 - Misleading -Werror=array-bounds error + Verify that the warning issued for calls to "bounded" string + functions when -Wstringop-overflow is disabled is -Warray-bounds + with the right wording. + { dg-do compile } + { dg-options "-O2 -Wall -Wno-stringop-overflow" } */ + +#define PTRDIFF_MAX __PTRDIFF_MAX__ +#define SIZE_MAX __SIZE_MAX__ + +typedef __SIZE_TYPE__ size_t; + +extern void* memcpy (void*, const void*, size_t); +extern void* memmove (void*, const void*, size_t); +extern void* memset (void*, int, size_t); + +extern char* stpncpy (char*, const char*, size_t); + +extern char* strncat (char*, const char*, size_t); +extern char* strncpy (char*, const char*, size_t); + +extern char* strndup (const char*, size_t); + +extern int strncmp (const char*, const char*, size_t); +extern int strncasecmp (const char*, const char*, size_t); + +extern size_t strnlen (const char*, size_t); + +extern char *d; +extern const char *s; + + +void test_memcpy (void) +{ + memcpy (d, s, SIZE_MAX); /* { dg-warning ".memcpy. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" } */ +} + +void test_memmove (void) +{ + memmove (d, s, SIZE_MAX - 1); /* { dg-warning ".memmove. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" } */ +} + +void test_memset (void) +{ + memset (d, 0, SIZE_MAX - 2); /* { dg-warning ".memset. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" "bug" { xfail *-*-* } } */ +} + + +char* test_stpncpy (void) +{ + return stpncpy (d, s, SIZE_MAX - 4); /* { dg-warning ".stpncpy. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" } */ +} + + +void test_strncat (void) +{ + strncat (d, s, SIZE_MAX - 3); /* { dg-warning ".strncat. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" } */ +} + +void test_strncpy (void) +{ + strncpy (d, s, SIZE_MAX - 4); /* { dg-warning ".strncpy. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" } */ +} + +char* test_strndup (void) +{ + return strndup (s, SIZE_MAX - 5); /* { dg-warning ".strndup. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" "bug" { xfail *-*-* } } */ +} + +size_t test_strnlen (void) +{ + return strnlen (s, SIZE_MAX - 6); /* { dg-warning ".strnlen. pointer overflow between offset 0 and size \[0-9\]+ \\\[-Warray-bounds" "bug" { xfail *-*-* } } */ +} Index: gcc/testsuite/gcc.dg/builtin-stpncpy.c =================================================================== --- gcc/testsuite/gcc.dg/builtin-stpncpy.c (revision 268583) +++ gcc/testsuite/gcc.dg/builtin-stpncpy.c (working copy) @@ -35,7 +35,7 @@ void test_cst (char *d) __builtin_stpncpy (d, "123", n); - __builtin_stpncpy (d, "123", n + 1); /* { dg-warning "specified size \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ + __builtin_stpncpy (d, "123", n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ } @@ -73,5 +73,5 @@ void test_rng (char *d) __builtin_stpncpy (d, "123", R (n - 1, n + 1)); - __builtin_stpncpy (d, "123", R (n + 1, n + 2)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ + __builtin_stpncpy (d, "123", R (n + 1, n + 2)); /* { dg-warning "specified bound between \[0-9\]+ and \[0-9\]+ exceeds maximum object size \[0-9\]+" } */ } Index: gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c =================================================================== --- gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c (revision 268583) +++ gcc/testsuite/gcc.dg/builtin-stringop-chk-4.c (working copy) @@ -102,13 +102,13 @@ void test_memcpy_range (void *d, const void *s) memcpy (buf + size_max, s, UR (1, 2)); /* { dg-warning "writing between 1 and 2 bytes into a region of size 0 overflows the destination" "excessive pointer offset" { xfail *-*-* } } */ memcpy (buf, s, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */ - memcpy (buf, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ - memcpy (buf, s, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memcpy (buf, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memcpy (buf, s, UR (size_max - 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ /* Exercise memcpy into a destination of unknown size with excessive number of bytes. */ memcpy (d, s, UR (ssize_max, size_max)); - memcpy (d, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memcpy (d, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ memcpy (buf, s, SR (-1, 1)); memcpy (buf, s, SR (-3, 2)); @@ -124,8 +124,8 @@ void test_memcpy_range (void *d, const void *s) memcpy (d, s, SR (-9, 5)); memcpy (d, s, SR (-11, 6)); - memcpy (buf, s, SR (-2, -1)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ - memcpy (d, s, SR (-2, -1)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memcpy (buf, s, SR (-2, -1)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memcpy (d, s, SR (-2, -1)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ /* Even though the following calls are bounded by the range of N's type they must not cause a warning for obvious reasons. */ @@ -187,13 +187,13 @@ void test_mempcpy_range (void *d, const void *s) mempcpy (buf, s, UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 overflows the destination" } */ mempcpy (buf, s, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */ - mempcpy (buf, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ - mempcpy (buf, s, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + mempcpy (buf, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + mempcpy (buf, s, UR (size_max - 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ /* Exercise mempcpy into a destination of unknown size with excessive number of bytes. */ mempcpy (d, s, UR (ssize_max, size_max)); - mempcpy (d, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + mempcpy (d, s, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ } /* Test memset with a number of bytes bounded by a known range. */ @@ -213,13 +213,13 @@ void test_memset_range (void *d) memset (buf, 0, UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 overflows the destination" } */ memset (buf, 0, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */ - memset (buf, 0, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ - memset (buf, 0, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memset (buf, 0, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memset (buf, 0, UR (size_max - 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ /* Exercise memset into a destination of unknown size with excessive number of bytes. */ memset (d, 0, UR (ssize_max, size_max)); - memset (d, 0, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + memset (d, 0, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ } /* Test bzero with a number of bytes bounded by a known range. */ @@ -239,13 +239,13 @@ void test_bzero_range (void *d) bzero (buf, UR (6, 7)); /* { dg-warning "writing between 6 and 7 bytes into a region of size 5 overflows the destination" } */ bzero (buf, UR (ssize_max, size_max)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 overflows the destination" } */ - bzero (buf, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ - bzero (buf, UR (size_max - 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + bzero (buf, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + bzero (buf, UR (size_max - 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ /* Exercise bzero into a destination of unknown size with excessive number of bytes. */ bzero (d, UR (ssize_max, size_max)); - bzero (d, UR (ssize_max + 1, size_max)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + bzero (d, UR (ssize_max + 1, size_max)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ } /* Test strcat with an argument referencing a non-constant string of @@ -343,15 +343,15 @@ void test_strncat_range (void) strncat (buf + 5, S (0), 0); - strncat (buf + 5, S (0), 1); /* { dg-warning "specified bound 1 exceeds destination size 0" } */ - strncat (buf + 5, S (1), 1); /* { dg-warning "specified bound 1 exceeds destination size 0" } */ + strncat (buf + 5, S (0), 1); /* { dg-warning "specified \(bound|size\) 1 exceeds destination size 0" } */ + strncat (buf + 5, S (1), 1); /* { dg-warning "specified \(bound|size\) 1 exceeds destination size 0" } */ /* Strncat always appends a terminating null after copying the N characters so the following triggers a warning pointing out that specifying sizeof(buf) as the upper bound may cause the nul to overflow the destination. */ - strncat (buf, S (0), 5); /* { dg-warning "specified bound 5 equals destination size" } */ - strncat (buf, S (0), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */ + strncat (buf, S (0), 5); /* { dg-warning "specified \(bound|size\) 5 equals destination size" } */ + strncat (buf, S (0), 6); /* { dg-warning "specified \(bound|size\) 6 exceeds destination size 5" } */ strncat (buf, S (1), 0); strncat (buf, S (1), 1); @@ -358,16 +358,16 @@ void test_strncat_range (void) strncat (buf, S (1), 2); strncat (buf, S (1), 3); strncat (buf, S (1), 4); - strncat (buf, S (1), 5); /* { dg-warning "specified bound 5 equals destination size" } */ - strncat (buf, S (1), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */ - strncat (buf, S (2), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */ + strncat (buf, S (1), 5); /* { dg-warning "specified \(bound|size\) 5 equals destination size" } */ + strncat (buf, S (1), 6); /* { dg-warning "specified \(bound|size\) 6 exceeds destination size 5" } */ + strncat (buf, S (2), 6); /* { dg-warning "specified \(bound|size\) 6 exceeds destination size 5" } */ /* The following could just as well say "writing 6 bytes into a region of size 5. Either would be correct and probably equally as clear in this case. But when the length of the source string is not known at all then the bound warning seems clearer. */ - strncat (buf, S (5), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */ - strncat (buf, S (7), 6); /* { dg-warning "specified bound 6 exceeds destination size 5" } */ + strncat (buf, S (5), 6); /* { dg-warning "specified \(bound|size\) 6 exceeds destination size 5" } */ + strncat (buf, S (7), 6); /* { dg-warning "specified \(bound|size\) 6 exceeds destination size 5" } */ { /* The implementation of the warning isn't smart enough to determine @@ -392,17 +392,17 @@ void test_strncat_chk_range (char *d) strncat_chk (buf, S (0), 2); strncat_chk (buf, S (0), 3); strncat_chk (buf, S (0), 4); - strncat_chk (buf, S (0), 5); /* { dg-warning "specified bound 5 equals destination size" } */ + strncat_chk (buf, S (0), 5); /* { dg-warning "specified \(bound|size\) 5 equals destination size" } */ strncat_chk (buf, S (5), 1); strncat_chk (buf, S (5), 2); strncat_chk (buf, S (5), 3); strncat_chk (buf, S (5), 4); - strncat_chk (buf, S (5), 5); /* { dg-warning "specified bound 5 equals destination size" } */ + strncat_chk (buf, S (5), 5); /* { dg-warning "specified \(bound|size\) 5 equals destination size" } */ - strncat_chk (buf, S (5), 10); /* { dg-warning "specified bound \[0-9\]+ exceeds destination size 5" } */ + strncat_chk (buf, S (5), 10); /* { dg-warning "specified \(bound|size\) \[0-9\]+ exceeds destination size 5" } */ - strncat_chk (d, S (5), size_max); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size " } */ + strncat_chk (d, S (5), size_max); /* { dg-warning "specified \(bound|size\) \[0-9\]+ exceeds maximum object size " } */ } /* Test strncpy with a non-constant source string of length in a known @@ -426,15 +426,15 @@ void test_strncpy_string_range (char *d) strncpy (buf, S (1), ssize_max - 1); /* { dg-warning "writing \[0-9\]+ bytes into a region of size 5" } */ strncpy (buf, S (2), ssize_max); /* { dg-warning "writing \[0-9\]+ bytes into a region of size 5" } */ - strncpy (buf, S (3), ssize_max + 1); /* { dg-warning "specified size \[0-9\]+ exceeds maximum object size" } */ - strncpy (buf, S (4), size_max); /* { dg-warning "specified size \[0-9\]+ exceeds maximum object size" } */ + strncpy (buf, S (3), ssize_max + 1); /* { dg-warning "specified \(bound|size\) \[0-9\]+ exceeds maximum object size" } */ + strncpy (buf, S (4), size_max); /* { dg-warning "specified \(bound|size\) \[0-9\]+ exceeds maximum object size" } */ /* Exercise strncpy into a destination of unknown size with a valid and invalid constant number of bytes. */ strncpy (d, S (1), ssize_max - 1); strncpy (d, S (2), ssize_max); - strncpy (d, S (3), ssize_max + 1); /* { dg-warning "specified size \[0-9\]+ exceeds maximum object size" } */ - strncpy (d, S (4), size_max); /* { dg-warning "specified size \[0-9\]+ exceeds maximum object size" } */ + strncpy (d, S (3), ssize_max + 1); /* { dg-warning "specified \(bound|size\) \[0-9\]+ exceeds maximum object size" } */ + strncpy (d, S (4), size_max); /* { dg-warning "specified \(bound|size\) \[0-9\]+ exceeds maximum object size" } */ } /* Test strncpy with a non-constant source string of length in a known @@ -472,7 +472,7 @@ void test_strncpy_string_count_range (char *dst, c strncpy (buf, S (1), UR (7, 8)); /* { dg-warning "writing between 7 and 8 bytes into a region of size 5 " } */ strncpy (buf, S (2), UR (ssize_max, ssize_max + 1)); /* { dg-warning "writing \[0-9\]+ or more bytes into a region of size 5 " } */ - strncpy (buf, S (2), UR (ssize_max + 1, ssize_max + 2)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + strncpy (buf, S (2), UR (ssize_max + 1, ssize_max + 2)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ strncpy (buf + 5, S (0), UR (0, 1)); strncpy (buf + 5, S (1), UR (0, 1)); @@ -500,5 +500,5 @@ void test_strncpy_string_count_range (char *dst, c strncpy (dst, S (3), UR (ssize_max, ssize_max + 1)); - strncpy (dst, S (4), UR (ssize_max + 1, ssize_max + 2)); /* { dg-warning "specified size between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ + strncpy (dst, S (4), UR (ssize_max + 1, ssize_max + 2)); /* { dg-warning "specified \(bound|size\) between \[0-9\]+ and \[0-9\]+ exceeds maximum object size" } */ } Index: gcc/testsuite/g++.dg/opt/memcpy1.C =================================================================== --- gcc/testsuite/g++.dg/opt/memcpy1.C (revision 268583) +++ gcc/testsuite/g++.dg/opt/memcpy1.C (working copy) @@ -62,7 +62,7 @@ namespace CS // OutV is initialized to SIZE_MAX in the ctor above causing // the multiplication below to produce a very large number // in excess of the maximum possible object size (SIZE_MAX/2). - __builtin_memcpy (this->OutP, InP, OutV * sizeof (csVector2)); // { dg-warning "specified size \[0-9\]+ exceeds maximum object size" } + __builtin_memcpy (this->OutP, InP, OutV * sizeof (csVector2)); // { dg-warning "exceeds maximum object size" } return 0; } };