public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Alejandro Colomar (man-pages)" <alx.manpages@gmail.com>
To: Joseph Myers <joseph@codesourcery.com>
Cc: gcc@gcc.gnu.org, cfe-dev@lists.llvm.org
Subject: Re: ISO C3X proposal: nonnull qualifier
Date: Thu, 2 Dec 2021 21:24:34 +0100	[thread overview]
Message-ID: <3178a917-e9df-36eb-4382-f8aec7b678a2@gmail.com> (raw)
In-Reply-To: <c9b2f273-c8ae-519d-78b9-1d4f34f51c19@gmail.com>



On 11/16/21 13:34, Alejandro Colomar (man-pages) wrote:
> $ cat _Nonnull.c
> #include <stdlib.h>
> 
> int *_Nonnull f(int *_Nullable p)
> {
>      if (!p)
>          exit(1);
>      return p;
> }
> 
> int *_Nonnull g(int *_Null_unspecified p)
> {
>      return p;
> }
> 
> int *_Nonnull h(int *p)
> {
>      return p;
> }
> 
> int *_Nullable i(int *_Nonnull p)
> {
>      return p;
> }
> 
> ---
> I see other problems:
> 
> - I don't get a warning from g(), nor from h(), which I'd want.
>    To get something like const-safety,
>    we need to design it so that it can be enforced;
>    either you guarantee that a pointer cannot be NULL (_Nonnull),
>    or you cannot guarantee it (not _Nonnull).
>    Otherwise,
>    [[gnu::nonnull]] would seem better to me.
> 
>    So, I'd leave out of the design everything but _Nonnull,
>    and consider everything else as nullable by default.

Getting warnings from h() and g() would be easy to impose.  Just forbid 
implicit addition of _Nonnull qualifier.

> 
> - I get a warning from f().
>    Ideally,
>    a programmer should not need to cast
>    (casts are dangerous),
>    to convert a nullable pointer to a _nonnull pointer.
>    For that,
>    appropriate checks should be in the preceeding code.
>    Otherwise, a diagnostic should be issued.
>    To be on the safe side,
>    if a compiler has doubts,
>    it should diagnose.
> 
>    There's some Clang document that talks about something similar.
>    I don't know its validity,
>    or if it was a draft before _Nonnull qualifiers.
>    <https://clang.llvm.org/docs/analyzer/developer-docs/nullability.html>

I came with an idea that would make this QoI, so that the ISO standard 
wouldn't need to force every compiler to be flow-sensitive, which would 
be a bad precedent.

Implicit additions of the qualifier could be allowed to be warned 
_always_ by the standard.

As an extension, quality compilers may not warn when they can see a NULL 
check just before the assignment.

User code could make of the following macro, to avoid having to add 
casts everywhere, which would be as bad as not having _Nonnull at all. 
I got the idea from the GCC __builtin_xxx_overflow() builtins.


	#if defined(__cplusplus)
	#define const_cast(t, x)  const_cast<t>(x)
	#else
	#define const_cast(t, x)  ((t) (x))
	#endif

	#if !defined(cplusplus)
	#define auto  __auto_type
	#endif

	#define nonnull_assign(nn, p)                         \
	({                                                    \
		auto p_  = p;                                 \
		auto nn_ = nn;                                \
                                                               \
		if (p_ == NULL)                               \
			*nn_ = const_cast(typeof(nn_), p_);  \
                                                               \
		p_ == NULL;                                   \
	})


And use it like this:


	int *_Nonnull f(int *_Nullable p)
	{
		int *_Nonnull q;

		if (nonnull_assign(&q, p))
			exit(1);
		return q;
	}


That way there's only one place where there's a cast, so it can be 
easily audited.  The above would be warning-free, without requiring a 
lot of complexity into the compiler.


Please, forgive the extensive use of GNU extensions in the above snippet 
(and the redefinition of auto), as I forgive those who don't use them :)


So, now this can be made non-flow-sensitive, which was a big concern. 
And now the biggest concern I can see is that this qualifier works 
opposite to const (here discarding is allowed but not adding it), and 
that is contrary to how compilers have been working for now.  As far as 
I could read in the standard, there's no mention to qualifiers being 
dropped in an rvalue; Joseph, could you please confirm?  Also, as I 
already mentioned, Clang already implements this somehow without 
discarding the _Nonnull qualifier, so I guess this can be done.


Cheers,
Alex


-- 
Alejandro Colomar
Linux man-pages comaintainer; http://www.kernel.org/doc/man-pages/

  parent reply	other threads:[~2021-12-02 20:24 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-15 16:01 Alejandro Colomar (man-pages)
2021-11-15 16:30 ` Alejandro Colomar (man-pages)
2021-11-15 20:18 ` Joseph Myers
2021-11-15 21:09   ` Alejandro Colomar (man-pages)
2021-11-15 22:17     ` Joseph Myers
2021-11-15 22:35       ` Alejandro Colomar (man-pages)
2021-11-15 22:47         ` Joseph Myers
2021-11-16 12:34           ` Alejandro Colomar (man-pages)
2021-11-17  0:06             ` Alejandro Colomar (man-pages)
2021-11-20 16:47               ` Ping: " Alejandro Colomar (man-pages)
2021-11-23 11:32               ` [cfe-dev] " Dmitri Gribenko
2021-11-23 11:17             ` Dmitri Gribenko
2021-11-23 11:45               ` Alejandro Colomar (man-pages)
2021-11-23 12:45                 ` Dmitri Gribenko
2021-12-01 22:24                   ` Alejandro Colomar (man-pages)
2021-12-02  0:39                     ` Dmitri Gribenko
2021-12-02  1:00                       ` Alejandro Colomar (man-pages)
2021-12-02 20:24             ` Alejandro Colomar (man-pages) [this message]
2021-12-02 20:31               ` Alejandro Colomar (man-pages)
2021-12-02 20:36               ` Joseph Myers
2021-11-16  9:30     ` Jonathan Wakely
2021-11-16 17:13       ` [cfe-dev] " Arthur O'Dwyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3178a917-e9df-36eb-4382-f8aec7b678a2@gmail.com \
    --to=alx.manpages@gmail.com \
    --cc=cfe-dev@lists.llvm.org \
    --cc=gcc@gcc.gnu.org \
    --cc=joseph@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).