Message ID | alpine.DEB.2.22.394.2110271656160.1681686@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
Series | Disable -Waggressive-loop-optimizations warnings in tst-dynarray.c | expand |
* Joseph Myers: > My build-many-glibcs.py bot shows -Waggressive-loop-optimizations > errors building the glibc testsuite for 32-bit architectures with GCC > mainline, which seem to have appeared between GCC commits > 4abc0c196b10251dc80d0743ba9e8ab3e56c61ed and > d8edfadfc7a9795b65177a50ce44fd348858e844: > > In function 'dynarray_long_noscratch_resize', > inlined from 'test_long_overflow' at tst-dynarray.c:489:5, > inlined from 'do_test' at tst-dynarray.c:571:3: > ../malloc/dynarray-skeleton.c:391:36: error: iteration 1073741823 invokes undefined behavior [-Werror=aggressive-loop-optimizations] > 391 | DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]); > tst-dynarray.c:39:37: note: in definition of macro 'DYNARRAY_ELEMENT_INIT' > 39 | #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 23) > | ^ > In file included from tst-dynarray.c:42: > ../malloc/dynarray-skeleton.c:389:37: note: within this loop > 389 | for (size_t i = old_size; i < size; ++i) > | ~~^~~~~~ > In function 'dynarray_long_resize', > inlined from 'test_long_overflow' at tst-dynarray.c:479:5, > inlined from 'do_test' at tst-dynarray.c:571:3: > ../malloc/dynarray-skeleton.c:391:36: error: iteration 1073741823 invokes undefined behavior [-Werror=aggressive-loop-optimizations] > 391 | DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]); > tst-dynarray.c:27:37: note: in definition of macro 'DYNARRAY_ELEMENT_INIT' > 27 | #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 17) > | ^ > In file included from tst-dynarray.c:28: > ../malloc/dynarray-skeleton.c:389:37: note: within this loop > 389 | for (size_t i = old_size; i < size; ++i) > | ~~^~~~~~ > > I don't know what GCC change made these errors appear, or why they > only appear for 32-bit architectures. However, the warnings appear to > be both true (that iteration would indeed involve undefined behavior > if executed) and useless in this particular case (that iteration is > never executed, because the allocation size overflows and so the > allocation fails - but the check for allocation size overflow is in a > separate source file and so can't be seen by the compiler when > compiling this test). So use the DIAG_* macros to disable > -Waggressive-loop-optimizations around the calls in question to > dynarray_long_resize and dynarray_long_noscratch_resize in this test. The glibc patch is okay, but I think this case is fairly common: A failed allocation ensuring that loops do not wrap around the address space. So this could hint to a defect in the GCC warning. Thanks, Florian
diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c index c33505711f..955fab696c 100644 --- a/malloc/tst-dynarray.c +++ b/malloc/tst-dynarray.c @@ -20,6 +20,7 @@ #include <errno.h> #include <stdint.h> +#include <libc-diag.h> #define DYNARRAY_STRUCT dynarray_long #define DYNARRAY_ELEMENT long @@ -476,8 +477,15 @@ test_long_overflow (void) struct dynarray_long dyn; dynarray_long_init (&dyn); errno = EINVAL; + DIAG_PUSH_NEEDS_COMMENT; + /* GCC 12 (on 32-bit platforms) warns that after inlining, a loop + iteration would invoke undefined behavior. That loop iteration + can never be executed because an allocation of this size must + fail. */ + DIAG_IGNORE_NEEDS_COMMENT (12, "-Waggressive-loop-optimizations"); TEST_VERIFY (!dynarray_long_resize (&dyn, (SIZE_MAX / sizeof (long)) + 1)); + DIAG_POP_NEEDS_COMMENT; TEST_VERIFY (errno == ENOMEM); TEST_VERIFY (dynarray_long_has_failed (&dyn)); } @@ -486,8 +494,15 @@ test_long_overflow (void) struct dynarray_long_noscratch dyn; dynarray_long_noscratch_init (&dyn); errno = EINVAL; + DIAG_PUSH_NEEDS_COMMENT; + /* GCC 12 (on 32-bit platforms) warns that after inlining, a loop + iteration would invoke undefined behavior. That loop iteration + can never be executed because an allocation of this size must + fail. */ + DIAG_IGNORE_NEEDS_COMMENT (12, "-Waggressive-loop-optimizations"); TEST_VERIFY (!dynarray_long_noscratch_resize (&dyn, (SIZE_MAX / sizeof (long)) + 1)); + DIAG_POP_NEEDS_COMMENT; TEST_VERIFY (errno == ENOMEM); TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn)); }