macos: Fix asm-c-connect-test
[tinycc.git] / tests / tcctest.c
blob73a90ca79ce56e1cccf29de835e6816361898370
1 /*
2 * TCC auto test program
3 */
4 #include "config.h"
6 /* Unfortunately, gcc version < 3 does not handle that! */
7 #define ALL_ISOC99
9 /* only gcc 3 handles _Bool correctly */
10 #define BOOL_ISOC99
12 /* gcc 2.95.3 does not handle correctly CR in strings or after strays */
13 #define CORRECT_CR_HANDLING
15 /* __VA_ARGS__ and __func__ support */
16 #define C99_MACROS
18 /* deprecated and no longer supported in gcc 3.3 */
19 //#define ACCEPT_CR_IN_STRINGS
21 #ifndef __TINYC__
22 typedef __SIZE_TYPE__ uintptr_t;
23 #endif
25 #if defined(_WIN32)
26 #define LONG_LONG_FORMAT "%lld"
27 #define ULONG_LONG_FORMAT "%llu"
28 #else
29 #define LONG_LONG_FORMAT "%Ld"
30 #define ULONG_LONG_FORMAT "%Lu"
31 #endif
33 // MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
34 #if defined(_WIN32) && defined(__GNUC__)
35 #define LONG_DOUBLE double
36 #define LONG_DOUBLE_LITERAL(x) x
37 #else
38 #define LONG_DOUBLE long double
39 #define LONG_DOUBLE_LITERAL(x) x ## L
40 #endif
42 /* test various include syntaxes */
44 #define TCCLIB_INC <tcclib.h>
45 #define TCCLIB_INC1 <tcclib
46 #define TCCLIB_INC2 h>
47 #define TCCLIB_INC3 "tcclib.h"
49 #include TCCLIB_INC
51 #include TCCLIB_INC1.TCCLIB_INC2
53 #include TCCLIB_INC1.h>
55 #include TCCLIB_INC3
57 #include <tcclib.h>
59 #include "tcclib.h"
61 #include "tcctest.h"
63 /* Test two more ways to include a file named like a pp-number */
64 #define INC(name) <tests/name.h>
65 #define funnyname 42test.h
66 #define incdir tests/
67 #ifdef __clang__
68 /* clang's preprocessor is broken in this regard and adds spaces
69 to the tokens 'incdir' and 'funnyname' when expanding */
70 #define incname <tests/42test.h>
71 #else
72 #define incname < incdir funnyname >
73 #endif
74 #define __stringify(x) #x
75 #define stringify(x) __stringify(x)
76 #include INC(42test)
77 #include incname
78 #include stringify(funnyname)
80 void intdiv_test();
81 void string_test();
82 void expr_test();
83 void macro_test();
84 void recursive_macro_test();
85 void scope_test();
86 void scope_test2();
87 void forward_test();
88 void funcptr_test();
89 void if_test();
90 void loop_test();
91 void switch_test();
92 void goto_test();
93 void enum_test();
94 void typedef_test();
95 void struct_test();
96 void array_test();
97 void expr_ptr_test();
98 void bool_test();
99 void optimize_out();
100 void expr2_test();
101 void constant_expr_test();
102 void expr_cmp_test();
103 void char_short_test();
104 void init_test(void);
105 void compound_literal_test(void);
106 int kr_test();
107 void struct_assign_test(void);
108 void cast_test(void);
109 void bitfield_test(void);
110 void c99_bool_test(void);
111 void float_test(void);
112 void longlong_test(void);
113 void manyarg_test(void);
114 void stdarg_test(void);
115 void whitespace_test(void);
116 void relocation_test(void);
117 void old_style_function(void);
118 void alloca_test(void);
119 void c99_vla_test(int size1, int size2);
120 void sizeof_test(void);
121 void typeof_test(void);
122 void local_label_test(void);
123 void statement_expr_test(void);
124 void asm_test(void);
125 void builtin_test(void);
126 void weak_test(void);
127 void global_data_test(void);
128 void cmp_comparison_test(void);
129 void math_cmp_test(void);
130 void callsave_test(void);
131 void builtin_frame_address_test(void);
132 void attrib_test(void);
133 void bounds_check1_test(void);
135 int fib(int n);
136 void num(int n);
137 void forward_ref(void);
138 int isid(int c);
140 /* Line joining happens before tokenization, so the following
141 must be parsed as ellipsis. */
142 void funny_line_continuation (int, ..\
143 . );
145 char via_volatile (char);
147 #define A 2
148 #define N 1234 + A
149 #define pf printf
150 #define M1(a, b) (a) + (b)
152 #define str\
153 (s) # s
154 #define glue(a, b) a ## b
155 #define xglue(a, b) glue(a, b)
156 #define HIGHLOW "hello"
157 #define LOW LOW ", world"
159 static int onetwothree = 123;
160 #define onetwothree4 onetwothree
161 #define onetwothree xglue(onetwothree,4)
163 #define min(a, b) ((a) < (b) ? (a) : (b))
165 #ifdef C99_MACROS
166 #define dprintf(level,...) printf(__VA_ARGS__)
167 #endif
169 /* gcc vararg macros */
170 #define dprintf1(level, fmt, args...) printf(fmt, ## args)
172 #define MACRO_NOARGS()
174 #define AAA 3
175 #undef AAA
176 #define AAA 4
178 #if 1
179 #define B3 1
180 #elif 1
181 #define B3 2
182 #elif 0
183 #define B3 3
184 #else
185 #define B3 4
186 #endif
188 #ifdef __TINYC__
189 /* We try to handle this syntax. Make at least sure it doesn't segfault. */
190 char invalid_function_def()[] {return 0;}
191 #endif
193 #define __INT64_C(c) c ## LL
194 #define INT64_MIN (-__INT64_C(9223372036854775807)-1)
196 int qq(int x)
198 return x + 40;
200 #define qq(x) x
202 #define spin_lock(lock) do { } while (0)
203 #define wq_spin_lock spin_lock
204 #define TEST2() wq_spin_lock(a)
206 #define UINT_MAX ((unsigned) -1)
208 void intdiv_test(void)
210 printf("18/21=%u\n", 18/21);
211 printf("18%%21=%u\n", 18%21);
212 printf("41/21=%u\n", 41/21);
213 printf("41%%21=%u\n", 41%21);
214 printf("42/21=%u\n", 42/21);
215 printf("42%%21=%u\n", 42%21);
216 printf("43/21=%u\n", 43/21);
217 printf("43%%21=%u\n", 43%21);
218 printf("126/21=%u\n", 126/21);
219 printf("126%%21=%u\n", 126%21);
220 printf("131/21=%u\n", 131/21);
221 printf("131%%21=%u\n", 131%21);
222 printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
223 printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
225 printf("18/-21=%u\n", 18/-21);
226 printf("18%%-21=%u\n", 18%-21);
227 printf("41/-21=%u\n", 41/-21);
228 printf("41%%-21=%u\n", 41%-21);
229 printf("42/-21=%u\n", 42/-21);
230 printf("42%%-21=%u\n", 42%-21);
231 printf("43/-21=%u\n", 43/-21);
232 printf("43%%-21=%u\n", 43%-21);
233 printf("126/-21=%u\n", 126/-21);
234 printf("126%%-21=%u\n", 126%-21);
235 printf("131/-21=%u\n", 131/-21);
236 printf("131%%-21=%u\n", 131%-21);
237 printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
238 printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
240 printf("-18/21=%u\n", -18/21);
241 printf("-18%%21=%u\n", -18%21);
242 printf("-41/21=%u\n", -41/21);
243 printf("-41%%21=%u\n", -41%21);
244 printf("-42/21=%u\n", -42/21);
245 printf("-42%%21=%u\n", -42%21);
246 printf("-43/21=%u\n", -43/21);
247 printf("-43%%21=%u\n", -43%21);
248 printf("-126/21=%u\n", -126/21);
249 printf("-126%%21=%u\n", -126%21);
250 printf("-131/21=%u\n", -131/21);
251 printf("-131%%21=%u\n", -131%21);
252 printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
253 printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
255 printf("-18/-21=%u\n", -18/-21);
256 printf("-18%%-21=%u\n", -18%-21);
257 printf("-41/-21=%u\n", -41/-21);
258 printf("-41%%-21=%u\n", -41%-21);
259 printf("-42/-21=%u\n", -42/-21);
260 printf("-42%%-21=%u\n", -42%-21);
261 printf("-43/-21=%u\n", -43/-21);
262 printf("-43%%-21=%u\n", -43%-21);
263 printf("-126/-21=%u\n", -126/-21);
264 printf("-126%%-21=%u\n", -126%-21);
265 printf("-131/-21=%u\n", -131/-21);
266 printf("-131%%-21=%u\n", -131%-21);
267 printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
268 printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
271 void macro_test(void)
273 printf("macro:\n");\f\v
274 pf("N=%d\n", N);
275 printf("aaa=%d\n", AAA);
277 printf("min=%d\n", min(1, min(2, -1)));
279 printf("s1=%s\n", glue(HIGH, LOW));
280 printf("s2=%s\n", xglue(HIGH, LOW));
281 printf("s3=%s\n", str("c"));
282 printf("s4=%s\n", str(a1));
283 printf("B3=%d\n", B3);
285 printf("onetwothree=%d\n", onetwothree);
287 #ifdef A
288 printf("A defined\n");
289 #endif
290 #ifdef B
291 printf("B defined\n");
292 #endif
293 #ifdef A
294 printf("A defined\n");
295 #else
296 printf("A not defined\n");
297 #endif
298 #ifdef B
299 printf("B defined\n");
300 #else
301 printf("B not defined\n");
302 #endif
304 #ifdef A
305 printf("A defined\n");
306 #ifdef B
307 printf("B1 defined\n");
308 #else
309 printf("B1 not defined\n");
310 #endif
311 #else
312 printf("A not defined\n");
313 #ifdef B
314 printf("B2 defined\n");
315 #else
316 printf("B2 not defined\n");
317 #endif
318 #endif
320 #if 1+1
321 printf("test true1\n");
322 #endif
323 #if 0
324 printf("test true2\n");
325 #endif
326 #if 1-1
327 printf("test true3\n");
328 #endif
329 #if defined(A)
330 printf("test trueA\n");
331 #endif
332 #if defined(B)
333 printf("test trueB\n");
334 #endif
336 #if 0
337 printf("test 0\n");
338 #elif 0
339 printf("test 1\n");
340 #elif 2
341 printf("test 2\n");
342 #else
343 printf("test 3\n");
344 #endif
346 MACRO_NOARGS();
348 #ifdef __LINE__
349 printf("__LINE__ defined\n");
350 #endif
352 printf("__LINE__=%d __FILE__=%s\n",
353 __LINE__, __FILE__);
354 #if 0
355 #line 200
356 printf("__LINE__=%d __FILE__=%s\n",
357 __LINE__, __FILE__);
358 #line 203 "test"
359 printf("__LINE__=%d __FILE__=%s\n",
360 __LINE__, __FILE__);
361 #line 227 "tcctest.c"
362 #endif
364 /* not strictly preprocessor, but we test it there */
365 #ifdef C99_MACROS
366 printf("__func__ = %s\n", __func__);
367 dprintf(1, "vaarg=%d\n", 1);
368 #endif
369 dprintf1(1, "vaarg1\n");
370 dprintf1(1, "vaarg1=%d\n", 2);
371 dprintf1(1, "vaarg1=%d %d\n", 1, 2);
373 /* gcc extension */
374 printf("func='%s'\n", __FUNCTION__);
376 /* complicated macros in glibc */
377 printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
379 int a;
380 a = 1;
381 glue(a+, +);
382 printf("a=%d\n", a);
383 glue(a <, <= 2);
384 printf("a=%d\n", a);
387 /* macro function with argument outside the macro string */
388 #define MF_s MF_hello
389 #define MF_hello(msg) printf("%s\n",msg)
391 #define MF_t printf("tralala\n"); MF_hello
393 MF_s("hi");
394 MF_t("hi");
396 /* test macro substitution inside args (should not eat stream) */
397 printf("qq=%d\n", qq(qq)(2));
399 /* test zero argument case. NOTE: gcc 2.95.x does not accept a
400 null argument without a space. gcc 3.2 fixes that. */
402 #define qq1(x) 1
403 printf("qq1=%d\n", qq1( ));
405 /* comment with stray handling *\
407 /* this is a valid *\/ comment */
408 /* this is a valid comment *\*/
409 // this is a valid\
410 comment
412 /* test function macro substitution when the function name is
413 substituted */
414 TEST2();
416 /* And again when the name and parentheses are separated by a
417 comment. */
418 TEST2 /* the comment */ ();
420 printf("basefromheader %s\n", get_basefile_from_header());
421 printf("base %s\n", __BASE_FILE__);
423 /* Some compilers (clang) prepend './' to __FILE__ from included
424 files. */
425 const char *fn = get_file_from_header();
426 if (fn[0] == '.' && fn[1] == '/')
427 fn += 2;
428 printf("filefromheader %s\n", fn);
430 printf("file %s\n", __FILE__);
432 /* Check that funnily named include was in fact included */
433 have_included_42test_h = 1;
434 have_included_42test_h_second = 1;
435 have_included_42test_h_third = 1;
437 /* Check that we don't complain about stray \ here */
438 printf("print a backslash: %s\n", stringify(\\));
442 static void print_num(char *fn, int line, int num) {
443 printf("fn %s, line %d, num %d\n", fn, line, num);
446 void recursive_macro_test(void)
449 #define ELF32_ST_TYPE(val) ((val) & 0xf)
450 #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
451 #define STB_WEAK 2 /* Weak symbol */
452 #define ELFW(type) ELF##32##_##type
453 printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
455 #define WRAP(x) x
457 #define print_num(x) print_num(__FILE__,__LINE__,x)
458 print_num(123);
459 WRAP(print_num(123));
460 WRAP(WRAP(print_num(123)));
462 static struct recursive_macro { int rm_field; } G;
463 #define rm_field (G.rm_field)
464 printf("rm_field = %d\n", rm_field);
465 printf("rm_field = %d\n", WRAP(rm_field));
466 WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field))));
469 int op(a,b)
471 return a / b;
474 int ret(a)
476 if (a == 2)
477 return 1;
478 if (a == 3)
479 return 2;
480 return 0;
483 char str_ag1[] = "b";
484 char str_ag2[] = { "b" };
485 /*char str_bg1[] = ("cccc"); GCC accepts this with pedantic warning, TCC not */
486 char str_ag3[] = { "ab"[1], 0 };
487 char str_ag4[2] = { "b" };
488 char str_x[2] = { "xy" "z"[2], 0 };
489 char *str_ar[] = { "one", "two" };
490 struct str_SS {unsigned char a[3], b; };
491 struct str_SS str_sinit15 = { "r" };
492 struct str_SS str_sinit16[] = { { "q" }, 2 };
494 static void string_test2()
496 char *p = "hello";
497 char a3[2] = { "p" };
498 char a4[2] = { "ab" "c"[2], 0 };
499 char *pa1 = "def" + 1;
500 char *pa2 = { "xyz" + 1 };
501 int i = 0;
502 struct str_SS ss = { { [0 ... 1] = 'a' }, 0 };
503 puts("string_test2");
504 puts(str_ag1);
505 puts(str_ag2);
506 /*puts(str_bg1);*/
507 puts(str_ag3);
508 puts(str_ag4);
509 puts(str_x);
510 puts(str_sinit15.a);
511 puts(str_sinit16[0].a);
512 puts(a3);
513 puts(a4);
514 puts(p);
515 puts("world");
516 printf("%s\n", "bla");
517 puts(str_ar[0]);
518 puts(str_ar[1]);
519 puts(ss.a);
520 puts(i >= 0 ? "one" : "two");
521 puts(pa1);
522 puts(pa2);
525 void ps(const char *s)
527 int c;
528 while (1) {
529 c = *s;
530 if (c == 0)
531 break;
532 printf("%c", c);
533 s++;
537 const char foo1_string[] = "\
538 bar\n\
539 test\14\
542 void string_test()
544 unsigned int b;
545 printf("string:\n");
546 printf("\141\1423\143\n");/* dezdez test */
547 printf("\x41\x42\x43\x3a\n");
548 printf("c=%c\n", 'r');
549 printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c');
550 printf("foo1_string='%s'\n", foo1_string);
551 #if 0
552 printf("wstring=%S\n", L"abc");
553 printf("wstring=%S\n", L"abc" L"def" "ghi");
554 printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
555 printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff');
556 #endif
557 ps("test\n");
558 b = 32;
559 while ((b = b + 1) < 96) {
560 printf("%c", b);
562 printf("\n");
563 printf("fib=%d\n", fib(33));
564 b = 262144;
565 while (b != 0x80000000) {
566 num(b);
567 b = b * 2;
569 string_test2();
573 void if1t(int n, int a, int b, int c)
575 if (a && b) printf("if1t: %d 1 %d %d\n", n, a, b);
576 if (a && !b) printf("if1t: %d 2 %d %d\n", n, a, b);
577 if (!a && b) printf("if1t: %d 3 %d %d\n", n, a, b);
578 if (!a && !b) printf("if1t: %d 4 %d %d\n", n, a, b);
579 if (a || b) printf("if1t: %d 5 %d %d\n", n, a, b);
580 if (a || !b) printf("if1t: %d 6 %d %d\n", n, a, b);
581 if (!a || b) printf("if1t: %d 7 %d %d\n", n, a, b);
582 if (!a || !b) printf("if1t: %d 8 %d %d\n", n, a, b);
583 if (a && b || c) printf("if1t: %d 9 %d %d %d\n", n, a, b, c);
584 if (a || b && c) printf("if1t: %d 10 %d %d %d\n", n, a, b, c);
585 if (a > b - 1 && c) printf("if1t: %d 11 %d %d %d\n", n, a, b, c);
586 if (a > b - 1 || c) printf("if1t: %d 12 %d %d %d\n", n, a, b, c);
587 if (a > 0 && 1) printf("if1t: %d 13 %d %d %d\n", n, a, b, c);
588 if (a > 0 || 0) printf("if1t: %d 14 %d %d %d\n", n, a, b, c);
591 void if2t(void)
593 if (0 && 1 || printf("if2t:ok\n") || 1)
594 printf("if2t:ok2\n");
595 printf("if2t:ok3\n");
598 void if_test(void)
600 if1t(1, 0, 0, 0);
601 if1t(2, 0, 3, 0);
602 if1t(3, 2, 0, 0);
603 if1t(4, 2, 3, 0);
604 if2t();
607 void loop_test()
609 int i;
610 i = 0;
611 while (i < 10)
612 printf("%d", i++);
613 printf("\n");
614 for(i = 0; i < 10;i++)
615 printf("%d", i);
616 printf("\n");
617 i = 0;
618 do {
619 printf("%d", i++);
620 } while (i < 10);
621 printf("\n");
623 char count = 123;
624 /* c99 for loop init test */
625 for (size_t count = 1; count < 3; count++)
626 printf("count=%d\n", count);
627 printf("count = %d\n", count);
629 /* break/continue tests */
630 i = 0;
631 while (1) {
632 if (i == 6)
633 break;
634 i++;
635 if (i == 3)
636 continue;
637 printf("%d", i);
639 printf("\n");
641 /* break/continue tests */
642 i = 0;
643 do {
644 if (i == 6)
645 break;
646 i++;
647 if (i == 3)
648 continue;
649 printf("%d", i);
650 } while(1);
651 printf("\n");
653 for(i = 0;i < 10;i++) {
654 if (i == 3)
655 continue;
656 printf("%d", i);
658 printf("\n");
661 typedef int typedef_and_label;
663 void goto_test()
665 int i;
666 static void *label_table[3] = { &&label1, &&label2, &&label3 };
668 printf("goto:\n");
669 i = 0;
670 /* This needs to parse as label, not as start of decl. */
671 typedef_and_label x;
672 typedef_and_label:
673 s_loop:
674 if (i >= 10)
675 goto s_end;
676 printf("%d", i);
677 i++;
678 goto s_loop;
679 s_end:
680 printf("\n");
682 /* we also test computed gotos (GCC extension) */
683 for(i=0;i<3;i++) {
684 goto *label_table[i];
685 label1:
686 printf("label1\n");
687 goto next;
688 label2:
689 printf("label2\n");
690 goto next;
691 label3:
692 printf("label3\n");
693 next: ;
697 enum {
699 E1 = 2,
700 E2 = 4,
705 enum test {
706 E5 = 1000,
709 struct S_enum {
710 enum {E6 = 42, E7, E8} e:8;
713 enum ELong {
714 /* This is either 0 on L32 machines, or a large number
715 on L64 machines. We should be able to store this. */
716 EL_large = ((unsigned long)0xf000 << 31) << 1,
719 enum { BIASU = -1U<<31 };
720 enum { BIASS = -1 << 31 };
722 static int getint(int i)
724 if (i)
725 return 0;
726 else
727 return (int)(-1U << 31);
730 void enum_test()
732 enum test b1;
733 /* The following should give no warning */
734 unsigned *p = &b1;
735 struct S_enum s = {E7};
736 printf("enum: %d\n", s.e);
737 printf("enum:\n%d %d %d %d %d %d\n",
738 E0, E1, E2, E3, E4, E5);
739 b1 = 1;
740 printf("b1=%d\n", b1);
741 printf("enum large: %ld\n", EL_large);
743 if (getint(0) == BIASU)
744 printf("enum unsigned: ok\n");
745 else
746 printf("enum unsigned: wrong\n");
747 if (getint(0) == BIASS)
748 printf("enum unsigned: ok\n");
749 else
750 printf("enum unsigned: wrong\n");
753 typedef int *my_ptr;
755 typedef int mytype1;
756 typedef int mytype2;
758 void typedef_test()
760 my_ptr a;
761 mytype1 mytype2;
762 int b;
764 a = &b;
765 *a = 1234;
766 printf("typedef:\n");
767 printf("a=%d\n", *a);
768 mytype2 = 2;
769 printf("mytype2=%d\n", mytype2);
772 void forward_test()
774 printf("forward:\n");
775 forward_ref();
776 forward_ref();
780 void forward_ref(void)
782 printf("forward ok\n");
785 typedef struct struct1 {
786 int f1;
787 int f2, f3;
788 union union1 {
789 int v1;
790 int v2;
791 } u;
792 char str[3];
793 } struct1;
795 struct struct2 {
796 int a;
797 char b;
800 union union2 {
801 int w1;
802 int w2;
805 struct struct1 st1, st2;
807 struct empty_mem {
808 /* nothing */ ;
809 int x;
812 int main(int argc, char **argv)
814 string_test();
815 expr_test();
816 macro_test();
817 recursive_macro_test();
818 scope_test();
819 scope_test2();
820 forward_test();
821 funcptr_test();
822 if_test();
823 loop_test();
824 switch_test();
825 goto_test();
826 enum_test();
827 typedef_test();
828 struct_test();
829 array_test();
830 expr_ptr_test();
831 bool_test();
832 optimize_out();
833 expr2_test();
834 constant_expr_test();
835 expr_cmp_test();
836 char_short_test();
837 init_test();
838 compound_literal_test();
839 kr_test();
840 struct_assign_test();
841 cast_test();
842 bitfield_test();
843 c99_bool_test();
844 float_test();
845 longlong_test();
846 manyarg_test();
847 stdarg_test();
848 whitespace_test();
849 relocation_test();
850 old_style_function();
851 alloca_test();
852 c99_vla_test(5, 2);
853 sizeof_test();
854 typeof_test();
855 statement_expr_test();
856 local_label_test();
857 asm_test();
858 builtin_test();
859 #ifndef _WIN32
860 weak_test();
861 #endif
862 global_data_test();
863 cmp_comparison_test();
864 math_cmp_test();
865 callsave_test();
866 builtin_frame_address_test();
867 intdiv_test();
868 if (via_volatile (42) != 42)
869 printf ("via_volatile broken\n");
870 attrib_test();
871 bounds_check1_test();
872 return 0;
875 int tab[3];
876 int tab2[3][2];
878 int g;
880 void f1(g)
882 printf("g1=%d\n", g);
885 void scope_test()
887 printf("scope:\n");
888 g = 2;
889 f1(1);
890 printf("g2=%d\n", g);
892 int g;
893 g = 3;
894 printf("g3=%d\n", g);
896 int g;
897 g = 4;
898 printf("g4=%d\n", g);
901 printf("g5=%d\n", g);
904 int st2_i;
905 int *st2_p = &st2_i;
906 void scope_test2()
908 char a[50];
909 st2_i = 42;
910 for (int st2_i = 1; st2_i < 10; st2_i++) {
911 extern int st2_i;
912 st2_i++;
913 printf("exloc: %d\n", st2_i);
915 printf("exloc: %d\n", *st2_p);
918 /* C has tentative definition, and they may be repeated. */
919 extern int st_global1;
920 int st_global1=42;
921 extern int st_global1;
922 int st_global1;
923 extern int st_global2;
924 int st_global2;
925 extern int st_global2;
926 int st_global2;
928 void array_test()
930 int i, j, a[4];
932 printf("array:\n");
933 printf("sizeof(a) = %d\n", sizeof(a));
934 printf("sizeof(\"a\") = %d\n", sizeof("a"));
935 #ifdef C99_MACROS
936 printf("sizeof(__func__) = %d\n", sizeof(__func__));
937 #endif
938 printf("sizeof tab %d\n", sizeof(tab));
939 printf("sizeof tab2 %d\n", sizeof tab2);
940 tab[0] = 1;
941 tab[1] = 2;
942 tab[2] = 3;
943 printf("%d %d %d\n", tab[0], tab[1], tab[2]);
944 for(i=0;i<3;i++)
945 for(j=0;j<2;j++)
946 tab2[i][j] = 10 * i + j;
947 for(i=0;i<3*2;i++) {
948 printf(" %3d", ((int *)tab2)[i]);
950 printf("\n");
951 printf("sizeof(size_t)=%d\n", sizeof(size_t));
952 printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
955 void expr_test()
957 int a, b;
958 a = 0;
959 printf("%d\n", a += 1);
960 printf("%d\n", a -= 2);
961 printf("%d\n", a *= 31232132);
962 printf("%d\n", a /= 4);
963 printf("%d\n", a %= 20);
964 printf("%d\n", a &= 6);
965 printf("%d\n", a ^= 7);
966 printf("%d\n", a |= 8);
967 printf("%d\n", a >>= 3);
968 printf("%d\n", a <<= 4);
970 a = 22321;
971 b = -22321;
972 printf("%d\n", a + 1);
973 printf("%d\n", a - 2);
974 printf("%d\n", a * 312);
975 printf("%d\n", a / 4);
976 printf("%d\n", b / 4);
977 printf("%d\n", (unsigned)b / 4);
978 printf("%d\n", a % 20);
979 printf("%d\n", b % 20);
980 printf("%d\n", (unsigned)b % 20);
981 printf("%d\n", a & 6);
982 printf("%d\n", a ^ 7);
983 printf("%d\n", a | 8);
984 printf("%d\n", a >> 3);
985 printf("%d\n", b >> 3);
986 printf("%d\n", (unsigned)b >> 3);
987 printf("%d\n", a << 4);
988 printf("%d\n", ~a);
989 printf("%d\n", -a);
990 printf("%d\n", +a);
992 printf("%d\n", 12 + 1);
993 printf("%d\n", 12 - 2);
994 printf("%d\n", 12 * 312);
995 printf("%d\n", 12 / 4);
996 printf("%d\n", 12 % 20);
997 printf("%d\n", 12 & 6);
998 printf("%d\n", 12 ^ 7);
999 printf("%d\n", 12 | 8);
1000 printf("%d\n", 12 >> 2);
1001 printf("%d\n", 12 << 4);
1002 printf("%d\n", ~12);
1003 printf("%d\n", -12);
1004 printf("%d\n", +12);
1005 printf("%d %d %d %d\n",
1006 isid('a'),
1007 isid('g'),
1008 isid('T'),
1009 isid('('));
1012 int isid(int c)
1014 return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
1017 /**********************/
1019 int vstack[10], *vstack_ptr;
1021 void vpush(int vt, int vc)
1023 *vstack_ptr++ = vt;
1024 *vstack_ptr++ = vc;
1027 void vpop(int *ft, int *fc)
1029 *fc = *--vstack_ptr;
1030 *ft = *--vstack_ptr;
1033 void expr2_test()
1035 int a, b;
1037 printf("expr2:\n");
1038 vstack_ptr = vstack;
1039 vpush(1432432, 2);
1040 vstack_ptr[-2] &= ~0xffffff80;
1041 vpop(&a, &b);
1042 printf("res= %d %d\n", a, b);
1045 int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */
1047 void constant_expr_test()
1049 int a;
1050 printf("constant_expr:\n");
1051 a = 3;
1052 printf("%d\n", a * 16);
1053 printf("%d\n", a * 1);
1054 printf("%d\n", a + 0);
1055 printf("%d\n", sizeof(const_len_ar));
1058 int tab4[10];
1060 void expr_ptr_test()
1062 int *p, *q;
1063 int i = -1;
1065 printf("expr_ptr:\n");
1066 p = tab4;
1067 q = tab4 + 10;
1068 printf("diff=%d\n", q - p);
1069 p++;
1070 printf("inc=%d\n", p - tab4);
1071 p--;
1072 printf("dec=%d\n", p - tab4);
1073 ++p;
1074 printf("inc=%d\n", p - tab4);
1075 --p;
1076 printf("dec=%d\n", p - tab4);
1077 printf("add=%d\n", p + 3 - tab4);
1078 printf("add=%d\n", 3 + p - tab4);
1080 /* check if 64bit support is ok */
1081 q = p = 0;
1082 q += i;
1083 printf("%p %p %ld\n", q, p, p-q);
1084 printf("%d %d %d %d %d %d\n",
1085 p == q, p != q, p < q, p <= q, p >= q, p > q);
1086 i = 0xf0000000;
1087 p += i;
1088 printf("%p %p %ld\n", q, p, p-q);
1089 printf("%d %d %d %d %d %d\n",
1090 p == q, p != q, p < q, p <= q, p >= q, p > q);
1091 p = (int *)((char *)p + 0xf0000000);
1092 printf("%p %p %ld\n", q, p, p-q);
1093 printf("%d %d %d %d %d %d\n",
1094 p == q, p != q, p < q, p <= q, p >= q, p > q);
1095 p += 0xf0000000;
1096 printf("%p %p %ld\n", q, p, p-q);
1097 printf("%d %d %d %d %d %d\n",
1098 p == q, p != q, p < q, p <= q, p >= q, p > q);
1100 struct size12 {
1101 int i, j, k;
1103 struct size12 s[2], *sp = s;
1104 int i, j;
1105 sp->i = 42;
1106 sp++;
1107 j = -1;
1108 printf("%d\n", sp[j].i);
1110 #ifdef __LP64__
1111 i = 1;
1112 p = (int*)0x100000000UL + i;
1113 i = ((long)p) >> 32;
1114 printf("largeptr: %p %d\n", p, i);
1115 #endif
1118 void expr_cmp_test()
1120 int a, b;
1121 printf("constant_expr:\n");
1122 a = -1;
1123 b = 1;
1124 printf("%d\n", a == a);
1125 printf("%d\n", a != a);
1127 printf("%d\n", a < b);
1128 printf("%d\n", a <= b);
1129 printf("%d\n", a <= a);
1130 printf("%d\n", b >= a);
1131 printf("%d\n", a >= a);
1132 printf("%d\n", b > a);
1134 printf("%d\n", (unsigned)a < b);
1135 printf("%d\n", (unsigned)a <= b);
1136 printf("%d\n", (unsigned)a <= a);
1137 printf("%d\n", (unsigned)b >= a);
1138 printf("%d\n", (unsigned)a >= a);
1139 printf("%d\n", (unsigned)b > a);
1142 struct empty {
1145 struct aligntest1 {
1146 char a[10];
1149 struct aligntest2 {
1150 int a;
1151 char b[10];
1154 struct aligntest3 {
1155 double a, b;
1158 struct aligntest4 {
1159 double a[0];
1162 struct __attribute__((aligned(16))) aligntest5
1164 int i;
1166 struct aligntest6
1168 int i;
1169 } __attribute__((aligned(16)));
1170 struct aligntest7
1172 int i;
1174 struct aligntest5 altest5[2];
1175 struct aligntest6 altest6[2];
1176 int pad1;
1177 /* altest7 is correctly aligned to 16 bytes also with TCC,
1178 but __alignof__ returns the wrong result (4) because we
1179 can't store the alignment yet when specified on symbols
1180 directly (it's stored in the type so we'd need to make
1181 a copy of it). -- FIXED */
1182 struct aligntest7 altest7[2] __attribute__((aligned(16)));
1184 struct aligntest8
1186 int i;
1187 } __attribute__((aligned(4096)));
1189 struct Large {
1190 unsigned long flags;
1191 union {
1192 void *u1;
1193 int *u2;
1196 struct {
1197 union {
1198 unsigned long index;
1199 void *freelist;
1201 union {
1202 unsigned long counters;
1203 struct {
1204 int bla;
1209 union {
1210 struct {
1211 long u3;
1212 long u4;
1214 void *u5;
1215 struct {
1216 unsigned long compound_head;
1217 unsigned int compound_dtor;
1218 unsigned int compound_order;
1221 } __attribute__((aligned(2 * sizeof(long))));
1223 typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
1225 struct aligntest9 {
1226 unsigned int buf_nr;
1227 unaligned_u64 start_lba;
1230 struct aligntest10 {
1231 unsigned int buf_nr;
1232 unsigned long long start_lba;
1235 void struct_test()
1237 struct1 *s;
1238 union union2 u;
1239 struct Large ls;
1241 printf("struct:\n");
1242 printf("sizes: %d %d %d %d\n",
1243 sizeof(struct struct1),
1244 sizeof(struct struct2),
1245 sizeof(union union1),
1246 sizeof(union union2));
1247 printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
1248 st1.f1 = 1;
1249 st1.f2 = 2;
1250 st1.f3 = 3;
1251 printf("st1: %d %d %d\n",
1252 st1.f1, st1.f2, st1.f3);
1253 st1.u.v1 = 1;
1254 st1.u.v2 = 2;
1255 printf("union1: %d\n", st1.u.v1);
1256 u.w1 = 1;
1257 u.w2 = 2;
1258 printf("union2: %d\n", u.w1);
1259 s = &st2;
1260 s->f1 = 3;
1261 s->f2 = 2;
1262 s->f3 = 1;
1263 printf("st2: %d %d %d\n",
1264 s->f1, s->f2, s->f3);
1265 printf("str_addr=%x\n", (int)(uintptr_t)st1.str - (int)(uintptr_t)&st1.f1);
1267 /* align / size tests */
1268 printf("aligntest1 sizeof=%d alignof=%d\n",
1269 sizeof(struct aligntest1), __alignof__(struct aligntest1));
1270 printf("aligntest2 sizeof=%d alignof=%d\n",
1271 sizeof(struct aligntest2), __alignof__(struct aligntest2));
1272 printf("aligntest3 sizeof=%d alignof=%d\n",
1273 sizeof(struct aligntest3), __alignof__(struct aligntest3));
1274 printf("aligntest4 sizeof=%d alignof=%d\n",
1275 sizeof(struct aligntest4), __alignof__(struct aligntest4));
1276 printf("aligntest5 sizeof=%d alignof=%d\n",
1277 sizeof(struct aligntest5), __alignof__(struct aligntest5));
1278 printf("aligntest6 sizeof=%d alignof=%d\n",
1279 sizeof(struct aligntest6), __alignof__(struct aligntest6));
1280 printf("aligntest7 sizeof=%d alignof=%d\n",
1281 sizeof(struct aligntest7), __alignof__(struct aligntest7));
1282 printf("aligntest8 sizeof=%d alignof=%d\n",
1283 sizeof(struct aligntest8), __alignof__(struct aligntest8));
1284 printf("aligntest9 sizeof=%d alignof=%d\n",
1285 sizeof(struct aligntest9), __alignof__(struct aligntest9));
1286 printf("aligntest10 sizeof=%d alignof=%d\n",
1287 sizeof(struct aligntest10), __alignof__(struct aligntest10));
1288 printf("altest5 sizeof=%d alignof=%d\n",
1289 sizeof(altest5), __alignof__(altest5));
1290 printf("altest6 sizeof=%d alignof=%d\n",
1291 sizeof(altest6), __alignof__(altest6));
1292 printf("altest7 sizeof=%d alignof=%d\n",
1293 sizeof(altest7), __alignof__(altest7));
1295 /* empty structures (GCC extension) */
1296 printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
1297 printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
1299 printf("Large: sizeof=%d\n", sizeof(ls));
1300 memset(&ls, 0, sizeof(ls));
1301 ls.compound_head = 42;
1302 printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
1305 /* simulate char/short return value with undefined upper bits */
1306 static int __csf(int x) { return x; }
1307 static void *_csf = __csf;
1308 #define csf(t,n) ((t(*)(int))_csf)(n)
1310 /* XXX: depend on endianness */
1311 void char_short_test()
1313 int var1, var2;
1314 signed char var3;
1315 long long var4;
1317 printf("char_short:\n");
1319 var1 = 0x01020304;
1320 var2 = 0xfffefdfc;
1321 printf("s8=%d %d\n",
1322 *(signed char *)&var1, *(signed char *)&var2);
1323 printf("u8=%d %d\n",
1324 *(unsigned char *)&var1, *(unsigned char *)&var2);
1325 printf("s16=%d %d\n",
1326 *(short *)&var1, *(short *)&var2);
1327 printf("u16=%d %d\n",
1328 *(unsigned short *)&var1, *(unsigned short *)&var2);
1329 printf("s32=%d %d\n",
1330 *(int *)&var1, *(int *)&var2);
1331 printf("u32=%d %d\n",
1332 *(unsigned int *)&var1, *(unsigned int *)&var2);
1333 *(signed char *)&var1 = 0x08;
1334 printf("var1=%x\n", var1);
1335 *(short *)&var1 = 0x0809;
1336 printf("var1=%x\n", var1);
1337 *(int *)&var1 = 0x08090a0b;
1338 printf("var1=%x\n", var1);
1340 var1 = 0x778899aa;
1341 var4 = 0x11223344aa998877ULL;
1342 var1 = var3 = var1 + 1;
1343 var4 = var3 = var4 + 1;
1344 printf("promote char/short assign %d "LONG_LONG_FORMAT"\n", var1, var4);
1345 var1 = 0x778899aa;
1346 var4 = 0x11223344aa998877ULL;
1347 printf("promote char/short assign VA %d %d\n", var3 = var1 + 1, var3 = var4 + 1);
1348 printf("promote char/short cast VA %d %d\n", (signed char)(var1 + 1), (signed char)(var4 + 1));
1349 #if !defined(__arm__)
1350 /* We can't really express GCC behaviour of return type promotion in
1351 the presence of undefined behaviour (like __csf is). */
1352 var1 = csf(unsigned char,0x89898989);
1353 var4 = csf(signed char,0xabababab);
1354 printf("promote char/short funcret %d "LONG_LONG_FORMAT"\n", var1, var4);
1355 printf("promote char/short fumcret VA %d %d %d %d\n",
1356 csf(unsigned short,0xcdcdcdcd),
1357 csf(short,0xefefefef),
1358 csf(_Bool,0x33221100),
1359 csf(_Bool,0x33221101));
1360 #endif
1361 var3 = -10;
1362 var1 = (signed char)(unsigned char)(var3 + 1);
1363 var4 = (signed char)(unsigned char)(var3 + 1);
1364 printf("promote multicast (char)(unsigned char) %d "LONG_LONG_FORMAT"\n", var1, var4);
1365 var4 = 0x11223344aa998877ULL;
1366 var4 = (unsigned)(int)(var4 + 1);
1367 printf("promote multicast (unsigned)(int) "LONG_LONG_FORMAT"\n", var4);
1368 var4 = 0x11223344bbaa9988ULL;
1369 var4 = (unsigned)(signed char)(var4 + 1);
1370 printf("promote multicast (unsigned)(char) "LONG_LONG_FORMAT"\n", var4);
1373 /******************/
1375 typedef struct Sym {
1376 int v;
1377 int t;
1378 int c;
1379 struct Sym *next;
1380 struct Sym *prev;
1381 } Sym;
1383 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
1384 #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
1386 static int toupper1(int a)
1388 return TOUPPER(a);
1391 static unsigned int calc_vm_flags(unsigned int prot)
1393 unsigned int prot_bits;
1394 /* This used to segfault in some revisions: */
1395 prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
1396 return prot_bits;
1399 void bool_test()
1401 int *s, a, b, t, f, i;
1403 a = 0;
1404 s = (void*)0;
1405 printf("!s=%d\n", !s);
1407 if (!s || !s[0])
1408 a = 1;
1409 printf("a=%d\n", a);
1411 printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
1412 printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
1413 printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
1414 #if 1 && 1
1415 printf("a1\n");
1416 #endif
1417 #if 1 || 0
1418 printf("a2\n");
1419 #endif
1420 #if 1 ? 0 : 1
1421 printf("a3\n");
1422 #endif
1423 #if 0 ? 0 : 1
1424 printf("a4\n");
1425 #endif
1427 a = 4;
1428 printf("b=%d\n", a + (0 ? 1 : a / 2));
1430 /* test register spilling */
1431 a = 10;
1432 b = 10;
1433 a = (a + b) * ((a < b) ?
1434 ((b - a) * (a - b)): a + b);
1435 printf("a=%d\n", a);
1437 /* test complex || or && expressions */
1438 t = 1;
1439 f = 0;
1440 a = 32;
1441 printf("exp=%d\n", f == (32 <= a && a <= 3));
1442 printf("r=%d\n", (t || f) + (t && f));
1444 /* test ? : cast */
1446 int aspect_on;
1447 int aspect_native = 65536;
1448 double bfu_aspect = 1.0;
1449 int aspect;
1450 for(aspect_on = 0; aspect_on < 2; aspect_on++) {
1451 aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
1452 printf("aspect=%d\n", aspect);
1456 /* test ? : GCC extension */
1458 static int v1 = 34 ? : -1; /* constant case */
1459 static int v2 = 0 ? : -1; /* constant case */
1460 int a = 30;
1462 printf("%d %d\n", v1, v2);
1463 printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
1466 /* again complex expression */
1467 for(i=0;i<256;i++) {
1468 if (toupper1 (i) != TOUPPER (i))
1469 printf("error %d\n", i);
1471 printf ("bits = 0x%x\n", calc_vm_flags (0x1));
1474 extern int undefined_function(void);
1475 extern int defined_function(void);
1477 static inline void refer_to_undefined(void)
1479 undefined_function();
1482 void optimize_out(void)
1484 int i = 0 ? undefined_function() : defined_function();
1485 printf ("oo:%d\n", i);
1486 int j = 1 ? defined_function() : undefined_function();
1487 printf ("oo:%d\n", j);
1488 if (0)
1489 printf("oo:%d\n", undefined_function());
1490 else
1491 printf("oo:%d\n", defined_function());
1492 if (1)
1493 printf("oo:%d\n", defined_function());
1494 else
1495 printf("oo:%d\n", undefined_function());
1496 while (1) {
1497 printf("oow:%d\n", defined_function());
1498 break;
1499 printf("oow:%d\n", undefined_function());
1501 j = 1;
1502 /* Following is a switch without {} block intentionally. */
1503 switch (j)
1504 case 1: break;
1505 printf ("oos:%d\n", defined_function());
1506 /* The following break shouldn't lead to disabled code after
1507 the while. */
1508 while (1)
1509 break;
1510 printf ("ool1:%d\n", defined_function());
1511 /* Same for the other types of loops. */
1513 break;
1514 while (1);
1515 printf ("ool2:%d\n", defined_function());
1516 for (;;)
1517 break;
1518 printf ("ool3:%d\n", defined_function());
1519 /* Normal {} blocks without controlling statements
1520 shouldn't reactivate code emission */
1521 while (1) {
1523 break;
1525 printf ("ool4:%d\n", undefined_function());
1527 j = 1;
1528 while (j) {
1529 if (j == 0)
1530 break; /* this break shouldn't disable code outside the if. */
1531 printf("ool5:%d\n", defined_function());
1532 j--;
1535 j = 1;
1536 while (j) {
1537 if (1)
1538 j--;
1539 else
1540 breakhere: break;
1541 printf("ool6:%d\n", defined_function());
1542 goto breakhere;
1544 j = 1;
1545 while (j) {
1546 j--;
1547 continue;
1548 printf("ool7:%d\n", undefined_function());
1551 /* Test that constants in logical && are optimized: */
1552 i = 0 && undefined_function();
1553 i = defined_function() && 0 && undefined_function();
1554 if (0 && undefined_function())
1555 undefined_function();
1556 if (defined_function() && 0)
1557 undefined_function();
1558 if (0 && 0)
1559 undefined_function();
1560 if (defined_function() && 0 && undefined_function())
1561 undefined_function();
1562 /* The same for || : */
1563 i = 1 || undefined_function();
1564 i = defined_function() || 1 || undefined_function();
1565 if (1 || undefined_function())
1567 else
1568 undefined_function();
1569 if (defined_function() || 1)
1571 else
1572 undefined_function();
1573 if (1 || 1)
1575 else
1576 undefined_function();
1577 if (defined_function() || 1 || undefined_function())
1579 else
1580 undefined_function();
1582 if (defined_function() && 0)
1583 refer_to_undefined();
1585 if (0) {
1586 (void)sizeof( ({
1587 do { } while (0);
1589 }) );
1590 undefined_function();
1593 /* Leave the "if(1)return; printf()" in this order and last in the function */
1594 if (1)
1595 return;
1596 printf ("oor:%d\n", undefined_function());
1599 int defined_function(void)
1601 static int i = 40;
1602 return i++;
1605 /* GCC accepts that */
1606 static int tab_reinit[];
1607 static int tab_reinit[10];
1609 static int tentative_ar[];
1610 static int tentative_ar[] = {1,2,3};
1612 //int cinit1; /* a global variable can be defined several times without error ! */
1613 int cinit1;
1614 int cinit1;
1615 int cinit1 = 0;
1616 int *cinit2 = (int []){3, 2, 1};
1618 void compound_literal_test(void)
1620 int *p, i;
1621 char *q, *q3;
1623 printf("compound_test:\n");
1625 p = (int []){1, 2, 3};
1626 for(i=0;i<3;i++)
1627 printf(" %d", p[i]);
1628 printf("\n");
1630 for(i=0;i<3;i++)
1631 printf("%d", cinit2[i]);
1632 printf("\n");
1634 q = "tralala1";
1635 printf("q1=%s\n", q);
1637 q = (char *){ "tralala2" };
1638 printf("q2=%s\n", q);
1640 q3 = (char *){ q };
1641 printf("q3=%s\n", q3);
1643 q = (char []){ "tralala3" };
1644 printf("q4=%s\n", q);
1646 #ifdef ALL_ISOC99
1647 p = (int []){1, 2, cinit1 + 3};
1648 for(i=0;i<3;i++)
1649 printf(" %d", p[i]);
1650 printf("\n");
1652 for(i=0;i<3;i++) {
1653 p = (int []){1, 2, 4 + i};
1654 printf("%d %d %d\n",
1655 p[0],
1656 p[1],
1657 p[2]);
1659 #endif
1662 /* K & R protos */
1664 kr_func1(a, b)
1666 return a + b;
1669 int kr_func2(a, b)
1671 return a + b;
1674 kr_test()
1676 printf("kr_test:\n");
1677 printf("func1=%d\n", kr_func1(3, 4));
1678 printf("func2=%d\n", kr_func2(3, 4));
1679 return 0;
1682 void num(int n)
1684 char *tab, *p;
1685 tab = (char*)malloc(20);
1686 p = tab;
1687 while (1) {
1688 *p = 48 + (n % 10);
1689 p++;
1690 n = n / 10;
1691 if (n == 0)
1692 break;
1694 while (p != tab) {
1695 p--;
1696 printf("%c", *p);
1698 printf("\n");
1699 free(tab);
1702 /* structure assignment tests */
1703 struct structa1 {
1704 int f1;
1705 char f2;
1708 struct structa1 ssta1;
1710 void struct_assign_test1(struct structa1 s1, int t, float f)
1712 printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
1715 struct structa1 struct_assign_test2(struct structa1 s1, int t)
1717 s1.f1 += t;
1718 s1.f2 -= t;
1719 return s1;
1722 void struct_assign_test(void)
1724 struct S {
1725 struct structa1 lsta1, lsta2;
1726 int i;
1727 } s, *ps;
1729 ps = &s;
1730 ps->i = 4;
1731 #if 0
1732 printf("struct_assign_test:\n");
1734 s.lsta1.f1 = 1;
1735 s.lsta1.f2 = 2;
1736 printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
1737 s.lsta2 = s.lsta1;
1738 printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
1739 #else
1740 s.lsta2.f1 = 1;
1741 s.lsta2.f2 = 2;
1742 #endif
1743 struct_assign_test1(ps->lsta2, 3, 4.5);
1745 printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
1746 ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
1747 printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
1749 static struct {
1750 void (*elem)();
1751 } t[] = {
1752 /* XXX: we should allow this even without braces */
1753 { struct_assign_test }
1755 printf("%d\n", struct_assign_test == t[0].elem);
1758 /* casts to short/char */
1760 void cast1(char a, short b, unsigned char c, unsigned short d)
1762 printf("%d %d %d %d\n", a, b, c, d);
1765 char bcast;
1766 short scast;
1768 void cast_test()
1770 int a;
1771 char c;
1772 char tab[10];
1773 unsigned b,d;
1774 short s;
1775 char *p = NULL;
1776 unsigned long ul = 0x80000000UL;
1777 p -= 0x700000000042;
1779 printf("cast_test:\n");
1780 a = 0xfffff;
1781 cast1(a, a, a, a);
1782 a = 0xffffe;
1783 printf("%d %d %d %d\n",
1784 (char)(a + 1),
1785 (short)(a + 1),
1786 (unsigned char)(a + 1),
1787 (unsigned short)(a + 1));
1788 printf("%d %d %d %d\n",
1789 (char)0xfffff,
1790 (short)0xfffff,
1791 (unsigned char)0xfffff,
1792 (unsigned short)0xfffff);
1794 a = (bcast = 128) + 1;
1795 printf("%d\n", a);
1796 a = (scast = 65536) + 1;
1797 printf("%d\n", a);
1799 printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
1801 /* test cast from unsigned to signed short to int */
1802 b = 0xf000;
1803 d = (short)b;
1804 printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
1805 b = 0xf0f0;
1806 d = (char)b;
1807 printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
1809 /* test implicit int casting for array accesses */
1810 c = 0;
1811 tab[1] = 2;
1812 tab[c] = 1;
1813 printf("%d %d\n", tab[0], tab[1]);
1815 /* test implicit casting on some operators */
1816 printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
1817 printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
1818 printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
1820 /* from pointer to integer types */
1821 printf("%d %d %ld %ld %lld %lld\n",
1822 (int)p, (unsigned int)p,
1823 (long)p, (unsigned long)p,
1824 (long long)p, (unsigned long long)p);
1826 /* from integers to pointers */
1827 printf("%p %p %p %p\n",
1828 (void *)a, (void *)b, (void *)c, (void *)d);
1830 /* int to int with sign set */
1831 printf("0x%lx\n", (unsigned long)(int)ul);
1834 /* initializers tests */
1835 struct structinit1 {
1836 int f1;
1837 char f2;
1838 short f3;
1839 int farray[3];
1842 int sinit1 = 2;
1843 int sinit2 = { 3 };
1844 int sinit3[3] = { 1, 2, {{3}}, };
1845 int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1846 int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
1847 int sinit6[] = { 1, 2, 3 };
1848 int sinit7[] = { [2] = 3, [0] = 1, 2 };
1849 char sinit8[] = "hello" "trala";
1851 struct structinit1 sinit9 = { 1, 2, 3 };
1852 struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
1853 struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
1854 #ifdef ALL_ISOC99
1855 .farray[0] = 10,
1856 .farray[1] = 11,
1857 .farray[2] = 12,
1858 #endif
1861 char *sinit12 = "hello world";
1862 char *sinit13[] = {
1863 "test1",
1864 "test2",
1865 "test3",
1867 char sinit14[10] = { "abc" };
1868 int sinit15[3] = { sizeof(sinit15), 1, 2 };
1870 struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
1872 struct bar {
1873 char *s;
1874 int len;
1875 } sinit17[] = {
1876 "a1", 4,
1877 "a2", 1
1880 int sinit18[10] = {
1881 [2 ... 5] = 20,
1883 [8] = 10,
1886 struct complexinit0 {
1887 int a;
1888 int b;
1891 struct complexinit {
1892 int a;
1893 const struct complexinit0 *b;
1896 const static struct complexinit cix[] = {
1897 [0] = {
1898 .a = 2000,
1899 .b = (const struct complexinit0[]) {
1900 { 2001, 2002 },
1901 { 2003, 2003 },
1907 struct complexinit2 {
1908 int a;
1909 int b[];
1912 struct complexinit2 cix20;
1914 struct complexinit2 cix21 = {
1915 .a = 3000,
1916 .b = { 3001, 3002, 3003 }
1919 struct complexinit2 cix22 = {
1920 .a = 4000,
1921 .b = { 4001, 4002, 4003, 4004, 4005, 4006 }
1924 typedef int arrtype1[];
1925 arrtype1 sinit19 = {1};
1926 arrtype1 sinit20 = {2,3};
1927 typedef int arrtype2[3];
1928 arrtype2 sinit21 = {4};
1929 arrtype2 sinit22 = {5,6,7};
1931 /* Address comparisons of non-weak symbols with zero can be const-folded */
1932 int sinit23[2] = { "astring" ? sizeof("astring") : -1,
1933 &sinit23 ? 42 : -1 };
1935 int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
1937 extern int external_inited = 42;
1939 void init_test(void)
1941 int linit1 = 2;
1942 int linit2 = { 3 };
1943 int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1944 int linit6[] = { 1, 2, 3 };
1945 int i, j;
1946 char linit8[] = "hello" "trala";
1947 int linit12[10] = { 1, 2 };
1948 int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
1949 char linit14[10] = "abc";
1950 int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
1951 struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
1952 int linit17 = sizeof(linit17);
1953 int zero = 0;
1954 /* Addresses on non-weak symbols are non-zero, but not the access itself */
1955 int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
1957 printf("init_test:\n");
1959 printf("sinit1=%d\n", sinit1);
1960 printf("sinit2=%d\n", sinit2);
1961 printf("sinit3=%d %d %d %d\n",
1962 sizeof(sinit3),
1963 sinit3[0],
1964 sinit3[1],
1965 sinit3[2]
1967 printf("sinit6=%d\n", sizeof(sinit6));
1968 printf("sinit7=%d %d %d %d\n",
1969 sizeof(sinit7),
1970 sinit7[0],
1971 sinit7[1],
1972 sinit7[2]
1974 printf("sinit8=%s\n", sinit8);
1975 printf("sinit9=%d %d %d\n",
1976 sinit9.f1,
1977 sinit9.f2,
1978 sinit9.f3
1980 printf("sinit10=%d %d %d\n",
1981 sinit10.f1,
1982 sinit10.f2,
1983 sinit10.f3
1985 printf("sinit11=%d %d %d %d %d %d\n",
1986 sinit11.f1,
1987 sinit11.f2,
1988 sinit11.f3,
1989 sinit11.farray[0],
1990 sinit11.farray[1],
1991 sinit11.farray[2]
1994 for(i=0;i<3;i++)
1995 for(j=0;j<2;j++)
1996 printf("[%d][%d] = %d %d %d\n",
1997 i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
1998 printf("linit1=%d\n", linit1);
1999 printf("linit2=%d\n", linit2);
2000 printf("linit6=%d\n", sizeof(linit6));
2001 printf("linit8=%d %s\n", sizeof(linit8), linit8);
2003 printf("sinit12=%s\n", sinit12);
2004 printf("sinit13=%d %s %s %s\n",
2005 sizeof(sinit13),
2006 sinit13[0],
2007 sinit13[1],
2008 sinit13[2]);
2009 printf("sinit14=%s\n", sinit14);
2011 for(i=0;i<10;i++) printf(" %d", linit12[i]);
2012 printf("\n");
2013 for(i=0;i<10;i++) printf(" %d", linit13[i]);
2014 printf("\n");
2015 for(i=0;i<10;i++) printf(" %d", linit14[i]);
2016 printf("\n");
2017 for(i=0;i<10;i++) printf(" %d", linit15[i]);
2018 printf("\n");
2019 printf("%d %d %d %d\n",
2020 linit16.a1,
2021 linit16.a2,
2022 linit16.a3,
2023 linit16.a4);
2024 /* test that initialisation is done after variable declare */
2025 printf("linit17=%d\n", linit17);
2026 printf("sinit15=%d\n", sinit15[0]);
2027 printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
2028 printf("sinit17=%s %d %s %d\n",
2029 sinit17[0].s, sinit17[0].len,
2030 sinit17[1].s, sinit17[1].len);
2031 for(i=0;i<10;i++)
2032 printf("%x ", sinit18[i]);
2033 printf("\n");
2034 /* complex init check */
2035 printf("cix: %d %d %d %d %d %d %d\n",
2036 cix[0].a,
2037 cix[0].b[0].a, cix[0].b[0].b,
2038 cix[0].b[1].a, cix[0].b[1].b,
2039 cix[0].b[2].a, cix[0].b[2].b);
2040 printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
2041 printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
2043 printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
2044 printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
2045 printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
2046 printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
2047 printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
2048 printf("arrtype6: %d\n", sizeof(arrtype2));
2050 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
2051 printf("sinit24=%d\n", sinit24);
2052 printf("linit18= %d %d\n", linit18[0], linit18[1]);
2055 void switch_uc(unsigned char uc)
2057 switch (uc) {
2058 case 0xfb ... 0xfe:
2059 printf("ucsw:1\n");
2060 break;
2061 case 0xff:
2062 printf("ucsw:2\n");
2063 break;
2064 case 0 ... 5:
2065 printf("ucsw:3\n");
2066 break;
2067 default:
2068 printf("ucsw: broken!\n");
2072 void switch_sc(signed char sc)
2074 switch (sc) {
2075 case -5 ... -2:
2076 printf("scsw:1\n");
2077 break;
2078 case -1:
2079 printf("scsw:2\n");
2080 break;
2081 case 0 ... 5:
2082 printf("scsw:3\n");
2083 break;
2084 default:
2085 printf("scsw: broken!\n");
2089 void switch_test()
2091 int i;
2092 unsigned long long ull;
2093 long long ll;
2095 for(i=0;i<15;i++) {
2096 switch(i) {
2097 case 0:
2098 case 1:
2099 printf("a");
2100 break;
2101 default:
2102 printf("%d", i);
2103 break;
2104 case 8 ... 12:
2105 printf("c");
2106 break;
2107 case 3:
2108 printf("b");
2109 break;
2110 case 0xc33c6b9fU:
2111 case 0x7c9eeeb9U:
2112 break;
2115 printf("\n");
2117 for (i = 1; i <= 5; i++) {
2118 ull = (unsigned long long)i << 61;
2119 switch (ull) {
2120 case 1ULL << 61:
2121 printf("ullsw:1\n");
2122 break;
2123 case 2ULL << 61:
2124 printf("ullsw:2\n");
2125 break;
2126 case 3ULL << 61:
2127 printf("ullsw:3\n");
2128 break;
2129 case 4ULL << 61:
2130 printf("ullsw:4\n");
2131 break;
2132 case 5ULL << 61:
2133 printf("ullsw:5\n");
2134 break;
2135 default:
2136 printf("ullsw: broken!\n");
2140 for (i = 1; i <= 5; i++) {
2141 ll = (long long)i << 61;
2142 switch (ll) {
2143 case 1LL << 61:
2144 printf("llsw:1\n");
2145 break;
2146 case 2LL << 61:
2147 printf("llsw:2\n");
2148 break;
2149 case 3LL << 61:
2150 printf("llsw:3\n");
2151 break;
2152 case 4LL << 61:
2153 printf("llsw:4\n");
2154 break;
2155 case 5LL << 61:
2156 printf("llsw:5\n");
2157 break;
2158 default:
2159 printf("llsw: broken!\n");
2163 for (i = -5; i <= 5; i++) {
2164 switch_uc((unsigned char)i);
2167 for (i = -5; i <= 5; i++) {
2168 switch_sc ((signed char)i);
2172 /* ISOC99 _Bool type */
2173 void c99_bool_test(void)
2175 #ifdef BOOL_ISOC99
2176 int a;
2177 _Bool b, b2;
2179 printf("bool_test:\n");
2180 printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
2181 a = 3;
2182 printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
2183 b = 3;
2184 printf("b = %d\n", b);
2185 b++;
2186 printf("b = %d\n", b);
2187 b2 = 0;
2188 printf("sizeof(x ? _Bool : _Bool) = %d (should be sizeof int)\n",
2189 sizeof((volatile)a ? b : b2));
2190 #endif
2193 void bitfield_test(void)
2195 int a;
2196 short sa;
2197 unsigned char ca;
2198 struct sbf1 {
2199 int f1 : 3;
2200 int : 2;
2201 int f2 : 1;
2202 int : 0;
2203 int f3 : 5;
2204 int f4 : 7;
2205 unsigned int f5 : 7;
2206 } st1;
2207 printf("bitfield_test:");
2208 printf("sizeof(st1) = %d\n", sizeof(st1));
2210 st1.f1 = 3;
2211 st1.f2 = 1;
2212 st1.f3 = 15;
2213 a = 120;
2214 st1.f4 = a;
2215 st1.f5 = a;
2216 st1.f5++;
2217 printf("%d %d %d %d %d\n",
2218 st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
2219 sa = st1.f5;
2220 ca = st1.f5;
2221 printf("%d %d\n", sa, ca);
2223 st1.f1 = 7;
2224 if (st1.f1 == -1)
2225 printf("st1.f1 == -1\n");
2226 else
2227 printf("st1.f1 != -1\n");
2228 if (st1.f2 == -1)
2229 printf("st1.f2 == -1\n");
2230 else
2231 printf("st1.f2 != -1\n");
2233 struct sbf2 {
2234 long long f1 : 45;
2235 long long : 2;
2236 long long f2 : 35;
2237 unsigned long long f3 : 38;
2238 } st2;
2239 st2.f1 = 0x123456789ULL;
2240 a = 120;
2241 st2.f2 = (long long)a << 25;
2242 st2.f3 = a;
2243 st2.f2++;
2244 printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
2246 #if 0
2247 Disabled for now until further clarification re GCC compatibility
2248 struct sbf3 {
2249 int f1 : 7;
2250 int f2 : 1;
2251 char f3;
2252 int f4 : 8;
2253 int f5 : 1;
2254 int f6 : 16;
2255 } st3;
2256 printf("sizeof(st3) = %d\n", sizeof(st3));
2257 #endif
2259 struct sbf4 {
2260 int x : 31;
2261 char y : 2;
2262 } st4;
2263 st4.y = 1;
2264 printf("st4.y == %d\n", st4.y);
2265 struct sbf5 {
2266 int a;
2267 char b;
2268 int x : 12, y : 4, : 0, : 4, z : 3;
2269 char c;
2270 } st5 = { 1, 2, 3, 4, -3, 6 };
2271 printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
2272 struct sbf6 {
2273 short x : 12;
2274 unsigned char y : 2;
2275 } st6;
2276 st6.y = 1;
2277 printf("st6.y == %d\n", st6.y);
2280 #ifdef __x86_64__
2281 #define FLOAT_FMT "%f\n"
2282 #else
2283 /* x86's float isn't compatible with GCC */
2284 #define FLOAT_FMT "%.5f\n"
2285 #endif
2287 /* declare strto* functions as they are C99 */
2288 double strtod(const char *nptr, char **endptr);
2290 #if defined(_WIN32)
2291 float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
2292 LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
2293 #else
2294 float strtof(const char *nptr, char **endptr);
2295 LONG_DOUBLE strtold(const char *nptr, char **endptr);
2296 #endif
2298 #define FTEST(prefix, typename, type, fmt)\
2299 void prefix ## cmp(type a, type b)\
2301 printf("%d %d %d %d %d %d\n",\
2302 a == b,\
2303 a != b,\
2304 a < b,\
2305 a > b,\
2306 a >= b,\
2307 a <= b);\
2308 printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
2311 a + b,\
2312 a - b,\
2313 a * b,\
2314 a / b,\
2315 -a);\
2316 printf(fmt "\n", ++a);\
2317 printf(fmt "\n", a++);\
2318 printf(fmt "\n", a);\
2319 b = 0;\
2320 printf("%d %d\n", !a, !b);\
2322 void prefix ## fcast(type a)\
2324 float fa;\
2325 double da;\
2326 LONG_DOUBLE la;\
2327 int ia;\
2328 long long llia;\
2329 unsigned int ua;\
2330 unsigned long long llua;\
2331 type b;\
2332 fa = a;\
2333 da = a;\
2334 la = a;\
2335 printf("ftof: %f %f %Lf\n", fa, da, la);\
2336 ia = (int)a;\
2337 llia = (long long)a;\
2338 a = (a >= 0) ? a : -a;\
2339 ua = (unsigned int)a;\
2340 llua = (unsigned long long)a;\
2341 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
2342 ia = -1234;\
2343 ua = 0x81234500;\
2344 llia = -0x123456789012345LL;\
2345 llua = 0xf123456789012345LLU;\
2346 b = ia;\
2347 printf("itof: " fmt "\n", b);\
2348 b = ua;\
2349 printf("utof: " fmt "\n", b);\
2350 b = llia;\
2351 printf("lltof: " fmt "\n", b);\
2352 b = llua;\
2353 printf("ulltof: " fmt "\n", b);\
2356 float prefix ## retf(type a) { return a; }\
2357 double prefix ## retd(type a) { return a; }\
2358 LONG_DOUBLE prefix ## retld(type a) { return a; }\
2360 void prefix ## call(void)\
2362 printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
2363 printf("double: %f\n", prefix ## retd(42.123456789));\
2364 printf("long double: %Lf\n", prefix ## retld(42.123456789));\
2365 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
2368 void prefix ## signed_zeros(void) \
2370 type x = 0.0, y = -0.0, n, p;\
2371 if (x == y)\
2372 printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\
2373 1.0 / x != 1.0 / y);\
2374 else\
2375 printf ("x != y; this is wrong!\n");\
2377 n = -x;\
2378 if (x == n)\
2379 printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
2380 1.0 / x != 1.0 / n);\
2381 else\
2382 printf ("x != -x; this is wrong!\n");\
2384 p = +y;\
2385 if (x == p)\
2386 printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
2387 1.0 / x != 1.0 / p);\
2388 else\
2389 printf ("x != +y; this is wrong!\n");\
2390 p = -y;\
2391 if (x == p)\
2392 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
2393 1.0 / x != 1.0 / p);\
2394 else\
2395 printf ("x != -y; this is wrong!\n");\
2397 void prefix ## test(void)\
2399 printf("testing '%s'\n", #typename);\
2400 prefix ## cmp(1, 2.5);\
2401 prefix ## cmp(2, 1.5);\
2402 prefix ## cmp(1, 1);\
2403 prefix ## fcast(234.6);\
2404 prefix ## fcast(-2334.6);\
2405 prefix ## call();\
2406 prefix ## signed_zeros();\
2409 FTEST(f, float, float, "%f")
2410 FTEST(d, double, double, "%f")
2411 FTEST(ld, long double, LONG_DOUBLE, "%Lf")
2413 double ftab1[3] = { 1.2, 3.4, -5.6 };
2416 void float_test(void)
2418 #if !defined(__arm__) || defined(__ARM_PCS_VFP)
2419 float fa, fb;
2420 double da, db;
2421 int a;
2422 unsigned int b;
2423 static double nan2 = 0.0/0.0;
2424 static double inf1 = 1.0/0.0;
2425 static double inf2 = 1e5000;
2427 printf("float_test:\n");
2428 printf("sizeof(float) = %d\n", sizeof(float));
2429 printf("sizeof(double) = %d\n", sizeof(double));
2430 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
2431 ftest();
2432 dtest();
2433 ldtest();
2434 printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
2435 printf("%f %f %f\n", 2.12, .5, 2.3e10);
2436 // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
2437 da = 123;
2438 printf("da=%f\n", da);
2439 fa = 123;
2440 printf("fa=%f\n", fa);
2441 a = 4000000000;
2442 da = a;
2443 printf("da = %f\n", da);
2444 b = 4000000000;
2445 db = b;
2446 printf("db = %f\n", db);
2447 printf("nan != nan = %d, inf1 = %f, inf2 = %f\n", nan2 != nan2, inf1, inf2);
2448 #endif
2451 int fib(int n)
2453 if (n <= 2)
2454 return 1;
2455 else
2456 return fib(n-1) + fib(n-2);
2459 #if __GNUC__ == 3
2460 # define aligned_function 0
2461 #else
2462 void __attribute__((aligned(16))) aligned_function(int i) {}
2463 #endif
2465 void funcptr_test()
2467 void (*func)(int);
2468 int a;
2469 struct {
2470 int dummy;
2471 void (*func)(int);
2472 } st1;
2473 long diff;
2475 printf("funcptr:\n");
2476 func = &num;
2477 (*func)(12345);
2478 func = num;
2479 a = 1;
2480 a = 1;
2481 func(12345);
2482 /* more complicated pointer computation */
2483 st1.func = num;
2484 st1.func(12346);
2485 printf("sizeof1 = %d\n", sizeof(funcptr_test));
2486 printf("sizeof2 = %d\n", sizeof funcptr_test);
2487 printf("sizeof3 = %d\n", sizeof(&funcptr_test));
2488 printf("sizeof4 = %d\n", sizeof &funcptr_test);
2489 a = 0;
2490 func = num + a;
2491 diff = func - num;
2492 func(42);
2493 (func + diff)(42);
2494 (num + a)(43);
2496 /* Check that we can align functions */
2497 func = aligned_function;
2498 printf("aligned_function (should be zero): %d\n", ((int)(uintptr_t)func) & 15);
2501 void lloptest(long long a, long long b)
2503 unsigned long long ua, ub;
2505 ua = a;
2506 ub = b;
2507 /* arith */
2508 printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2509 a + b,
2510 a - b,
2511 a * b);
2513 if (b != 0) {
2514 printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2515 a / b,
2516 a % b);
2519 /* binary */
2520 printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2521 a & b,
2522 a | b,
2523 a ^ b);
2525 /* tests */
2526 printf("test: %d %d %d %d %d %d\n",
2527 a == b,
2528 a != b,
2529 a < b,
2530 a > b,
2531 a >= b,
2532 a <= b);
2534 printf("utest: %d %d %d %d %d %d\n",
2535 ua == ub,
2536 ua != ub,
2537 ua < ub,
2538 ua > ub,
2539 ua >= ub,
2540 ua <= ub);
2542 /* arith2 */
2543 a++;
2544 b++;
2545 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2546 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
2547 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
2548 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2549 b = ub = 0;
2550 printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
2553 void llshift(long long a, int b)
2555 printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2556 (unsigned long long)a >> b,
2557 a >> b,
2558 a << b);
2559 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2560 (unsigned long long)a >> 3,
2561 a >> 3,
2562 a << 3);
2563 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2564 (unsigned long long)a >> 35,
2565 a >> 35,
2566 a << 35);
2569 void llfloat(void)
2571 float fa;
2572 double da;
2573 LONG_DOUBLE lda;
2574 long long la, lb, lc;
2575 unsigned long long ula, ulb, ulc;
2576 la = 0x12345678;
2577 ula = 0x72345678;
2578 la = (la << 20) | 0x12345;
2579 ula = ula << 33;
2580 printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
2582 fa = la;
2583 da = la;
2584 lda = la;
2585 printf("lltof: %f %f %Lf\n", fa, da, lda);
2587 la = fa;
2588 lb = da;
2589 lc = lda;
2590 printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
2592 fa = ula;
2593 da = ula;
2594 lda = ula;
2595 printf("ulltof: %f %f %Lf\n", fa, da, lda);
2597 ula = fa;
2598 ulb = da;
2599 ulc = lda;
2600 printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
2603 long long llfunc1(int a)
2605 return a * 2;
2608 struct S {
2609 int id;
2610 char item;
2613 long long int value(struct S *v)
2615 return ((long long int)v->item);
2618 long long llfunc2(long long x, long long y, int z)
2620 return x * y * z;
2623 void check_opl_save_regs(char *a, long long b, int c)
2625 *a = b < 0 && !c;
2628 void longlong_test(void)
2630 long long a, b, c;
2631 int ia;
2632 unsigned int ua;
2633 printf("longlong_test:\n");
2634 printf("sizeof(long long) = %d\n", sizeof(long long));
2635 ia = -1;
2636 ua = -2;
2637 a = ia;
2638 b = ua;
2639 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2640 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
2641 (long long)1,
2642 (long long)-2,
2643 1LL,
2644 0x1234567812345679);
2645 a = llfunc1(-3);
2646 printf(LONG_LONG_FORMAT "\n", a);
2648 lloptest(1000, 23);
2649 lloptest(0xff, 0x1234);
2650 b = 0x72345678 << 10;
2651 lloptest(-3, b);
2652 llshift(0x123, 5);
2653 llshift(-23, 5);
2654 b = 0x72345678LL << 10;
2655 llshift(b, 47);
2657 llfloat();
2658 #if 1
2659 b = 0x12345678;
2660 a = -1;
2661 c = a + b;
2662 printf("%Lx\n", c);
2663 #endif
2665 /* long long reg spill test */
2667 struct S a;
2669 a.item = 3;
2670 printf("%lld\n", value(&a));
2672 lloptest(0x80000000, 0);
2675 long long *p, v, **pp;
2676 v = 1;
2677 p = &v;
2678 p[0]++;
2679 printf("another long long spill test : %lld\n", *p);
2680 pp = &p;
2682 v = llfunc2(**pp, **pp, ia);
2683 printf("a long long function (arm-)reg-args test : %lld\n", v);
2685 a = 68719476720LL;
2686 b = 4294967295LL;
2687 printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
2689 printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
2691 /* long long pointer deref in argument passing test */
2692 a = 0x123;
2693 long long *p = &a;
2694 llshift(*p, 5);
2696 /* shortening followed by widening */
2697 unsigned long long u = 0x8000000000000001ULL;
2698 u = (unsigned)(u + 1);
2699 printf("long long u=" ULONG_LONG_FORMAT "\n", u);
2700 u = 0x11223344aa998877ULL;
2701 u = (unsigned)(int)(u + 1);
2702 printf("long long u=" ULONG_LONG_FORMAT "\n", u);
2704 /* was a problem with missing save_regs in gen_opl on 32-bit platforms */
2705 char cc = 78;
2706 check_opl_save_regs(&cc, -1, 0);
2707 printf("check_opl_save_regs: %d\n", cc);
2710 void manyarg_test(void)
2712 LONG_DOUBLE ld = 1234567891234LL;
2713 printf("manyarg_test:\n");
2714 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2715 1, 2, 3, 4, 5, 6, 7, 8,
2716 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2717 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2718 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2719 1, 2, 3, 4, 5, 6, 7, 8,
2720 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2721 1234567891234LL, 987654321986LL,
2722 42.0, 43.0);
2723 printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2724 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2725 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2726 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2727 1234567891234LL, 987654321986LL,
2728 42.0, 43.0);
2729 printf("%d %d %d %d %d %d %d %d %Lf\n",
2730 1, 2, 3, 4, 5, 6, 7, 8, ld);
2731 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2732 LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
2733 1, 2, 3, 4, 5, 6, 7, 8,
2734 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2735 1234567891234LL, 987654321986LL,
2736 42.0, 43.0, ld);
2737 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2738 "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
2739 1, 2, 3, 4, 5, 6, 7, 8,
2740 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2741 ld, 1234567891234LL, 987654321986LL,
2742 42.0, 43.0, ld);
2745 void*
2746 va_arg_with_struct_ptr(va_list ap) {
2748 * This was a BUG identified with FFTW-3.3.8 on arm64.
2749 * The test case only checks it compiles on all supported
2750 * architectures. This function is not currently called.
2752 struct X { int _x; };
2753 struct X *x = va_arg(ap, struct X *);
2754 return x;
2757 void vprintf1(const char *fmt, ...)
2759 va_list ap, aq;
2760 const char *p;
2761 int c, i;
2762 double d;
2763 long long ll;
2764 LONG_DOUBLE ld;
2766 va_start(aq, fmt);
2767 va_copy(ap, aq);
2769 p = fmt;
2770 for(;;) {
2771 c = *p;
2772 if (c == '\0')
2773 break;
2774 p++;
2775 if (c == '%') {
2776 c = *p;
2777 switch(c) {
2778 case '\0':
2779 goto the_end;
2780 case 'd':
2781 i = va_arg(ap, int);
2782 printf("%d", i);
2783 break;
2784 case 'f':
2785 d = va_arg(ap, double);
2786 printf("%f", d);
2787 break;
2788 case 'l':
2789 ll = va_arg(ap, long long);
2790 printf(LONG_LONG_FORMAT, ll);
2791 break;
2792 case 'F':
2793 ld = va_arg(ap, LONG_DOUBLE);
2794 printf("%Lf", ld);
2795 break;
2797 p++;
2798 } else {
2799 putchar(c);
2802 the_end:
2803 va_end(aq);
2804 va_end(ap);
2807 struct myspace {
2808 short int profile;
2811 void stdarg_for_struct(struct myspace bob, ...)
2813 struct myspace george, bill;
2814 va_list ap;
2815 short int validate;
2817 va_start(ap, bob);
2818 bill = va_arg(ap, struct myspace);
2819 george = va_arg(ap, struct myspace);
2820 validate = va_arg(ap, int);
2821 printf("stdarg_for_struct: %d %d %d %d\n",
2822 bob.profile, bill.profile, george.profile, validate);
2823 va_end(ap);
2826 void stdarg_for_libc(const char *fmt, ...)
2828 va_list args;
2829 va_start(args, fmt);
2830 vprintf(fmt, args);
2831 va_end(args);
2834 void stdarg_syntax(int n, ...)
2836 int i;
2837 va_list ap;
2838 if (1)
2839 va_start(ap, n);
2840 else
2842 i = va_arg(ap, int);
2843 printf("stdarg_void_expr: %d\n", i);
2844 (va_end(ap));
2847 void stdarg_test(void)
2849 LONG_DOUBLE ld = 1234567891234LL;
2850 struct myspace bob;
2852 vprintf1("%d %d %d\n", 1, 2, 3);
2853 vprintf1("%f %d %f\n", 1.0, 2, 3.0);
2854 vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
2855 vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
2856 vprintf1("%d %f %l %F %d %f %l %F\n",
2857 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
2858 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
2859 1, 2, 3, 4, 5, 6, 7, 8,
2860 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
2861 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2862 1, 2, 3, 4, 5, 6, 7, 8,
2863 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2864 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2865 "%l %l %f %f\n",
2866 1, 2, 3, 4, 5, 6, 7, 8,
2867 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2868 1234567891234LL, 987654321986LL,
2869 42.0, 43.0);
2870 vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2871 "%l %l %f %f\n",
2872 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2873 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2874 1234567891234LL, 987654321986LL,
2875 42.0, 43.0);
2876 vprintf1("%d %d %d %d %d %d %d %d %F\n",
2877 1, 2, 3, 4, 5, 6, 7, 8, ld);
2878 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2879 "%l %l %f %f %F\n",
2880 1, 2, 3, 4, 5, 6, 7, 8,
2881 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2882 1234567891234LL, 987654321986LL,
2883 42.0, 43.0, ld);
2884 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2885 "%F %l %l %f %f %F\n",
2886 1, 2, 3, 4, 5, 6, 7, 8,
2887 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2888 ld, 1234567891234LL, 987654321986LL,
2889 42.0, 43.0, ld);
2891 bob.profile = 42;
2892 stdarg_for_struct(bob, bob, bob, bob.profile);
2893 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
2894 stdarg_syntax(1, 17);
2897 void whitespace_test(void)
2899 char *str;
2901 \f\v #if 1
2902 pri\
2903 ntf("whitspace:\n");\f\v
2904 #endif
2905 pf("N=%d\n", 2);
2907 #ifdef CORRECT_CR_HANDLING
2908 pri\
2909 ntf("aaa=%d\n", 3);
2910 #endif
2912 pri\
2914 ntf("min=%d\n", 4);
2916 #ifdef ACCEPT_CR_IN_STRINGS
2917 printf("len1=%d\n", strlen("
2918 "));
2919 #ifdef CORRECT_CR_HANDLING
2920 str = "
2922 printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
2923 #endif
2924 printf("len1=%d\n", strlen(" a
2925 "));
2926 #endif /* ACCEPT_CR_IN_STRINGS */
2929 int reltab[3] = { 1, 2, 3 };
2931 int *rel1 = &reltab[1];
2932 int *rel2 = &reltab[2];
2934 #ifdef _WIN64
2935 void relocation_test(void) {}
2936 #else
2937 void getmyaddress(void)
2939 printf("in getmyaddress\n");
2942 #ifdef __LP64__
2943 long __pa_symbol(void)
2945 /* This 64bit constant was handled incorrectly, it was used as addend
2946 (which can hold 64bit just fine) in connection with a symbol,
2947 and TCC generates wrong code for that (displacements are 32bit only).
2948 This effectively is "+ 0x80000000", and if addresses of globals
2949 are below 2GB the result should be a number without high 32 bits set. */
2950 return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
2952 #endif
2954 unsigned long theaddress = (unsigned long)getmyaddress;
2955 void relocation_test(void)
2957 void (*fptr)(void) = (void (*)(void))theaddress;
2958 printf("*rel1=%d\n", *rel1);
2959 printf("*rel2=%d\n", *rel2);
2960 fptr();
2961 #ifdef __LP64__
2962 printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
2963 #endif
2965 #endif
2967 void old_style_f(a,b,c)
2968 int a, b;
2969 double c;
2971 printf("a=%d b=%d b=%f\n", a, b, c);
2974 void decl_func1(int cmpfn())
2976 printf("cmpfn=%lx\n", (long)cmpfn);
2979 void decl_func2(cmpfn)
2980 int cmpfn();
2982 printf("cmpfn=%lx\n", (long)cmpfn);
2985 void old_style_function(void)
2987 old_style_f((void *)1, 2, 3.0);
2988 decl_func1(NULL);
2989 decl_func2(NULL);
2992 void alloca_test()
2994 #if defined __i386__ || defined __x86_64__ || defined __arm__
2995 char *p = alloca(16);
2996 strcpy(p,"123456789012345");
2997 printf("alloca: p is %s\n", p);
2998 char *demo = "This is only a test.\n";
2999 /* Test alloca embedded in a larger expression */
3000 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
3001 #endif
3004 void *bounds_checking_is_enabled()
3006 char ca[10], *cp = ca-1;
3007 return (ca != cp + 1) ? cp : NULL;
3010 typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
3012 void c99_vla_test(int size1, int size2)
3014 #if defined __i386__ || defined __x86_64__
3015 int size = size1 * size2;
3016 int tab1[size][2], tab2[10][2];
3017 void *tab1_ptr, *tab2_ptr, *bad_ptr;
3019 /* "size" should have been 'captured' at tab1 declaration,
3020 so modifying it should have no effect on VLA behaviour. */
3021 size = size-1;
3023 printf("Test C99 VLA 1 (sizeof): ");
3024 printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
3025 tab1_ptr = tab1;
3026 tab2_ptr = tab2;
3027 printf("Test C99 VLA 2 (ptrs subtract): ");
3028 printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
3029 printf("Test C99 VLA 3 (ptr add): ");
3030 printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
3031 printf("Test C99 VLA 4 (ptr access): ");
3032 tab1[size1][1] = 42;
3033 printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
3035 printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
3036 if (bad_ptr = bounds_checking_is_enabled()) {
3037 int *t1 = &tab1[size1 * size2 - 1][3];
3038 int *t2 = &tab2[9][3];
3039 printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED");
3040 printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED");
3042 char*c1 = 1 + sizeof(tab1) + (char*)tab1;
3043 char*c2 = 1 + sizeof(tab2) + (char*)tab2;
3044 printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED");
3045 printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED");
3047 int *i1 = tab1[-1];
3048 int *i2 = tab2[-1];
3049 printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED");
3050 printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED");
3052 int *x1 = tab1[size1 * size2 + 1];
3053 int *x2 = tab2[10 + 1];
3054 printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED");
3055 printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED");
3056 } else {
3057 printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
3059 printf("\n");
3060 #endif
3063 void sizeof_test(void)
3065 int a;
3066 int **ptr;
3068 printf("sizeof(int) = %d\n", sizeof(int));
3069 printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
3070 printf("sizeof(long) = %d\n", sizeof(long));
3071 printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
3072 printf("sizeof(short) = %d\n", sizeof(short));
3073 printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
3074 printf("sizeof(char) = %d\n", sizeof(char));
3075 printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
3076 printf("sizeof(func) = %d\n", sizeof sizeof_test());
3077 a = 1;
3078 printf("sizeof(a++) = %d\n", sizeof a++);
3079 printf("a=%d\n", a);
3080 ptr = NULL;
3081 printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
3083 /* The type of sizeof should be as large as a pointer, actually
3084 it should be size_t. */
3085 printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
3086 uintptr_t t = 1;
3087 uintptr_t t2;
3088 /* Effectively <<32, but defined also on 32bit machines. */
3089 t <<= 16;
3090 t <<= 16;
3091 t++;
3092 /* This checks that sizeof really can be used to manipulate
3093 uintptr_t objects, without truncation. */
3094 t2 = t & -sizeof(uintptr_t);
3095 printf ("%lu %lu\n", t, t2);
3097 /* some alignof tests */
3098 printf("__alignof__(int) = %d\n", __alignof__(int));
3099 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
3100 printf("__alignof__(short) = %d\n", __alignof__(short));
3101 printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
3102 printf("__alignof__(char) = %d\n", __alignof__(char));
3103 printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
3104 printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
3106 /* sizes of VLAs need to be evaluated even inside sizeof: */
3107 a = 2;
3108 printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
3109 /* And checking if sizeof compound literal works. Parenthesized: */
3110 printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
3111 sizeof( (struct {int i; int j;}){4,5} ));
3112 /* And as direct sizeof argument (as unary expression): */
3113 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
3114 sizeof (struct {short i; short j;}){4,5} );
3116 /* sizeof(x && y) should be sizeof(int), even if constant
3117 evaluating is possible. */
3118 printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
3119 printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
3120 printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
3121 printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
3124 void typeof_test(void)
3126 double a;
3127 typeof(a) b;
3128 typeof(float) c;
3130 a = 1.5;
3131 b = 2.5;
3132 c = 3.5;
3133 printf("a=%f b=%f c=%f\n", a, b, c);
3137 struct hlist_node;
3138 struct hlist_head {
3139 struct hlist_node *first, *last;
3142 void consume_ulong (unsigned long i)
3144 i = 0;
3147 void statement_expr_test(void)
3149 int a, i;
3151 /* Basic stmt expr test */
3152 a = 0;
3153 for(i=0;i<10;i++) {
3154 a += 1 +
3155 ( { int b, j;
3156 b = 0;
3157 for(j=0;j<5;j++)
3158 b += j; b;
3159 } );
3161 printf("a=%d\n", a);
3163 /* Test that symbols aren't freed prematurely.
3164 With SYM_DEBUG valgrind will show a read from a freed
3165 symbol, and tcc will show an (invalid) warning on the initialization
3166 of 'ptr' below, if symbols are popped after the stmt expr. */
3167 void *v = (void*)39;
3168 typeof(({
3169 (struct hlist_node *)v;
3170 })) x;
3171 typeof (x)
3172 ptr = (struct hlist_node *)v;
3174 /* This part used to segfault when symbols were popped prematurely.
3175 The symbols for the static local would be overwritten with
3176 helper symbols from the pre-processor expansions in between. */
3177 #define some_attr __attribute__((aligned(1)))
3178 #define tps(str) ({ \
3179 static const char *t some_attr = str; \
3180 t; \
3182 printf ("stmtexpr: %s %s\n",
3183 tps("somerandomlongstring"),
3184 tps("anotherlongstring"));
3186 /* Test that the three decls of 't' don't interact. */
3187 int t = 40;
3188 int b = ({ int t = 41; t; });
3189 int c = ({ int t = 42; t; });
3191 /* Test that aggregate return values work. */
3192 struct hlist_head h
3193 = ({
3194 typedef struct hlist_head T;
3195 long pre = 48;
3196 T t = { (void*)43, (void*)44 };
3197 long post = 49;
3200 printf ("stmtexpr: %d %d %d\n", t, b, c);
3201 printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
3203 /* Test that we can give out addresses of local labels. */
3204 consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
3206 /* Test interaction between local and global label stacks and the
3207 need to defer popping symbol from them when within statement
3208 expressions. Note how the labels are both named LBL. */
3209 i = 0;
3212 __label__ LBL;
3213 LBL: if (i++ == 0) goto LBL;
3215 /* jump to a classical label out of an expr-stmt that had previously
3216 overshadowed that classical label */
3217 goto LBL;
3219 LBL:
3220 printf("stmtexpr: %d should be 2\n", i);
3223 void local_label_test(void)
3225 int a;
3226 goto l1;
3228 a = 1 + ({
3229 __label__ l1, l2, l3, l4;
3230 goto l1;
3232 printf("aa1\n");
3233 goto l3;
3235 printf("aa3\n");
3236 goto l4;
3238 printf("aa2\n");
3239 goto l2;
3240 l3:;
3243 printf("a=%d\n", a);
3244 return;
3246 printf("bb1\n");
3247 goto l2;
3249 printf("bb2\n");
3250 goto l4;
3253 /* inline assembler test */
3254 #if defined(__i386__) || defined(__x86_64__)
3256 /* from linux kernel */
3257 static char * strncat1(char * dest,const char * src,size_t count)
3259 long d0, d1, d2, d3;
3260 __asm__ __volatile__(
3261 "repne\n\t"
3262 "scasb\n\t"
3263 "dec %1\n\t"
3264 "mov %8,%3\n"
3265 "1:\tdec %3\n\t"
3266 "js 2f\n\t"
3267 "lodsb\n\t"
3268 "stosb\n\t"
3269 "testb %%al,%%al\n\t"
3270 "jne 1b\n"
3271 "2:\txor %2,%2\n\t"
3272 "stosb"
3273 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3274 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3275 : "memory");
3276 return dest;
3279 static char * strncat2(char * dest,const char * src,size_t count)
3281 long d0, d1, d2, d3;
3282 __asm__ __volatile__(
3283 "repne scasb\n\t" /* one-line repne prefix + string op */
3284 "dec %1\n\t"
3285 "mov %8,%3\n"
3286 "1:\tdec %3\n\t"
3287 "js 2f\n\t"
3288 "lodsb\n\t"
3289 "stosb\n\t"
3290 "testb %%al,%%al\n\t"
3291 "jne 1b\n"
3292 "2:\txor %2,%2\n\t"
3293 "stosb"
3294 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3295 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3296 : "memory");
3297 return dest;
3300 static inline void * memcpy1(void * to, const void * from, size_t n)
3302 long d0, d1, d2;
3303 __asm__ __volatile__(
3304 "rep ; movsl\n\t"
3305 "testb $2,%b4\n\t"
3306 "je 1f\n\t"
3307 "movsw\n"
3308 "1:\ttestb $1,%b4\n\t"
3309 "je 2f\n\t"
3310 "movsb\n"
3311 "2:"
3312 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3313 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3314 : "memory");
3315 return (to);
3318 static inline void * memcpy2(void * to, const void * from, size_t n)
3320 long d0, d1, d2;
3321 __asm__ __volatile__(
3322 "rep movsl\n\t" /* one-line rep prefix + string op */
3323 "testb $2,%b4\n\t"
3324 "je 1f\n\t"
3325 "movsw\n"
3326 "1:\ttestb $1,%b4\n\t"
3327 "je 2f\n\t"
3328 "movsb\n"
3329 "2:"
3330 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3331 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3332 : "memory");
3333 return (to);
3336 static __inline__ void sigaddset1(unsigned int *set, int _sig)
3338 __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
3341 static __inline__ void sigdelset1(unsigned int *set, int _sig)
3343 asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
3346 #ifndef __APPLE__
3347 /* clang's inline asm is uncapable of 'xchgb %b0,%h0' */
3348 static __inline__ __const__ unsigned int swab32(unsigned int x)
3350 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
3351 "rorl $16,%0\n\t" /* swap words */
3352 "xchgb %b0,%h0" /* swap higher bytes */
3353 :"=" "q" (x)
3354 : "0" (x));
3355 return x;
3357 #endif
3359 static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
3361 unsigned long long res;
3362 #ifdef __x86_64__
3363 /* Using the A constraint is wrong (it means rdx:rax, which is too large)
3364 but still test the 32bit->64bit mull. */
3365 unsigned int resh, resl;
3366 __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
3367 res = ((unsigned long long)resh << 32) | resl;
3368 #else
3369 __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
3370 #endif
3371 return res;
3374 static __inline__ unsigned long long inc64(unsigned long long a)
3376 unsigned long long res;
3377 #ifdef __x86_64__
3378 /* Using the A constraint is wrong, and increments are tested
3379 elsewhere. */
3380 res = a + 1;
3381 #else
3382 __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
3383 #endif
3384 return res;
3387 struct struct123 {
3388 int a;
3389 int b;
3391 struct struct1231 {
3392 unsigned long addr;
3395 unsigned long mconstraint_test(struct struct1231 *r)
3397 unsigned long ret;
3398 unsigned int a[2];
3399 a[0] = 0;
3400 __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
3401 : "=&r" (ret), "=m" (a)
3402 : "m" (*(struct struct123 *)r->addr));
3403 return ret + a[0];
3406 #ifdef __x86_64__
3407 int fls64(unsigned long long x)
3409 int bitpos = -1;
3410 asm("bsrq %1,%q0"
3411 : "+r" (bitpos)
3412 : "rm" (x));
3413 return bitpos + 1;
3415 #endif
3417 void other_constraints_test(void)
3419 unsigned long ret;
3420 int var;
3421 #ifndef _WIN64
3422 __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
3423 printf ("oc1: %d\n", ret == (unsigned long)&var);
3424 #endif
3427 #ifndef _WIN32
3428 /* Test global asm blocks playing with aliases. */
3429 void base_func(void)
3431 printf ("asmc: base\n");
3434 #ifndef __APPLE__
3435 extern void override_func1 (void);
3436 extern void override_func2 (void);
3438 asm(".weak override_func1\n.set override_func1, base_func");
3439 asm(".set override_func1, base_func");
3440 asm(".set override_func2, base_func");
3442 void override_func2 (void)
3444 printf ("asmc: override2\n");
3447 /* This checks a construct used by the linux kernel to encode
3448 references to strings by PC relative references. */
3449 extern int bug_table[] __attribute__((section("__bug_table")));
3450 char * get_asm_string (void)
3452 /* On i386 when -fPIC is enabled this would cause a compile error with GCC,
3453 the problem being the "i" constraint used with a symbolic operand
3454 resolving to a local label. That check is overly zealous as the code
3455 within the asm makes sure to use it only in PIC-possible contexts,
3456 but all GCC versions behave like so. We arrange for PIC to be disabled
3457 for compiling tcctest.c in the Makefile.
3459 Additionally the usage of 'c' in "%c0" in the template is actually wrong,
3460 as that would expect an operand that is a condition code. The operand
3461 as is (a local label) is accepted by GCC in non-PIC mode, and on x86-64.
3462 What the linux kernel really wanted is 'p' to disable the addition of '$'
3463 to the printed operand (as in "$.LC0" where the template only wants the
3464 bare operand ".LC0"). But the code below is what the linux kernel
3465 happens to use and as such is the one we want to test. */
3466 extern int some_symbol;
3467 asm volatile (".globl some_symbol\n"
3468 "jmp .+6\n"
3469 "1:\n"
3470 "some_symbol: .long 0\n"
3471 ".pushsection __bug_table, \"a\"\n"
3472 ".globl bug_table\n"
3473 "bug_table:\n"
3474 /* The first entry (1b-2b) is unused in this test,
3475 but we include it to check if cross-section
3476 PC-relative references work. */
3477 "2:\t.long 1b - 2b, %c0 - 2b\n"
3478 ".popsection\n" : : "i" ("A string"));
3479 char * str = ((char*)bug_table) + bug_table[1];
3480 return str;
3483 /* This checks another constructs with local labels. */
3484 extern unsigned char alld_stuff[];
3485 asm(".data\n"
3486 ".byte 41\n"
3487 "alld_stuff:\n"
3488 "661:\n"
3489 ".byte 42\n"
3490 "662:\n"
3491 ".pushsection .data.ignore\n"
3492 ".long 661b - .\n" /* This reference to 661 generates an external sym
3493 which shouldn't somehow overwrite the offset that's
3494 already determined for it. */
3495 ".popsection\n"
3496 ".byte 662b - 661b\n" /* So that this value is undeniably 1. */);
3498 void asm_local_label_diff (void)
3500 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
3502 #endif
3504 /* This checks that static local variables are available from assembler. */
3505 void asm_local_statics (void)
3507 static int localint = 41;
3508 asm("incl %0" : "+m" (localint));
3509 printf ("asm_local_statics: %d\n", localint);
3511 #endif
3513 static
3514 unsigned int set;
3516 void fancy_copy (unsigned *in, unsigned *out)
3518 asm volatile ("" : "=r" (*out) : "0" (*in));
3521 void fancy_copy2 (unsigned *in, unsigned *out)
3523 asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
3526 #if defined __x86_64__ && !defined _WIN64
3527 void clobber_r12(void)
3529 asm volatile("mov $1, %%r12" ::: "r12");
3531 #endif
3533 void test_high_clobbers_really(void)
3535 #if defined __x86_64__ && !defined _WIN64
3536 register long val asm("r12");
3537 long val2;
3538 /* This tests if asm clobbers correctly save/restore callee saved
3539 registers if they are clobbered and if it's the high 8 x86-64
3540 registers. This is fragile for GCC as the constraints do not
3541 correctly capture the data flow, but good enough for us. */
3542 asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
3543 clobber_r12();
3544 asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
3545 printf("asmhc: 0x%x\n", val2);
3546 #endif
3549 void test_high_clobbers(void)
3551 #if defined __x86_64__ && !defined _WIN64
3552 long x1, x2;
3553 asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */
3554 test_high_clobbers_really();
3555 asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */
3556 asm volatile("mov %0,%%r12" :: "m" (x1)); /* restore r12 */
3557 /* should be 0 but tcc doesn't save r12 automatically, which has
3558 bad effects when gcc helds TCCState *s in r12 in tcc.c:main */
3559 //printf("r12-clobber-diff: %lx\n", x2 - x1);
3560 #endif
3563 static long cpu_number;
3564 void trace_console(long len, long len2)
3566 #ifdef __x86_64__
3567 /* This generated invalid code when the emission of the switch
3568 table isn't disabled. The asms are necessary to show the bug,
3569 normal statements don't work (they need to generate some code
3570 even under nocode_wanted, which normal statements don't do,
3571 but asms do). Also at least these number of cases is necessary
3572 to generate enough "random" bytes. They ultimately are enough
3573 to create invalid instruction patterns to which the first
3574 skip-to-decision-table jump jumps. If decision table emission
3575 is disabled all of this is no problem.
3577 It also is necessary that the switches are in a statement expression
3578 (which has the property of not being enterable from outside. no
3579 matter what). */
3580 if (0
3583 long pscr_ret__;
3584 switch(len) {
3585 case 4:
3587 long pfo_ret__;
3588 switch (len2) {
3589 case 8: printf("bla"); pfo_ret__ = 42; break;
3591 pscr_ret__ = pfo_ret__;
3593 break;
3594 case 8:
3596 long pfo_ret__;
3597 switch (len2) {
3598 case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3599 case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3600 case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3601 case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3602 default: printf("impossible\n");
3604 pscr_ret__ = pfo_ret__;
3606 break;
3608 pscr_ret__;
3611 printf("huh?\n");
3613 #endif
3616 void test_asm_dead_code(void)
3618 long rdi;
3619 /* Try to make sure that xdi contains a zero, and hence will
3620 lead to a segfault if the next asm is evaluated without
3621 arguments being set up. */
3622 asm volatile ("" : "=D" (rdi) : "0" (0));
3623 (void)sizeof (({
3624 int var;
3625 /* This shouldn't trigger a segfault, either the argument
3626 registers need to be set up and the asm emitted despite
3627 this being in an unevaluated context, or both the argument
3628 setup _and_ the asm emission need to be suppressed. The latter
3629 is better. Disabling asm code gen when suppression is on
3630 also fixes the above trace_console bug, but that came earlier
3631 than asm suppression. */
3632 asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
3633 var;
3634 }));
3637 void test_asm_call(void)
3639 #if defined __x86_64__ && !defined _WIN64
3640 static char str[] = "PATH";
3641 char *s;
3642 /* This tests if a reference to an undefined symbol from an asm
3643 block, which isn't otherwise referenced in this file, is correctly
3644 regarded as global symbol, so that it's resolved by other object files
3645 or libraries. We chose getenv here, which isn't used anywhere else
3646 in this file. (If we used e.g. printf, which is used we already
3647 would have a global symbol entry, not triggering the bug which is
3648 tested here). */
3649 /* two pushes so stack remains aligned */
3650 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
3651 #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) && !defined(__APPLE__)
3652 "call getenv@plt;"
3653 #elif defined(__APPLE__)
3654 "call _getenv;"
3655 #else
3656 "call getenv;"
3657 #endif
3658 "pop %%rdi; pop %%rdi"
3659 : "=a" (s) : "r" (str));
3660 printf("asmd: %s\n", s);
3661 #endif
3664 #if defined __x86_64__
3665 # define RX "(%rip)"
3666 #else
3667 # define RX
3668 #endif
3670 void asm_dot_test(void)
3672 int x;
3673 for (x = 1;; ++x) {
3674 int r = x;
3675 switch (x) {
3676 case 1:
3677 asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
3678 case 2:
3679 #ifndef __APPLE__
3680 /* clangs internal assembler is broken */
3681 asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
3682 #else
3683 asm(".text; mov $0, %eax; jmp p0");
3684 #endif
3685 case 3:
3686 #if !defined(_WIN32) && !defined(__APPLE__)
3687 asm(".pushsection \".data\"; Y=.; .int 999; X=Y; .int 456; X=.-4; .popsection");
3688 #else
3689 asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4; .text");
3690 #endif
3691 asm(".text; mov X"RX",%eax; jmp p0");
3692 case 4:
3693 #ifdef __APPLE__
3694 /* Bah! Clang! Doesn't want to redefine 'X' */
3695 asm(".text; mov $123,%eax; jmp p0");
3696 #else
3697 #ifndef _WIN32
3698 asm(".data; X=.; .int 789; Y=.; .int 999; .previous");
3699 #else
3700 asm(".data; X=.; .int 789; Y=.; .int 999; .text");
3701 #endif
3702 asm(".text; mov X"RX",%eax; X=Y; jmp p0");
3703 #endif
3704 case 0:
3705 asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
3707 if (r == x)
3708 break;
3709 printf("asm_dot_test %d: %d\n", x, r);
3713 void asm_test(void)
3715 char buf[128];
3716 unsigned int val, val2;
3717 struct struct123 s1;
3718 struct struct1231 s2 = { (unsigned long)&s1 };
3719 /* Hide the outer base_func, but check later that the inline
3720 asm block gets the outer one. */
3721 int base_func = 42;
3722 void override_func3 (void);
3723 unsigned long asmret;
3724 #ifdef BOOL_ISOC99
3725 _Bool somebool;
3726 #endif
3727 register int regvar asm("%esi");
3729 printf("inline asm:\n");
3731 // parse 0x1E-1 as 3 tokens in asm mode
3732 asm volatile ("mov $0x1E-1,%eax");
3734 /* test the no operand case */
3735 asm volatile ("xorl %eax, %eax");
3737 memcpy1(buf, "hello", 6);
3738 strncat1(buf, " worldXXXXX", 3);
3739 printf("%s\n", buf);
3741 memcpy2(buf, "hello", 6);
3742 strncat2(buf, " worldXXXXX", 3);
3743 printf("%s\n", buf);
3745 /* 'A' constraint test */
3746 printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
3747 printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
3749 s1.a = 42;
3750 s1.b = 43;
3751 printf("mconstraint: %d", mconstraint_test(&s2));
3752 printf(" %d %d\n", s1.a, s1.b);
3753 other_constraints_test();
3754 set = 0xff;
3755 sigdelset1(&set, 2);
3756 sigaddset1(&set, 16);
3757 /* NOTE: we test here if C labels are correctly restored after the
3758 asm statement */
3759 goto label1;
3760 label2:
3761 __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
3762 printf("set=0x%x\n", set);
3763 val = 0x01020304;
3764 #ifndef __APPLE__
3765 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
3766 #endif
3767 #ifndef _WIN32
3768 #ifndef __APPLE__
3769 override_func1();
3770 override_func2();
3771 /* The base_func ref from the following inline asm should find
3772 the global one, not the local decl from this function. */
3773 asm volatile(".weak override_func3\n.set override_func3, base_func");
3774 override_func3();
3775 printf("asmstr: %s\n", get_asm_string());
3776 asm_local_label_diff();
3777 #endif
3778 asm_local_statics();
3779 #endif
3780 #ifndef __APPLE__
3781 /* clang can't deal with the type change */
3782 /* Check that we can also load structs of appropriate layout
3783 into registers. */
3784 asm volatile("" : "=r" (asmret) : "0"(s2));
3785 if (asmret != s2.addr)
3786 printf("asmstr: failed\n");
3787 #endif
3788 #ifdef BOOL_ISOC99
3789 /* Check that the typesize correctly sets the register size to
3790 8 bit. */
3791 asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
3792 if (!somebool)
3793 printf("asmbool: failed\n");
3794 #endif
3795 val = 43;
3796 fancy_copy (&val, &val2);
3797 printf ("fancycpy(%d)=%d\n", val, val2);
3798 val = 44;
3799 fancy_copy2 (&val, &val2);
3800 printf ("fancycpy2(%d)=%d\n", val, val2);
3801 asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
3802 printf ("regvar=%x\n", regvar);
3803 test_high_clobbers();
3804 trace_console(8, 8);
3805 test_asm_dead_code();
3806 test_asm_call();
3807 asm_dot_test();
3808 return;
3809 label1:
3810 goto label2;
3813 #else
3815 void asm_test(void)
3819 #endif
3821 #define COMPAT_TYPE(type1, type2) \
3823 printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
3824 __builtin_types_compatible_p (type1, type2));\
3827 int constant_p_var;
3829 void builtin_test(void)
3831 short s;
3832 int i;
3833 long long ll;
3834 #if GCC_MAJOR >= 3
3835 COMPAT_TYPE(int, int);
3836 COMPAT_TYPE(int, unsigned int);
3837 COMPAT_TYPE(int, char);
3838 COMPAT_TYPE(int, const int);
3839 COMPAT_TYPE(int, volatile int);
3840 COMPAT_TYPE(int *, int *);
3841 COMPAT_TYPE(int *, void *);
3842 COMPAT_TYPE(int *, const int *);
3843 COMPAT_TYPE(char *, unsigned char *);
3844 COMPAT_TYPE(char *, signed char *);
3845 COMPAT_TYPE(char *, char *);
3846 /* space is needed because tcc preprocessor introduces a space between each token */
3847 COMPAT_TYPE(char * *, void *);
3848 #endif
3849 printf("res1 = %d\n", __builtin_constant_p(1));
3850 printf("res2 = %d\n", __builtin_constant_p(1 + 2));
3851 printf("res3 = %d\n", __builtin_constant_p(&constant_p_var));
3852 printf("res4 = %d\n", __builtin_constant_p(constant_p_var));
3853 printf("res5 = %d\n", __builtin_constant_p(100000 / constant_p_var));
3854 #ifndef __APPLE__
3855 /* clang doesn't regard this as constant expression */
3856 printf("res6 = %d\n", __builtin_constant_p(i && 0));
3857 #endif
3858 printf("res7 = %d\n", __builtin_constant_p(i && 1));
3859 #ifndef __APPLE__
3860 printf("res8 = %d\n", __builtin_constant_p(i && 0 ? i : 34));
3861 #endif
3862 s = 1;
3863 ll = 2;
3864 i = __builtin_choose_expr (1 != 0, ll, s);
3865 printf("bce: %d\n", i);
3866 i = __builtin_choose_expr (1 != 1, ll, s);
3867 printf("bce: %d\n", i);
3868 i = sizeof (__builtin_choose_expr (1, ll, s));
3869 printf("bce: %d\n", i);
3870 i = sizeof (__builtin_choose_expr (0, ll, s));
3871 printf("bce: %d\n", i);
3873 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
3876 #ifndef _WIN32
3877 extern int __attribute__((weak)) weak_f1(void);
3878 extern int __attribute__((weak)) weak_f2(void);
3879 extern int weak_f3(void);
3880 extern int __attribute__((weak)) weak_v1;
3881 extern int __attribute__((weak)) weak_v2;
3882 extern int weak_v3;
3884 extern int (*weak_fpa)() __attribute__((weak));
3885 extern int __attribute__((weak)) (*weak_fpb)();
3886 extern __attribute__((weak)) int (*weak_fpc)();
3888 extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
3889 extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ;
3890 extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
3891 extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak));
3892 extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ;
3893 extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
3895 #ifndef __APPLE__
3896 static const size_t dummy = 0;
3897 extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy")));
3898 extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2;
3899 extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3;
3900 #endif
3902 int some_lib_func(void);
3903 int dummy_impl_of_slf(void) { return 444; }
3904 #ifndef __APPLE__
3905 int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf")));
3906 #endif
3908 int weak_toolate() __attribute__((weak));
3909 int weak_toolate() { return 0; }
3911 void __attribute__((weak)) weak_test(void)
3913 printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
3914 printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123);
3915 printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123);
3916 printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123);
3917 printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123);
3918 printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123);
3920 printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
3921 printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
3922 printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
3924 printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
3925 printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
3926 printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
3927 printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
3928 printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
3929 printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
3930 #ifndef __APPLE__
3931 printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
3932 #endif
3935 int __attribute__((weak)) weak_f2() { return 222; }
3936 int __attribute__((weak)) weak_f3() { return 333; }
3937 int __attribute__((weak)) weak_v2 = 222;
3938 int __attribute__((weak)) weak_v3 = 333;
3939 #endif
3941 void const_func(const int a)
3945 void const_warn_test(void)
3947 const_func(1);
3950 struct condstruct {
3951 int i;
3954 int getme (struct condstruct *s, int i)
3956 int i1 = (i == 0 ? 0 : s)->i;
3957 int i2 = (i == 0 ? s : 0)->i;
3958 int i3 = (i == 0 ? (void*)0 : s)->i;
3959 int i4 = (i == 0 ? s : (void*)0)->i;
3960 return i1 + i2 + i3 + i4;
3963 struct global_data
3965 int a[40];
3966 int *b[40];
3969 struct global_data global_data;
3971 int global_data_getstuff (int *, int);
3973 void global_data_callit (int i)
3975 *global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
3978 int global_data_getstuff (int *p, int i)
3980 return *p + i;
3983 void global_data_test (void)
3985 global_data.a[0] = 42;
3986 global_data.b[0] = &global_data.a[0];
3987 global_data_callit (0);
3988 printf ("%d\n", global_data.a[0]);
3991 struct cmpcmpS
3993 unsigned char fill : 3;
3994 unsigned char b1 : 1;
3995 unsigned char b2 : 1;
3996 unsigned char fill2 : 3;
3999 int glob1, glob2, glob3;
4001 void compare_comparisons (struct cmpcmpS *s)
4003 if (s->b1 != (glob1 == glob2)
4004 || (s->b2 != (glob1 == glob3)))
4005 printf ("comparing comparisons broken\n");
4008 void cmp_comparison_test(void)
4010 struct cmpcmpS s;
4011 s.b1 = 1;
4012 glob1 = 42; glob2 = 42;
4013 s.b2 = 0;
4014 glob3 = 43;
4015 compare_comparisons (&s);
4018 int fcompare (double a, double b, int code)
4020 switch (code) {
4021 case 0: return a == b;
4022 case 1: return a != b;
4023 case 2: return a < b;
4024 case 3: return a >= b;
4025 case 4: return a > b;
4026 case 5: return a <= b;
4028 return 0;
4031 void math_cmp_test(void)
4033 double nan = 0.0/0.0;
4034 double one = 1.0;
4035 double two = 2.0;
4036 int comp = 0;
4037 int v;
4038 #define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
4040 /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
4041 And it does this in various ways so that all code generation paths
4042 are checked (generating inverted tests, or non-inverted tests, or
4043 producing a 0/1 value without jumps (that's done in the fcompare
4044 function). */
4045 #define FCMP(a,b,op,iop,code) \
4046 if (fcompare (a,b,code)) \
4047 bug (a,b,op,iop,1); \
4048 if (a op b) \
4049 bug (a,b,op,iop,2); \
4050 if (a iop b) \
4052 else \
4053 bug (a,b,op,iop,3); \
4054 if ((a op b) || comp) \
4055 bug (a,b,op,iop,4); \
4056 if ((a iop b) || comp) \
4058 else \
4059 bug (a,b,op,iop,5); \
4060 if (v = !(a op b), !v) bug(a,b,op,iop,7);
4062 /* Equality tests. */
4063 FCMP(nan, nan, ==, !=, 0);
4064 FCMP(one, two, ==, !=, 0);
4065 FCMP(one, one, !=, ==, 1);
4066 /* Non-equality is a bit special. */
4067 if (!fcompare (nan, nan, 1))
4068 bug (nan, nan, !=, ==, 6);
4070 /* Relational tests on numbers. */
4071 FCMP(two, one, <, >=, 2);
4072 FCMP(one, two, >=, <, 3);
4073 FCMP(one, two, >, <=, 4);
4074 FCMP(two, one, <=, >, 5);
4076 /* Relational tests on NaNs. Note that the inverse op here is
4077 always !=, there's no operator in C that is equivalent to !(a < b),
4078 when NaNs are involved, same for the other relational ops. */
4079 FCMP(nan, nan, <, !=, 2);
4080 FCMP(nan, nan, >=, !=, 3);
4081 FCMP(nan, nan, >, !=, 4);
4082 FCMP(nan, nan, <=, !=, 5);
4085 double get100 () { return 100.0; }
4087 void callsave_test(void)
4089 #if defined __i386__ || defined __x86_64__ || defined __arm__
4090 int i, s; double *d; double t;
4091 s = sizeof (double);
4092 printf ("callsavetest: %d\n", s);
4093 d = alloca (sizeof(double));
4094 d[0] = 10.0;
4095 /* x86-64 had a bug were the next call to get100 would evict
4096 the lvalue &d[0] as VT_LLOCAL, and the reload would be done
4097 in int type, not pointer type. When alloca returns a pointer
4098 with the high 32 bit set (which is likely on x86-64) the access
4099 generates a segfault. */
4100 i = d[0] > get100 ();
4101 printf ("%d\n", i);
4102 #endif
4106 void bfa3(ptrdiff_t str_offset)
4108 printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
4110 void bfa2(ptrdiff_t str_offset)
4112 printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
4113 bfa3(str_offset);
4115 void bfa1(ptrdiff_t str_offset)
4117 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
4118 bfa2(str_offset);
4121 void builtin_frame_address_test(void)
4123 /* builtin_frame_address fails on ARM with gcc which make test3 fail */
4124 #ifndef __arm__
4125 char str[] = "__builtin_frame_address";
4126 char *fp0 = __builtin_frame_address(0);
4128 printf("str: %s\n", str);
4129 #ifndef __riscv
4130 bfa1(str-fp0);
4131 #endif
4132 #endif
4135 char via_volatile (char i)
4137 char volatile vi;
4138 vi = i;
4139 return vi;
4142 struct __attribute__((__packed__)) Spacked {
4143 char a;
4144 short b;
4145 int c;
4147 struct Spacked spacked;
4148 typedef struct __attribute__((__packed__)) {
4149 char a;
4150 short b;
4151 int c;
4152 } Spacked2;
4153 Spacked2 spacked2;
4154 typedef struct Spacked3_s {
4155 char a;
4156 short b;
4157 int c;
4158 } __attribute__((__packed__)) Spacked3;
4159 Spacked3 spacked3;
4160 struct gate_struct64 {
4161 unsigned short offset_low;
4162 unsigned short segment;
4163 unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
4164 unsigned short offset_middle;
4165 unsigned offset_high;
4166 unsigned zero1;
4167 } __attribute__((packed));
4168 typedef struct gate_struct64 gate_desc;
4169 gate_desc a_gate_desc;
4170 void attrib_test(void)
4172 #ifndef _WIN32
4173 printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
4174 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
4175 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
4176 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
4177 #endif
4179 extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
4180 strange_attrib_placement (void);
4182 void * __attribute__((__unused__)) get_void_ptr (void *a)
4184 return a;
4187 /* This part checks for a bug in TOK_GET (used for inline expansion),
4188 where the large long long constant left the the high bits set for
4189 the integer constant token. */
4190 static inline
4191 int __get_order(unsigned long long size)
4193 int order;
4194 size -= 0xffff880000000000ULL; // this const left high bits set in the token
4196 struct S { int i : 1; } s; // constructed for this '1'
4198 order = size;
4199 return order;
4202 /* This just forces the above inline function to be actually emitted. */
4203 int force_get_order(unsigned long s)
4205 return __get_order(s);
4208 #define pv(m) printf(sizeof (s->m + 0) == 8 ? "%016llx\n" : "%02x\n", s->m)
4210 /* Test failed when using bounds checking */
4211 void bounds_check1_test (void)
4213 struct s {
4214 int x;
4215 long long y;
4216 } _s, *s = &_s;
4217 s->x = 10;
4218 s->y = 20;
4219 pv(x);
4220 pv(y);