134 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx14 -std=c++14 %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2b %s4 5 6typedef __SIZE_TYPE__ size_t;7 8namespace basic {9// Ensuring that __bos can be used in constexpr functions without anything10// sketchy going on...11constexpr int bos0() {12 int k = 5;13 char cs[10] = {};14 return __builtin_object_size(&cs[k], 0);15}16 17constexpr int bos1() {18 int k = 5;19 char cs[10] = {};20 return __builtin_object_size(&cs[k], 1);21}22 23constexpr int bos2() {24 int k = 5;25 char cs[10] = {};26 return __builtin_object_size(&cs[k], 2);27}28 29constexpr int bos3() {30 int k = 5;31 char cs[10] = {};32 return __builtin_object_size(&cs[k], 3);33}34 35static_assert(bos0() == sizeof(char) * 5, "");36static_assert(bos1() == sizeof(char) * 5, "");37static_assert(bos2() == sizeof(char) * 5, "");38static_assert(bos3() == sizeof(char) * 5, "");39}40 41namespace in_enable_if {42// The code that prompted these changes was __bos in enable_if43 44void copy5CharsInto(char *buf) // expected-note{{candidate}}45 __attribute__((enable_if(__builtin_object_size(buf, 0) != -1 &&46 __builtin_object_size(buf, 0) > 5,47 "")));48 49// We use different EvalModes for __bos with type 0 versus 1. Ensure 1 works,50// too...51void copy5CharsIntoStrict(char *buf) // expected-note{{candidate}}52 __attribute__((enable_if(__builtin_object_size(buf, 1) != -1 &&53 __builtin_object_size(buf, 1) > 5,54 "")));55 56struct LargeStruct {57 int pad;58 char buf[6];59 int pad2;60};61 62struct SmallStruct {63 int pad;64 char buf[5];65 int pad2;66};67 68void noWriteToBuf() {69 char buf[6];70 copy5CharsInto(buf);71 72 LargeStruct large;73 copy5CharsIntoStrict(large.buf);74}75 76void initTheBuf() {77 char buf[6] = {};78 copy5CharsInto(buf);79 80 LargeStruct large = {0, {}, 0};81 copy5CharsIntoStrict(large.buf);82}83 84int getI();85void initTheBufWithALoop() {86 char buf[6] = {};87 for (unsigned I = getI(); I != sizeof(buf); ++I)88 buf[I] = I;89 copy5CharsInto(buf);90 91 LargeStruct large;92 for (unsigned I = getI(); I != sizeof(buf); ++I)93 large.buf[I] = I;94 copy5CharsIntoStrict(large.buf);95}96 97void tooSmallBuf() {98 char buf[5];99 copy5CharsInto(buf); // expected-error{{no matching function for call}}100 101 SmallStruct small;102 copy5CharsIntoStrict(small.buf); // expected-error{{no matching function for call}}103}104}105 106namespace InvalidBase {107 // Ensure this doesn't crash.108 struct S { const char *name; };109 S invalid_base();110 constexpr size_t bos_name = __builtin_object_size(invalid_base().name, 1);111 static_assert(bos_name == -1, "");112 113 struct T { ~T(); };114 T invalid_base_2();115 constexpr size_t bos_dtor = __builtin_object_size(&(T&)(T&&)invalid_base_2(), 0);116 static_assert(bos_dtor == -1, "");117}118 119// PR44268120constexpr int bos_new() { // cxx14-error {{constant expression}}121 void *p = new int; // cxx14-note {{until C++20}}122 return __builtin_object_size(p, 0);123}124 125 126namespace GH129397 {127 128struct incomplete;129void test(incomplete &ref) {130 __builtin_object_size(&ref, 1);131}132 133}134