Bug 85362 - unnecessary checks with -fsanitize=object-size and non-int indices
Summary: unnecessary checks with -fsanitize=object-size and non-int indices
Status: RESOLVED DUPLICATE of bug 83356
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 7.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-04-12 01:26 UTC by John Breitenbach
Modified: 2018-04-12 07:27 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
example .c file - check for invalid index optimized out of foo() only (139 bytes, text/x-csrc)
2018-04-12 01:26 UTC, John Breitenbach
Details

Note You need to log in before you can comment on or make changes to this bug.
Description John Breitenbach 2018-04-12 01:26:50 UTC
Created attachment 43915 [details]
example .c file - check for invalid index optimized out of foo() only

The following code, when compiled with gcc-6.4 or gcc-7.2 and -fsanitize=object-size and -O2 or higher creates unnecessary code to ensure a valid index.  I'm configured for aarch64, but also see this with armv7.

When indexing a 256-element array with either a uint8_t variable or an integer variable shifted right by 24 or more, gcc inserts code to ensure a valid index.  That code DOES get optimized out when using an integer variable with a smaller or variable shift count and an explicit mask with 0xff.

With the index clearly being an unsigned 8-bit value, the check for > 256 should not be needed.  Even explicitly and'ing with 0xff does not cause the check to get optimized out when using an 8-bit datatype.

lut[(*pi >> 23) & 0xff]);  // good
lut[(*pi >> 24) & 0xff]);  // extra check
lut[(*pi >> 25) & 0xff]);  // extra check
lut[(*pi >> 24) & 0x1]);   // extra check
lut[*pb]		   // extra check
lut[*pb & 0xff];           // extra check
lut[*pb >> 7];             // extra check
lut[*pb >> 8];             // good - loads first element

/bonus/scratch/gcc64/poky/proj/tmp/work/aarch64-poky-linux/graph/*/recipe-sysroot-native/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gcc  -mcpu=cortex-a53   --sysroot=/bonus/scratch/gcc64/poky/proj/tmp/work/aarch64-poky-linux/graph/*/recipe-sysroot -S -O4  -fsanitize=object-size  -fno-sanitize-recover -fsanitize-undefined-trap-on-error -Wall -Wextra   ~/sanitize.c

gcc-7.2 assembly output follows:
	.arch armv8-a+crc
	.file	"sanitize.c"
	.text
	.align	2
	.p2align 4,,15
	.global	foo
	.type	foo, %function
foo:
	ldrb	w1, [x0, 1]
	adrp	x0, lut
	add	x0, x0, :lo12:lut
	ldr	w0, [x0, x1, lsl 2]
	ret
	.size	foo, .-foo
	.align	2
	.p2align 4,,15
	.global	bar
	.type	bar, %function
bar:
	ldrb	w2, [x0, 3]
	adrp	x1, lut
	add	x0, x1, :lo12:lut
	add	x3, x0, x2, lsl 2
	sub	x0, x3, x0
	add	x0, x0, 4
	cmp	x0, 1024
	bhi	.L6
.L4:
	add	x1, x1, :lo12:lut
	ldr	w0, [x1, x2, lsl 2]
	ret
.L6:
	add	x0, x3, x0
	cmp	x3, x0
	bhi	.L4
	brk #1000
	.size	bar, .-bar
	.align	2
	.p2align 4,,15
	.global	baz
	.type	baz, %function
baz:
	ldrb	w2, [x0]
	adrp	x1, lut
	add	x0, x1, :lo12:lut
	add	x3, x0, x2, uxtb 2
	sub	x0, x3, x0
	add	x0, x0, 4
	cmp	x0, 1024
	bhi	.L10
.L8:
	add	x1, x1, :lo12:lut
	ldr	w0, [x1, x2, lsl 2]
	ret
.L10:
	add	x0, x3, x0
	cmp	x3, x0
	bhi	.L8
	brk #1000
	.size	baz, .-baz
	.ident	"GCC: (GNU) 7.2.0"
	.section	.note.GNU-stack,"",@progbits
Comment 1 Jakub Jelinek 2018-04-12 07:22:26 UTC
This is intentional.  For sanitization we don't want to heavily rely on value range propagation, because value range propagation is relying on no undefined behavior occuring in the program and the sanitizer's purpose is exactly catch undefined behavior in the program.  We don't have 2 sets of value ranges where one would be extra conservative and another another one what we have right now where we could use the extra conservative for sanitization.  And by using the normal value range we would just not detect many undefined behaviors.
Comment 2 Jakub Jelinek 2018-04-12 07:27:16 UTC
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83356#c9 for more details.

*** This bug has been marked as a duplicate of bug 83356 ***