From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id CDE2A3858D32 for ; Sat, 11 Feb 2023 00:32:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CDE2A3858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ed1-x532.google.com with SMTP id c1so2556307edt.4 for ; Fri, 10 Feb 2023 16:32:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=c8owBf0Wial50qPw7IFbF5U5ZEdnMc9iRfTwkjQp37A=; b=g5Kwg5G5zBHBU27kqJDaX0sx0MOoPzmZlcbpmxGABQ8zRqL8VGV+Pge24uWOgshC+C hP/AGa9X22ftFdSKQSmXIF7o6vprUR6UL8qcL91v3g9vLgCR8+9FW/CyKsdd6YRbeNg8 yPcPSjR1qMPJNptwEcu48YQn4C0tmGPI9e4hY7P7tcoo+8Sb4Hhuma+X17BM4ttV5f1P hdrLyXDopr8gIfMAjDuvJB8FE5Xc49G9E63gQoxsaybol9TdN6JWlg+bUB+S6y87VdOG yYqZAsA6MNO7QpCYQzBgmTHU/FbZPJV3bziprolcCPXokpx5sFuO15kbD1Mx9Pj3qi4y zQQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=c8owBf0Wial50qPw7IFbF5U5ZEdnMc9iRfTwkjQp37A=; b=iaVtaBQLys29bCvkKvR6Yu781pFpc81RQhT5rinWq4zm8wJ/TGV3hUlg6IOcQ4z8Bv 23VJOnSC9aD7XpplGeU/gb3aZdseIsfHuCedj67pFtRXgZvwCf6Ly5RoeczFv9cL/xGc iQu2FEBTPs+HjFxtijhkZvYA/IlA3/FWtbnnIr0opUY76XCgFXQqjY6eJeySFTdeyBSO OK4fMBXDqbV10x0NQtVdAdgxhfhqihnX+4XcHKUvc9j9yJk5dBhd1/hu9guaGackURSJ cyj/nsVHQUZ6mMpg6aLNVP8FtYOH8c+X+YtLu7+DIxUIyMM3yp4OeirABN9mVFlbjgIJ YcfA== X-Gm-Message-State: AO0yUKVwXBFhDzRkNyoa0lUVgaqU1zU0Ejh5DWU64c/WSGVUm4tQH7Q/ DSAX/ZJesPolKNt5yHEm3uIYfCfKHVqILCfl648= X-Google-Smtp-Source: AK7set+wstl7p9/eoRUpeXLygA2wEMcB8tO1wkSP8qEL+Wd0K/iBIC29nNITCUifox4daBZqtAd7siOfTyOUTdQrrqw= X-Received: by 2002:a05:6402:1d54:b0:4ac:b38f:ae5 with SMTP id dz20-20020a0564021d5400b004acb38f0ae5mr760514edb.1.1676075556440; Fri, 10 Feb 2023 16:32:36 -0800 (PST) MIME-Version: 1.0 References: <7e6e3bbf-0dac-0632-0e8f-372bd32a6923@jguk.org> <6e30ed8e6c6f08407a5b8259e73fd18a492376b5.camel@xry111.site> <8cfbab8b-07e8-7dab-c829-6de77cc8cf39@jguk.org> <6b530d67-723a-a0c9-15bc-12b7341653a7@jguk.org> In-Reply-To: <6b530d67-723a-a0c9-15bc-12b7341653a7@jguk.org> From: Jonathan Wakely Date: Sat, 11 Feb 2023 00:32:25 +0000 Message-ID: Subject: Re: std::string add nullptr attribute To: Jonny Grant Cc: Xi Ruoyao , gcc-help Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Fri, 10 Feb 2023 at 22:38, Jonny Grant wrote: > > > > On 10/02/2023 22:03, Jonathan Wakely wrote: > > On Fri, 10 Feb 2023 at 21:30, Jonny Grant wrote: > >> > >> > >> > >> On 09/02/2023 17:52, Jonathan Wakely wrote: > >>> On Thu, 9 Feb 2023 at 16:30, Xi Ruoyao wrote: > >>>> > >>>> On Thu, 2023-02-09 at 14:56 +0000, Jonathan Wakely via Gcc-help wrot= e: > >>>>>> Note, my code isn't like this, it is just an example to suggest > >>>>>> adding the nullptr attribute, as its clearly already rejected at > >>>>>> runtime. > >>>>> > >>>>> I assume you mean the nonnull attribute. That was added in 2020 and > >>>>> then reverted because it broke some things: > >>>> > >>>> I remember I'd once made the same mistake when I suggested to add > >>>> nonnull for ostream::operator<<(const string &) and I was lectured: > >>>> nonnull is not only a diagnostic attribute, it also allows the compi= ler > >>>> to assume the parameter is never null and rendering std::string(null= ptr) > >>>> an undefined behavior. > >>> > >>> Yes, I think that's what might have happened with the std::string cha= nge. > >> > >> My apologies, Jonathan, Xi, yes it is the __attribute__((nonnull)); I = was mistaken to type as nullptr. > >> > >> I re-read, and it does seem nonnull is really an optimization that as = a side effect may give some warnings. So I'm going to stop using it. > >> https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Com= mon-Function-Attributes > >> > >> (there is a typo in that manual section saying "nonnul" - I don't know= if you have a moment to make a change in git? I didn't get replies on gcc-= patches to my patches...) > >> > >> I searched and see like someone investigated this problem and saw it r= emoved NULL checks http://www.rkoucha.fr/tech_corner/nonnull_gcc_attribute.= html > >> > >> I saw wget2 removed the nonnull attribute due to the optimizer removin= g checks against NULL too > >> https://gitlab.com/gnuwget/wget2/-/issues/200 > >> > >>>> Then the example may just silently continue to run, instead of throw= ing > >>>> an exception. It would be an ironic example: an attempt to improve > >>>> diagnostic finally made diagnostic more difficult. > >>> > >>> Indeed. > >>> > >>> Maybe we can add __attribute__((access(read, 1))) instead, which says > >>> that we will read from the pointer, which also implies it must be > >>> non-null. > >> > >> I tried this with gcc 12, as read_only, but it didn't stop when compil= ing. Maybe you have an example that demonstrates please? > >> > >> void f(const char * p) __attribute__((access(read_only, 1))); > >> > >>> > >>> N.B. in C++23 string(nullptr) produces an error, although > >>> string((const char*)nullptr) doesn't, so in practice it only prevents > >>> the dumbest calls with a literal 'nullptr' token, and not the more > >>> realistic problems where you have a pointer that happens to be null. > >> > >> That's good it stops compiling, the error is not that clear "use of de= leted function" for me though. > >> > >> string.cpp: In function =E2=80=98int main()=E2=80=99: > >> string.cpp:13:26: error: use of deleted function =E2=80=98std::__cxx11= ::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::nullptr_t) [with= _CharT =3D char; _Traits =3D std::char_traits; _Alloc =3D std::alloc= ator; std::nullptr_t =3D std::nullptr_t]=E2=80=99 > >> 13 | std::string c(nullptr); > >> > >> > >> > >> > >> I made my own test class str_string which stops the build a different = way. It only works if the dumbest calls with 'nullptr' as you found in your= test. > >> > >> void nullptr_compile_abort() __attribute__((error("nullptr compile err= or"))); > >> > >> str_string(nullptr_t) { nullptr_compile_abort(); } > > > > This doesn't work because std::is_constructible_v > std::nullptr_t> would be true, and we want it to be false. > > Hmm, for me, this output is 0. > std::cout << std::is_constructible_v << "\n= "; For C++23, yes, but if you add a constructor like your str_string(nullptr_t) it would become 1. Using a deleted function is observably different to using a constructor that then produces an error when called.