https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67513
Bug ID: 67513 Summary: ASAN: Not optimal shadow value check (unlikely condition checked in fast path) Product: gcc Version: 5.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: ryabinin.a.a at gmail dot com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org Target Milestone: --- Created attachment 36311 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36311&action=edit repro case Consider following simple case: void foo(unsigned int *a) { *a = 0; } Compiling this with 'gcc -O2 -fsanitize=address asan_test.c -S -o -' gave me the following code: foo: .LASANPC0: .LFB0: .cfi_startproc movq %rdi, %rax shrq $3, %rax movzbl 2147450880(%rax), %edx movq %rdi, %rax andl $7, %eax addl $3, %eax cmpb %dl, %al jl .L2 testb %dl, %dl jne .L11 .L2: movl $0, (%rdi) ret .L11: pushq %rax .cfi_def_cfa_offset 16 call __asan_report_store4 .cfi_endproc if I read this assembly correctly, GCC did something like this: foo(addr): { if (((addr & 7) + 3) < *shadow) goto access; if (*shadow) report_error(addr); access: *a = 0 return; } So the problem here is that check '((addr & 7) + 3) < *shadow)' is in the fast-path, while it should be in a slow-path (shadow value is usually zero).