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...
bos0()6 constexpr int bos0() {
7 int k = 5;
8 char cs[10] = {};
9 return __builtin_object_size(&cs[k], 0);
10 }
11
bos1()12 constexpr int bos1() {
13 int k = 5;
14 char cs[10] = {};
15 return __builtin_object_size(&cs[k], 1);
16 }
17
bos2()18 constexpr int bos2() {
19 int k = 5;
20 char cs[10] = {};
21 return __builtin_object_size(&cs[k], 2);
22 }
23
bos3()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
noWriteToBuf()63 void noWriteToBuf() {
64 char buf[6];
65 copy5CharsInto(buf);
66
67 LargeStruct large;
68 copy5CharsIntoStrict(large.buf);
69 }
70
initTheBuf()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();
initTheBufWithALoop()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
tooSmallBuf()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