Home | History | Annotate | Download | only in SemaCXX
      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