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