From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by sourceware.org (Postfix) with ESMTPS id 0ACBE3858D33 for ; Wed, 9 Aug 2023 12:37:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0ACBE3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2BF4C638DF; Wed, 9 Aug 2023 12:37:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69844C433C9; Wed, 9 Aug 2023 12:37:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691584653; bh=kY5/9H1rD06QMQCv5gya318HHPYNrctYZysU0LnV0Gc=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=NMKDYkQViD3YB64XT7LpWk5u4tBt0pvaCyPwyiX95mp/wPlQ9F47eGh3uGj5in5iS ujmr2nieUxyXNLKN6ZCrvWpFNHsEYvsw3WzZjj/p85/TXwaNsSqbGtfqkVlL56evAM y3PHnfk6wj8EuzZE7ZIyCKDulM6izYI5YK79fx4H1xtcTvhiEPyr3v6tU+Q1EqllGh +QDPWjkw2IICI+Bd7cGe0eMmvOb1sfKKjfG8YH5oGa78Hv12tN09EV52AKKv/3UdMc DU51Q7C4yUcEVxkmi6gvPhEJU03tLO26Za/9ak2izzy0SJ/654fML46pDMKlrWxg4c UgvQfx3m5ctwg== Message-ID: Date: Wed, 9 Aug 2023 14:37:22 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.1 Subject: Re: ISO C's [static] (was: _Nullable and _Nonnull in GCC's analyzer) Content-Language: en-US To: Martin Uecker Cc: Xi Ruoyao , Andrew Pinski , GNU libc development , Adhemerval Zanella , Carlos O'Donell , Andreas Schwab , Siddhesh Poyarekar , Zack Weinberg , "gcc@gcc.gnu.org" , enh References: <20230710161300.1678172-1-xry111@xry111.site> <1efbe0b2dd8fefffc945c6734222c7d6e04cf465.camel@xry111.site> <10994861-c244-ba4f-70ad-86d66acf7277@kernel.org> <08d7552c-d90a-ae84-4b7e-2f6f2136dd66@kernel.org> From: Alejandro Colomar Organization: Linux In-Reply-To: Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="------------WZLkiyrbMawArbtPuR0IE877" X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00,BODY_8BITS,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --------------WZLkiyrbMawArbtPuR0IE877 Content-Type: multipart/mixed; boundary="------------zOGeTA0iWraXrcQZwugRs9eE"; protected-headers="v1" From: Alejandro Colomar To: Martin Uecker Cc: Xi Ruoyao , Andrew Pinski , GNU libc development , Adhemerval Zanella , Carlos O'Donell , Andreas Schwab , Siddhesh Poyarekar , Zack Weinberg , "gcc@gcc.gnu.org" , enh Message-ID: Subject: Re: ISO C's [static] (was: _Nullable and _Nonnull in GCC's analyzer) References: <20230710161300.1678172-1-xry111@xry111.site> <1efbe0b2dd8fefffc945c6734222c7d6e04cf465.camel@xry111.site> <10994861-c244-ba4f-70ad-86d66acf7277@kernel.org> <08d7552c-d90a-ae84-4b7e-2f6f2136dd66@kernel.org> In-Reply-To: --------------zOGeTA0iWraXrcQZwugRs9eE Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Martin! On 2023-08-09 14:03, Martin Uecker wrote: [...] >> GCC could perfectly add a warning for the following case: >> >> =C2=A0=C2=A0=C2=A0=C2=A0void foo(size_t n, int a[n]); >> >> =C2=A0=C2=A0=C2=A0=C2=A0int >> =C2=A0=C2=A0=C2=A0=C2=A0main(void) >> =C2=A0=C2=A0=C2=A0=C2=A0{ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int a[7]; >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0foo(42, a); >> =C2=A0=C2=A0=C2=A0=C2=A0} >> >> Nobody in their right mind would specify a size of an array >> in a parameter and expect that passing a smaller array than >> that can produce a valid program. So, why not make that a >> Wall warning? >=20 > But we have this warning! is even activated by=C2=A0 > default without -Wall and already since GCC 11: Ahh, I hadn't realized that was added (relatievly) recently. That's great news! Thanks! > https://godbolt.org/z/sMbTon458 >=20 > But this is for minimum required elements. How do=C2=A0 > we differentiate between null and non-null? >=20 > We have: >=20 > int[] or int* // no bound, nullable > int[N] // at least N, nullable > int[static N] // at least N, nonnull >=20 > The 'static' implies nonnull, so we could=C2=A0 > use 'static' to diffentiate between nonnull=C2=A0 > and nullable.=20 Since static is only for arrays (okay, they're all pointers, but it's only usable with array syntax), and nullability is a thing of pointers, I think static is not the right choice. I oppose using array syntax for pointers, as it can confuse programmers. In any case, [static] is not that different from [_Nonnull], and _Nonnull is more flexible, since you can also use it as *_Nonnull. Regarding the issues you have with _Nonnull being a qualifier, I've been thinking about it for a long time and don't yet have a concrete answer. The more I think about it, the more I'm convinced it is like `restrict`. You can't have null correctness as we can do with `const`. With const, we know it's always bad to store a const object in a non-const pointer. With NULL, it depends on the context: if you've checked for NULL in the lines above, then it's fine to do the conversion. There is a proposal for Clang to add `_Optional`, a qualifier to the pointee, as a more correct version of _Nullable. The following would be equivalent: int *_Nullable i; _Optional int *j; However, I don't believe it's a good choice, because of the above. Instead, I think _Nullable or _Nonnull should be like `restrict` and used only in function prototypes. Let the analyzer do the job. I know `restrict` is hard to grasp, but I couldn't think of anything better. >=20 > What is missing something which implies bounds > also inside the callee. You can use the "access" > attribute or we extend the meaning of int[N] > and int[static N] also imply a maximum bound. Why is the upper bound important? It's usually irrelevant. In the case where one wants to make sure that an array is of an exact size (instead of just "at least"), pointers to arrays can be used. They're just not often used, because you don't need that so often. I don't think we need a new addition to the language, do we? $ cat ap.c #include void foo(size_t n, int (*a)[n]) { for (size_t i =3D 0; i < n; i++) (*a)[i] =3D 42; } $ gcc-13 -S -Wall -Wextra ap.c=20 $=20 In the function above, n is not a lower bound, but an exact bound. GCC should add a warning for the following code: $ cat ap2.c #include void foo(size_t n, int (*a)[n]); void bar(void) { int x[7]; foo(3, &x); foo(9, &x); } $ gcc-13 -S -Wall -Wextra ap2.c $=20 Neither GCC nor Clang warn about that. Not even with -fanalyzer. Cheers, Alex --=20 GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5 --------------zOGeTA0iWraXrcQZwugRs9eE-- --------------WZLkiyrbMawArbtPuR0IE877 Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="OpenPGP_signature" -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIFAmTTiIIACgkQnowa+77/ 2zKzZA//YinvDmAhouM5PqCiXyBbCtw5gGfbrOL055yKy3HLuXGJdlEfOdSZtrAw qZuGue23EaUq9Wd4LLuA+XTfuyz+ZL0JV4XPCcXan11UAQyD2eIWlZvGv8EoEMsH USLorcyljeei1IBuy5us2TBgrLnnLKZOGbzEs4LLM4ESn5yh5xT3yXnBLyJagDuQ 78cNQ5ft1XrTvDOFkvb44JwNv2h1dDFSk1xl2/95e2/iGTUoeJNF9e05vQLc9GV3 TCSd3beIohGTrhfF4vyf5ITQ8QzE8j1fFnNg9wkyuBqIISVHibKBNQZQVtK17VIG EfyZOB9jm07yzM4WD6fBEoAru9k9SOeySKUNy4dhgwktsdjSV62ePGbDBuNdWME0 1mMv2VtqsoTzSpYKZZvxxRVVYepX9zM9wmAdtbfQNPrl7AOy4CERe0/Zj5w/hRxD 7QpjB5Fi7kib8FrvWXpd2/QfC2uz1bGdJ3YrKz1HkCvVb5MKxKH38bI1Ur47+RsU B1K7neH5CL9Vd5l1SOdo8F/VhqtdwbURrhSbMn4lgzQ6iFcuk7Ap+qkVtk5pb+dn YOgabJx3Z9k1rWFuXlep33N8nQqE1hC9AAlOl/y8p/kNMkhJzfoieqyWVPJmskKy YkO6w9Ekx9nAzjgxmV4LkTWhV/L9dLDZ10LKjJ1sxIsYwFeLNf8= =qVMg -----END PGP SIGNATURE----- --------------WZLkiyrbMawArbtPuR0IE877--