From patchwork Thu Nov 25 02:16:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 48117 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 035863857C66 for ; Thu, 25 Nov 2021 02:16:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 035863857C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637806599; bh=1unpC8pMxirxPx9MqIDrzIX5S/Mrf789YYvlEJf34zY=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=jeVDKnJP22QNgTFTevrafkJLx2boRuky4F15Wlv5BbZwCwdO+mSztXPWfUKMqTLzI +AdC4b9WUKHsD7VqFfmdxPcrFlipvUMnV82gvdQw06XVwIaTiFhHlJvIvFmq9Hd+uY jD3K/pxf+h7bIf3Y/PVfbl1y6jNgmtkn5LnHmV2w= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by sourceware.org (Postfix) with ESMTPS id 407B13858403 for ; Thu, 25 Nov 2021 02:16:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 407B13858403 Received: by mail-qv1-xf2f.google.com with SMTP id bu11so3194191qvb.0 for ; Wed, 24 Nov 2021 18:16:09 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=1unpC8pMxirxPx9MqIDrzIX5S/Mrf789YYvlEJf34zY=; b=PwtXFedhfeelyHqdE1awQPLhRpr3nozMBT2N1EQYeyGnwvn0kCY8k8I7LD7rBmDw43 ec0m8q9Dqwko8LZLJTPMfES2LykoB2GGu15VWG3YB5gxz0Vicd2gd/AliWFVvNdrrQbb /7gDFR38Ujotul/8CZ3KKTful07sJSSuzXrQk+5mzidqEBkUIeoMNj8FkyMhffLgemKv nCDE75MULrebfDS422ynG2eiXkGqpkZYZYzcFNJr7JFeQSE841tvd6Vt0HHzXe8ZS5nc FWW8zt9bEHAZLHluVWJMLdFqMMPcKGN5Vdh0RiBbRnkTOWyEh+2B9uUyujeB8uO3OC5T UAiA== X-Gm-Message-State: AOAM531fIO7TG7Tyfk2KU0ZOEdtTDcVVr7dWgPv339eeoKFhhLrAqYRW yqEc8FD4pi0V5VOhxwwAYfVEsj0Rk94= X-Google-Smtp-Source: ABdhPJxwJdMcmyI0ivPf8AlZMrU4pW6Mj3OTlz7seIFlCmxBtSdDbloys2eUV8kYlWSdMadRG3QoCw== X-Received: by 2002:a05:6214:194e:: with SMTP id q14mr13815663qvk.0.1637806568601; Wed, 24 Nov 2021 18:16:08 -0800 (PST) Received: from [192.168.0.41] (97-118-114-9.hlrn.qwest.net. [97.118.114.9]) by smtp.gmail.com with ESMTPSA id 22sm797543qtw.12.2021.11.24.18.16.07 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 24 Nov 2021 18:16:07 -0800 (PST) Subject: [PATCH] Avoid expecting nonzero size for access none void* arguments [PR101751] To: gcc-patches Message-ID: <93d80da9-c2fa-9324-bf19-53b606984b3a@gmail.com> Date: Wed, 24 Nov 2021 19:16:06 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Martin Sebor via Gcc-patches From: Martin Sebor Reply-To: Martin Sebor Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" When the optional size-index argument to attribute index is omitted for a pointer, GCC expects the actual pointer argument to point to an object at least as big as its size implies, or at least one byte for void*. This is done to make it possible to detect past-the-end accesses in calls to functions that only take a pointer (and not a size). This logic has proved to be overly restrictive for the "none" access mode applied to void* pointer arguments as a signal that a function doesn't access the object. The use case that brought this to light is a function that only stores its pointer argument somewhere for later use, without ever dereferencing it, like pthread_setspecific() does. pthread_setspecific() needs to use attribute access because it takes a const void* argument, and GCC assumes that functions with const-qualified pointer arguments read from the memory they point to (as most do) and issues -Wuninitialized when it detects the object such a pointer points to is not initialized. The attached tweak adjusts the logic to exempt void* arguments with access none from the usual bounds checking by setting the expected object size to zero. This lets Glibc to continue to annotate pthread_setspecific() with attribute access none in its headers to avoid the -Wuninitialized in user code. Tested on x86_64-linux. Martin Avoid expecting nonzero size for access none void* arguments [PR101751]. Resolves: PR middle-end/101751 - attribute access none with void pointer expects nonzero size gcc/ChangeLog: PR middle-end/101751 * doc/invoke.texi (attribute access): Adjust. * gimple-ssa-warn-access.cc (pass_waccess::maybe_check_access_sizes): gcc/testsuite/ChangeLog: PR middle-end/101751 * gcc.dg/Wstringop-overflow-86.c: New test. diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index 9a9f48685b9..11c99e5dfab 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -2999,6 +2999,10 @@ pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype, if (access.second.minsize && access.second.minsize != HOST_WIDE_INT_M1U) access_nelts = build_int_cstu (sizetype, access.second.minsize); + else if (VOID_TYPE_P (argtype) && access.second.mode == access_none) + /* Treat access mode none on a void* argument as expecting + as little as zero bytes. */ + access_nelts = size_zero_node; else access_nelts = size_one_node; } diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-86.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-86.c new file mode 100644 index 00000000000..345abe4a274 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-86.c @@ -0,0 +1,63 @@ +/* PR middle-end/101751 - attribute access none with void pointer expects + nonzero size + { dg-do compile } + { dg-options "-Wall" } */ + +__attribute__ ((access (none, 1))) void +fvp_m1 (const void*); + +void nowarn_m1 (void) +{ + /* Verify these don't trigger a warning for calls to a function + declared with attribute access none. */ + fvp_m1 ((void*)-1); // { dg-bogus "-Wstringop-" } + fvp_m1 ((void*)1); // { dg-bogus "-Wstringop-" } +} + + +__attribute__ ((access (none, 1))) void +fvp_none (void*); + +void nowarn_c_cp1 (void) +{ + char c; + fvp_none (&c); + fvp_none (&c + 1); // { dg-bogus "-Wstringop-" } +} + +void nowarn_f_fp1 (void) +{ + fvp_none ((char*)&nowarn_f_fp1); + fvp_none ((char*)&nowarn_f_fp1 + 1); +} + +void nowarn_sp1_sp_4 (void) +{ + fvp_none ("" + 1); // { dg-bogus "-Wstringop-" } + fvp_none ("123" + 4); // { dg-bogus "-Wstringop-" } +} + + +__attribute__ ((access (none, 1))) void +wfvp_none (void*); // { dg-message "in a call to function 'wfvp_none' declared with attribute 'access \\\(none, 1\\\)'" } + +void warn_cm1_p1 (void) +{ + char c; + /* With optimization both of the following are diagnosed by -Warray-bounds. + The second also without optimization by -Wstringop-overread. They + should both be diagnosed by the same warning even without optimization. */ + wfvp_none (&c - 1); // { dg-warning "" "pr??????" { xfail *-*-* } } + wfvp_none (&c + 2); // { dg-warning "" } +} + +void warn_fp2 (void) +{ + void *p = (char*)&warn_fp2 + sizeof warn_fp2; + fvp_none (p); // { dg-warning "" "pr??????" { xfail *-*-* } } +} + +void warn_sp2 (void) +{ + wfvp_none ("" + 2); // { dg-warning "" } +} diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index ef654d7b878..266ef76e5c3 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2524,7 +2524,6 @@ The following attributes are supported on most targets. @table @code @c Keep this table alphabetized by attribute name. Treat _ as space. -@item access @itemx access (@var{access-mode}, @var{ref-index}) @itemx access (@var{access-mode}, @var{ref-index}, @var{size-index}) @@ -2598,7 +2597,9 @@ __attribute__ ((access (write_only, 1, 2), access (read_write, 3))) int fgets (c The access mode @code{none} specifies that the pointer to which it applies is not used to access the referenced object at all. Unless the pointer is null the pointed-to object must exist and have at least the size as denoted -by the @var{size-index} argument. The object need not be initialized. +by the @var{size-index} argument. When the optional @var{size-index} +argument is omitted for an argument of @code{void*} type the actual pointer +agument is ignored. The referenced object need not be initialized. The mode is intended to be used as a means to help validate the expected object size, for example in functions that call @code{__builtin_object_size}. @xref{Object Size Checking}.