1 // RUN: %clang_cc1 -std=c23 %s --embed-dir=%S/Inputs -fsyntax-only -verify 2 3 const char data[] = { 4 #embed <jk.txt> 5 }; 6 const char offset_data[] = { 7 #embed <jk.txt> limit(1) 8 }; 9 static_assert(sizeof(data) == 2); 10 static_assert('j' == data[0]); 11 static_assert('k' == data[1]); 12 static_assert(sizeof(offset_data) == 1); 13 static_assert('j' == offset_data[0]); 14 static_assert(offset_data[0] == data[0]); 15 16 // Cannot have a negative limit. 17 #embed <jk.txt> limit(-1) 18 // expected-error@-1 {{invalid value '-1'; must be positive}} 19 20 // It can have a limit of 0, in which case the __has_embed should return false. 21 #if __has_embed(<jk.txt> limit(0)) != __STDC_EMBED_EMPTY__ 22 #error "__has_embed should return false when there's no data" 23 #endif 24 25 // When the limit is zero, the resource is empty, so if_empty kicks in. 26 const unsigned char buffer[] = { 27 #embed <jk.txt> limit(0) if_empty(1) 28 }; 29 static_assert(sizeof(buffer) == 1); 30 static_assert(buffer[0] == 1); 31 32 // However, prefix and suffix do not kick in. 33 const unsigned char other_buffer[] = { 34 1, 35 #embed <jk.txt> limit(0) prefix(2,) suffix(3) 36 }; 37 static_assert(sizeof(other_buffer) == 1); 38 static_assert(other_buffer[0] == 1); 39 40 // Ensure we can limit to something larger than the file size as well. 41 const unsigned char third_buffer[] = { 42 #embed <jk.txt> limit(100) 43 }; 44 static_assert(sizeof(third_buffer) == 2); 45 static_assert('j' == third_buffer[0]); 46 static_assert('k' == third_buffer[1]); 47 48 // Test the limits of a file with more than one character in it. 49 const unsigned char fourth_buffer[] = { 50 #embed <media/art.txt> limit(10) 51 }; 52 static_assert(sizeof(fourth_buffer) == 10); 53 static_assert(' ' == fourth_buffer[0]); 54 static_assert(' ' == fourth_buffer[1]); 55 static_assert(' ' == fourth_buffer[2]); 56 static_assert(' ' == fourth_buffer[3]); 57 static_assert(' ' == fourth_buffer[4]); 58 static_assert(' ' == fourth_buffer[5]); 59 static_assert(' ' == fourth_buffer[6]); 60 static_assert(' ' == fourth_buffer[7]); 61 static_assert(' ' == fourth_buffer[8]); 62 static_assert(' ' == fourth_buffer[9]); 63 64 // Ensure that a limit larger than what can fit into a 64-bit value is 65 // rejected. This limit is fine because it fits in a 64-bit value. 66 const unsigned char fifth_buffer[] = { 67 #embed <jk.txt> limit(0xFFFF'FFFF'FFFF'FFFF) 68 }; 69 static_assert(sizeof(fifth_buffer) == 2); 70 static_assert('j' == fifth_buffer[0]); 71 static_assert('k' == fifth_buffer[1]); 72 73 // But this one is not fine because it does not fit into a 64-bit value. 74 const unsigned char sixth_buffer[] = { 75 #embed <jk.txt> limit(0xFFFF'FFFF'FFFF'FFFF'1) 76 }; 77 // expected-error@-2 {{integer literal is too large to be represented in any integer type}} 78 // Note: the preprocessor will continue with the truncated value, so the parser 79 // will treat this case and the previous one identically in terms of what 80 // contents are retained from the embedded resource (which is the entire file). 81 82 // Ensure we diagnose duplicate parameters even if they're the same value. 83 const unsigned char a[] = { 84 #embed <jk.txt> limit(1) prefix() limit(1) 85 // expected-error@-1 {{cannot specify parameter 'limit' twice in the same '#embed' directive}} 86 , 87 #embed <jk.txt> limit(1) if_empty() limit(2) 88 // expected-error@-1 {{cannot specify parameter 'limit' twice in the same '#embed' directive}} 89 }; 90 91 // C23 6.10.3.2p2 92 static_assert( 93 #embed <jk.txt> limit(defined(FOO)) // expected-error {{'defined' cannot appear within this context}} 94 == 0); // expected-error {{expected expression}} 95