1f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s 2cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer 3cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer#define strcpy(dest, src) \ 4cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer ((__builtin_object_size(dest, 0) != -1ULL) \ 5cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \ 6cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer : __inline_strcpy_chk(dest, src)) 7cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer 8cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramerstatic char *__inline_strcpy_chk (char *dest, const char *src) { 9cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1)); 10cc179cb24ffc6686c788c6849e59fc1b04ecf03eBenjamin Kramer} 1164eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 1264eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stumpchar gbuf[63]; 1364eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stumpchar *gp; 1448c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stumpint gi, gj; 1564eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 16d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test1 1764eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stumpvoid test1() { 18d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // 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) 1964eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump strcpy(&gbuf[4], "Hi there"); 2064eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump} 2164eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 22d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test2 2364eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stumpvoid test2() { 24d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // 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) 2564eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump strcpy(gbuf, "Hi there"); 2664eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump} 2764eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 28d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test3 2906bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stumpvoid test3() { 30d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // 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) 3106bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump strcpy(&gbuf[100], "Hi there"); 3206bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump} 3306bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump 34d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test4 3564eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stumpvoid test4() { 36d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // 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) 3706bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump strcpy((char*)(void*)&gbuf[-1], "Hi there"); 3806bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump} 3906bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump 40d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test5 4106bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stumpvoid test5() { 42d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = load i8** @gp 433e86a0433db4c664d29f2b19eb977138e071a68aNuno Lopes // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false) 4406bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stump strcpy(gp, "Hi there"); 4564eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump} 4664eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 47d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test6 4806bc9bcc705e5fee714d4b00c3c3c9f01715c195Mike Stumpvoid test6() { 49660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump char buf[57]; 50660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump 51d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) 52660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump strcpy(&buf[4], "Hi there"); 53660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump} 5448c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump 55d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test7 5648c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stumpvoid test7() { 5748c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump int i; 58c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith // Ensure we only evaluate the side-effect once. 59c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith // CHECK: = add 60c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith // CHECK-NOT: = add 61c6794850a570a91c5f224b6f0293db9f560f4213Richard Smith // 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) 6248c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump strcpy((++i, gbuf), "Hi there"); 6348c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump} 6448c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump 65d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test8 6648c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stumpvoid test8() { 6748c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump char *buf[50]; 68bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 69d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 7048c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump strcpy(buf[++gi], "Hi there"); 7148c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump} 7248c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump 73d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test9 7448c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stumpvoid test9() { 75bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 76d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 7748c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump strcpy((char *)((++gi) + gj), "Hi there"); 7848c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump} 7948c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump 80d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test10 8148c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stumpchar **p; 8248c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stumpvoid test10() { 83bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 84d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 8548c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump strcpy(*(++p), "Hi there"); 8648c2af821ef9ffb51499f37ac1d332766fc20f1eMike Stump} 872623aa283772f629189620a993e2343f2525d262Mike Stump 88d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test11 892623aa283772f629189620a993e2343f2525d262Mike Stumpvoid test11() { 90bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 91d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar // 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)) 922623aa283772f629189620a993e2343f2525d262Mike Stump strcpy(gp = gbuf, "Hi there"); 932623aa283772f629189620a993e2343f2525d262Mike Stump} 942623aa283772f629189620a993e2343f2525d262Mike Stump 95d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test12 962623aa283772f629189620a993e2343f2525d262Mike Stumpvoid test12() { 97bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 98d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 992623aa283772f629189620a993e2343f2525d262Mike Stump strcpy(++gp, "Hi there"); 1002623aa283772f629189620a993e2343f2525d262Mike Stump} 1012623aa283772f629189620a993e2343f2525d262Mike Stump 102d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test13 1032623aa283772f629189620a993e2343f2525d262Mike Stumpvoid test13() { 104bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 105d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 1062623aa283772f629189620a993e2343f2525d262Mike Stump strcpy(gp++, "Hi there"); 1072623aa283772f629189620a993e2343f2525d262Mike Stump} 1082623aa283772f629189620a993e2343f2525d262Mike Stump 109d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test14 1102623aa283772f629189620a993e2343f2525d262Mike Stumpvoid test14() { 111bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 112d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 1132623aa283772f629189620a993e2343f2525d262Mike Stump strcpy(--gp, "Hi there"); 1142623aa283772f629189620a993e2343f2525d262Mike Stump} 1152623aa283772f629189620a993e2343f2525d262Mike Stump 116d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test15 1172623aa283772f629189620a993e2343f2525d262Mike Stumpvoid test15() { 118bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 119d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 1202623aa283772f629189620a993e2343f2525d262Mike Stump strcpy(gp--, "Hi there"); 1212623aa283772f629189620a993e2343f2525d262Mike Stump} 1223f0147e161df4725ff15fbb731f4f727afcc229fMike Stump 123d7f7d0895dc43db20c43112a24684f11eed305deDaniel Dunbar// CHECK: define void @test16 1243f0147e161df4725ff15fbb731f4f727afcc229fMike Stumpvoid test16() { 125bc773a0bd20231c405476d15c5e8bfb3eb365293Mike Stump // CHECK-NOT: __strcpy_chk 126d2635a45dfafbf84fc4056415e8c0bf632c12dbbMike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 1273f0147e161df4725ff15fbb731f4f727afcc229fMike Stump strcpy(gp += 1, "Hi there"); 1283f0147e161df4725ff15fbb731f4f727afcc229fMike Stump} 1293f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer 130f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes// CHECK: @test17 1313f27b384801de26ce7efaa395699b42719372f24Benjamin Kramervoid test17() { 1323f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer // CHECK: store i32 -1 1333f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer gi = __builtin_object_size(gp++, 0); 1343f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer // CHECK: store i32 -1 1353f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer gi = __builtin_object_size(gp++, 1); 1363f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer // CHECK: store i32 0 1373f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer gi = __builtin_object_size(gp++, 2); 1383f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer // CHECK: store i32 0 1393f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer gi = __builtin_object_size(gp++, 3); 1403f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer} 141f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes 142f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes// CHECK: @test18 143f195f2cacf149286232d66578fad3370efa5f567Nuno Lopesunsigned test18(int cond) { 144f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes int a[4], b[4]; 145f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes // CHECK: phi i32* 146f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes // CHECK: call i64 @llvm.objectsize.i64 147f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes return __builtin_object_size(cond ? a : b, 0); 148f195f2cacf149286232d66578fad3370efa5f567Nuno Lopes} 149