> On Nov 12, 2024, at 01:51, Martin Uecker <uec...@tugraz.at> wrote: > > 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?
Sounds reasonable to me. Yes, it’s not a good idea to mix them together with one attribute. Qing > > 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