From patchwork Fri Aug 26 15:20:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 786 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:ecc5:0:0:0:0:0 with SMTP id s5csp283752wro; Fri, 26 Aug 2022 08:22:14 -0700 (PDT) X-Google-Smtp-Source: AA6agR52ppdZo/hscMe6cDyUVDnIoLEH+Ef98WM8BYbs5OX/jkWJAyvQkOjrHVLth9RZY13Hs+QL X-Received: by 2002:a05:6402:270c:b0:446:f754:371a with SMTP id y12-20020a056402270c00b00446f754371amr7231088edd.388.1661527334849; Fri, 26 Aug 2022 08:22:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661527334; cv=none; d=google.com; s=arc-20160816; b=qiPYINmIbZm66Dfp0KpOKHEVRWrF2QiuDVPe339Uj3N3VbP/X3nCM23jJYN18LcAAr 2zSuUiVFVvrPRehQfq0xlvDKjIFtMAr1sV+OpS2yPh9uDY6BH/DXkez8Oy3b8Aig3oAX nZbSsE8NyP1QCqeW7CBCnMvtJ+9wNxTRefKDixgS702877Bd2llTA5f2+kxIO7nsCo14 SDDZBkgaJKKNoypGgonWYDQwo57ctXGLUHtOcRwQuN3sS98+0fuvaJCjPSuHWkT5RR6i 3goY/jM9z8Ti8Gp7OdOOiEkmE5wYtTo0dTOKl2uuvDPItgLeG4u0K9Swhzi13zu2OPaZ GL5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=OYxai4+5ws/LG8KXdr4GtNQOBEbmcgLeSvKwFFEngqQ=; b=J21EwYnRSI0QrRtjr0D+svME7BGBuf/FQ4E0pEn/jLBQA8/Dpw4bTq31cLKn3m5iQO XoZ8wiQT1U0vlXQqdtM+Tfkxr230vBkKyWkr+70ZOSEVmFFsfY2LGUdWFg3DHO1I0gM2 Xc0l6aYS0bs7Fh6g4MIpaMC7r/44xxNlbvkFnZUMRlH1niLXPuz4W1qXKdcq/YoZ48Dq nIkO6wbJuuUh+sraohu/0cnCYtXtQCYxVl6vtgts6nOa9YJA56TIIB9d52Tv2TzJiPZp rS8R9hxNT+g/zku2T3pDgVoEgxiGvXmIafK9kFpz4wlOxAEYSw/uGHqqk06Err9D2ZNg QK4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=GVN9zTHC; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id gn37-20020a1709070d2500b0073d82e1ec9bsi1386422ejc.547.2022.08.26.08.22.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Aug 2022 08:22:14 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=GVN9zTHC; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EA4CC3851172 for ; Fri, 26 Aug 2022 15:22:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EA4CC3851172 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661527322; bh=OYxai4+5ws/LG8KXdr4GtNQOBEbmcgLeSvKwFFEngqQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=GVN9zTHCDGZEbO3D4gbtDDEPldGA5CXw0O4y0yYHC8BXVtAt20XeafRwovbC25A1e bqsLLmFIBIEzd0hfRc/GMGIPNwCUkNZLb5KDJSqlLQBnvfeMwVpgmUSPrvO0sBV+lz H85lcC64ccjjM/20lYTyUulFUlKsIdoQZLujS74U= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 539D5385829E for ; Fri, 26 Aug 2022 15:21:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 539D5385829E Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-398-GDWXfralNFyaq8Rxmp-Axw-1; Fri, 26 Aug 2022 11:21:00 -0400 X-MC-Unique: GDWXfralNFyaq8Rxmp-Axw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EEF9D1C0337E; Fri, 26 Aug 2022 15:20:58 +0000 (UTC) Received: from localhost (unknown [10.33.36.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id B59752026D4C; Fri, 26 Aug 2022 15:20:58 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Add nonnull to starts_with/ends_with/contains string members Date: Fri, 26 Aug 2022 16:20:58 +0100 Message-Id: <20220826152058.166976-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1742237686539683397?= X-GMAIL-MSGID: =?utf-8?q?1742237686539683397?= Tested powerpc64le-linux, pushed to trunk. -- >8 -- Ideally this wouldn't be needed, because eventually these pointers all get passed to either the basic_string_view(const CharT*) constructor, or to basic_string_view::find(const CharT*), both of which already have the attribute. But for that to work requires optimization, so that the null value gets propagated through the call chain. Adding it explicitly to each member that requires a non-null pointer makes the diagnostics more reliable even without optimization. It's better to give a diagnostic earlier anyway, at the actual problematic call in the user's code. libstdc++-v3/ChangeLog: * include/bits/basic_string.h (starts_with, ends_with, contains): Add nonnull attribute. * include/bits/cow_string.h (starts_with, ends_with, contains): Likewise. * include/std/string_view (starts_with, ends_with, contains): Likewise. * testsuite/21_strings/basic_string/operations/contains/nonnull.cc * testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc * testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc * testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc * testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc * testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc --- libstdc++-v3/include/bits/basic_string.h | 3 +++ libstdc++-v3/include/bits/cow_string.h | 3 +++ libstdc++-v3/include/std/string_view | 3 +++ .../basic_string/operations/contains/nonnull.cc | 12 ++++++++++++ .../basic_string/operations/ends_with/nonnull.cc | 12 ++++++++++++ .../basic_string/operations/starts_with/nonnull.cc | 12 ++++++++++++ .../basic_string_view/operations/contains/nonnull.cc | 12 ++++++++++++ .../operations/ends_with/nonnull.cc | 12 ++++++++++++ .../operations/starts_with/nonnull.cc | 12 ++++++++++++ 9 files changed, 81 insertions(+) create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index b04fba95678..9d8b415302b 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -3400,6 +3400,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 starts_with(_CharT __x) const noexcept { return __sv_type(this->data(), this->size()).starts_with(__x); } + [[__gnu__::__nonnull__]] constexpr bool starts_with(const _CharT* __x) const noexcept { return __sv_type(this->data(), this->size()).starts_with(__x); } @@ -3412,6 +3413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 ends_with(_CharT __x) const noexcept { return __sv_type(this->data(), this->size()).ends_with(__x); } + [[__gnu__::__nonnull__]] constexpr bool ends_with(const _CharT* __x) const noexcept { return __sv_type(this->data(), this->size()).ends_with(__x); } @@ -3426,6 +3428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 contains(_CharT __x) const noexcept { return __sv_type(this->data(), this->size()).contains(__x); } + [[__gnu__::__nonnull__]] constexpr bool contains(const _CharT* __x) const noexcept { return __sv_type(this->data(), this->size()).contains(__x); } diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index f16e33ac1ef..f5f03338eec 100644 --- a/libstdc++-v3/include/bits/cow_string.h +++ b/libstdc++-v3/include/bits/cow_string.h @@ -3012,6 +3012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION starts_with(_CharT __x) const noexcept { return __sv_type(this->data(), this->size()).starts_with(__x); } + [[__gnu__::__nonnull__]] bool starts_with(const _CharT* __x) const noexcept { return __sv_type(this->data(), this->size()).starts_with(__x); } @@ -3024,6 +3025,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ends_with(_CharT __x) const noexcept { return __sv_type(this->data(), this->size()).ends_with(__x); } + [[__gnu__::__nonnull__]] bool ends_with(const _CharT* __x) const noexcept { return __sv_type(this->data(), this->size()).ends_with(__x); } @@ -3038,6 +3040,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION contains(_CharT __x) const noexcept { return __sv_type(this->data(), this->size()).contains(__x); } + [[__gnu__::__nonnull__]] bool contains(const _CharT* __x) const noexcept { return __sv_type(this->data(), this->size()).contains(__x); } diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index 30ff136b1cb..5b96ffeecd6 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -360,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION starts_with(_CharT __x) const noexcept { return !this->empty() && traits_type::eq(this->front(), __x); } + [[__gnu__::__nonnull__]] constexpr bool starts_with(const _CharT* __x) const noexcept { return this->starts_with(basic_string_view(__x)); } @@ -377,6 +378,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ends_with(_CharT __x) const noexcept { return !this->empty() && traits_type::eq(this->back(), __x); } + [[__gnu__::__nonnull__]] constexpr bool ends_with(const _CharT* __x) const noexcept { return this->ends_with(basic_string_view(__x)); } @@ -392,6 +394,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION contains(_CharT __x) const noexcept { return this->find(__x) != npos; } + [[__gnu__::__nonnull__]] constexpr bool contains(const _CharT* __x) const noexcept { return this->find(__x) != npos; } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc new file mode 100644 index 00000000000..e987cb7d297 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/contains/nonnull.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++23 -Wnonnull -O0" } +// { dg-do compile { target c++23 } } + +#include + +void +test01(const std::string& s) +{ + s.contains((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.contains((char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.contains(nullptr); // { dg-warning "\\\[-Wnonnull" } +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc new file mode 100644 index 00000000000..1f2a156bace --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/ends_with/nonnull.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++20 -Wnonnull -O0" } +// { dg-do compile { target c++20 } } + +#include + +void +test01(const std::string& s) +{ + s.ends_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.ends_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.ends_with(nullptr); // { dg-warning "\\\[-Wnonnull" } +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc new file mode 100644 index 00000000000..8514359c877 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/starts_with/nonnull.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++20 -Wnonnull -O0" } +// { dg-do compile { target c++20 } } + +#include + +void +test01(const std::string& s) +{ + s.starts_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.starts_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.starts_with(nullptr); // { dg-warning "\\\[-Wnonnull" } +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc new file mode 100644 index 00000000000..c0d274f095b --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/contains/nonnull.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++23 -Wnonnull -O0" } +// { dg-do compile { target c++23 } } + +#include + +void +test01(std::string_view s) +{ + s.contains((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.contains((char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.contains(nullptr); // { dg-warning "\\\[-Wnonnull" } +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc new file mode 100644 index 00000000000..09a99978a37 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/ends_with/nonnull.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++20 -Wnonnull -O0" } +// { dg-do compile { target c++20 } } + +#include + +void +test01(std::string_view s) +{ + s.ends_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.ends_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.ends_with(nullptr); // { dg-warning "\\\[-Wnonnull" } +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc new file mode 100644 index 00000000000..c47f1dae832 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/starts_with/nonnull.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++20 -Wnonnull -O0" } +// { dg-do compile { target c++20 } } + +#include + +void +test01(std::string_view s) +{ + s.starts_with((const char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.starts_with((char*)nullptr); // { dg-warning "\\\[-Wnonnull" } + s.starts_with(nullptr); // { dg-warning "\\\[-Wnonnull" } +}