https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116130
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Based on private discussions with the N2956 paper author, encountering call to exit in [[unsequenced]]/[[reproduceable]] at runtime should be UB, quick_exit/_Exit questionable whether it is UB now but maybe should be clarified as not ok, infinite loops are likely valid unless they already invoke UB. As for other cases, int ok (int *x) [[unsequenced]] { *x = 15; return 42; } int foo (uintptr_t x) [[unsequenced]] { *(int *)x = 1; return 1; } struct S { int *p; }; int bar (struct S x) [[unsequenced]] { x.p[0] = 1; return 1; } int baz (...) [[unsequenced]] { va_list ap; va_start (ap); int *p = va_arg (ap, int *); va_end (ap); *p = 1; return 1; } union U { int *p; long long *q; }; int qux (int x, union U y) [[unsequenced]] { if (x) y.p[0] = 1; else y.q[1] = 2; return 3; } int corge (int **x) [[unsequenced]] { *x[0] = 42; return 5; } ok is valid if actually called, foo is certainly not, bar/baz/qux/corge are not, so it is just pointer type arguments (let's extend that for C++ with references, thoughts on references to pointers) and what they point directly to which can be modified and kept modified, not pointers to pointers, not pointers embedded in structs/unions/arrays or variadic parameters. And the directly pointed memory can be read or stored or first stored and then read, but not first read and then stored, at least if it results in observable side-effect. So, I guess e.g. memchr would be [[gnu::pure]] and [[unsequenced]], as it only reads from the directly pointed elements and not other global state.