1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s 2 3namespace basic { 4// Ensuring that __bos can be used in constexpr functions without anything 5// sketchy going on... 6constexpr int bos0() { 7 int k = 5; 8 char cs[10] = {}; 9 return __builtin_object_size(&cs[k], 0); 10} 11 12constexpr int bos1() { 13 int k = 5; 14 char cs[10] = {}; 15 return __builtin_object_size(&cs[k], 1); 16} 17 18constexpr int bos2() { 19 int k = 5; 20 char cs[10] = {}; 21 return __builtin_object_size(&cs[k], 2); 22} 23 24constexpr int bos3() { 25 int k = 5; 26 char cs[10] = {}; 27 return __builtin_object_size(&cs[k], 3); 28} 29 30static_assert(bos0() == sizeof(char) * 5, ""); 31static_assert(bos1() == sizeof(char) * 5, ""); 32static_assert(bos2() == sizeof(char) * 5, ""); 33static_assert(bos3() == sizeof(char) * 5, ""); 34} 35 36namespace in_enable_if { 37// The code that prompted these changes was __bos in enable_if 38 39void 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... 46void 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 51struct LargeStruct { 52 int pad; 53 char buf[6]; 54 int pad2; 55}; 56 57struct SmallStruct { 58 int pad; 59 char buf[5]; 60 int pad2; 61}; 62 63void noWriteToBuf() { 64 char buf[6]; 65 copy5CharsInto(buf); 66 67 LargeStruct large; 68 copy5CharsIntoStrict(large.buf); 69} 70 71void initTheBuf() { 72 char buf[6] = {}; 73 copy5CharsInto(buf); 74 75 LargeStruct large = {0, {}, 0}; 76 copy5CharsIntoStrict(large.buf); 77} 78 79int getI(); 80void 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 92void 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