https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101419
Bug ID: 101419 Summary: collapsing memset() calls can break __builtin_object_size() Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: kees at outflux dot net Target Milestone: --- Created attachment 51131 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51131&action=edit memset collapsing breaks __builtin_object_size() I've found a strange misoptimization around memset() and __builtin_object_size(). If there are two memset() calls that can be collapsed (due to being fully overlapping, I assume), use of __builtin_object_size() may return the wrong result. The example code shows that __builtin_object_size(&int_value, 1) returns 1 instead of 4: > $ gcc -Wall -Wextra -fno-strict-aliasing -fwrapv -O2 -c -o wat.o wat.c > In function ‘do_wipe’, > inlined from ‘loops’ at wat.c:24:3: > wat.c:15:3: warning: call to ‘__detected_overflow’ declared with attribute > warning: detected overflow [-Wattribute-warning] > 15 | __detected_overflow(__builtin_object_size(&info->lg, 1), > sizeof(info->lg)); > | > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here, info->lg is int, but the call to __builtin_object_size() resolves to the size of info->sm (char). This can be seen directly in the resulting output: > $ objdump -rd wat.o > ... > 0000000000000000 <loops>: > 0: 53 push %rbx > 1: be 04 00 00 00 mov $0x4,%esi > 6: 48 89 fb mov %rdi,%rbx > 9: c6 07 00 movb $0x0,(%rdi) > c: bf 01 00 00 00 mov $0x1,%edi > 11: e8 00 00 00 00 call 16 <loops+0x16> > 12: R_X86_64_PLT32 __detected_overflow-0x4 > 16: c7 03 00 00 00 00 movl $0x0,(%rbx) > 1c: 5b pop %rbx > 1d: c3 ret The first argument to __detected_overflow() is "1", instead of 4. Any changes to this example code makes the bug disappear (removal of loops, removal of empty asm, or reordering of memset() calls). Using Compiler Explorer, this bug appears to have been introduced between GCC 8.5 and 9.1: https://godbolt.org/z/oGq5K9fE4