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