1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s 2 3 #define strcpy(dest, src) \ 4 ((__builtin_object_size(dest, 0) != -1ULL) \ 5 ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \ 6 : __inline_strcpy_chk(dest, src)) 7 8 static char *__inline_strcpy_chk (char *dest, const char *src) { 9 return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1)); 10 } 11 12 char gbuf[63]; 13 char *gp; 14 int gi, gj; 15 16 // CHECK: define void @test1 17 void test1() { 18 // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59) 19 strcpy(&gbuf[4], "Hi there"); 20 } 21 22 // CHECK: define void @test2 23 void test2() { 24 // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63) 25 strcpy(gbuf, "Hi there"); 26 } 27 28 // CHECK: define void @test3 29 void test3() { 30 // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) 31 strcpy(&gbuf[100], "Hi there"); 32 } 33 34 // CHECK: define void @test4 35 void test4() { 36 // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) 37 strcpy((char*)(void*)&gbuf[-1], "Hi there"); 38 } 39 40 // CHECK: define void @test5 41 void test5() { 42 // CHECK: = load i8** @gp 43 // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false) 44 strcpy(gp, "Hi there"); 45 } 46 47 // CHECK: define void @test6 48 void test6() { 49 char buf[57]; 50 51 // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) 52 strcpy(&buf[4], "Hi there"); 53 } 54 55 // CHECK: define void @test7 56 void test7() { 57 int i; 58 // CHECK: = call i64 @llvm.objectsize.i64(i8* {{.*}}@gbuf{{.*}}, i1 false) 59 strcpy((++i, gbuf), "Hi there"); 60 } 61 62 // CHECK: define void @test8 63 void test8() { 64 char *buf[50]; 65 // CHECK-NOT: __strcpy_chk 66 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 67 strcpy(buf[++gi], "Hi there"); 68 } 69 70 // CHECK: define void @test9 71 void test9() { 72 // CHECK-NOT: __strcpy_chk 73 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 74 strcpy((char *)((++gi) + gj), "Hi there"); 75 } 76 77 // CHECK: define void @test10 78 char **p; 79 void test10() { 80 // CHECK-NOT: __strcpy_chk 81 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 82 strcpy(*(++p), "Hi there"); 83 } 84 85 // CHECK: define void @test11 86 void test11() { 87 // CHECK-NOT: __strcpy_chk 88 // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 89 strcpy(gp = gbuf, "Hi there"); 90 } 91 92 // CHECK: define void @test12 93 void test12() { 94 // CHECK-NOT: __strcpy_chk 95 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 96 strcpy(++gp, "Hi there"); 97 } 98 99 // CHECK: define void @test13 100 void test13() { 101 // CHECK-NOT: __strcpy_chk 102 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 103 strcpy(gp++, "Hi there"); 104 } 105 106 // CHECK: define void @test14 107 void test14() { 108 // CHECK-NOT: __strcpy_chk 109 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 110 strcpy(--gp, "Hi there"); 111 } 112 113 // CHECK: define void @test15 114 void test15() { 115 // CHECK-NOT: __strcpy_chk 116 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 117 strcpy(gp--, "Hi there"); 118 } 119 120 // CHECK: define void @test16 121 void test16() { 122 // CHECK-NOT: __strcpy_chk 123 // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 124 strcpy(gp += 1, "Hi there"); 125 } 126 127 void test17() { 128 // CHECK: store i32 -1 129 gi = __builtin_object_size(gp++, 0); 130 // CHECK: store i32 -1 131 gi = __builtin_object_size(gp++, 1); 132 // CHECK: store i32 0 133 gi = __builtin_object_size(gp++, 2); 134 // CHECK: store i32 0 135 gi = __builtin_object_size(gp++, 3); 136 } 137