13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s 27b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer 37b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer#define strcpy(dest, src) \ 47b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer ((__builtin_object_size(dest, 0) != -1ULL) \ 57b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \ 67b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer : __inline_strcpy_chk(dest, src)) 77b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer 87b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramerstatic char *__inline_strcpy_chk (char *dest, const char *src) { 97b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1)); 107b83de5e2b28533be349f48552b665a2ea95ddecBenjamin Kramer} 11d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump 12d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stumpchar gbuf[63]; 13d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stumpchar *gp; 14dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stumpint gi, gj; 15d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump 1631bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test1 17d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stumpvoid test1() { 18954589735392ac96da5ac2af7f1e72f1b80cf187Mike 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) 19d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump strcpy(&gbuf[4], "Hi there"); 20d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump} 21d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump 2231bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test2 23d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stumpvoid test2() { 24954589735392ac96da5ac2af7f1e72f1b80cf187Mike 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) 25d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump strcpy(gbuf, "Hi there"); 26d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump} 27d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump 2831bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test3 294e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stumpvoid test3() { 30954589735392ac96da5ac2af7f1e72f1b80cf187Mike 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) 314e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump strcpy(&gbuf[100], "Hi there"); 324e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump} 334e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump 3431bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test4 35d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stumpvoid test4() { 36954589735392ac96da5ac2af7f1e72f1b80cf187Mike 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) 374e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump strcpy((char*)(void*)&gbuf[-1], "Hi there"); 384e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump} 394e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump 4031bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test5 414e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stumpvoid test5() { 42954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = load i8** @gp 43954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false) 444e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stump strcpy(gp, "Hi there"); 45d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump} 46d3be5cda6ab48629d28ae9f0609f526dff16eb87Mike Stump 4731bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test6 484e930c282a06a088e84e6b34c5bb721ed8fd52c7Mike Stumpvoid test6() { 4907677bbc5b3ebd35868bc3a2a6fd4597373485e0Mike Stump char buf[57]; 5007677bbc5b3ebd35868bc3a2a6fd4597373485e0Mike Stump 51954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) 5207677bbc5b3ebd35868bc3a2a6fd4597373485e0Mike Stump strcpy(&buf[4], "Hi there"); 5307677bbc5b3ebd35868bc3a2a6fd4597373485e0Mike Stump} 54dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump 5531bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test7 56dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stumpvoid test7() { 57dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump int i; 587592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 59954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // 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)) 60dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump strcpy((++i, gbuf), "Hi there"); 61dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump} 62dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump 6331bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test8 64dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stumpvoid test8() { 65dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump char *buf[50]; 667592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 67954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 68dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump strcpy(buf[++gi], "Hi there"); 69dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump} 70dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump 7131bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test9 72dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stumpvoid test9() { 737592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 74954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 75dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump strcpy((char *)((++gi) + gj), "Hi there"); 76dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump} 77dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump 7831bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test10 79dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stumpchar **p; 80dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stumpvoid test10() { 817592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 82954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 83dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump strcpy(*(++p), "Hi there"); 84dcead8e2ce0078f75eda5be5774865a7f4ac0223Mike Stump} 85bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump 8631bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test11 87bab3457bcb5fe58a093026002769c9cd68a157ecMike Stumpvoid test11() { 887592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 8931bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel 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)) 90bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump strcpy(gp = gbuf, "Hi there"); 91bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump} 92bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump 9331bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test12 94bab3457bcb5fe58a093026002769c9cd68a157ecMike Stumpvoid test12() { 957592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 96954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 97bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump strcpy(++gp, "Hi there"); 98bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump} 99bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump 10031bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test13 101bab3457bcb5fe58a093026002769c9cd68a157ecMike Stumpvoid test13() { 1027592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 103954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 104bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump strcpy(gp++, "Hi there"); 105bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump} 106bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump 10731bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test14 108bab3457bcb5fe58a093026002769c9cd68a157ecMike Stumpvoid test14() { 1097592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 110954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 111bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump strcpy(--gp, "Hi there"); 112bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump} 113bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump 11431bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test15 115bab3457bcb5fe58a093026002769c9cd68a157ecMike Stumpvoid test15() { 1167592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 117954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 118bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump strcpy(gp--, "Hi there"); 119bab3457bcb5fe58a093026002769c9cd68a157ecMike Stump} 120abe84d3316a002df684a595d9bfa54e9bc3e64fbMike Stump 12131bb25d9d5be2d3a68858ce8094cb7e9131bc24cDaniel Dunbar// CHECK: define void @test16 122abe84d3316a002df684a595d9bfa54e9bc3e64fbMike Stumpvoid test16() { 1237592f30a01a7f53b2dc509eff2bdfd221c16d822Mike Stump // CHECK-NOT: __strcpy_chk 124954589735392ac96da5ac2af7f1e72f1b80cf187Mike Stump // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) 125abe84d3316a002df684a595d9bfa54e9bc3e64fbMike Stump strcpy(gp += 1, "Hi there"); 126abe84d3316a002df684a595d9bfa54e9bc3e64fbMike Stump} 12781bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer 12881bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramervoid test17() { 12981bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer // CHECK: store i32 -1 13081bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer gi = __builtin_object_size(gp++, 0); 13181bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer // CHECK: store i32 -1 13281bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer gi = __builtin_object_size(gp++, 1); 13381bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer // CHECK: store i32 0 13481bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer gi = __builtin_object_size(gp++, 2); 13581bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer // CHECK: store i32 0 13681bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer gi = __builtin_object_size(gp++, 3); 13781bcc4ac937f901e9e94754122350ee673dce573Benjamin Kramer} 138