Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / AST / Interp / builtin-functions.cpp
bloba78a0fbdf11b1d70dfb01250d47f6ea82d36862e
1 // RUN: %clang_cc1 -Wno-string-plus-int -fexperimental-new-constant-interpreter %s -verify
2 // RUN: %clang_cc1 -Wno-string-plus-int -fexperimental-new-constant-interpreter -triple i686 %s -verify
3 // RUN: %clang_cc1 -Wno-string-plus-int -verify=ref %s -Wno-constant-evaluated
4 // RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -fexperimental-new-constant-interpreter %s -verify
5 // RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -fexperimental-new-constant-interpreter -triple i686 %s -verify
6 // RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -verify=ref %s -Wno-constant-evaluated
7 // RUN: %clang_cc1 -triple avr -std=c++20 -Wno-string-plus-int -fexperimental-new-constant-interpreter %s -verify
8 // RUN: %clang_cc1 -triple avr -std=c++20 -Wno-string-plus-int -verify=ref %s -Wno-constant-evaluated
11 namespace strcmp {
12 constexpr char kFoobar[6] = {'f','o','o','b','a','r'};
13 constexpr char kFoobazfoobar[12] = {'f','o','o','b','a','z','f','o','o','b','a','r'};
15 static_assert(__builtin_strcmp("", "") == 0, "");
16 static_assert(__builtin_strcmp("abab", "abab") == 0, "");
17 static_assert(__builtin_strcmp("abab", "abba") == -1, "");
18 static_assert(__builtin_strcmp("abab", "abaa") == 1, "");
19 static_assert(__builtin_strcmp("ababa", "abab") == 1, "");
20 static_assert(__builtin_strcmp("abab", "ababa") == -1, "");
21 static_assert(__builtin_strcmp("a\203", "a") == 1, "");
22 static_assert(__builtin_strcmp("a\203", "a\003") == 1, "");
23 static_assert(__builtin_strcmp("abab\0banana", "abab") == 0, "");
24 static_assert(__builtin_strcmp("abab", "abab\0banana") == 0, "");
25 static_assert(__builtin_strcmp("abab\0banana", "abab\0canada") == 0, "");
26 static_assert(__builtin_strcmp(0, "abab") == 0, ""); // expected-error {{not an integral constant}} \
27 // expected-note {{dereferenced null}} \
28 // expected-note {{in call to}} \
29 // ref-error {{not an integral constant}} \
30 // ref-note {{dereferenced null}}
31 static_assert(__builtin_strcmp("abab", 0) == 0, ""); // expected-error {{not an integral constant}} \
32 // expected-note {{dereferenced null}} \
33 // expected-note {{in call to}} \
34 // ref-error {{not an integral constant}} \
35 // ref-note {{dereferenced null}}
37 static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar) == -1, "");
38 static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar + 6) == 0, ""); // expected-error {{not an integral constant}} \
39 // expected-note {{dereferenced one-past-the-end}} \
40 // expected-note {{in call to}} \
41 // ref-error {{not an integral constant}} \
42 // ref-note {{dereferenced one-past-the-end}}
45 /// Copied from constant-expression-cxx11.cpp
46 namespace strlen {
47 constexpr const char *a = "foo\0quux";
48 constexpr char b[] = "foo\0quux";
49 constexpr int f() { return 'u'; }
50 constexpr char c[] = { 'f', 'o', 'o', 0, 'q', f(), 'u', 'x', 0 };
52 static_assert(__builtin_strlen("foo") == 3, "");
53 static_assert(__builtin_strlen("foo\0quux") == 3, "");
54 static_assert(__builtin_strlen("foo\0quux" + 4) == 4, "");
56 constexpr bool check(const char *p) {
57 return __builtin_strlen(p) == 3 &&
58 __builtin_strlen(p + 1) == 2 &&
59 __builtin_strlen(p + 2) == 1 &&
60 __builtin_strlen(p + 3) == 0 &&
61 __builtin_strlen(p + 4) == 4 &&
62 __builtin_strlen(p + 5) == 3 &&
63 __builtin_strlen(p + 6) == 2 &&
64 __builtin_strlen(p + 7) == 1 &&
65 __builtin_strlen(p + 8) == 0;
68 static_assert(check(a), "");
69 static_assert(check(b), "");
70 static_assert(check(c), "");
72 constexpr int over1 = __builtin_strlen(a + 9); // expected-error {{constant expression}} \
73 // expected-note {{one-past-the-end}} \
74 // expected-note {{in call to}} \
75 // ref-error {{constant expression}} \
76 // ref-note {{one-past-the-end}}
77 constexpr int over2 = __builtin_strlen(b + 9); // expected-error {{constant expression}} \
78 // expected-note {{one-past-the-end}} \
79 // expected-note {{in call to}} \
80 // ref-error {{constant expression}} \
81 // ref-note {{one-past-the-end}}
82 constexpr int over3 = __builtin_strlen(c + 9); // expected-error {{constant expression}} \
83 // expected-note {{one-past-the-end}} \
84 // expected-note {{in call to}} \
85 // ref-error {{constant expression}} \
86 // ref-note {{one-past-the-end}}
88 constexpr int under1 = __builtin_strlen(a - 1); // expected-error {{constant expression}} \
89 // expected-note {{cannot refer to element -1}} \
90 // ref-error {{constant expression}} \
91 // ref-note {{cannot refer to element -1}}
92 constexpr int under2 = __builtin_strlen(b - 1); // expected-error {{constant expression}} \
93 // expected-note {{cannot refer to element -1}} \
94 // ref-error {{constant expression}} \
95 // ref-note {{cannot refer to element -1}}
96 constexpr int under3 = __builtin_strlen(c - 1); // expected-error {{constant expression}} \
97 // expected-note {{cannot refer to element -1}} \
98 // ref-error {{constant expression}} \
99 // ref-note {{cannot refer to element -1}}
101 constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
102 constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} \
103 // expected-note {{one-past-the-end}} \
104 // expected-note {{in call to}} \
105 // ref-error {{constant expression}} \
106 // ref-note {{one-past-the-end}}
109 namespace nan {
110 constexpr double NaN1 = __builtin_nan("");
112 /// The current interpreter does not accept this, but it should.
113 constexpr float NaN2 = __builtin_nans([](){return "0xAE98";}()); // ref-error {{must be initialized by a constant expression}}
114 #if __cplusplus < 201703L
115 // expected-error@-2 {{must be initialized by a constant expression}}
116 #endif
118 constexpr double NaN3 = __builtin_nan("foo"); // expected-error {{must be initialized by a constant expression}} \
119 // ref-error {{must be initialized by a constant expression}}
120 constexpr float NaN4 = __builtin_nanf("");
121 //constexpr long double NaN5 = __builtin_nanf128("");
123 /// FIXME: This should be accepted by the current interpreter as well.
124 constexpr char f[] = {'0', 'x', 'A', 'E', '\0'};
125 constexpr double NaN6 = __builtin_nan(f); // ref-error {{must be initialized by a constant expression}}
127 /// FIXME: Current interpreter misses diagnostics.
128 constexpr char f2[] = {'0', 'x', 'A', 'E'}; /// No trailing 0 byte.
129 constexpr double NaN7 = __builtin_nan(f2); // ref-error {{must be initialized by a constant expression}} \
130 // expected-error {{must be initialized by a constant expression}} \
131 // expected-note {{read of dereferenced one-past-the-end pointer}} \
132 // expected-note {{in call to}}
133 static_assert(!__builtin_issignaling(__builtin_nan("")), "");
134 static_assert(__builtin_issignaling(__builtin_nans("")), "");
137 namespace fmin {
138 constexpr float f1 = __builtin_fmin(1.0, 2.0f);
139 static_assert(f1 == 1.0f, "");
141 constexpr float min = __builtin_fmin(__builtin_nan(""), 1);
142 static_assert(min == 1, "");
143 constexpr float min2 = __builtin_fmin(1, __builtin_nan(""));
144 static_assert(min2 == 1, "");
145 constexpr float min3 = __builtin_fmin(__builtin_inf(), __builtin_nan(""));
146 static_assert(min3 == __builtin_inf(), "");
149 namespace inf {
150 static_assert(__builtin_isinf(__builtin_inf()), "");
151 static_assert(!__builtin_isinf(1.0), "");
153 static_assert(__builtin_isfinite(1.0), "");
154 static_assert(!__builtin_isfinite(__builtin_inf()), "");
156 static_assert(__builtin_isnormal(1.0), "");
157 static_assert(!__builtin_isnormal(__builtin_inf()), "");
159 #ifndef __AVR__
160 static_assert(__builtin_issubnormal(0x1p-1070), "");
161 #endif
162 static_assert(!__builtin_issubnormal(__builtin_inf()), "");
164 static_assert(__builtin_iszero(0.0), "");
165 static_assert(!__builtin_iszero(__builtin_inf()), "");
167 static_assert(__builtin_issignaling(__builtin_nans("")), "");
168 static_assert(!__builtin_issignaling(__builtin_inf()), "");
171 namespace isfpclass {
172 char isfpclass_inf_pos_0[__builtin_isfpclass(__builtin_inf(), 0x0200) ? 1 : -1]; // fcPosInf
173 char isfpclass_inf_pos_1[!__builtin_isfpclass(__builtin_inff(), 0x0004) ? 1 : -1]; // fcNegInf
174 char isfpclass_inf_pos_2[__builtin_isfpclass(__builtin_infl(), 0x0207) ? 1 : -1]; // fcSNan|fcQNan|fcNegInf|fcPosInf
175 char isfpclass_inf_pos_3[!__builtin_isfpclass(__builtin_inf(), 0x01F8) ? 1 : -1]; // fcFinite
176 char isfpclass_pos_0 [__builtin_isfpclass(1.0, 0x0100) ? 1 : -1]; // fcPosNormal
177 char isfpclass_pos_1 [!__builtin_isfpclass(1.0f, 0x0008) ? 1 : -1]; // fcNegNormal
178 char isfpclass_pos_2 [__builtin_isfpclass(1.0L, 0x01F8) ? 1 : -1]; // fcFinite
179 char isfpclass_pos_3 [!__builtin_isfpclass(1.0, 0x0003) ? 1 : -1]; // fcSNan|fcQNan
180 #ifndef __AVR__
181 char isfpclass_pdenorm_0[__builtin_isfpclass(1.0e-40f, 0x0080) ? 1 : -1]; // fcPosSubnormal
182 char isfpclass_pdenorm_1[__builtin_isfpclass(1.0e-310, 0x01F8) ? 1 : -1]; // fcFinite
183 char isfpclass_pdenorm_2[!__builtin_isfpclass(1.0e-40f, 0x003C) ? 1 : -1]; // fcNegative
184 char isfpclass_pdenorm_3[!__builtin_isfpclass(1.0e-310, 0x0207) ? 1 : -1]; // ~fcFinite
185 #endif
186 char isfpclass_pzero_0 [__builtin_isfpclass(0.0f, 0x0060) ? 1 : -1]; // fcZero
187 char isfpclass_pzero_1 [__builtin_isfpclass(0.0, 0x01F8) ? 1 : -1]; // fcFinite
188 char isfpclass_pzero_2 [!__builtin_isfpclass(0.0L, 0x0020) ? 1 : -1]; // fcNegZero
189 char isfpclass_pzero_3 [!__builtin_isfpclass(0.0, 0x0003) ? 1 : -1]; // fcNan
190 char isfpclass_nzero_0 [__builtin_isfpclass(-0.0f, 0x0060) ? 1 : -1]; // fcZero
191 char isfpclass_nzero_1 [__builtin_isfpclass(-0.0, 0x01F8) ? 1 : -1]; // fcFinite
192 char isfpclass_nzero_2 [!__builtin_isfpclass(-0.0L, 0x0040) ? 1 : -1]; // fcPosZero
193 char isfpclass_nzero_3 [!__builtin_isfpclass(-0.0, 0x0003) ? 1 : -1]; // fcNan
194 char isfpclass_ndenorm_0[__builtin_isfpclass(-1.0e-40f, 0x0010) ? 1 : -1]; // fcNegSubnormal
195 char isfpclass_ndenorm_2[!__builtin_isfpclass(-1.0e-40f, 0x03C0) ? 1 : -1]; // fcPositive
196 #ifndef __AVR__
197 char isfpclass_ndenorm_1[__builtin_isfpclass(-1.0e-310, 0x01F8) ? 1 : -1]; // fcFinite
198 char isfpclass_ndenorm_3[!__builtin_isfpclass(-1.0e-310, 0x0207) ? 1 : -1]; // ~fcFinite
199 #endif
200 char isfpclass_neg_0 [__builtin_isfpclass(-1.0, 0x0008) ? 1 : -1]; // fcNegNormal
201 char isfpclass_neg_1 [!__builtin_isfpclass(-1.0f, 0x00100) ? 1 : -1]; // fcPosNormal
202 char isfpclass_neg_2 [__builtin_isfpclass(-1.0L, 0x01F8) ? 1 : -1]; // fcFinite
203 char isfpclass_neg_3 [!__builtin_isfpclass(-1.0, 0x0003) ? 1 : -1]; // fcSNan|fcQNan
204 char isfpclass_inf_neg_0[__builtin_isfpclass(-__builtin_inf(), 0x0004) ? 1 : -1]; // fcNegInf
205 char isfpclass_inf_neg_1[!__builtin_isfpclass(-__builtin_inff(), 0x0200) ? 1 : -1]; // fcPosInf
206 char isfpclass_inf_neg_2[__builtin_isfpclass(-__builtin_infl(), 0x0207) ? 1 : -1]; // ~fcFinite
207 char isfpclass_inf_neg_3[!__builtin_isfpclass(-__builtin_inf(), 0x03C0) ? 1 : -1]; // fcPositive
208 char isfpclass_qnan_0 [__builtin_isfpclass(__builtin_nan(""), 0x0002) ? 1 : -1]; // fcQNan
209 char isfpclass_qnan_1 [!__builtin_isfpclass(__builtin_nanf(""), 0x0001) ? 1 : -1]; // fcSNan
210 char isfpclass_qnan_2 [__builtin_isfpclass(__builtin_nanl(""), 0x0207) ? 1 : -1]; // ~fcFinite
211 char isfpclass_qnan_3 [!__builtin_isfpclass(__builtin_nan(""), 0x01F8) ? 1 : -1]; // fcFinite
212 char isfpclass_snan_0 [__builtin_isfpclass(__builtin_nansf(""), 0x0001) ? 1 : -1]; // fcSNan
213 char isfpclass_snan_1 [!__builtin_isfpclass(__builtin_nans(""), 0x0002) ? 1 : -1]; // fcQNan
214 char isfpclass_snan_2 [__builtin_isfpclass(__builtin_nansl(""), 0x0207) ? 1 : -1]; // ~fcFinite
215 char isfpclass_snan_3 [!__builtin_isfpclass(__builtin_nans(""), 0x01F8) ? 1 : -1]; // fcFinite
218 namespace fpclassify {
219 char classify_nan [__builtin_fpclassify(+1, -1, -1, -1, -1, __builtin_nan(""))];
220 char classify_snan [__builtin_fpclassify(+1, -1, -1, -1, -1, __builtin_nans(""))];
221 char classify_inf [__builtin_fpclassify(-1, +1, -1, -1, -1, __builtin_inf())];
222 char classify_neg_inf [__builtin_fpclassify(-1, +1, -1, -1, -1, -__builtin_inf())];
223 char classify_normal [__builtin_fpclassify(-1, -1, +1, -1, -1, 1.539)];
224 #ifndef __AVR__
225 char classify_normal2 [__builtin_fpclassify(-1, -1, +1, -1, -1, 1e-307)];
226 char classify_denorm [__builtin_fpclassify(-1, -1, -1, +1, -1, 1e-308)];
227 char classify_denorm2 [__builtin_fpclassify(-1, -1, -1, +1, -1, -1e-308)];
228 #endif
229 char classify_zero [__builtin_fpclassify(-1, -1, -1, -1, +1, 0.0)];
230 char classify_neg_zero[__builtin_fpclassify(-1, -1, -1, -1, +1, -0.0)];
231 char classify_subnorm [__builtin_fpclassify(-1, -1, -1, +1, -1, 1.0e-38f)];
234 namespace fabs {
235 static_assert(__builtin_fabs(-14.0) == 14.0, "");
238 namespace std {
239 struct source_location {
240 struct __impl {
241 unsigned int _M_line;
242 const char *_M_file_name;
243 signed char _M_column;
244 const char *_M_function_name;
246 using BuiltinT = decltype(__builtin_source_location()); // OK.
250 namespace SourceLocation {
251 constexpr auto A = __builtin_source_location();
252 static_assert(A->_M_line == __LINE__ -1, "");
253 static_assert(A->_M_column == 22, "");
254 static_assert(__builtin_strcmp(A->_M_function_name, "") == 0, "");
255 static_assert(__builtin_strcmp(A->_M_file_name, __FILE__) == 0, "");
257 static_assert(__builtin_LINE() == __LINE__, "");
259 struct Foo {
260 int a = __builtin_LINE();
263 static_assert(Foo{}.a == __LINE__, "");
265 struct AA {
266 int n = __builtin_LINE();
268 struct B {
269 AA a = {};
271 constexpr void f() {
272 constexpr B c = {};
273 static_assert(c.a.n == __LINE__ - 1, "");
277 namespace popcount {
278 static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned int), "");
279 static_assert(__builtin_popcount(0) == 0, "");
280 static_assert(__builtin_popcountl(~0ul) == __CHAR_BIT__ * sizeof(unsigned long), "");
281 static_assert(__builtin_popcountl(0) == 0, "");
282 static_assert(__builtin_popcountll(~0ull) == __CHAR_BIT__ * sizeof(unsigned long long), "");
283 static_assert(__builtin_popcountll(0) == 0, "");
285 /// From test/Sema/constant-builtins-2.c
286 #define BITSIZE(x) (sizeof(x) * 8)
287 char popcount1[__builtin_popcount(0) == 0 ? 1 : -1];
288 char popcount2[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
289 char popcount3[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
290 char popcount4[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
291 char popcount5[__builtin_popcountl(0L) == 0 ? 1 : -1];
292 char popcount6[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
293 char popcount7[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
294 char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1];
295 char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
296 char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];