From patchwork Fri May 11 23:09:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 912247 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-477604-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="SvN+iJdT"; 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 40jQm8505zz9s1b for ; Sat, 12 May 2018 09:09:59 +1000 (AEST) 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=Kj9EMvpyIHjQG31/P4f1keTUV8/x7BvOT8SqxMehElyODKelms YPS4T0OwW9dxxsGcuVdzEfDXiWyIg45y6e25jbKy90z/YfjGpkN7QV2IXyQ43Diq gPTgWiFGDZCN9T1A1bQZS/YyeiWRyTBqFHDcK+kChjloqEQTTK+Rk5l5c= 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=HE4gKw3M604vdzVNwuFdY47yg6k=; b=SvN+iJdTgETz9RLCOkdz gri0UMA9jT2FTCKDrZTOlf5u37xPx9GByxneBt3mSHippyVB79W6pH3bKFhRDF4U mVo+nbemPa5FF4mzvT1tr8HSW9xSaEBFg5YuciV+6zgxC8nxvj5u0+EPU4E7hm9S KkPkw78ksGAC1vw2+rFazxk= Received: (qmail 40774 invoked by alias); 11 May 2018 23:09:52 -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 39473 invoked by uid 89); 11 May 2018 23:09:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=exceeds X-HELO: mail-oi0-f67.google.com Received: from mail-oi0-f67.google.com (HELO mail-oi0-f67.google.com) (209.85.218.67) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 May 2018 23:09:50 +0000 Received: by mail-oi0-f67.google.com with SMTP id p62-v6so6081071oie.10 for ; Fri, 11 May 2018 16:09:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version; bh=dx2TQKrNi9pd70rMa19/tG87xKob4I39V1My9SD8fh0=; b=IOCFhFPhaMRONpOMnqWoUmNhQHseu1qF4drMrvP6/Vd9rF2wziIc9Y601mT/xY60Mh g84QzfeKkkY9GpIaCzOGAR26eQVtL2sMN52PJMbjDI9YQyXEMQrmEnmRfQIX/M71m129 JHH3iN98PnDO4PYFet8aqkg+4Tjk0QZbQLpXoesBTKH4bZtMnyQLBwA9Wx/hr83mP6K/ 24fZoJ2kaIjbwXXcCH3DJJpi6uEqd+a24yY5kmQk2Rz7w/6wzYIUoHAmA+j9ZaTwIFsQ ToA2LWeRcUGnCwDDv1TVzRLD2Yh6wA8oMEZuNFY5bPnaJvtIsRPzIAO7SdM63CT9IDYQ XZmA== X-Gm-Message-State: ALKqPwepR+tV0XAiCXbJ7jfRaM91XNFxb0GoBPBJI4duxjAoPqwYI0QK 1riasd1NycBITI/shIqD+yrSBw== X-Google-Smtp-Source: AB8JxZougYMmPaf9F2Mr1SHeDtCHWxocr4ILMpU7TPAtTryRFZZu/RlOtjOBvC/vdMTDc+o++Patjw== X-Received: by 2002:aca:edd2:: with SMTP id l201-v6mr531063oih.65.1526080188023; Fri, 11 May 2018 16:09:48 -0700 (PDT) Received: from localhost.localdomain (174-16-119-16.hlrn.qwest.net. [174.16.119.16]) by smtp.gmail.com with ESMTPSA id e37-v6sm2533299otd.81.2018.05.11.16.09.46 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 May 2018 16:09:46 -0700 (PDT) To: Gcc Patch List From: Martin Sebor Subject: [PATCH] improve -Wrestrict for struct members (PR 85753) Message-ID: Date: Fri, 11 May 2018 17:09:44 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 X-IsSubscribed: yes The attached patch extends -Wrestrict to constrain valid offset ranges into objects of struct types to the bounds of the object type, the same way the warning already handles arrays. This makes it possible to detect overlapping accesses in cases like the second call to memcpy below: char a[16]; struct { char a[16]; } x; void f (int i, int j) { memcpy (&a[i], &a[j], 9); // -Wrestrict (good) memcpy (&x.a[i], &x.a[j], 9); // missing -Wrestrict } These is no way to copy 9 bytes within a 16 byte array without either overlap or without accessing memory outside the bounaries of the object. This is for GCC 9. Thanks Martin PR tree-optimization/85753 - missing -Wrestrict on memcpy into a member array gcc/ChangeLog: PR tree-optimization/85753 * gimple-ssa-warn-restrict.c (builtin_memref::builtin_memref): Handle RECORD_TYPE in addition to ARRAY_TYPE. gcc/testsuite/ChangeLog: PR tree-optimization/85753 * gcc.dg/Wrestrict-10.c: Adjust. * gcc.dg/Wrestrict-16.c: New test. diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index 3d0664d..f461b84 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -263,27 +263,33 @@ builtin_memref::builtin_memref (tree expr, tree size) else sizrange[1] = maxobjsize; + if (!DECL_P (base)) + return; + tree basetype = TREE_TYPE (base); - if (DECL_P (base) && TREE_CODE (basetype) == ARRAY_TYPE) + if (TREE_CODE (basetype) != ARRAY_TYPE + && TREE_CODE (basetype) != RECORD_TYPE) + return; + + /* If the offset could be in the range of the referenced object + constrain its bounds so neither exceeds those of the object. */ + if (offrange[0] < 0 && offrange[1] > 0) + offrange[0] = 0; + + offset_int maxoff = maxobjsize; + if (TREE_CODE (basetype) == ARRAY_TYPE + && ref + && array_at_struct_end_p (ref)) + ; /* Use the maximum possible offset for last member arrays. */ + else if (tree basesize = TYPE_SIZE_UNIT (basetype)) + maxoff = wi::to_offset (basesize); + + if (offrange[0] >= 0) { - /* If the offset could be in range of the referenced object - constrain its bounds so neither exceeds those of the object. */ - if (offrange[0] < 0 && offrange[1] > 0) - offrange[0] = 0; - - offset_int maxoff = maxobjsize; - if (ref && array_at_struct_end_p (ref)) - ; /* Use the maximum possible offset for last member arrays. */ - else if (tree basesize = TYPE_SIZE_UNIT (basetype)) - maxoff = wi::to_offset (basesize); - - if (offrange[0] >= 0) - { - if (offrange[1] < 0) - offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize; - else if (offrange[0] <= maxoff && offrange[1] > maxoff) - offrange[1] = maxoff; - } + if (offrange[1] < 0) + offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize; + else if (offrange[0] <= maxoff && offrange[1] > maxoff) + offrange[1] = maxoff; } } diff --git a/gcc/testsuite/gcc.dg/Wrestrict-10.c b/gcc/testsuite/gcc.dg/Wrestrict-10.c index a5a5ff1..c412e42 100644 --- a/gcc/testsuite/gcc.dg/Wrestrict-10.c +++ b/gcc/testsuite/gcc.dg/Wrestrict-10.c @@ -58,7 +58,7 @@ test_arr_strncat_2 (void) void __attribute__ ((noclone, noinline)) test_arr_strcpy_1 (void) { - strcpy (&b.a[i], b.a); + strcpy (&b.a[i], b.a); /* { dg-warning "\\\[-Wrestrict" } */ } void __attribute__ ((noclone, noinline)) diff --git a/gcc/testsuite/gcc.dg/Wrestrict-16.c b/gcc/testsuite/gcc.dg/Wrestrict-16.c new file mode 100644 index 0000000..136e122 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wrestrict-16.c @@ -0,0 +1,34 @@ +/* PR tree-optimization/85753 - missing -Wrestrict on memcpy into a member + array + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +#define memcpy __builtin_memcpy + +char a[16]; + +struct { char a[16]; } x; + +void test_idx_nowarn (int i, int j) +{ + memcpy (&a[i], &a[j], 7); + memcpy (&x.a[i], &x.a[j], 7); +} + +void test_idx_warn (int i, int j) +{ + memcpy (&a[i], &a[j], 9); /* { dg-warning "\\\[-Wrestrict" } */ + memcpy (&x.a[i], &x.a[j], 9); /* { dg-warning "\\\[-Wrestrict" } */ +} + +void test_off_nowarn (int i, int j) +{ + memcpy (a + i, a + j, 5); + memcpy (x.a + i, x.a + j, 5); +} + +void test_off_warn (int i, int j) +{ + memcpy (a + i, a + j, 9); /* { dg-warning "\\\[-Wrestrict" } */ + memcpy (x.a + i, x.a + j, 9); /* { dg-warning "\\\[-Wrestrict" } */ +}