1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s 2 3 namespace basic { 4 // Ensuring that __bos can be used in constexpr functions without anything 5 // sketchy going on... 6 constexpr int bos0() { 7 int k = 5; 8 char cs[10] = {}; 9 return __builtin_object_size(&cs[k], 0); 10 } 11 12 constexpr int bos1() { 13 int k = 5; 14 char cs[10] = {}; 15 return __builtin_object_size(&cs[k], 1); 16 } 17 18 constexpr int bos2() { 19 int k = 5; 20 char cs[10] = {}; 21 return __builtin_object_size(&cs[k], 2); 22 } 23 24 constexpr int bos3() { 25 int k = 5; 26 char cs[10] = {}; 27 return __builtin_object_size(&cs[k], 3); 28 } 29 30 static_assert(bos0() == sizeof(char) * 5, ""); 31 static_assert(bos1() == sizeof(char) * 5, ""); 32 static_assert(bos2() == sizeof(char) * 5, ""); 33 static_assert(bos3() == sizeof(char) * 5, ""); 34 } 35 36 namespace in_enable_if { 37 // The code that prompted these changes was __bos in enable_if 38 39 void copy5CharsInto(char *buf) // expected-note{{candidate}} 40 __attribute__((enable_if(__builtin_object_size(buf, 0) != -1 && 41 __builtin_object_size(buf, 0) > 5, 42 ""))); 43 44 // We use different EvalModes for __bos with type 0 versus 1. Ensure 1 works, 45 // too... 46 void copy5CharsIntoStrict(char *buf) // expected-note{{candidate}} 47 __attribute__((enable_if(__builtin_object_size(buf, 1) != -1 && 48 __builtin_object_size(buf, 1) > 5, 49 ""))); 50 51 struct LargeStruct { 52 int pad; 53 char buf[6]; 54 int pad2; 55 }; 56 57 struct SmallStruct { 58 int pad; 59 char buf[5]; 60 int pad2; 61 }; 62 63 void noWriteToBuf() { 64 char buf[6]; 65 copy5CharsInto(buf); 66 67 LargeStruct large; 68 copy5CharsIntoStrict(large.buf); 69 } 70 71 void initTheBuf() { 72 char buf[6] = {}; 73 copy5CharsInto(buf); 74 75 LargeStruct large = {0, {}, 0}; 76 copy5CharsIntoStrict(large.buf); 77 } 78 79 int getI(); 80 void initTheBufWithALoop() { 81 char buf[6] = {}; 82 for (unsigned I = getI(); I != sizeof(buf); ++I) 83 buf[I] = I; 84 copy5CharsInto(buf); 85 86 LargeStruct large; 87 for (unsigned I = getI(); I != sizeof(buf); ++I) 88 large.buf[I] = I; 89 copy5CharsIntoStrict(large.buf); 90 } 91 92 void tooSmallBuf() { 93 char buf[5]; 94 copy5CharsInto(buf); // expected-error{{no matching function for call}} 95 96 SmallStruct small; 97 copy5CharsIntoStrict(small.buf); // expected-error{{no matching function for call}} 98 } 99 } 100