Handling C2Y zero-length operations on null pointers
Martin Uecker
uecker@tugraz.at
Tue Nov 12 06:51:06 GMT 2024
Am Montag, dem 07.10.2024 um 15:14 +0000 schrieb Qing Zhao:
>
> > On Oct 7, 2024, at 10:13, Jakub Jelinek via Gcc <gcc@gcc.gnu.org> wrote:
> >
> > On Fri, Oct 04, 2024 at 12:42:24AM +0200, Florian Weimer wrote:
> > > * Joseph Myers:
> > >
> > > > The real question is how to achieve optimal warnings in the absence of the
> > > > attribute. Should we have a variant of the nonnull attribute that warns
> > > > for NULL arguments but without optimizing based on them?
> > >
> > > I think attribute access already covers part of it:
> > >
> > > #include <stddef.h>
> > > void read_array (void *, size_t) __attribute__ ((access (read_only, 1, 2)));
> > > void
> > > f (void)
> > > {
> > > read_array (NULL, 0); // No warning.
> > > read_array (NULL, 1); // Warning.
> > > }
> > >
> > > It does not work for functions like strndup that support both string
> > > arguments (of any length) and array arguments of a specified size.
> > > The read_only variant requires an initialized array of the specified
> > > length.
> >
> > access attribute can't deal with various other things.
> >
> > Consider the qsort case. My understanding was that the paper is making
> > typedef int (*cmpfn) (const void *, const void *);
> > qsort (NULL, 0, 1, (cmpfn) NULL);
> > valid (but is
> > qsort (NULL, 1, 0, (cmpfn) NULL);
> > still invalid?).
> > How do you express that with access attribute, which can only have 1 size
> > argument? The accessed memory for the read/write pointee of the first
> > argument has nmemb * size parameter bytes size.
>
> For the other attribute “alloc_size”, we have two forms,
> A. alloc_size (position)
> and
> B. alloc_size (position-1, position-2)
>
> The 2nd form is used to represent nmemb * size.
>
> Is it possible that we extend the attribute “access” similarly?
>
> Then we can use the attribute “access” consistently for this purpose?
We also miss sanitizer support.
How about letting "access" only be about access range
and instead have separate attribute that can be used to
express more complicated preconditions?
void* foo(void *p, size_t mmemb, size_t size)
[[precondition((p == NULL) == (mmemb * size == 0)]];
(not saying this is the right condition for any function
in the standard library)
Martin
>
> Qing
>
> > And using access attribute for function pointers doesn't work, there is
> > no data to be read/written there, just code.
> >
> > Guess some of the nonnull cases could be replaced by access attribute
> > if we clarify the documentation that if SIZE_INDEX is specified and that
> > argument is non-zero then the pointer has to be non-NULL, and teach
> > sanitizers etc. to sanitize those.
> >
> > For the rest, perhaps we need some nonnull_if_nonzero argument
> > which requires that the parameter identified by the first attribute
> > argument must be pointer which is non-NULL if the parameter identified
> > by the second attribute argument is non-zero.
> > And get clarified the qsort/bsearch cases whether it is about just
> > nmemb == 0 or nmemb * size == 0.
> >
> > Jakub
> >
>
More information about the Libc-alpha
mailing list