> On Apr 10, 2025, at 15:22, Qing Zhao <qing.z...@oracle.com> wrote: > > > >> On Apr 10, 2025, at 13:43, Martin Uecker <uec...@tugraz.at> wrote: >> >> Am Donnerstag, dem 10.04.2025 um 17:05 +0000 schrieb Qing Zhao: >>> Hi, Martin, >>> >>> Thanks a lot for all your comments and questions, really helpful. >>> >>> >> >> ... >>>> >>>> An example I could imagine is when you memcpy >>>> the struct. (but it is also not entirely clear why this >>>> should not be allowed to go beyond the counted_by size >>>> if the underlying storage is larger). >>>> >>>> Maybe you could add it when a pointer to an annotated >>>> struct is passed as parameter, but also there it is not >>>> clear to me that we might want to materialize new >>>> accesses to the struct at this point. >>> >>> This is true too, and this is even true for the current implementation for >>> p->array, >>> as I checked with a small example as below: >>> >>> [opc@qinzhao-aarch64-ol8 counted_by_whole]$ cat t2.c >>> #include <stdlib.h> >>> #include <stddef.h> >>> >>> struct annotated { >>> size_t count; >>> char array[]; >>> }; >>> >>> static size_t __attribute__((__noinline__,__noipa__)) size_of (struct >>> annotated * obj) >>> { >>> return __builtin_dynamic_object_size (obj->array, 1); >>> } >>> >>> int main() >>> { >>> __builtin_printf ("the bdos whole is %ld\n", size_of (0)); >>> return 0; >>> } >>> >>> In the above example, the parameter to the function “size_of” has pointer >>> type to “struct annotated”, >>> However, I passed a NULL to “size_of”, is this legal C? Looks like -Wall >>> did not issue any warning >>> for it. >> >> It is legal to pass a NULL pointer. Here, the issue is >> that the builtin does not evaluate its argument, so it >> is perhaps surprising that you can get a segfault. If >> the access it outside of the builtin, then this is not >> a problem >> >> static size_t __attribute__((__noinline__,__noipa__)) size_of (struct >> annotated * obj) >> { >> char *p = obj->array; >> return __builtin_dynamic_object_size (p, 1); >> } > > The above acts the same as > > static size_t __attribute__((__noinline__,__noipa__)) size_of (struct > annotated * obj) > { > return __builtin_dynamic_object_size (obj->array, 1); > } > > Only after I changed it as: > > static size_t __attribute__((__noinline__,__noipa__)) size_of (struct > annotated * obj) > { > char *p = obj->array; > p[1] = 0; > return __builtin_dynamic_object_size (p, 1); > } > > I got a segmentation fault before evaluating _bdos. >> >> because you get the segault anyway when the first line >> is executed. > > Yes. That’s right. >> >> Maybe we need to document that the BDOS builtin requires >> obj->array to be accessible even though it is not >> evaluated. > > Yes, this needs to be at least documented. >> >> But I wonder whether there are other cases where >> the object-size path can walk into dead code and create >> accesses in this way. Not sure, but I found this bug though: >> https://godbolt.org/z/ejP918nW7 > > Thanks, will file bugs and fix them first.
I filed two bugs against GCC15: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119716 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119717 And assigned to myself. Qing