blob: 2b8551ac1f4dff0d968299c27eec5cd220461b0a [file] [log] [blame]
; OOB indexing example reduced from 483.xalancbmk
;RUN: dsaopt %s -dsa-local -disable-output
;RUN: dsaopt %s -dsa-bu -disable-output
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%structType = type { i32, i8*, i32 }
; Index OOB in a single function
define i32 @foo(%structType* %t) {
; Treat 't' as an array of structs, and index to the 'i8*' in the second one
%ptr = getelementptr inbounds %structType* %t, i64 1, i32 1
; Cast so indexing past end of struct is 'allowed'
%cast = bitcast i8** %ptr to %structType*
; Get pointer to second 'i32' that's now OOB of the original struct type
%ptr2 = getelementptr inbounds %structType* %cast, i32 0, i32 2
ret i32 0
}
; Same thing, only split across two functions
define i32 @fooStart(%structType* %t) {
; Treat 't' as an array of structs, and index to the 'i8*' in the second one
%ptr = getelementptr inbounds %structType* %t, i64 1, i32 1
; Cast so indexing past end of struct is 'allowed'
%cast = bitcast i8** %ptr to %structType*
; Call other function to finish
%val = tail call i32 @fooGEP(%structType* %cast)
ret i32 %val
}
declare void @fooEmpty(i32* %val)
define i32 @fooGEP(%structType* %t) {
; Get pointer to second 'i32' that's now OOB of the original struct type
%ptr = getelementptr inbounds %structType* %t, i32 0, i32 2
; Use in call, triggers similar bug in inlining calls
call void @fooEmpty(i32* %ptr)
ret i32 0
}