179 lines · cpp
1// RUN: rm -rf %t && mkdir -p %t/media2// RUN: cp %S/Inputs/single_byte.txt %S/Inputs/jk.txt %S/Inputs/numbers.txt %t/3// RUN: cp %S/Inputs/media/empty %t/media/4// RUN: printf "\0" > %t/null_byte.bin5// RUN: %clang_cc1 %s -fsyntax-only --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions6// RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only --embed-dir=%t -verify=expected,c7// RUN: %clang_cc1 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,cxx -Wno-c23-extensions8// RUN: %clang_cc1 -x c -std=c23 %s -fsyntax-only -fexperimental-new-constant-interpreter --embed-dir=%t -verify=expected,c9#embed <media/empty>10;11 12void f (unsigned char x) { (void)x;}13void g () {}14void h (unsigned char x, int y) {(void)x; (void)y;}15int i () {16 return17#embed <single_byte.txt>18 ;19}20 21_Static_assert(22#embed <single_byte.txt> suffix(,)23""24);25_Static_assert(26#embed <single_byte.txt>27, ""28);29_Static_assert(sizeof(30#embed <single_byte.txt>31) ==32sizeof(int)33, ""34);35_Static_assert(sizeof36#embed <single_byte.txt>37, ""38);39_Static_assert(sizeof(40#embed <jk.txt>41) ==42sizeof(int)43, ""44);45 46#ifdef __cplusplus47template <int First, int Second>48void j() {49 static_assert(First == 'j', "");50 static_assert(Second == 'k', "");51}52#endif53 54void do_stuff() {55 f(56#embed <single_byte.txt>57 );58 g(59#embed <media/empty>60 );61 h(62#embed <jk.txt>63 );64 int r = i();65 (void)r;66#ifdef __cplusplus67 j<68#embed <jk.txt>69 >(70#embed <media/empty>71 );72#endif73}74 75// Ensure that we don't accidentally allow you to initialize an unsigned char *76// from embedded data; the data is modeled as a string literal internally, but77// is not actually a string literal.78const unsigned char *ptr = (79#embed <jk.txt> // expected-warning {{left operand of comma operator has no effect}}80 ); // c-error@-2 {{incompatible integer to pointer conversion initializing 'const unsigned char *' with an expression of type 'int'}} \81 cxx-error@-2 {{cannot initialize a variable of type 'const unsigned char *' with an rvalue of type 'int'}}82 83// However, there are some cases where this is fine and should work.84const unsigned char *null_ptr_1 =85#embed <media/empty> if_empty(0)86;87 88const unsigned char *null_ptr_2 =89#embed <null_byte.bin>90;91 92const unsigned char *null_ptr_3 = {93#embed <null_byte.bin>94};95 96#define FILE_NAME <null_byte.bin>97#define LIMIT 198#define OFFSET 099#define EMPTY_SUFFIX suffix()100 101constexpr unsigned char ch =102#embed FILE_NAME limit(LIMIT) clang::offset(OFFSET) EMPTY_SUFFIX103;104static_assert(ch == 0);105 106void foobar(float x, char y, char z);107void g1() { foobar((float)108#embed "numbers.txt" limit(3)109);110}111 112#if __cplusplus113struct S { S(char x); ~S(); };114void f1() {115 S s[] = {116#embed "null_byte.bin"117 };118}119#endif120 121static_assert(_Generic(122#embed __FILE__ limit(1)123 , int : 1, default : 0));124 125static_assert(alignof(typeof(126#embed __FILE__ limit(1)127)) == alignof(int));128 129struct HasChar {130 signed char ch;131};132 133constexpr struct HasChar c = {134#embed "Inputs/big_char.txt" // cxx-error {{constant expression evaluates to 255 which cannot be narrowed to type 'signed char'}} \135 cxx-note {{insert an explicit cast to silence this issue}} \136 c-error {{constexpr initializer evaluates to 255 which is not exactly representable in type 'signed char'}}137 138};139 140#if __cplusplus141namespace std {142typedef decltype(sizeof(int)) size_t;143 144template <class _E> class initializer_list {145 const _E *__begin_;146 size_t __size_;147 148 constexpr initializer_list(const _E *__b, size_t __s)149 : __begin_(__b), __size_(__s) {}150 151public:152 constexpr initializer_list() : __begin_(nullptr), __size_(0) {}153};154} // namespace std155 156class S2 {157public:158 constexpr S2(std::initializer_list<char>) { // cxx-error {{constexpr constructor never produces a constant expression}}159 1/0; // cxx-warning {{division by zero is undefined}}160 // cxx-warning@-1 {{unused}}161 // cxx-note@-2 4{{division by zero}}162 }163};164 165 166constexpr S2 s2 { // cxx-error {{must be initialized by a constant expression}}167 // cxx-note-re@-1 {{in call to 'S2{{.*}} #embed <jk.txt>}}168#embed <jk.txt> prefix(0x2c, 0x20, )limit(5)169};170constexpr S2 s3 {1, // cxx-error {{must be initialized by a constant expression}}171 // cxx-note-re@-1 {{in call to 'S2{{.*}} #embed "jk.txt"}}172#embed "jk.txt"173};174constexpr S2 s4 { // cxx-error {{must be initialized by a constant expression}}175 // cxx-note-re@-1 {{in call to 'S2{{.*}}"jk"}}176#embed "jk.txt"177};178#endif179