1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Verify that calls to known string library functions declared with
; incompatible signatures are handled gracefully and without aborting.
;
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
@a = constant [2 x i8] c"1\00"
declare ptr @atoi(ptr)
declare ptr @atol(ptr)
declare ptr @atoll(ptr)
define void @call_bad_ato(ptr %ps) {
; CHECK-LABEL: @call_bad_ato(
; CHECK-NEXT: [[IR:%.*]] = call ptr @atoi(ptr nonnull @a)
; CHECK-NEXT: store ptr [[IR]], ptr [[PS:%.*]], align 8
; CHECK-NEXT: [[LR:%.*]] = call ptr @atol(ptr nonnull @a)
; CHECK-NEXT: [[PS1:%.*]] = getelementptr ptr, ptr [[PS]], i64 1
; CHECK-NEXT: store ptr [[LR]], ptr [[PS1]], align 8
; CHECK-NEXT: [[LLR:%.*]] = call ptr @atol(ptr nonnull @a)
; CHECK-NEXT: [[PS2:%.*]] = getelementptr ptr, ptr [[PS]], i64 2
; CHECK-NEXT: store ptr [[LLR]], ptr [[PS2]], align 8
; CHECK-NEXT: ret void
;
%ir = call ptr @atoi(ptr @a)
store ptr %ir, ptr %ps
%lr = call ptr @atol(ptr @a)
%ps1 = getelementptr ptr, ptr %ps, i32 1
store ptr %lr, ptr %ps1
%llr = call ptr @atol(ptr @a)
%ps2 = getelementptr ptr, ptr %ps, i32 2
store ptr %llr, ptr %ps2
ret void
}
declare ptr @strncasecmp(ptr, ptr)
define ptr @call_bad_strncasecmp() {
; CHECK-LABEL: @call_bad_strncasecmp(
; CHECK-NEXT: [[CMP:%.*]] = call ptr @strncasecmp(ptr nonnull @a, ptr nonnull getelementptr inbounds ([2 x i8], ptr @a, i64 0, i64 1))
; CHECK-NEXT: ret ptr [[CMP]]
;
%p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1
%cmp = call ptr @strncasecmp(ptr @a, ptr %p1)
ret ptr %cmp
}
declare i1 @strcoll(ptr, ptr, ptr)
define i1 @call_bad_strcoll() {
; CHECK-LABEL: @call_bad_strcoll(
; CHECK-NEXT: [[I:%.*]] = call i1 @strcoll(ptr nonnull @a, ptr nonnull getelementptr inbounds ([2 x i8], ptr @a, i64 0, i64 1), ptr nonnull @a)
; CHECK-NEXT: ret i1 [[I]]
;
%p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1
%i = call i1 @strcoll(ptr @a, ptr %p1, ptr @a)
ret i1 %i
}
declare ptr @strndup(ptr)
define ptr @call_bad_strndup() {
; CHECK-LABEL: @call_bad_strndup(
; CHECK-NEXT: [[D:%.*]] = call ptr @strndup(ptr nonnull @a)
; CHECK-NEXT: ret ptr [[D]]
;
%d = call ptr @strndup(ptr @a)
ret ptr %d
}
declare i1 @strtok(ptr, ptr, i1)
define i1 @call_bad_strtok() {
; CHECK-LABEL: @call_bad_strtok(
; CHECK-NEXT: [[RET:%.*]] = call i1 @strtok(ptr nonnull @a, ptr nonnull getelementptr inbounds ([2 x i8], ptr @a, i64 0, i64 1), i1 false)
; CHECK-NEXT: ret i1 [[RET]]
;
%p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1
%ret = call i1 @strtok(ptr @a, ptr %p1, i1 0)
ret i1 %ret
}
declare i1 @strtok_r(ptr, ptr)
define i1 @call_bad_strtok_r() {
; CHECK-LABEL: @call_bad_strtok_r(
; CHECK-NEXT: [[RET:%.*]] = call i1 @strtok_r(ptr nonnull @a, ptr nonnull getelementptr inbounds ([2 x i8], ptr @a, i64 0, i64 1))
; CHECK-NEXT: ret i1 [[RET]]
;
%p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1
%ret = call i1 @strtok_r(ptr @a, ptr %p1)
ret i1 %ret
}
declare i32 @strtol(ptr, ptr)
declare i32 @strtoul(ptr, ptr)
declare i64 @strtoll(ptr, ptr)
declare i64 @strtoull(ptr, ptr)
define void @call_bad_strto(ptr %psi32, ptr %psi64) {
; CHECK-LABEL: @call_bad_strto(
; CHECK-NEXT: [[LR:%.*]] = call i32 @strtol(ptr nonnull @a, ptr null)
; CHECK-NEXT: store i32 [[LR]], ptr [[PSI32:%.*]], align 4
; CHECK-NEXT: [[ULR:%.*]] = call i32 @strtoul(ptr nonnull @a, ptr null)
; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PSI32]], i64 1
; CHECK-NEXT: store i32 [[ULR]], ptr [[PS1]], align 4
; CHECK-NEXT: [[LLR:%.*]] = call i64 @strtoll(ptr nonnull @a, ptr null)
; CHECK-NEXT: store i64 [[LLR]], ptr [[PSI64:%.*]], align 4
; CHECK-NEXT: [[ULLR:%.*]] = call i64 @strtoull(ptr nonnull @a, ptr null)
; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PSI64]], i64 3
; CHECK-NEXT: store i64 [[ULLR]], ptr [[PS3]], align 4
; CHECK-NEXT: ret void
;
%lr = call i32 @strtol(ptr @a, ptr null)
store i32 %lr, ptr %psi32
%ulr = call i32 @strtoul(ptr @a, ptr null)
%ps1 = getelementptr i32, ptr %psi32, i32 1
store i32 %ulr, ptr %ps1
%llr = call i64 @strtoll(ptr @a, ptr null)
store i64 %llr, ptr %psi64
%ullr = call i64 @strtoull(ptr @a, ptr null)
%ps3 = getelementptr i64, ptr %psi64, i32 3
store i64 %ullr, ptr %ps3
ret void
}
declare ptr @strxfrm(ptr, ptr)
define ptr @call_bad_strxfrm() {
; CHECK-LABEL: @call_bad_strxfrm(
; CHECK-NEXT: [[RET:%.*]] = call ptr @strxfrm(ptr nonnull @a, ptr nonnull getelementptr inbounds ([2 x i8], ptr @a, i64 0, i64 1))
; CHECK-NEXT: ret ptr [[RET]]
;
%p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1
%ret = call ptr @strxfrm(ptr @a, ptr %p1)
ret ptr %ret
}
|