revert 'no-libtcc1' feature
[tinycc.git] / tests / tcctest.c
blob4696779d82333211c5e7e398d8e247e4ff51f381
1 /*
2 * TCC auto test program
3 */
4 #include "config.h"
6 /* identify the configured reference compiler in use */
7 #define CC_gcc 1
8 #define CC_clang 2
9 #define CC_tcc 3
11 /* Unfortunately, gcc version < 3 does not handle that! */
12 #define ALL_ISOC99
14 /* only gcc 3 handles _Bool correctly */
15 #define BOOL_ISOC99
17 /* __VA_ARGS__ and __func__ support */
18 #define C99_MACROS
20 #ifndef __TINYC__
21 typedef __SIZE_TYPE__ uintptr_t;
22 #endif
24 #if defined(_WIN32)
25 #define LONG_LONG_FORMAT "%lld"
26 #define ULONG_LONG_FORMAT "%llu"
27 #else
28 #define LONG_LONG_FORMAT "%Ld"
29 #define ULONG_LONG_FORMAT "%Lu"
30 #endif
32 // MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
33 #if defined(_WIN32) && defined(__GNUC__)
34 #define LONG_DOUBLE double
35 #define LONG_DOUBLE_LITERAL(x) x
36 #else
37 #define LONG_DOUBLE long double
38 #define LONG_DOUBLE_LITERAL(x) x ## L
39 #endif
41 /* test various include syntaxes */
43 #define TCCLIB_INC <tcclib.h>
44 #define TCCLIB_INC1 <tcclib
45 #define TCCLIB_INC2 h>
46 #define TCCLIB_INC3 "tcclib.h"
48 #include TCCLIB_INC
50 #include TCCLIB_INC1.TCCLIB_INC2
52 #include TCCLIB_INC1.h>
54 #include TCCLIB_INC3
56 #include <tcclib.h>
58 #include "tcclib.h"
60 #include "tcctest.h"
62 /* Test two more ways to include a file named like a pp-number */
63 #define INC(name) <tests/name.h>
64 #define funnyname 42test.h
65 #define incdir tests/
66 #ifdef __clang__
67 /* clang's preprocessor is broken in this regard and adds spaces
68 to the tokens 'incdir' and 'funnyname' when expanding */
69 #define incname <tests/42test.h>
70 #else
71 #define incname < incdir funnyname >
72 #endif
73 #define __stringify(x) #x
74 #define stringify(x) __stringify(x)
75 #include INC(42test)
76 #include incname
77 #include stringify(funnyname)
79 int fib(int n);
80 void num(int n);
81 void forward_ref(void);
82 int isid(int c);
84 /* Line joining happens before tokenization, so the following
85 must be parsed as ellipsis. */
86 void funny_line_continuation (int, ..\
87 . );
89 #define A 2
90 #define N 1234 + A
91 #define pf printf
92 #define M1(a, b) (a) + (b)
94 #define str\
95 (s) # s
96 #define glue(a, b) a ## b
97 #define xglue(a, b) glue(a, b)
98 #define HIGHLOW "hello"
99 #define LOW LOW ", world"
101 static int onetwothree = 123;
102 #define onetwothree4 onetwothree
103 #define onetwothree xglue(onetwothree,4)
105 #define min(a, b) ((a) < (b) ? (a) : (b))
107 #ifdef C99_MACROS
108 #define dprintf(level,...) printf(__VA_ARGS__)
109 #endif
111 /* gcc vararg macros */
112 #define dprintf1(level, fmt, args...) printf(fmt, ## args)
114 #define MACRO_NOARGS()
116 #define AAA 3
117 #undef AAA
118 #define AAA 4
120 #if 1
121 #define B3 1
122 #elif 1
123 #define B3 2
124 #elif 0
125 #define B3 3
126 #else
127 #define B3 4
128 #endif
130 #ifdef __TINYC__
131 /* We try to handle this syntax. Make at least sure it doesn't segfault. */
132 char invalid_function_def()[] {return 0;}
133 #endif
135 #define __INT64_C(c) c ## LL
136 #define INT64_MIN (-__INT64_C(9223372036854775807)-1)
138 int qq(int x)
140 return x + 40;
142 #define qq(x) x
144 #define spin_lock(lock) do { } while (0)
145 #define wq_spin_lock spin_lock
146 #define TEST2() wq_spin_lock(a)
148 void macro_test(void)
150 pf("N=%d\n", N);
151 printf("aaa=%d\n", AAA);
153 printf("min=%d\n", min(1, min(2, -1)));
155 printf("s1=%s\n", glue(HIGH, LOW));
156 printf("s2=%s\n", xglue(HIGH, LOW));
157 printf("s3=%s\n", str("c"));
158 printf("s4=%s\n", str(a1));
159 printf("B3=%d\n", B3);
161 printf("onetwothree=%d\n", onetwothree);
163 #ifdef A
164 printf("A defined\n");
165 #endif
166 #ifdef B
167 printf("B defined\n");
168 #endif
169 #ifdef A
170 printf("A defined\n");
171 #else
172 printf("A not defined\n");
173 #endif
174 #ifdef B
175 printf("B defined\n");
176 #else
177 printf("B not defined\n");
178 #endif
180 #ifdef A
181 printf("A defined\n");
182 #ifdef B
183 printf("B1 defined\n");
184 #else
185 printf("B1 not defined\n");
186 #endif
187 #else
188 printf("A not defined\n");
189 #ifdef B
190 printf("B2 defined\n");
191 #else
192 printf("B2 not defined\n");
193 #endif
194 #endif
196 #if 1+1
197 printf("test true1\n");
198 #endif
199 #if 0
200 printf("test true2\n");
201 #endif
202 #if 1-1
203 printf("test true3\n");
204 #endif
205 #if defined(A)
206 printf("test trueA\n");
207 #endif
208 #if defined(B)
209 printf("test trueB\n");
210 #endif
212 #if 0
213 printf("test 0\n");
214 #elif 0
215 printf("test 1\n");
216 #elif 2
217 printf("test 2\n");
218 #else
219 printf("test 3\n");
220 #endif
222 MACRO_NOARGS();
224 /* not strictly preprocessor, but we test it there */
225 #ifdef C99_MACROS
226 printf("__func__ = %s\n", __func__);
227 dprintf(1, "vaarg=%d\n", 1);
228 #endif
229 dprintf1(1, "vaarg1\n");
230 dprintf1(1, "vaarg1=%d\n", 2);
231 dprintf1(1, "vaarg1=%d %d\n", 1, 2);
233 /* gcc extension */
234 printf("func='%s'\n", __FUNCTION__);
236 /* complicated macros in glibc */
237 printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
239 int a;
240 a = 1;
241 glue(a+, +);
242 printf("a=%d\n", a);
243 glue(a <, <= 2);
244 printf("a=%d\n", a);
247 /* macro function with argument outside the macro string */
248 #define MF_s MF_hello
249 #define MF_hello(msg) printf("%s\n",msg)
251 #define MF_t printf("tralala\n"); MF_hello
253 MF_s("hi");
254 MF_t("hi");
256 /* test macro substitution inside args (should not eat stream) */
257 printf("qq=%d\n", qq(qq)(2));
259 /* test zero argument case. NOTE: gcc 2.95.x does not accept a
260 null argument without a space. gcc 3.2 fixes that. */
262 #define qq1(x) 1
263 printf("qq1=%d\n", qq1( ));
265 /* comment with stray handling *\
267 /* this is a valid *\/ comment */
268 /* this is a valid comment *\*/
269 // this is a valid\
270 comment
272 /* test function macro substitution when the function name is
273 substituted */
274 TEST2();
276 /* And again when the name and parentheses are separated by a
277 comment. */
278 TEST2 /* the comment */ ();
280 printf("basefromheader %s\n", get_basefile_from_header());
281 printf("base %s\n", __BASE_FILE__);
283 /* Some compilers (clang) prepend './' to __FILE__ from included
284 files. */
285 const char *fn = get_file_from_header();
286 if (fn[0] == '.' && fn[1] == '/')
287 fn += 2;
288 printf("filefromheader %s\n", fn);
290 printf("file %s\n", __FILE__);
292 /* Check that funnily named include was in fact included */
293 have_included_42test_h = 1;
294 have_included_42test_h_second = 1;
295 have_included_42test_h_third = 1;
297 /* Check that we don't complain about stray \ here */
298 printf("print a backslash: %s\n", stringify(\\));
302 static void print_num(char *fn, int line, int num) {
303 printf("fn %s, line %d, num %d\n", fn, line, num);
306 void recursive_macro_test(void)
309 #define ELF32_ST_TYPE(val) ((val) & 0xf)
310 #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
311 #define STB_WEAK 2 /* Weak symbol */
312 #define ELFW(type) ELF##32##_##type
313 printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
315 #define WRAP(x) x
317 #define print_num(x) print_num(__FILE__,__LINE__,x)
318 print_num(123);
319 WRAP(print_num(123));
320 WRAP(WRAP(print_num(123)));
322 static struct recursive_macro { int rm_field; } G;
323 #define rm_field (G.rm_field)
324 printf("rm_field = %d\n", rm_field);
325 printf("rm_field = %d\n", WRAP(rm_field));
326 WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field))));
329 int op(a,b)
331 return a / b;
334 int ret(a)
336 if (a == 2)
337 return 1;
338 if (a == 3)
339 return 2;
340 return 0;
343 #if !defined(__TINYC__) && (__GNUC__ >= 8)
344 /* Old GCCs don't regard "foo"[1] as constant, even in GNU dialect. */
345 #define CONSTANTINDEXEDSTRLIT
346 #endif
347 char str_ag1[] = "b";
348 char str_ag2[] = { "b" };
349 /*char str_bg1[] = ("cccc"); GCC accepts this with pedantic warning, TCC not */
350 #ifdef CONSTANTINDEXEDSTRLIT
351 char str_ag3[] = { "ab"[1], 0 };
352 char str_x[2] = { "xy" "z"[2], 0 };
353 #endif
354 char *str_ar[] = { "one", "two" };
355 struct str_SS {unsigned char a[3], b; };
356 struct str_SS str_sinit15 = { "r" };
357 struct str_SS str_sinit16[] = { { "q" }, 2 };
359 static void string_test2()
361 char *p = "hello";
362 char a3[2] = { "p" };
363 char a4[2] = { "ab" "c"[2], 0 };
364 char *pa1 = "def" + 1;
365 char *pa2 = { "xyz" + 1 };
366 int i = 0;
367 struct str_SS ss = { { [0 ... 1] = 'a' }, 0 };
368 #ifndef CONSTANTINDEXEDSTRLIT
369 char str_ag3[] = { "ab"[1], 0 };
370 char str_x[2] = { "xy" "z"[2], 0 };
371 #endif
372 puts("string_test2");
373 puts(str_ag1);
374 puts(str_ag2);
375 /*puts(str_bg1);*/
376 puts(str_ag3);
377 puts(str_x);
378 puts(str_sinit15.a);
379 puts(str_sinit16[0].a);
380 puts(a3);
381 puts(a4);
382 puts(p);
383 puts("world");
384 printf("%s\n", "bla");
385 puts(str_ar[0]);
386 puts(str_ar[1]);
387 puts(ss.a);
388 puts(i >= 0 ? "one" : "two");
389 puts(pa1);
390 puts(pa2);
393 void ps(const char *s)
395 int c;
396 while (1) {
397 c = *s;
398 if (c == 0)
399 break;
400 printf("%c", c);
401 s++;
405 const char foo1_string[] = "\
406 bar\n\
407 test\14\
410 void string_test()
412 unsigned int b;
413 printf("string:\n");
414 printf("\141\1423\143\n");/* dezdez test */
415 printf("\x41\x42\x43\x3a\n");
416 printf("c=%c\n", 'r');
417 printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c');
418 printf("foo1_string='%s'\n", foo1_string);
419 #if 0
420 printf("wstring=%S\n", L"abc");
421 printf("wstring=%S\n", L"abc" L"def" "ghi");
422 printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
423 printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff');
424 #endif
425 ps("test\n");
426 b = 32;
427 while ((b = b + 1) < 96) {
428 printf("%c", b);
430 printf("\n");
431 printf("fib=%d\n", fib(33));
432 b = 262144;
433 while (b != 0x80000000) {
434 num(b);
435 b = b * 2;
437 string_test2();
441 void if1t(int n, int a, int b, int c)
443 if (a && b) printf("if1t: %d 1 %d %d\n", n, a, b);
444 if (a && !b) printf("if1t: %d 2 %d %d\n", n, a, b);
445 if (!a && b) printf("if1t: %d 3 %d %d\n", n, a, b);
446 if (!a && !b) printf("if1t: %d 4 %d %d\n", n, a, b);
447 if (a || b) printf("if1t: %d 5 %d %d\n", n, a, b);
448 if (a || !b) printf("if1t: %d 6 %d %d\n", n, a, b);
449 if (!a || b) printf("if1t: %d 7 %d %d\n", n, a, b);
450 if (!a || !b) printf("if1t: %d 8 %d %d\n", n, a, b);
451 if (a && b || c) printf("if1t: %d 9 %d %d %d\n", n, a, b, c);
452 if (a || b && c) printf("if1t: %d 10 %d %d %d\n", n, a, b, c);
453 if (a > b - 1 && c) printf("if1t: %d 11 %d %d %d\n", n, a, b, c);
454 if (a > b - 1 || c) printf("if1t: %d 12 %d %d %d\n", n, a, b, c);
455 if (a > 0 && 1) printf("if1t: %d 13 %d %d %d\n", n, a, b, c);
456 if (a > 0 || 0) printf("if1t: %d 14 %d %d %d\n", n, a, b, c);
459 void if2t(void)
461 if (0 && 1 || printf("if2t:ok\n") || 1)
462 printf("if2t:ok2\n");
463 printf("if2t:ok3\n");
466 void if3t(void)
468 volatile long long i = 1;
469 if (i <= 18446744073709551615ULL)
471 else
472 printf ("if3t:wrong 1\n");
475 void if_test(void)
477 if1t(1, 0, 0, 0);
478 if1t(2, 0, 3, 0);
479 if1t(3, 2, 0, 0);
480 if1t(4, 2, 3, 0);
481 if2t();
482 if3t();
485 void loop_test()
487 int i;
488 i = 0;
489 while (i < 10)
490 printf("%d", i++);
491 printf("\n");
492 for(i = 0; i < 10;i++)
493 printf("%d", i);
494 printf("\n");
495 i = 0;
496 do {
497 printf("%d", i++);
498 } while (i < 10);
499 printf("\n");
501 char count = 123;
502 /* c99 for loop init test */
503 for (size_t count = 1; count < 3; count++)
504 printf("count=%d\n", count);
505 printf("count = %d\n", count);
507 /* break/continue tests */
508 i = 0;
509 while (1) {
510 if (i == 6)
511 break;
512 i++;
513 if (i == 3)
514 continue;
515 printf("%d", i);
517 printf("\n");
519 /* break/continue tests */
520 i = 0;
521 do {
522 if (i == 6)
523 break;
524 i++;
525 if (i == 3)
526 continue;
527 printf("%d", i);
528 } while(1);
529 printf("\n");
531 for(i = 0;i < 10;i++) {
532 if (i == 3)
533 continue;
534 printf("%d", i);
536 printf("\n");
539 typedef int typedef_and_label;
541 void goto_test()
543 int i;
544 static void *label_table[3] = { &&label1, &&label2, &&label3 };
546 printf("\ngoto:\n");
547 i = 0;
548 /* This needs to parse as label, not as start of decl. */
549 typedef_and_label x;
550 typedef_and_label:
551 s_loop:
552 if (i >= 10)
553 goto s_end;
554 printf("%d", i);
555 i++;
556 goto s_loop;
557 s_end:
558 printf("\n");
560 /* we also test computed gotos (GCC extension) */
561 for(i=0;i<3;i++) {
562 goto *label_table[i];
563 label1:
564 printf("label1\n");
565 goto next;
566 label2:
567 printf("label2\n");
568 goto next;
569 label3:
570 printf("label3\n");
571 next: ;
575 enum {
577 E1 = 2,
578 E2 = 4,
583 enum test {
584 E5 = 1000,
587 struct S_enum {
588 enum {E6 = 42, E7, E8} e:8;
591 enum ELong {
592 /* This is either 0 on L32 machines, or a large number
593 on L64 machines. We should be able to store this. */
594 EL_large = ((unsigned long)0xf000 << 31) << 1,
597 enum { BIASU = -1U<<31 };
598 enum { BIASS = -1 << 31 };
600 static int getint(int i)
602 if (i)
603 return 0;
604 else
605 return (int)(-1U << 31);
608 void enum_test()
610 enum test b1;
611 /* The following should give no warning */
612 unsigned *p = &b1;
613 struct S_enum s = {E7};
614 printf("%d %d %d %d %d %d %d\n", s.e,
615 E0, E1, E2, E3, E4, E5);
616 b1 = 1;
617 printf("b1=%d\n", b1);
618 printf("enum large: %ld\n", EL_large);
620 if (getint(0) == BIASU)
621 printf("enum unsigned: ok\n");
622 else
623 printf("enum unsigned: wrong\n");
624 if (getint(0) == BIASS)
625 printf("enum unsigned: ok\n");
626 else
627 printf("enum unsigned: wrong\n");
630 typedef int *my_ptr;
632 typedef int mytype1;
633 typedef int mytype2;
635 void typedef_test()
637 my_ptr a;
638 mytype1 mytype2;
639 int b;
641 a = &b;
642 *a = 1234;
643 printf("a=%d\n", *a);
644 mytype2 = 2;
645 printf("mytype2=%d\n", mytype2);
648 void forward_test()
650 forward_ref();
651 forward_ref();
655 void forward_ref(void)
657 printf("forward ok\n");
660 typedef struct struct1 {
661 int f1;
662 int f2, f3;
663 union union1 {
664 int v1;
665 int v2;
666 } u;
667 char str[3];
668 } struct1;
670 struct struct2 {
671 int a;
672 char b;
675 union union2 {
676 int w1;
677 int w2;
680 struct struct1 st1, st2;
682 struct empty_mem {
683 /* nothing */ ;
684 int x;
687 int tab[3];
688 int tab2[3][2];
690 int g;
692 void f1(g)
694 printf("g1=%d\n", g);
697 void scope_test()
699 g = 2;
700 f1(1);
701 printf("g2=%d\n", g);
703 int g;
704 g = 3;
705 printf("g3=%d\n", g);
707 int g;
708 g = 4;
709 printf("g4=%d\n", g);
712 printf("g5=%d\n", g);
715 int st2_i;
716 int *st2_p = &st2_i;
717 void scope2_test()
719 char a[50];
720 st2_i = 42;
721 for (int st2_i = 1; st2_i < 10; st2_i++) {
722 extern int st2_i;
723 st2_i++;
724 printf("exloc: %d\n", st2_i);
726 printf("exloc: %d\n", *st2_p);
729 /* C has tentative definition, and they may be repeated. */
730 extern int st_global1;
731 int st_global1=42;
732 extern int st_global1;
733 int st_global1;
734 extern int st_global2;
735 int st_global2;
736 extern int st_global2;
737 int st_global2;
739 void array_test()
741 int i, j, a[4];
743 printf("sizeof(a) = %d\n", sizeof(a));
744 printf("sizeof(\"a\") = %d\n", sizeof("a"));
745 #ifdef C99_MACROS
746 printf("sizeof(__func__) = %d\n", sizeof(__func__));
747 #endif
748 printf("sizeof tab %d\n", sizeof(tab));
749 printf("sizeof tab2 %d\n", sizeof tab2);
750 tab[0] = 1;
751 tab[1] = 2;
752 tab[2] = 3;
753 printf("%d %d %d\n", tab[0], tab[1], tab[2]);
754 for(i=0;i<3;i++)
755 for(j=0;j<2;j++)
756 tab2[i][j] = 10 * i + j;
757 for(i=0;i<3*2;i++) {
758 printf(" %3d", ((int *)tab2)[i]);
760 printf("\n");
761 printf("sizeof(size_t)=%d\n", sizeof(size_t));
762 printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
765 void expr_test()
767 int a, b;
768 a = 0;
769 printf("%d\n", a += 1);
770 printf("%d\n", a -= 2);
771 printf("%d\n", a *= 31232132);
772 printf("%d\n", a /= 4);
773 printf("%d\n", a %= 20);
774 printf("%d\n", a &= 6);
775 printf("%d\n", a ^= 7);
776 printf("%d\n", a |= 8);
777 printf("%d\n", a >>= 3);
778 printf("%d\n", a <<= 4);
780 a = 22321;
781 b = -22321;
782 printf("%d\n", a + 1);
783 printf("%d\n", a - 2);
784 printf("%d\n", a * 312);
785 printf("%d\n", a / 4);
786 printf("%d\n", b / 4);
787 printf("%d\n", (unsigned)b / 4);
788 printf("%d\n", a % 20);
789 printf("%d\n", b % 20);
790 printf("%d\n", (unsigned)b % 20);
791 printf("%d\n", a & 6);
792 printf("%d\n", a ^ 7);
793 printf("%d\n", a | 8);
794 printf("%d\n", a >> 3);
795 printf("%d\n", b >> 3);
796 printf("%d\n", (unsigned)b >> 3);
797 printf("%d\n", a << 4);
798 printf("%d\n", ~a);
799 printf("%d\n", -a);
800 printf("%d\n", +a);
802 printf("%d\n", 12 + 1);
803 printf("%d\n", 12 - 2);
804 printf("%d\n", 12 * 312);
805 printf("%d\n", 12 / 4);
806 printf("%d\n", 12 % 20);
807 printf("%d\n", 12 & 6);
808 printf("%d\n", 12 ^ 7);
809 printf("%d\n", 12 | 8);
810 printf("%d\n", 12 >> 2);
811 printf("%d\n", 12 << 4);
812 printf("%d\n", ~12);
813 printf("%d\n", -12);
814 printf("%d\n", +12);
815 printf("%d %d %d %d\n",
816 isid('a'),
817 isid('g'),
818 isid('T'),
819 isid('('));
822 int isid(int c)
824 return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
827 /**********************/
829 int vstack[10], *vstack_ptr;
831 void vpush(int vt, int vc)
833 *vstack_ptr++ = vt;
834 *vstack_ptr++ = vc;
837 void vpop(int *ft, int *fc)
839 *fc = *--vstack_ptr;
840 *ft = *--vstack_ptr;
843 void expr2_test()
845 int a, b;
847 vstack_ptr = vstack;
848 vpush(1432432, 2);
849 vstack_ptr[-2] &= ~0xffffff80;
850 vpop(&a, &b);
851 printf("res= %d %d\n", a, b);
854 int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */
856 void constant_expr_test()
858 int a;
859 a = 3;
860 printf("%d\n", a * 16);
861 printf("%d\n", a * 1);
862 printf("%d\n", a + 0);
863 printf("%d\n", sizeof(const_len_ar));
866 int tab4[10];
868 void expr_ptr_test()
870 int *p, *q;
871 int i = -1;
873 p = tab4;
874 q = tab4 + 10;
875 printf("diff=%d\n", q - p);
876 p++;
877 printf("inc=%d\n", p - tab4);
878 p--;
879 printf("dec=%d\n", p - tab4);
880 ++p;
881 printf("inc=%d\n", p - tab4);
882 --p;
883 printf("dec=%d\n", p - tab4);
884 printf("add=%d\n", p + 3 - tab4);
885 printf("add=%d\n", 3 + p - tab4);
887 /* check if 64bit support is ok */
888 q = p = 0;
889 q += i;
890 printf("%p %p %ld\n", q, p, p-q);
891 printf("%d %d %d %d %d %d\n",
892 p == q, p != q, p < q, p <= q, p >= q, p > q);
893 i = 0xf0000000;
894 p += i;
895 printf("%p %p %ld\n", q, p, p-q);
896 printf("%d %d %d %d %d %d\n",
897 p == q, p != q, p < q, p <= q, p >= q, p > q);
898 p = (int *)((char *)p + 0xf0000000);
899 printf("%p %p %ld\n", q, p, p-q);
900 printf("%d %d %d %d %d %d\n",
901 p == q, p != q, p < q, p <= q, p >= q, p > q);
902 p += 0xf0000000;
903 printf("%p %p %ld\n", q, p, p-q);
904 printf("%d %d %d %d %d %d\n",
905 p == q, p != q, p < q, p <= q, p >= q, p > q);
907 struct size12 {
908 int i, j, k;
910 struct size12 s[2], *sp = s;
911 int i, j;
912 sp->i = 42;
913 sp++;
914 j = -1;
915 printf("%d\n", sp[j].i);
917 #ifdef __LP64__
918 i = 1;
919 p = (int*)0x100000000UL + i;
920 i = ((long)p) >> 32;
921 printf("largeptr: %p %d\n", p, i);
922 #endif
925 void expr_cmp_test()
927 int a, b;
928 a = -1;
929 b = 1;
930 printf("%d\n", a == a);
931 printf("%d\n", a != a);
933 printf("%d\n", a < b);
934 printf("%d\n", a <= b);
935 printf("%d\n", a <= a);
936 printf("%d\n", b >= a);
937 printf("%d\n", a >= a);
938 printf("%d\n", b > a);
940 printf("%d\n", (unsigned)a < b);
941 printf("%d\n", (unsigned)a <= b);
942 printf("%d\n", (unsigned)a <= a);
943 printf("%d\n", (unsigned)b >= a);
944 printf("%d\n", (unsigned)a >= a);
945 printf("%d\n", (unsigned)b > a);
948 struct empty {
951 struct aligntest1 {
952 char a[10];
955 struct aligntest2 {
956 int a;
957 char b[10];
960 struct aligntest3 {
961 double a, b;
964 struct aligntest4 {
965 double a[0];
968 struct __attribute__((aligned(16))) aligntest5
970 int i;
972 struct aligntest6
974 int i;
975 } __attribute__((aligned(16)));
976 struct aligntest7
978 int i;
980 struct aligntest5 altest5[2];
981 struct aligntest6 altest6[2];
982 int pad1;
983 /* altest7 is correctly aligned to 16 bytes also with TCC,
984 but __alignof__ returns the wrong result (4) because we
985 can't store the alignment yet when specified on symbols
986 directly (it's stored in the type so we'd need to make
987 a copy of it). -- FIXED */
988 struct aligntest7 altest7[2] __attribute__((aligned(16)));
990 struct aligntest8
992 int i;
993 } __attribute__((aligned(4096)));
995 struct Large {
996 unsigned long flags;
997 union {
998 void *u1;
999 int *u2;
1002 struct {
1003 union {
1004 unsigned long index;
1005 void *freelist;
1007 union {
1008 unsigned long counters;
1009 struct {
1010 int bla;
1015 union {
1016 struct {
1017 long u3;
1018 long u4;
1020 void *u5;
1021 struct {
1022 unsigned long compound_head;
1023 unsigned int compound_dtor;
1024 unsigned int compound_order;
1027 } __attribute__((aligned(2 * sizeof(long))));
1029 typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
1031 struct aligntest9 {
1032 unsigned int buf_nr;
1033 unaligned_u64 start_lba;
1036 struct aligntest10 {
1037 unsigned int buf_nr;
1038 unsigned long long start_lba;
1041 void struct_test()
1043 struct1 *s;
1044 union union2 u;
1045 struct Large ls;
1047 printf("sizes: %d %d %d %d\n",
1048 sizeof(struct struct1),
1049 sizeof(struct struct2),
1050 sizeof(union union1),
1051 sizeof(union union2));
1052 printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
1053 st1.f1 = 1;
1054 st1.f2 = 2;
1055 st1.f3 = 3;
1056 printf("st1: %d %d %d\n",
1057 st1.f1, st1.f2, st1.f3);
1058 st1.u.v1 = 1;
1059 st1.u.v2 = 2;
1060 printf("union1: %d\n", st1.u.v1);
1061 u.w1 = 1;
1062 u.w2 = 2;
1063 printf("union2: %d\n", u.w1);
1064 s = &st2;
1065 s->f1 = 3;
1066 s->f2 = 2;
1067 s->f3 = 1;
1068 printf("st2: %d %d %d\n",
1069 s->f1, s->f2, s->f3);
1070 printf("str_addr=%x\n", (int)(uintptr_t)st1.str - (int)(uintptr_t)&st1.f1);
1072 /* align / size tests */
1073 printf("aligntest1 sizeof=%d alignof=%d\n",
1074 sizeof(struct aligntest1), __alignof__(struct aligntest1));
1075 printf("aligntest2 sizeof=%d alignof=%d\n",
1076 sizeof(struct aligntest2), __alignof__(struct aligntest2));
1077 printf("aligntest3 sizeof=%d alignof=%d\n",
1078 sizeof(struct aligntest3), __alignof__(struct aligntest3));
1079 printf("aligntest4 sizeof=%d alignof=%d\n",
1080 sizeof(struct aligntest4), __alignof__(struct aligntest4));
1081 printf("aligntest5 sizeof=%d alignof=%d\n",
1082 sizeof(struct aligntest5), __alignof__(struct aligntest5));
1083 printf("aligntest6 sizeof=%d alignof=%d\n",
1084 sizeof(struct aligntest6), __alignof__(struct aligntest6));
1085 printf("aligntest7 sizeof=%d alignof=%d\n",
1086 sizeof(struct aligntest7), __alignof__(struct aligntest7));
1087 printf("aligntest8 sizeof=%d alignof=%d\n",
1088 sizeof(struct aligntest8), __alignof__(struct aligntest8));
1089 printf("aligntest9 sizeof=%d alignof=%d\n",
1090 sizeof(struct aligntest9), __alignof__(struct aligntest9));
1091 printf("aligntest10 sizeof=%d alignof=%d\n",
1092 sizeof(struct aligntest10), __alignof__(struct aligntest10));
1093 printf("altest5 sizeof=%d alignof=%d\n",
1094 sizeof(altest5), __alignof__(altest5));
1095 printf("altest6 sizeof=%d alignof=%d\n",
1096 sizeof(altest6), __alignof__(altest6));
1097 printf("altest7 sizeof=%d alignof=%d\n",
1098 sizeof(altest7), __alignof__(altest7));
1100 /* empty structures (GCC extension) */
1101 printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
1102 printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
1104 printf("Large: sizeof=%d\n", sizeof(ls));
1105 memset(&ls, 0, sizeof(ls));
1106 ls.compound_head = 42;
1107 printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
1110 /* simulate char/short return value with undefined upper bits */
1111 static int __csf(int x) { return x; }
1112 static void *_csf = __csf;
1113 #define csf(t,n) ((t(*)(int))_csf)(n)
1115 /* XXX: depend on endianness */
1116 void char_short_test()
1118 int var1, var2;
1119 signed char var3;
1120 long long var4;
1122 var1 = 0x01020304;
1123 var2 = 0xfffefdfc;
1124 printf("s8=%d %d\n",
1125 *(signed char *)&var1, *(signed char *)&var2);
1126 printf("u8=%d %d\n",
1127 *(unsigned char *)&var1, *(unsigned char *)&var2);
1128 printf("s16=%d %d\n",
1129 *(short *)&var1, *(short *)&var2);
1130 printf("u16=%d %d\n",
1131 *(unsigned short *)&var1, *(unsigned short *)&var2);
1132 printf("s32=%d %d\n",
1133 *(int *)&var1, *(int *)&var2);
1134 printf("u32=%d %d\n",
1135 *(unsigned int *)&var1, *(unsigned int *)&var2);
1136 *(signed char *)&var1 = 0x08;
1137 printf("var1=%x\n", var1);
1138 *(short *)&var1 = 0x0809;
1139 printf("var1=%x\n", var1);
1140 *(int *)&var1 = 0x08090a0b;
1141 printf("var1=%x\n", var1);
1143 var1 = 0x778899aa;
1144 var4 = 0x11223344aa998877ULL;
1145 var1 = var3 = var1 + 1;
1146 var4 = var3 = var4 + 1;
1147 printf("promote char/short assign %d "LONG_LONG_FORMAT"\n", var1, var4);
1148 var1 = 0x778899aa;
1149 var4 = 0x11223344aa998877ULL;
1150 printf("promote char/short assign VA %d %d\n", var3 = var1 + 1, var3 = var4 + 1);
1151 printf("promote char/short cast VA %d %d\n", (signed char)(var1 + 1), (signed char)(var4 + 1));
1152 #if !defined(__arm__)
1153 /* We can't really express GCC behaviour of return type promotion in
1154 the presence of undefined behaviour (like __csf is). */
1155 var1 = csf(unsigned char,0x89898989);
1156 var4 = csf(signed char,0xabababab);
1157 printf("promote char/short funcret %d "LONG_LONG_FORMAT"\n", var1, var4);
1158 printf("promote char/short fumcret VA %d %d %d %d\n",
1159 csf(unsigned short,0xcdcdcdcd),
1160 csf(short,0xefefefef),
1161 csf(_Bool,0x33221100),
1162 csf(_Bool,0x33221101));
1163 #endif
1164 var3 = -10;
1165 var1 = (signed char)(unsigned char)(var3 + 1);
1166 var4 = (signed char)(unsigned char)(var3 + 1);
1167 printf("promote multicast (char)(unsigned char) %d "LONG_LONG_FORMAT"\n", var1, var4);
1168 var4 = 0x11223344aa998877ULL;
1169 var4 = (unsigned)(int)(var4 + 1);
1170 printf("promote multicast (unsigned)(int) "LONG_LONG_FORMAT"\n", var4);
1171 var4 = 0x11223344bbaa9988ULL;
1172 var4 = (unsigned)(signed char)(var4 + 1);
1173 printf("promote multicast (unsigned)(char) "LONG_LONG_FORMAT"\n", var4);
1176 /******************/
1178 typedef struct Sym {
1179 int v;
1180 int t;
1181 int c;
1182 struct Sym *next;
1183 struct Sym *prev;
1184 } Sym;
1186 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
1187 #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
1189 static int toupper1(int a)
1191 return TOUPPER(a);
1194 static unsigned int calc_vm_flags(unsigned int prot)
1196 unsigned int prot_bits;
1197 /* This used to segfault in some revisions: */
1198 prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
1199 return prot_bits;
1202 void bool_test()
1204 int *s, a, b, t, f, i;
1206 a = 0;
1207 s = (void*)0;
1208 printf("!s=%d\n", !s);
1210 if (!s || !s[0])
1211 a = 1;
1212 printf("a=%d\n", a);
1214 printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
1215 printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
1216 printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
1217 #if 1 && 1
1218 printf("a1\n");
1219 #endif
1220 #if 1 || 0
1221 printf("a2\n");
1222 #endif
1223 #if 1 ? 0 : 1
1224 printf("a3\n");
1225 #endif
1226 #if 0 ? 0 : 1
1227 printf("a4\n");
1228 #endif
1230 a = 4;
1231 printf("b=%d\n", a + (0 ? 1 : a / 2));
1233 /* test register spilling */
1234 a = 10;
1235 b = 10;
1236 a = (a + b) * ((a < b) ?
1237 ((b - a) * (a - b)): a + b);
1238 printf("a=%d\n", a);
1240 /* test complex || or && expressions */
1241 t = 1;
1242 f = 0;
1243 a = 32;
1244 printf("exp=%d\n", f == (32 <= a && a <= 3));
1245 printf("r=%d\n", (t || f) + (t && f));
1247 /* test ? : cast */
1249 int aspect_on;
1250 int aspect_native = 65536;
1251 double bfu_aspect = 1.0;
1252 int aspect;
1253 for(aspect_on = 0; aspect_on < 2; aspect_on++) {
1254 aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
1255 printf("aspect=%d\n", aspect);
1259 /* test ? : GCC extension */
1261 static int v1 = 34 ? : -1; /* constant case */
1262 static int v2 = 0 ? : -1; /* constant case */
1263 int a = 30;
1265 printf("%d %d\n", v1, v2);
1266 printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
1269 /* again complex expression */
1270 for(i=0;i<256;i++) {
1271 if (toupper1 (i) != TOUPPER (i))
1272 printf("error %d\n", i);
1274 printf ("bits = 0x%x\n", calc_vm_flags (0x1));
1277 extern int undefined_function(void);
1278 extern int defined_function(void);
1280 #ifdef __clang__
1281 int undefined_function(void) {}
1282 #endif
1284 static inline void refer_to_undefined(void)
1286 undefined_function();
1289 void optimize_out_test(void)
1291 int i = 0 ? undefined_function() : defined_function();
1292 printf ("oo:%d\n", i);
1293 int j = 1 ? defined_function() : undefined_function();
1294 printf ("oo:%d\n", j);
1295 if (0)
1296 printf("oo:%d\n", undefined_function());
1297 else
1298 printf("oo:%d\n", defined_function());
1299 if (1)
1300 printf("oo:%d\n", defined_function());
1301 else
1302 printf("oo:%d\n", undefined_function());
1303 while (1) {
1304 printf("oow:%d\n", defined_function());
1305 break;
1306 printf("oow:%d\n", undefined_function());
1308 j = 1;
1309 /* Following is a switch without {} block intentionally. */
1310 switch (j)
1311 case 1: break;
1312 printf ("oos:%d\n", defined_function());
1313 /* The following break shouldn't lead to disabled code after
1314 the while. */
1315 while (1)
1316 break;
1317 printf ("ool1:%d\n", defined_function());
1318 /* Same for the other types of loops. */
1320 break;
1321 while (1);
1322 printf ("ool2:%d\n", defined_function());
1323 for (;;)
1324 break;
1325 printf ("ool3:%d\n", defined_function());
1326 /* Normal {} blocks without controlling statements
1327 shouldn't reactivate code emission */
1328 while (1) {
1330 break;
1332 printf ("ool4:%d\n", undefined_function());
1334 j = 1;
1335 while (j) {
1336 if (j == 0)
1337 break; /* this break shouldn't disable code outside the if. */
1338 printf("ool5:%d\n", defined_function());
1339 j--;
1342 j = 1;
1343 while (j) {
1344 if (1)
1345 j--;
1346 else
1347 breakhere: break;
1348 printf("ool6:%d\n", defined_function());
1349 goto breakhere;
1351 j = 1;
1352 while (j) {
1353 j--;
1354 continue;
1355 printf("ool7:%d\n", undefined_function());
1358 /* Test that constants in logical && are optimized: */
1359 i = 0 && undefined_function();
1360 i = defined_function() && 0 && undefined_function();
1361 if (0 && undefined_function())
1362 undefined_function();
1363 if (defined_function() && 0)
1364 undefined_function();
1365 if (0 && 0)
1366 undefined_function();
1367 if (defined_function() && 0 && undefined_function())
1368 undefined_function();
1369 /* The same for || : */
1370 i = 1 || undefined_function();
1371 i = defined_function() || 1 || undefined_function();
1372 if (1 || undefined_function())
1374 else
1375 undefined_function();
1376 if (defined_function() || 1)
1378 else
1379 undefined_function();
1380 if (1 || 1)
1382 else
1383 undefined_function();
1384 if (defined_function() || 1 || undefined_function())
1386 else
1387 undefined_function();
1389 if (defined_function() && 0)
1390 refer_to_undefined();
1392 if (0) {
1393 (void)sizeof( ({
1394 do { } while (0);
1396 }) );
1397 undefined_function();
1400 /* Leave the "if(1)return; printf()" in this order and last in the function */
1401 if (1)
1402 return;
1403 printf ("oor:%d\n", undefined_function());
1406 int defined_function(void)
1408 static int i = 40;
1409 return i++;
1412 /* GCC accepts that */
1413 static int tab_reinit[];
1414 static int tab_reinit[10];
1416 static int tentative_ar[];
1417 static int tentative_ar[] = {1,2,3};
1419 //int cinit1; /* a global variable can be defined several times without error ! */
1420 int cinit1;
1421 int cinit1;
1422 int cinit1 = 0;
1423 int *cinit2 = (int []){3, 2, 1};
1425 void compound_literal_test(void)
1427 int *p, i;
1428 char *q, *q3;
1430 p = (int []){1, 2, 3};
1431 for(i=0;i<3;i++)
1432 printf(" %d", p[i]);
1433 printf("\n");
1435 for(i=0;i<3;i++)
1436 printf("%d", cinit2[i]);
1437 printf("\n");
1439 q = "tralala1";
1440 printf("q1=%s\n", q);
1442 q = (char *){ "tralala2" };
1443 printf("q2=%s\n", q);
1445 q3 = (char *){ q };
1446 printf("q3=%s\n", q3);
1448 q = (char []){ "tralala3" };
1449 printf("q4=%s\n", q);
1451 #ifdef ALL_ISOC99
1452 p = (int []){1, 2, cinit1 + 3};
1453 for(i=0;i<3;i++)
1454 printf(" %d", p[i]);
1455 printf("\n");
1457 for(i=0;i<3;i++) {
1458 p = (int []){1, 2, 4 + i};
1459 printf("%d %d %d\n",
1460 p[0],
1461 p[1],
1462 p[2]);
1464 #endif
1467 /* K & R protos */
1469 kr_func1(a, b)
1471 return a + b;
1474 int kr_func2(a, b)
1476 return a + b;
1479 kr_test()
1481 printf("func1=%d\n", kr_func1(3, 4));
1482 printf("func2=%d\n", kr_func2(3, 4));
1483 return 0;
1486 void num(int n)
1488 char *tab, *p;
1489 tab = (char*)malloc(20);
1490 p = tab;
1491 while (1) {
1492 *p = 48 + (n % 10);
1493 p++;
1494 n = n / 10;
1495 if (n == 0)
1496 break;
1498 while (p != tab) {
1499 p--;
1500 printf("%c", *p);
1502 printf("\n");
1503 free(tab);
1506 /* structure assignment tests */
1507 struct structa1 {
1508 int f1;
1509 char f2;
1512 struct structa1 ssta1;
1514 void struct_assign_test1(struct structa1 s1, int t, float f)
1516 printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
1519 struct structa1 struct_assign_test2(struct structa1 s1, int t)
1521 s1.f1 += t;
1522 s1.f2 -= t;
1523 return s1;
1526 void struct_assign_test(void)
1528 struct S {
1529 struct structa1 lsta1, lsta2;
1530 int i;
1531 } s, *ps;
1533 ps = &s;
1534 ps->i = 4;
1535 #if 0
1536 s.lsta1.f1 = 1;
1537 s.lsta1.f2 = 2;
1538 printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
1539 s.lsta2 = s.lsta1;
1540 printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
1541 #else
1542 s.lsta2.f1 = 1;
1543 s.lsta2.f2 = 2;
1544 #endif
1545 struct_assign_test1(ps->lsta2, 3, 4.5);
1547 printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
1548 ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
1549 printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
1551 static struct {
1552 void (*elem)();
1553 } t[] = {
1554 /* XXX: we should allow this even without braces */
1555 { struct_assign_test }
1557 printf("%d\n", struct_assign_test == t[0].elem);
1560 /* casts to short/char */
1562 void cast1(char a, short b, unsigned char c, unsigned short d)
1564 printf("%d %d %d %d\n", a, b, c, d);
1567 char bcast;
1568 short scast;
1570 void cast_test()
1572 int a;
1573 char c;
1574 char tab[10];
1575 unsigned b,d;
1576 short s;
1577 char *p = NULL;
1578 unsigned long ul = 0x80000000UL;
1579 p -= 0x700000000042;
1581 a = 0xfffff;
1582 cast1(a, a, a, a);
1583 a = 0xffffe;
1584 printf("%d %d %d %d\n",
1585 (char)(a + 1),
1586 (short)(a + 1),
1587 (unsigned char)(a + 1),
1588 (unsigned short)(a + 1));
1589 printf("%d %d %d %d\n",
1590 (char)0xfffff,
1591 (short)0xfffff,
1592 (unsigned char)0xfffff,
1593 (unsigned short)0xfffff);
1595 a = (bcast = 128) + 1;
1596 printf("%d\n", a);
1597 a = (scast = 65536) + 1;
1598 printf("%d\n", a);
1600 printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
1602 /* test cast from unsigned to signed short to int */
1603 b = 0xf000;
1604 d = (short)b;
1605 printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
1606 b = 0xf0f0;
1607 d = (char)b;
1608 printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
1610 /* test implicit int casting for array accesses */
1611 c = 0;
1612 tab[1] = 2;
1613 tab[c] = 1;
1614 printf("%d %d\n", tab[0], tab[1]);
1616 /* test implicit casting on some operators */
1617 printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
1618 printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
1619 printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
1621 #if CC_NAME != CC_clang /* clang doesn't support non-portable conversions */
1622 /* from pointer to integer types */
1623 printf("%d %d %ld %ld %lld %lld\n",
1624 (int)p, (unsigned int)p,
1625 (long)p, (unsigned long)p,
1626 (long long)p, (unsigned long long)p);
1627 #endif
1629 /* from integers to pointers */
1630 printf("%p %p %p %p\n",
1631 (void *)a, (void *)b, (void *)c, (void *)d);
1633 /* int to int with sign set */
1634 printf("0x%lx\n", (unsigned long)(int)ul);
1637 /* initializers tests */
1638 struct structinit1 {
1639 int f1;
1640 char f2;
1641 short f3;
1642 int farray[3];
1645 int sinit1 = 2;
1646 int sinit2 = { 3 };
1647 int sinit3[3] = { 1, 2, {{3}}, };
1648 int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1649 int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
1650 int sinit6[] = { 1, 2, 3 };
1651 int sinit7[] = { [2] = 3, [0] = 1, 2 };
1652 char sinit8[] = "hello" "trala";
1654 struct structinit1 sinit9 = { 1, 2, 3 };
1655 struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
1656 struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
1657 #ifdef ALL_ISOC99
1658 .farray[0] = 10,
1659 .farray[1] = 11,
1660 .farray[2] = 12,
1661 #endif
1664 char *sinit12 = "hello world";
1665 char *sinit13[] = {
1666 "test1",
1667 "test2",
1668 "test3",
1670 char sinit14[10] = { "abc" };
1671 int sinit15[3] = { sizeof(sinit15), 1, 2 };
1673 struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
1675 struct bar {
1676 char *s;
1677 int len;
1678 } sinit17[] = {
1679 "a1", 4,
1680 "a2", 1
1683 int sinit18[10] = {
1684 [2 ... 5] = 20,
1686 [8] = 10,
1689 struct complexinit0 {
1690 int a;
1691 int b;
1694 struct complexinit {
1695 int a;
1696 const struct complexinit0 *b;
1699 const static struct complexinit cix[] = {
1700 [0] = {
1701 .a = 2000,
1702 .b = (const struct complexinit0[]) {
1703 { 2001, 2002 },
1704 { 2003, 2003 },
1710 struct complexinit2 {
1711 int a;
1712 int b[];
1715 struct complexinit2 cix20;
1717 struct complexinit2 cix21 = {
1718 .a = 3000,
1719 .b = { 3001, 3002, 3003 }
1722 struct complexinit2 cix22 = {
1723 .a = 4000,
1724 .b = { 4001, 4002, 4003, 4004, 4005, 4006 }
1727 typedef int arrtype1[];
1728 arrtype1 sinit19 = {1};
1729 arrtype1 sinit20 = {2,3};
1730 typedef int arrtype2[3];
1731 arrtype2 sinit21 = {4};
1732 arrtype2 sinit22 = {5,6,7};
1734 /* Address comparisons of non-weak symbols with zero can be const-folded */
1735 int sinit23[2] = { "astring" ? sizeof("astring") : -1,
1736 &sinit23 ? 42 : -1 };
1738 int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
1740 extern int external_inited = 42;
1742 void init_test(void)
1744 int linit1 = 2;
1745 int linit2 = { 3 };
1746 int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1747 int linit6[] = { 1, 2, 3 };
1748 int i, j;
1749 char linit8[] = "hello" "trala";
1750 int linit12[10] = { 1, 2 };
1751 int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
1752 char linit14[10] = "abc";
1753 int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
1754 struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
1755 int linit17 = sizeof(linit17);
1756 int zero = 0;
1757 /* Addresses on non-weak symbols are non-zero, but not the access itself */
1758 int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
1760 printf("sinit1=%d\n", sinit1);
1761 printf("sinit2=%d\n", sinit2);
1762 printf("sinit3=%d %d %d %d\n",
1763 sizeof(sinit3),
1764 sinit3[0],
1765 sinit3[1],
1766 sinit3[2]
1768 printf("sinit6=%d\n", sizeof(sinit6));
1769 printf("sinit7=%d %d %d %d\n",
1770 sizeof(sinit7),
1771 sinit7[0],
1772 sinit7[1],
1773 sinit7[2]
1775 printf("sinit8=%s\n", sinit8);
1776 printf("sinit9=%d %d %d\n",
1777 sinit9.f1,
1778 sinit9.f2,
1779 sinit9.f3
1781 printf("sinit10=%d %d %d\n",
1782 sinit10.f1,
1783 sinit10.f2,
1784 sinit10.f3
1786 printf("sinit11=%d %d %d %d %d %d\n",
1787 sinit11.f1,
1788 sinit11.f2,
1789 sinit11.f3,
1790 sinit11.farray[0],
1791 sinit11.farray[1],
1792 sinit11.farray[2]
1795 for(i=0;i<3;i++)
1796 for(j=0;j<2;j++)
1797 printf("[%d][%d] = %d %d %d\n",
1798 i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
1799 printf("linit1=%d\n", linit1);
1800 printf("linit2=%d\n", linit2);
1801 printf("linit6=%d\n", sizeof(linit6));
1802 printf("linit8=%d %s\n", sizeof(linit8), linit8);
1804 printf("sinit12=%s\n", sinit12);
1805 printf("sinit13=%d %s %s %s\n",
1806 sizeof(sinit13),
1807 sinit13[0],
1808 sinit13[1],
1809 sinit13[2]);
1810 printf("sinit14=%s\n", sinit14);
1812 for(i=0;i<10;i++) printf(" %d", linit12[i]);
1813 printf("\n");
1814 for(i=0;i<10;i++) printf(" %d", linit13[i]);
1815 printf("\n");
1816 for(i=0;i<10;i++) printf(" %d", linit14[i]);
1817 printf("\n");
1818 for(i=0;i<10;i++) printf(" %d", linit15[i]);
1819 printf("\n");
1820 printf("%d %d %d %d\n",
1821 linit16.a1,
1822 linit16.a2,
1823 linit16.a3,
1824 linit16.a4);
1825 /* test that initialisation is done after variable declare */
1826 printf("linit17=%d\n", linit17);
1827 printf("sinit15=%d\n", sinit15[0]);
1828 printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
1829 printf("sinit17=%s %d %s %d\n",
1830 sinit17[0].s, sinit17[0].len,
1831 sinit17[1].s, sinit17[1].len);
1832 for(i=0;i<10;i++)
1833 printf("%x ", sinit18[i]);
1834 printf("\n");
1835 /* complex init check */
1836 printf("cix: %d %d %d %d %d %d %d\n",
1837 cix[0].a,
1838 cix[0].b[0].a, cix[0].b[0].b,
1839 cix[0].b[1].a, cix[0].b[1].b,
1840 cix[0].b[2].a, cix[0].b[2].b);
1841 printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
1842 printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
1844 printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
1845 printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
1846 printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
1847 printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
1848 printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
1849 printf("arrtype6: %d\n", sizeof(arrtype2));
1851 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
1852 printf("sinit24=%d\n", sinit24);
1853 printf("linit18= %d %d\n", linit18[0], linit18[1]);
1856 void switch_uc(unsigned char uc)
1858 switch (uc) {
1859 case 0xfb ... 0xfe:
1860 printf("ucsw:1\n");
1861 break;
1862 case 0xff:
1863 printf("ucsw:2\n");
1864 break;
1865 case 0 ... 5:
1866 printf("ucsw:3\n");
1867 break;
1868 default:
1869 printf("ucsw: broken!\n");
1873 void switch_sc(signed char sc)
1875 switch (sc) {
1876 case -5 ... -2:
1877 printf("scsw:1\n");
1878 break;
1879 case -1:
1880 printf("scsw:2\n");
1881 break;
1882 case 0 ... 5:
1883 printf("scsw:3\n");
1884 break;
1885 default:
1886 printf("scsw: broken!\n");
1890 void switch_test()
1892 int i;
1893 unsigned long long ull;
1894 long long ll;
1896 for(i=0;i<15;i++) {
1897 switch(i) {
1898 case 0:
1899 case 1:
1900 printf("a");
1901 break;
1902 default:
1903 printf("%d", i);
1904 break;
1905 case 8 ... 12:
1906 printf("c");
1907 break;
1908 case 3:
1909 printf("b");
1910 break;
1911 case 0xc33c6b9fU:
1912 case 0x7c9eeeb9U:
1913 break;
1916 printf("\n");
1918 for (i = 1; i <= 5; i++) {
1919 ull = (unsigned long long)i << 61;
1920 switch (ull) {
1921 case 1ULL << 61:
1922 printf("ullsw:1\n");
1923 break;
1924 case 2ULL << 61:
1925 printf("ullsw:2\n");
1926 break;
1927 case 3ULL << 61:
1928 printf("ullsw:3\n");
1929 break;
1930 case 4ULL << 61:
1931 printf("ullsw:4\n");
1932 break;
1933 case 5ULL << 61:
1934 printf("ullsw:5\n");
1935 break;
1936 default:
1937 printf("ullsw: broken!\n");
1941 for (i = 1; i <= 5; i++) {
1942 ll = (long long)i << 61;
1943 switch (ll) {
1944 case 1LL << 61:
1945 printf("llsw:1\n");
1946 break;
1947 case 2LL << 61:
1948 printf("llsw:2\n");
1949 break;
1950 case 3LL << 61:
1951 printf("llsw:3\n");
1952 break;
1953 case 4LL << 61:
1954 printf("llsw:4\n");
1955 break;
1956 case 5LL << 61:
1957 printf("llsw:5\n");
1958 break;
1959 default:
1960 printf("llsw: broken!\n");
1964 for (i = -5; i <= 5; i++) {
1965 switch_uc((unsigned char)i);
1968 for (i = -5; i <= 5; i++) {
1969 switch_sc ((signed char)i);
1973 /* ISOC99 _Bool type */
1974 void c99_bool_test(void)
1976 #ifdef BOOL_ISOC99
1977 int a;
1978 _Bool b, b2;
1980 printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
1981 a = 3;
1982 printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
1983 b = 3;
1984 printf("b = %d\n", b);
1985 b++;
1986 printf("b = %d\n", b);
1987 b2 = 0;
1988 printf("sizeof(x ? _Bool : _Bool) = %d (should be sizeof int)\n",
1989 sizeof((volatile)a ? b : b2));
1990 #endif
1993 void bitfield_test(void)
1995 int a;
1996 short sa;
1997 unsigned char ca;
1998 struct sbf1 {
1999 int f1 : 3;
2000 int : 2;
2001 int f2 : 1;
2002 int : 0;
2003 int f3 : 5;
2004 int f4 : 7;
2005 unsigned int f5 : 7;
2006 } st1;
2007 printf("sizeof(st1) = %d\n", sizeof(st1));
2009 st1.f1 = 3;
2010 st1.f2 = 1;
2011 st1.f3 = 15;
2012 a = 120;
2013 st1.f4 = a;
2014 st1.f5 = a;
2015 st1.f5++;
2016 printf("%d %d %d %d %d\n",
2017 st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
2018 sa = st1.f5;
2019 ca = st1.f5;
2020 printf("%d %d\n", sa, ca);
2022 st1.f1 = 7;
2023 if (st1.f1 == -1)
2024 printf("st1.f1 == -1\n");
2025 else
2026 printf("st1.f1 != -1\n");
2027 if (st1.f2 == -1)
2028 printf("st1.f2 == -1\n");
2029 else
2030 printf("st1.f2 != -1\n");
2032 struct sbf2 {
2033 long long f1 : 45;
2034 long long : 2;
2035 long long f2 : 35;
2036 unsigned long long f3 : 38;
2037 } st2;
2038 st2.f1 = 0x123456789ULL;
2039 a = 120;
2040 st2.f2 = (long long)a << 25;
2041 st2.f3 = a;
2042 st2.f2++;
2043 printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
2045 #if 0
2046 Disabled for now until further clarification re GCC compatibility
2047 struct sbf3 {
2048 int f1 : 7;
2049 int f2 : 1;
2050 char f3;
2051 int f4 : 8;
2052 int f5 : 1;
2053 int f6 : 16;
2054 } st3;
2055 printf("sizeof(st3) = %d\n", sizeof(st3));
2056 #endif
2058 struct sbf4 {
2059 int x : 31;
2060 char y : 2;
2061 } st4;
2062 st4.y = 1;
2063 printf("st4.y == %d\n", st4.y);
2064 struct sbf5 {
2065 int a;
2066 char b;
2067 int x : 12, y : 4, : 0, : 4, z : 3;
2068 char c;
2069 } st5 = { 1, 2, 3, 4, -3, 6 };
2070 printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
2071 struct sbf6 {
2072 short x : 12;
2073 unsigned char y : 2;
2074 } st6;
2075 st6.y = 1;
2076 printf("st6.y == %d\n", st6.y);
2079 #ifdef __x86_64__
2080 #define FLOAT_FMT "%f\n"
2081 #else
2082 /* x86's float isn't compatible with GCC */
2083 #define FLOAT_FMT "%.5f\n"
2084 #endif
2086 /* declare strto* functions as they are C99 */
2087 double strtod(const char *nptr, char **endptr);
2089 #if defined(_WIN32)
2090 float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
2091 LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
2092 #else
2093 float strtof(const char *nptr, char **endptr);
2094 LONG_DOUBLE strtold(const char *nptr, char **endptr);
2095 #endif
2097 #define FTEST(prefix, typename, type, fmt)\
2098 void prefix ## cmp(type a, type b)\
2100 printf("%d %d %d %d %d %d\n",\
2101 a == b,\
2102 a != b,\
2103 a < b,\
2104 a > b,\
2105 a >= b,\
2106 a <= b);\
2107 printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
2110 a + b,\
2111 a - b,\
2112 a * b,\
2113 a / b,\
2114 -a);\
2115 printf(fmt "\n", ++a);\
2116 printf(fmt "\n", a++);\
2117 printf(fmt "\n", a);\
2118 b = 0;\
2119 printf("%d %d\n", !a, !b);\
2121 void prefix ## fcast(type a)\
2123 float fa;\
2124 double da;\
2125 LONG_DOUBLE la;\
2126 int ia;\
2127 long long llia;\
2128 unsigned int ua;\
2129 unsigned long long llua;\
2130 type b;\
2131 fa = a;\
2132 da = a;\
2133 la = a;\
2134 printf("ftof: %f %f %Lf\n", fa, da, la);\
2135 ia = (int)a;\
2136 llia = (long long)a;\
2137 a = (a >= 0) ? a : -a;\
2138 ua = (unsigned int)a;\
2139 llua = (unsigned long long)a;\
2140 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
2141 ia = -1234;\
2142 ua = 0x81234500;\
2143 llia = -0x123456789012345LL;\
2144 llua = 0xf123456789012345LLU;\
2145 b = ia;\
2146 printf("itof: " fmt "\n", b);\
2147 b = ua;\
2148 printf("utof: " fmt "\n", b);\
2149 b = llia;\
2150 printf("lltof: " fmt "\n", b);\
2151 b = llua;\
2152 printf("ulltof: " fmt "\n", b);\
2155 float prefix ## retf(type a) { return a; }\
2156 double prefix ## retd(type a) { return a; }\
2157 LONG_DOUBLE prefix ## retld(type a) { return a; }\
2159 void prefix ## call(void)\
2161 printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
2162 printf("double: %f\n", prefix ## retd(42.123456789));\
2163 printf("long double: %Lf\n", prefix ## retld(42.123456789));\
2164 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
2167 void prefix ## signed_zeros(void) \
2169 type x = 0.0, y = -0.0, n, p;\
2170 if (x == y)\
2171 printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\
2172 1.0 / x != 1.0 / y);\
2173 else\
2174 printf ("x != y; this is wrong!\n");\
2176 n = -x;\
2177 if (x == n)\
2178 printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
2179 1.0 / x != 1.0 / n);\
2180 else\
2181 printf ("x != -x; this is wrong!\n");\
2183 p = +y;\
2184 if (x == p)\
2185 printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
2186 1.0 / x != 1.0 / p);\
2187 else\
2188 printf ("x != +y; this is wrong!\n");\
2189 p = -y;\
2190 if (x == p)\
2191 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
2192 1.0 / x != 1.0 / p);\
2193 else\
2194 printf ("x != -y; this is wrong!\n");\
2196 void prefix ## test(void)\
2198 printf("testing '%s'\n", #typename);\
2199 prefix ## cmp(1, 2.5);\
2200 prefix ## cmp(2, 1.5);\
2201 prefix ## cmp(1, 1);\
2202 prefix ## fcast(234.6);\
2203 prefix ## fcast(-2334.6);\
2204 prefix ## call();\
2205 prefix ## signed_zeros();\
2208 FTEST(f, float, float, "%f")
2209 FTEST(d, double, double, "%f")
2210 FTEST(ld, long double, LONG_DOUBLE, "%Lf")
2212 double ftab1[3] = { 1.2, 3.4, -5.6 };
2215 void float_test(void)
2217 #if !defined(__arm__) || defined(__ARM_PCS_VFP)
2218 volatile float fa, fb;
2219 volatile double da, db;
2220 int a;
2221 unsigned int b;
2222 static double nan2 = 0.0/0.0;
2223 static double inf1 = 1.0/0.0;
2224 static double inf2 = 1e5000;
2225 volatile LONG_DOUBLE la;
2227 printf("sizeof(float) = %d\n", sizeof(float));
2228 printf("sizeof(double) = %d\n", sizeof(double));
2229 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
2230 ftest();
2231 dtest();
2232 ldtest();
2233 printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
2234 printf("%f %f %f\n", 2.12, .5, 2.3e10);
2235 // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
2236 da = 123;
2237 printf("da=%f\n", da);
2238 fa = 123;
2239 printf("fa=%f\n", fa);
2240 a = 4000000000;
2241 da = a;
2242 printf("da = %f\n", da);
2243 b = 4000000000;
2244 db = b;
2245 printf("db = %f\n", db);
2246 printf("nan != nan = %d, inf1 = %f, inf2 = %f\n", nan2 != nan2, inf1, inf2);
2247 da = 0x0.88p-1022; /* a subnormal */
2248 la = da;
2249 printf ("da subnormal = %a\n", da);
2250 printf ("da subnormal = %.40g\n", da);
2251 printf ("la subnormal = %La\n", la);
2252 printf ("la subnormal = %.40Lg\n", la);
2253 da /= 2;
2254 la = da;
2255 printf ("da/2 subnormal = %a\n", da);
2256 printf ("da/2 subnormal = %.40g\n", da);
2257 printf ("la/2 subnormal = %La\n", la);
2258 printf ("la/2 subnormal = %.40Lg\n", la);
2259 fa = 0x0.88p-126f; /* a subnormal */
2260 la = fa;
2261 printf ("fa subnormal = %a\n", fa);
2262 printf ("fa subnormal = %.40g\n", fa);
2263 printf ("la subnormal = %La\n", la);
2264 printf ("la subnormal = %.40Lg\n", la);
2265 fa /= 2;
2266 la = fa;
2267 printf ("fa/2 subnormal = %a\n", fa);
2268 printf ("fa/2 subnormal = %.40g\n", fa);
2269 printf ("la/2 subnormal = %La\n", la);
2270 printf ("la/2 subnormal = %.40Lg\n", la);
2271 #endif
2274 int fib(int n)
2276 if (n <= 2)
2277 return 1;
2278 else
2279 return fib(n-1) + fib(n-2);
2282 #if __GNUC__ == 3
2283 # define aligned_function 0
2284 #else
2285 void __attribute__((aligned(16))) aligned_function(int i) {}
2286 #endif
2288 void funcptr_test()
2290 void (*func)(int);
2291 int a;
2292 struct {
2293 int dummy;
2294 void (*func)(int);
2295 } st1;
2296 long diff;
2298 func = &num;
2299 (*func)(12345);
2300 func = num;
2301 a = 1;
2302 a = 1;
2303 func(12345);
2304 /* more complicated pointer computation */
2305 st1.func = num;
2306 st1.func(12346);
2307 printf("sizeof1 = %d\n", sizeof(funcptr_test));
2308 printf("sizeof2 = %d\n", sizeof funcptr_test);
2309 printf("sizeof3 = %d\n", sizeof(&funcptr_test));
2310 printf("sizeof4 = %d\n", sizeof &funcptr_test);
2311 a = 0;
2312 func = num + a;
2313 diff = func - num;
2314 func(42);
2315 (func + diff)(42);
2316 (num + a)(43);
2318 /* Check that we can align functions */
2319 func = aligned_function;
2320 printf("aligned_function (should be zero): %d\n", ((int)(uintptr_t)func) & 15);
2323 void lloptest(long long a, long long b)
2325 unsigned long long ua, ub;
2327 ua = a;
2328 ub = b;
2329 /* arith */
2330 printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2331 a + b,
2332 a - b,
2333 a * b);
2335 if (b != 0) {
2336 printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2337 a / b,
2338 a % b);
2341 /* binary */
2342 printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2343 a & b,
2344 a | b,
2345 a ^ b);
2347 /* tests */
2348 printf("test: %d %d %d %d %d %d\n",
2349 a == b,
2350 a != b,
2351 a < b,
2352 a > b,
2353 a >= b,
2354 a <= b);
2356 printf("utest: %d %d %d %d %d %d\n",
2357 ua == ub,
2358 ua != ub,
2359 ua < ub,
2360 ua > ub,
2361 ua >= ub,
2362 ua <= ub);
2364 /* arith2 */
2365 a++;
2366 b++;
2367 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2368 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
2369 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
2370 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2371 b = ub = 0;
2372 printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
2375 void llshift(long long a, int b)
2377 printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2378 (unsigned long long)a >> b,
2379 a >> b,
2380 a << b);
2381 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2382 (unsigned long long)a >> 3,
2383 a >> 3,
2384 a << 3);
2385 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2386 (unsigned long long)a >> 35,
2387 a >> 35,
2388 a << 35);
2391 void llfloat(void)
2393 float fa;
2394 double da;
2395 LONG_DOUBLE lda;
2396 long long la, lb, lc;
2397 unsigned long long ula, ulb, ulc;
2398 la = 0x12345678;
2399 ula = 0x72345678;
2400 la = (la << 20) | 0x12345;
2401 ula = ula << 33;
2402 printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
2404 fa = la;
2405 da = la;
2406 lda = la;
2407 printf("lltof: %f %f %Lf\n", fa, da, lda);
2409 la = fa;
2410 lb = da;
2411 lc = lda;
2412 printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
2414 fa = ula;
2415 da = ula;
2416 lda = ula;
2417 printf("ulltof: %f %f %Lf\n", fa, da, lda);
2419 ula = fa;
2420 ulb = da;
2421 ulc = lda;
2422 printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
2425 long long llfunc1(int a)
2427 return a * 2;
2430 struct S {
2431 int id;
2432 char item;
2435 long long int value(struct S *v)
2437 return ((long long int)v->item);
2440 long long llfunc2(long long x, long long y, int z)
2442 return x * y * z;
2445 void check_opl_save_regs(char *a, long long b, int c)
2447 *a = b < 0 && !c;
2450 void longlong_test(void)
2452 long long a, b, c;
2453 int ia;
2454 unsigned int ua;
2455 printf("sizeof(long long) = %d\n", sizeof(long long));
2456 ia = -1;
2457 ua = -2;
2458 a = ia;
2459 b = ua;
2460 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2461 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
2462 (long long)1,
2463 (long long)-2,
2464 1LL,
2465 0x1234567812345679);
2466 a = llfunc1(-3);
2467 printf(LONG_LONG_FORMAT "\n", a);
2469 lloptest(1000, 23);
2470 lloptest(0xff, 0x1234);
2471 b = 0x72345678 << 10;
2472 lloptest(-3, b);
2473 llshift(0x123, 5);
2474 llshift(-23, 5);
2475 b = 0x72345678LL << 10;
2476 llshift(b, 47);
2478 llfloat();
2479 #if 1
2480 b = 0x12345678;
2481 a = -1;
2482 c = a + b;
2483 printf("%Lx\n", c);
2484 #endif
2486 /* long long reg spill test */
2488 struct S a;
2490 a.item = 3;
2491 printf("%lld\n", value(&a));
2493 lloptest(0x80000000, 0);
2496 long long *p, v, **pp;
2497 v = 1;
2498 p = &v;
2499 p[0]++;
2500 printf("another long long spill test : %lld\n", *p);
2501 pp = &p;
2503 v = llfunc2(**pp, **pp, ia);
2504 printf("a long long function (arm-)reg-args test : %lld\n", v);
2506 a = 68719476720LL;
2507 b = 4294967295LL;
2508 printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
2510 printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
2512 /* long long pointer deref in argument passing test */
2513 a = 0x123;
2514 long long *p = &a;
2515 llshift(*p, 5);
2517 /* shortening followed by widening */
2518 unsigned long long u = 0x8000000000000001ULL;
2519 u = (unsigned)(u + 1);
2520 printf("long long u=" ULONG_LONG_FORMAT "\n", u);
2521 u = 0x11223344aa998877ULL;
2522 u = (unsigned)(int)(u + 1);
2523 printf("long long u=" ULONG_LONG_FORMAT "\n", u);
2525 /* was a problem with missing save_regs in gen_opl on 32-bit platforms */
2526 char cc = 78;
2527 check_opl_save_regs(&cc, -1, 0);
2528 printf("check_opl_save_regs: %d\n", cc);
2531 void manyarg_test(void)
2533 LONG_DOUBLE ld = 1234567891234LL;
2534 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2535 1, 2, 3, 4, 5, 6, 7, 8,
2536 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2537 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2538 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2539 1, 2, 3, 4, 5, 6, 7, 8,
2540 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2541 1234567891234LL, 987654321986LL,
2542 42.0, 43.0);
2543 printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2544 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2545 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2546 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2547 1234567891234LL, 987654321986LL,
2548 42.0, 43.0);
2549 printf("%d %d %d %d %d %d %d %d %Lf\n",
2550 1, 2, 3, 4, 5, 6, 7, 8, ld);
2551 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2552 LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
2553 1, 2, 3, 4, 5, 6, 7, 8,
2554 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2555 1234567891234LL, 987654321986LL,
2556 42.0, 43.0, ld);
2557 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2558 "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
2559 1, 2, 3, 4, 5, 6, 7, 8,
2560 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2561 ld, 1234567891234LL, 987654321986LL,
2562 42.0, 43.0, ld);
2565 void*
2566 va_arg_with_struct_ptr(va_list ap) {
2568 * This was a BUG identified with FFTW-3.3.8 on arm64.
2569 * The test case only checks it compiles on all supported
2570 * architectures. This function is not currently called.
2572 struct X { int _x; };
2573 struct X *x = va_arg(ap, struct X *);
2574 return x;
2577 void vprintf1(const char *fmt, ...)
2579 va_list ap, aq;
2580 const char *p;
2581 int c, i;
2582 double d;
2583 long long ll;
2584 LONG_DOUBLE ld;
2586 va_start(aq, fmt);
2587 va_copy(ap, aq);
2589 p = fmt;
2590 for(;;) {
2591 c = *p;
2592 if (c == '\0')
2593 break;
2594 p++;
2595 if (c == '%') {
2596 c = *p;
2597 switch(c) {
2598 case '\0':
2599 goto the_end;
2600 case 'd':
2601 i = va_arg(ap, int);
2602 printf("%d", i);
2603 break;
2604 case 'f':
2605 d = va_arg(ap, double);
2606 printf("%f", d);
2607 break;
2608 case 'l':
2609 ll = va_arg(ap, long long);
2610 printf(LONG_LONG_FORMAT, ll);
2611 break;
2612 case 'F':
2613 ld = va_arg(ap, LONG_DOUBLE);
2614 printf("%Lf", ld);
2615 break;
2617 p++;
2618 } else {
2619 putchar(c);
2622 the_end:
2623 va_end(aq);
2624 va_end(ap);
2627 struct myspace {
2628 short int profile;
2630 struct myspace2 {
2631 char a[0];
2633 struct myspace3 {
2634 char a[1];
2636 struct myspace4 {
2637 char a[2];
2640 void stdarg_for_struct(struct myspace bob, ...)
2642 struct myspace george, bill;
2643 struct myspace2 alex1;
2644 struct myspace3 alex2;
2645 struct myspace4 alex3;
2646 va_list ap;
2647 short int validate;
2649 va_start(ap, bob);
2650 alex1 = va_arg(ap, struct myspace2);
2651 alex2 = va_arg(ap, struct myspace3);
2652 alex3 = va_arg(ap, struct myspace4);
2653 bill = va_arg(ap, struct myspace);
2654 george = va_arg(ap, struct myspace);
2655 validate = va_arg(ap, int);
2656 printf("stdarg_for_struct: %d %d %d %d %d %d %d\n",
2657 alex2.a[0], alex3.a[0], alex3.a[1],
2658 bob.profile, bill.profile, george.profile, validate);
2659 va_end(ap);
2662 void stdarg_for_libc(const char *fmt, ...)
2664 va_list args;
2665 va_start(args, fmt);
2666 vprintf(fmt, args);
2667 va_end(args);
2670 void stdarg_syntax(int n, ...)
2672 int i;
2673 va_list ap;
2674 if (1)
2675 va_start(ap, n);
2676 else
2678 i = va_arg(ap, int);
2679 printf("stdarg_void_expr: %d\n", i);
2680 (va_end(ap));
2683 typedef struct{
2684 double x,y;
2685 } point;
2686 point pts[]={{1.0,2.0},{3.0,4.0},{5.0,6.0},{7.0,8.0},{9.0,10.0},{11.0,12.0}};
2688 static void stdarg_double_struct(int nargs, int posd,...)
2690 int i;
2691 double d;
2692 point pi;
2693 va_list args;
2695 printf ("stdarg_double_struct: %d\n", posd);
2696 va_start(args,posd);
2697 for(i = 0; i < nargs; i++) {
2698 if (i == posd) {
2699 d = va_arg (args, double);
2700 printf ("d %d = %g\n", i, d);
2702 else {
2703 pi = va_arg (args, point);
2704 printf ("pts[%d] = %g %g\n", i, pi.x, pi.y);
2707 va_end(args);
2710 void stdarg_test(void)
2712 LONG_DOUBLE ld = 1234567891234LL;
2713 struct myspace bob;
2714 struct myspace2 bob2;
2715 struct myspace3 bob3;
2716 struct myspace4 bob4;
2718 vprintf1("%d %d %d\n", 1, 2, 3);
2719 vprintf1("%f %d %f\n", 1.0, 2, 3.0);
2720 vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
2721 vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
2722 vprintf1("%d %f %l %F %d %f %l %F\n",
2723 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
2724 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
2725 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);
2727 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2728 1, 2, 3, 4, 5, 6, 7, 8,
2729 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2730 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2731 "%l %l %f %f\n",
2732 1, 2, 3, 4, 5, 6, 7, 8,
2733 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2734 1234567891234LL, 987654321986LL,
2735 42.0, 43.0);
2736 vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2737 "%l %l %f %f\n",
2738 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2739 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2740 1234567891234LL, 987654321986LL,
2741 42.0, 43.0);
2742 vprintf1("%d %d %d %d %d %d %d %d %F\n",
2743 1, 2, 3, 4, 5, 6, 7, 8, ld);
2744 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2745 "%l %l %f %f %F\n",
2746 1, 2, 3, 4, 5, 6, 7, 8,
2747 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2748 1234567891234LL, 987654321986LL,
2749 42.0, 43.0, ld);
2750 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2751 "%F %l %l %f %f %F\n",
2752 1, 2, 3, 4, 5, 6, 7, 8,
2753 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2754 ld, 1234567891234LL, 987654321986LL,
2755 42.0, 43.0, ld);
2757 bob.profile = 42;
2758 bob3.a[0] = 1;
2759 bob4.a[0] = 2;
2760 bob4.a[1] = 3;
2761 stdarg_for_struct(bob, bob2, bob3, bob4, bob, bob, bob.profile);
2762 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
2763 stdarg_syntax(1, 17);
2764 #ifndef __riscv
2765 stdarg_double_struct(6,-1,pts[0],pts[1],pts[2],pts[3],pts[4],pts[5]);
2766 stdarg_double_struct(7,1,pts[0],-1.0,pts[1],pts[2],pts[3],pts[4],pts[5]);
2767 stdarg_double_struct(7,2,pts[0],pts[1],-1.0,pts[2],pts[3],pts[4],pts[5]);
2768 stdarg_double_struct(7,3,pts[0],pts[1],pts[2],-1.0,pts[3],pts[4],pts[5]);
2769 stdarg_double_struct(7,4,pts[0],pts[1],pts[2],pts[3],-1.0,pts[4],pts[5]);
2770 stdarg_double_struct(7,5,pts[0],pts[1],pts[2],pts[3],pts[4],-1.0,pts[5]);
2771 #endif
2774 int reltab[3] = { 1, 2, 3 };
2776 int *rel1 = &reltab[1];
2777 int *rel2 = &reltab[2];
2779 #ifdef _WIN64
2780 void relocation_test(void) {}
2781 #else
2782 void getmyaddress(void)
2784 printf("in getmyaddress\n");
2787 #ifdef __LP64__
2788 long __pa_symbol(void)
2790 /* This 64bit constant was handled incorrectly, it was used as addend
2791 (which can hold 64bit just fine) in connection with a symbol,
2792 and TCC generates wrong code for that (displacements are 32bit only).
2793 This effectively is "+ 0x80000000", and if addresses of globals
2794 are below 2GB the result should be a number without high 32 bits set. */
2795 return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
2797 #endif
2799 unsigned long theaddress = (unsigned long)getmyaddress;
2800 void relocation_test(void)
2802 void (*fptr)(void) = (void (*)(void))theaddress;
2803 printf("*rel1=%d\n", *rel1);
2804 printf("*rel2=%d\n", *rel2);
2805 fptr();
2806 #ifdef __LP64__
2807 printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
2808 #endif
2810 #endif
2812 void old_style_f(a,b,c)
2813 int a, b;
2814 double c;
2816 printf("a=%d b=%d b=%f\n", a, b, c);
2819 void decl_func1(int cmpfn())
2821 printf("cmpfn=%lx\n", (long)cmpfn);
2824 void decl_func2(cmpfn)
2825 int cmpfn();
2827 printf("cmpfn=%lx\n", (long)cmpfn);
2830 void old_style_function_test(void)
2832 old_style_f((void *)1, 2, 3.0);
2833 decl_func1(NULL);
2834 decl_func2(NULL);
2837 void alloca_test()
2839 #if defined __i386__ || defined __x86_64__ || defined __arm__
2840 char *p = alloca(16);
2841 strcpy(p,"123456789012345");
2842 printf("alloca: p is %s\n", p);
2843 char *demo = "This is only a test.\n";
2844 /* Test alloca embedded in a larger expression */
2845 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
2846 #endif
2849 void *bounds_checking_is_enabled()
2851 char ca[10], *cp = ca-1;
2852 return (ca != cp + 1) ? cp : NULL;
2855 typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
2857 void c99_vla_test_1(int size1, int size2)
2859 #if defined __i386__ || defined __x86_64__
2860 int size = size1 * size2;
2861 int tab1[size][2], tab2[10][2];
2862 void *tab1_ptr, *tab2_ptr, *bad_ptr;
2864 /* "size" should have been 'captured' at tab1 declaration,
2865 so modifying it should have no effect on VLA behaviour. */
2866 size = size-1;
2868 printf("Test C99 VLA 1 (sizeof): ");
2869 printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
2870 tab1_ptr = tab1;
2871 tab2_ptr = tab2;
2872 printf("Test C99 VLA 2 (ptrs subtract): ");
2873 printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
2874 printf("Test C99 VLA 3 (ptr add): ");
2875 printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
2876 printf("Test C99 VLA 4 (ptr access): ");
2877 tab1[size1][1] = 42;
2878 printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
2880 printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
2881 if (bad_ptr = bounds_checking_is_enabled()) {
2882 int *t1 = &tab1[size1 * size2 - 1][3];
2883 int *t2 = &tab2[9][3];
2884 printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED");
2885 printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED");
2887 char*c1 = 1 + sizeof(tab1) + (char*)tab1;
2888 char*c2 = 1 + sizeof(tab2) + (char*)tab2;
2889 printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED");
2890 printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED");
2892 int *i1 = tab1[-1];
2893 int *i2 = tab2[-1];
2894 printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED");
2895 printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED");
2897 int *x1 = tab1[size1 * size2 + 1];
2898 int *x2 = tab2[10 + 1];
2899 printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED");
2900 printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED");
2901 } else {
2902 printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
2904 printf("\n");
2905 #endif
2908 void c99_vla_test(void)
2910 c99_vla_test_1(5, 2);
2914 void sizeof_test(void)
2916 int a;
2917 int **ptr;
2919 printf("sizeof(int) = %d\n", sizeof(int));
2920 printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
2921 printf("sizeof(long) = %d\n", sizeof(long));
2922 printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
2923 printf("sizeof(short) = %d\n", sizeof(short));
2924 printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
2925 printf("sizeof(char) = %d\n", sizeof(char));
2926 printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
2927 printf("sizeof(func) = %d\n", sizeof sizeof_test());
2928 a = 1;
2929 printf("sizeof(a++) = %d\n", sizeof a++);
2930 printf("a=%d\n", a);
2931 ptr = NULL;
2932 printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
2934 /* The type of sizeof should be as large as a pointer, actually
2935 it should be size_t. */
2936 printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
2937 uintptr_t t = 1;
2938 uintptr_t t2;
2939 /* Effectively <<32, but defined also on 32bit machines. */
2940 t <<= 16;
2941 t <<= 16;
2942 t++;
2943 /* This checks that sizeof really can be used to manipulate
2944 uintptr_t objects, without truncation. */
2945 t2 = t & -sizeof(uintptr_t);
2946 printf ("%lu %lu\n", t, t2);
2948 /* some alignof tests */
2949 printf("__alignof__(int) = %d\n", __alignof__(int));
2950 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
2951 printf("__alignof__(short) = %d\n", __alignof__(short));
2952 printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
2953 printf("__alignof__(char) = %d\n", __alignof__(char));
2954 printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
2955 printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
2957 /* sizes of VLAs need to be evaluated even inside sizeof: */
2958 a = 2;
2959 printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
2960 /* And checking if sizeof compound literal works. Parenthesized: */
2961 printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
2962 sizeof( (struct {int i; int j;}){4,5} ));
2963 /* And as direct sizeof argument (as unary expression): */
2964 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
2965 sizeof (struct {short i; short j;}){4,5} );
2967 /* sizeof(x && y) should be sizeof(int), even if constant
2968 evaluating is possible. */
2969 printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
2970 printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
2971 printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
2972 printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
2975 void typeof_test(void)
2977 double a;
2978 typeof(a) b;
2979 typeof(float) c;
2981 a = 1.5;
2982 b = 2.5;
2983 c = 3.5;
2984 printf("a=%f b=%f c=%f\n", a, b, c);
2988 struct hlist_node;
2989 struct hlist_head {
2990 struct hlist_node *first, *last;
2993 void consume_ulong (unsigned long i)
2995 i = 0;
2998 void statement_expr_test(void)
3000 int a, i;
3002 /* Basic stmt expr test */
3003 a = 0;
3004 for(i=0;i<10;i++) {
3005 a += 1 +
3006 ( { int b, j;
3007 b = 0;
3008 for(j=0;j<5;j++)
3009 b += j; b;
3010 } );
3012 printf("a=%d\n", a);
3014 /* Test that symbols aren't freed prematurely.
3015 With SYM_DEBUG valgrind will show a read from a freed
3016 symbol, and tcc will show an (invalid) warning on the initialization
3017 of 'ptr' below, if symbols are popped after the stmt expr. */
3018 void *v = (void*)39;
3019 typeof(({
3020 (struct hlist_node *)v;
3021 })) x;
3022 typeof (x)
3023 ptr = (struct hlist_node *)v;
3025 /* This part used to segfault when symbols were popped prematurely.
3026 The symbols for the static local would be overwritten with
3027 helper symbols from the pre-processor expansions in between. */
3028 #define some_attr __attribute__((aligned(1)))
3029 #define tps(str) ({ \
3030 static const char *t some_attr = str; \
3031 t; \
3033 printf ("stmtexpr: %s %s\n",
3034 tps("somerandomlongstring"),
3035 tps("anotherlongstring"));
3037 /* Test that the three decls of 't' don't interact. */
3038 int t = 40;
3039 int b = ({ int t = 41; t; });
3040 int c = ({ int t = 42; t; });
3042 /* Test that aggregate return values work. */
3043 struct hlist_head h
3044 = ({
3045 typedef struct hlist_head T;
3046 long pre = 48;
3047 T t = { (void*)43, (void*)44 };
3048 long post = 49;
3051 printf ("stmtexpr: %d %d %d\n", t, b, c);
3052 printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
3054 /* Test that we can give out addresses of local labels. */
3055 consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
3057 /* Test interaction between local and global label stacks and the
3058 need to defer popping symbol from them when within statement
3059 expressions. Note how the labels are both named LBL. */
3060 i = 0;
3063 __label__ LBL;
3064 LBL: if (i++ == 0) goto LBL;
3066 /* jump to a classical label out of an expr-stmt that had previously
3067 overshadowed that classical label */
3068 goto LBL;
3070 LBL:
3071 printf("stmtexpr: %d should be 2\n", i);
3074 void local_label_test(void)
3076 int a;
3077 goto l1;
3079 a = 1 + ({
3080 __label__ l1, l2, l3, l4;
3081 goto l1;
3083 printf("aa1\n");
3084 goto l3;
3086 printf("aa3\n");
3087 goto l4;
3089 printf("aa2\n");
3090 goto l2;
3091 l3:;
3094 printf("a=%d\n", a);
3095 return;
3097 printf("bb1\n");
3098 goto l2;
3100 printf("bb2\n");
3101 goto l4;
3104 /* inline assembler test */
3105 #if defined(__i386__) || defined(__x86_64__)
3107 /* from linux kernel */
3108 static char * strncat1(char * dest,const char * src,size_t count)
3110 long d0, d1, d2, d3;
3111 __asm__ __volatile__(
3112 "repne\n\t"
3113 "scasb\n\t"
3114 "dec %1\n\t"
3115 "mov %8,%3\n"
3116 "1:\tdec %3\n\t"
3117 "js 2f\n\t"
3118 "lodsb\n\t"
3119 "stosb\n\t"
3120 "testb %%al,%%al\n\t"
3121 "jne 1b\n"
3122 "2:\txor %2,%2\n\t"
3123 "stosb"
3124 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3125 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3126 : "memory");
3127 return dest;
3130 static char * strncat2(char * dest,const char * src,size_t count)
3132 long d0, d1, d2, d3;
3133 __asm__ __volatile__(
3134 "repne scasb\n\t" /* one-line repne prefix + string op */
3135 "dec %1\n\t"
3136 "mov %8,%3\n"
3137 "1:\tdec %3\n\t"
3138 "js 2f\n\t"
3139 "lodsb\n\t"
3140 "stosb\n\t"
3141 "testb %%al,%%al\n\t"
3142 "jne 1b\n"
3143 "2:\txor %2,%2\n\t"
3144 "stosb"
3145 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3146 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3147 : "memory");
3148 return dest;
3151 static inline void * memcpy1(void * to, const void * from, size_t n)
3153 long d0, d1, d2;
3154 __asm__ __volatile__(
3155 "rep ; movsl\n\t"
3156 "testb $2,%b4\n\t"
3157 "je 1f\n\t"
3158 "movsw\n"
3159 "1:\ttestb $1,%b4\n\t"
3160 "je 2f\n\t"
3161 "movsb\n"
3162 "2:"
3163 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3164 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3165 : "memory");
3166 return (to);
3169 static inline void * memcpy2(void * to, const void * from, size_t n)
3171 long d0, d1, d2;
3172 __asm__ __volatile__(
3173 "rep movsl\n\t" /* one-line rep prefix + string op */
3174 "testb $2,%b4\n\t"
3175 "je 1f\n\t"
3176 "movsw\n"
3177 "1:\ttestb $1,%b4\n\t"
3178 "je 2f\n\t"
3179 "movsb\n"
3180 "2:"
3181 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3182 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3183 : "memory");
3184 return (to);
3187 static __inline__ void sigaddset1(unsigned int *set, int _sig)
3189 __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
3192 static __inline__ void sigdelset1(unsigned int *set, int _sig)
3194 asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
3197 #ifndef __APPLE__
3198 /* clang's inline asm is uncapable of 'xchgb %b0,%h0' */
3199 static __inline__ __const__ unsigned int swab32(unsigned int x)
3201 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
3202 "rorl $16,%0\n\t" /* swap words */
3203 "xchgb %b0,%h0" /* swap higher bytes */
3204 :"=" "q" (x)
3205 : "0" (x));
3206 return x;
3208 #endif
3210 static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
3212 unsigned long long res;
3213 #ifdef __x86_64__
3214 /* Using the A constraint is wrong (it means rdx:rax, which is too large)
3215 but still test the 32bit->64bit mull. */
3216 unsigned int resh, resl;
3217 __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
3218 res = ((unsigned long long)resh << 32) | resl;
3219 #else
3220 __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
3221 #endif
3222 return res;
3225 static __inline__ unsigned long long inc64(unsigned long long a)
3227 unsigned long long res;
3228 #ifdef __x86_64__
3229 /* Using the A constraint is wrong, and increments are tested
3230 elsewhere. */
3231 res = a + 1;
3232 #else
3233 __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
3234 #endif
3235 return res;
3238 struct struct123 {
3239 int a;
3240 int b;
3242 struct struct1231 {
3243 unsigned long addr;
3246 unsigned long mconstraint_test(struct struct1231 *r)
3248 unsigned long ret;
3249 unsigned int a[2];
3250 a[0] = 0;
3251 __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
3252 : "=&r" (ret), "=m" (a)
3253 : "m" (*(struct struct123 *)r->addr));
3254 return ret + a[0];
3257 #ifdef __x86_64__
3258 int fls64(unsigned long long x)
3260 int bitpos = -1;
3261 asm("bsrq %1,%q0"
3262 : "+r" (bitpos)
3263 : "rm" (x));
3264 return bitpos + 1;
3266 #endif
3268 void other_constraints_test(void)
3270 unsigned long ret;
3271 int var;
3272 #ifndef _WIN64
3273 __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
3274 printf ("oc1: %d\n", ret == (unsigned long)&var);
3275 #endif
3278 #ifndef _WIN32
3279 /* Test global asm blocks playing with aliases. */
3280 void base_func(void)
3282 printf ("asmc: base\n");
3285 #ifndef __APPLE__
3286 extern void override_func1 (void);
3287 extern void override_func2 (void);
3289 asm(".weak override_func1\n.set override_func1, base_func");
3290 asm(".set override_func1, base_func");
3291 asm(".set override_func2, base_func");
3293 void override_func2 (void)
3295 printf ("asmc: override2\n");
3298 /* This checks a construct used by the linux kernel to encode
3299 references to strings by PC relative references. */
3300 extern int bug_table[] __attribute__((section("__bug_table")));
3301 char * get_asm_string (void)
3303 /* On i386 when -fPIC is enabled this would cause a compile error with GCC,
3304 the problem being the "i" constraint used with a symbolic operand
3305 resolving to a local label. That check is overly zealous as the code
3306 within the asm makes sure to use it only in PIC-possible contexts,
3307 but all GCC versions behave like so. We arrange for PIC to be disabled
3308 for compiling tcctest.c in the Makefile.
3310 Additionally the usage of 'c' in "%c0" in the template is actually wrong,
3311 as that would expect an operand that is a condition code. The operand
3312 as is (a local label) is accepted by GCC in non-PIC mode, and on x86-64.
3313 What the linux kernel really wanted is 'p' to disable the addition of '$'
3314 to the printed operand (as in "$.LC0" where the template only wants the
3315 bare operand ".LC0"). But the code below is what the linux kernel
3316 happens to use and as such is the one we want to test. */
3317 #ifndef __clang__
3318 extern int some_symbol;
3319 asm volatile (".globl some_symbol\n"
3320 "jmp .+6\n"
3321 "1:\n"
3322 "some_symbol: .long 0\n"
3323 ".pushsection __bug_table, \"a\"\n"
3324 ".globl bug_table\n"
3325 "bug_table:\n"
3326 /* The first entry (1b-2b) is unused in this test,
3327 but we include it to check if cross-section
3328 PC-relative references work. */
3329 "2:\t.long 1b - 2b, %c0 - 2b\n"
3330 ".popsection\n" : : "i" ("A string"));
3331 char * str = ((char*)bug_table) + bug_table[1];
3332 return str;
3333 #else
3334 return (char *) "A string";
3335 #endif
3338 /* This checks another constructs with local labels. */
3339 extern unsigned char alld_stuff[];
3340 asm(".data\n"
3341 ".byte 41\n"
3342 "alld_stuff:\n"
3343 "661:\n"
3344 ".byte 42\n"
3345 "662:\n"
3346 ".pushsection .data.ignore\n"
3347 ".long 661b - .\n" /* This reference to 661 generates an external sym
3348 which shouldn't somehow overwrite the offset that's
3349 already determined for it. */
3350 ".popsection\n"
3351 ".byte 662b - 661b\n" /* So that this value is undeniably 1. */);
3353 void asm_local_label_diff (void)
3355 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
3357 #endif
3359 /* This checks that static local variables are available from assembler. */
3360 void asm_local_statics (void)
3362 static int localint = 41;
3363 asm("incl %0" : "+m" (localint));
3364 printf ("asm_local_statics: %d\n", localint);
3366 #endif
3368 static
3369 unsigned int set;
3371 void fancy_copy (unsigned *in, unsigned *out)
3373 asm volatile ("" : "=r" (*out) : "0" (*in));
3376 void fancy_copy2 (unsigned *in, unsigned *out)
3378 asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
3381 #if defined __x86_64__ && !defined _WIN64
3382 void clobber_r12(void)
3384 asm volatile("mov $1, %%r12" ::: "r12");
3386 #endif
3388 void test_high_clobbers_really(void)
3390 #if defined __x86_64__ && !defined _WIN64
3391 register long val asm("r12");
3392 long val2;
3393 /* This tests if asm clobbers correctly save/restore callee saved
3394 registers if they are clobbered and if it's the high 8 x86-64
3395 registers. This is fragile for GCC as the constraints do not
3396 correctly capture the data flow, but good enough for us. */
3397 asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
3398 clobber_r12();
3399 asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
3400 printf("asmhc: 0x%x\n", val2);
3401 #endif
3404 void test_high_clobbers(void)
3406 #if defined __x86_64__ && !defined _WIN64
3407 long x1, x2;
3408 asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */
3409 test_high_clobbers_really();
3410 asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */
3411 asm volatile("mov %0,%%r12" :: "m" (x1)); /* restore r12 */
3412 /* should be 0 but tcc doesn't save r12 automatically, which has
3413 bad effects when gcc helds TCCState *s in r12 in tcc.c:main */
3414 //printf("r12-clobber-diff: %lx\n", x2 - x1);
3415 #endif
3418 static long cpu_number;
3419 void trace_console(long len, long len2)
3421 #ifdef __x86_64__
3422 /* This generated invalid code when the emission of the switch
3423 table isn't disabled. The asms are necessary to show the bug,
3424 normal statements don't work (they need to generate some code
3425 even under nocode_wanted, which normal statements don't do,
3426 but asms do). Also at least these number of cases is necessary
3427 to generate enough "random" bytes. They ultimately are enough
3428 to create invalid instruction patterns to which the first
3429 skip-to-decision-table jump jumps. If decision table emission
3430 is disabled all of this is no problem.
3432 It also is necessary that the switches are in a statement expression
3433 (which has the property of not being enterable from outside. no
3434 matter what). */
3435 if (0
3438 long pscr_ret__;
3439 switch(len) {
3440 case 4:
3442 long pfo_ret__;
3443 switch (len2) {
3444 case 8: printf("bla"); pfo_ret__ = 42; break;
3446 pscr_ret__ = pfo_ret__;
3448 break;
3449 case 8:
3451 long pfo_ret__;
3452 switch (len2) {
3453 case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3454 case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3455 case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3456 case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3457 default: printf("impossible\n");
3459 pscr_ret__ = pfo_ret__;
3461 break;
3463 pscr_ret__;
3466 printf("huh?\n");
3468 #endif
3471 void test_asm_dead_code(void)
3473 long rdi;
3474 /* Try to make sure that xdi contains a zero, and hence will
3475 lead to a segfault if the next asm is evaluated without
3476 arguments being set up. */
3477 asm volatile ("" : "=D" (rdi) : "0" (0));
3478 (void)sizeof (({
3479 int var;
3480 /* This shouldn't trigger a segfault, either the argument
3481 registers need to be set up and the asm emitted despite
3482 this being in an unevaluated context, or both the argument
3483 setup _and_ the asm emission need to be suppressed. The latter
3484 is better. Disabling asm code gen when suppression is on
3485 also fixes the above trace_console bug, but that came earlier
3486 than asm suppression. */
3487 asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
3488 var;
3489 }));
3492 void test_asm_call(void)
3494 #if defined __x86_64__ && !defined _WIN64
3495 static char str[] = "PATH";
3496 char *s;
3497 /* This tests if a reference to an undefined symbol from an asm
3498 block, which isn't otherwise referenced in this file, is correctly
3499 regarded as global symbol, so that it's resolved by other object files
3500 or libraries. We chose getenv here, which isn't used anywhere else
3501 in this file. (If we used e.g. printf, which is used we already
3502 would have a global symbol entry, not triggering the bug which is
3503 tested here). */
3504 /* two pushes so stack remains aligned */
3505 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
3506 #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) && !defined(__APPLE__)
3507 "call getenv@plt;"
3508 #elif defined(__APPLE__)
3509 "call _getenv;"
3510 #else
3511 "call getenv;"
3512 #endif
3513 "pop %%rdi; pop %%rdi"
3514 : "=a" (s) : "r" (str));
3515 printf("asmd: %s\n", s);
3516 #endif
3519 #if defined __x86_64__
3520 # define RX "(%rip)"
3521 #else
3522 # define RX
3523 #endif
3525 void asm_dot_test(void)
3527 #ifndef __APPLE__
3528 int x;
3529 for (x = 1;; ++x) {
3530 int r = x;
3531 switch (x) {
3532 case 1:
3533 asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
3534 case 2:
3535 #ifndef __clang__
3536 /* clangs internal assembler is broken */
3537 asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
3538 #else
3539 asm(".text; mov $123, %eax; jmp p0");
3540 #endif
3541 case 3:
3542 #if !defined(_WIN32) && !defined(__clang__)
3543 asm(".pushsection \".data\"; Y=.; .int 999; X=Y; .int 456; X=.-4; .popsection");
3544 #else
3545 asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4; .text");
3546 #endif
3547 asm(".text; mov X"RX",%eax; jmp p0");
3548 case 4:
3549 #ifdef __clang__
3550 /* Bah! Clang! Doesn't want to redefine 'X' */
3551 asm(".text; mov $789,%eax; jmp p0");
3552 #else
3553 #ifndef _WIN32
3554 asm(".data; X=.; .int 789; Y=.; .int 999; .previous");
3555 #else
3556 asm(".data; X=.; .int 789; Y=.; .int 999; .text");
3557 #endif
3558 asm(".text; mov X"RX",%eax; X=Y; jmp p0");
3559 #endif
3560 case 0:
3561 asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
3563 if (r == x)
3564 break;
3565 printf("asm_dot_test %d: %d\n", x, r);
3567 #endif
3570 void asm_test(void)
3572 char buf[128];
3573 unsigned int val, val2;
3574 struct struct123 s1;
3575 struct struct1231 s2 = { (unsigned long)&s1 };
3576 /* Hide the outer base_func, but check later that the inline
3577 asm block gets the outer one. */
3578 int base_func = 42;
3579 void override_func3 (void);
3580 unsigned long asmret;
3581 #ifdef BOOL_ISOC99
3582 _Bool somebool;
3583 #endif
3584 register int regvar asm("%esi");
3586 // parse 0x1E-1 as 3 tokens in asm mode
3587 asm volatile ("mov $0x1E-1,%eax");
3589 /* test the no operand case */
3590 asm volatile ("xorl %eax, %eax");
3592 memcpy1(buf, "hello", 6);
3593 strncat1(buf, " worldXXXXX", 3);
3594 printf("%s\n", buf);
3596 memcpy2(buf, "hello", 6);
3597 strncat2(buf, " worldXXXXX", 3);
3598 printf("%s\n", buf);
3600 /* 'A' constraint test */
3601 printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
3602 printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
3604 s1.a = 42;
3605 s1.b = 43;
3606 printf("mconstraint: %d", mconstraint_test(&s2));
3607 printf(" %d %d\n", s1.a, s1.b);
3608 other_constraints_test();
3609 set = 0xff;
3610 sigdelset1(&set, 2);
3611 sigaddset1(&set, 16);
3612 /* NOTE: we test here if C labels are correctly restored after the
3613 asm statement */
3614 goto label1;
3615 label2:
3616 __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
3617 printf("set=0x%x\n", set);
3618 val = 0x01020304;
3619 #ifndef __APPLE__
3620 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
3621 #endif
3622 #ifndef _WIN32
3623 #ifndef __APPLE__
3624 override_func1();
3625 override_func2();
3626 /* The base_func ref from the following inline asm should find
3627 the global one, not the local decl from this function. */
3628 asm volatile(".weak override_func3\n.set override_func3, base_func");
3629 override_func3();
3630 printf("asmstr: %s\n", get_asm_string());
3631 asm_local_label_diff();
3632 #endif
3633 asm_local_statics();
3634 #endif
3635 #ifndef __clang__
3636 /* clang can't deal with the type change */
3637 /* Check that we can also load structs of appropriate layout
3638 into registers. */
3639 asm volatile("" : "=r" (asmret) : "0"(s2));
3640 if (asmret != s2.addr)
3641 printf("asmstr: failed\n");
3642 #endif
3643 #ifdef BOOL_ISOC99
3644 /* Check that the typesize correctly sets the register size to
3645 8 bit. */
3646 asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
3647 if (!somebool)
3648 printf("asmbool: failed\n");
3649 #endif
3650 val = 43;
3651 fancy_copy (&val, &val2);
3652 printf ("fancycpy(%d)=%d\n", val, val2);
3653 val = 44;
3654 fancy_copy2 (&val, &val2);
3655 printf ("fancycpy2(%d)=%d\n", val, val2);
3656 asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
3657 printf ("regvar=%x\n", regvar);
3658 test_high_clobbers();
3659 trace_console(8, 8);
3660 test_asm_dead_code();
3661 test_asm_call();
3662 asm_dot_test();
3663 return;
3664 label1:
3665 goto label2;
3668 #else
3670 void asm_test(void)
3674 #endif
3676 #define COMPAT_TYPE(type1, type2) \
3678 printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
3679 __builtin_types_compatible_p (type1, type2));\
3682 int constant_p_var;
3684 int func(void);
3686 void builtin_test(void)
3688 short s;
3689 int i;
3690 long long ll;
3691 #if GCC_MAJOR >= 3
3692 COMPAT_TYPE(int, int);
3693 COMPAT_TYPE(int, unsigned int);
3694 COMPAT_TYPE(int, char);
3695 COMPAT_TYPE(int, const int);
3696 COMPAT_TYPE(int, volatile int);
3697 COMPAT_TYPE(int *, int *);
3698 COMPAT_TYPE(int *, void *);
3699 COMPAT_TYPE(int *, const int *);
3700 COMPAT_TYPE(char *, unsigned char *);
3701 COMPAT_TYPE(char *, signed char *);
3702 COMPAT_TYPE(char *, char *);
3703 /* space is needed because tcc preprocessor introduces a space between each token */
3704 COMPAT_TYPE(char * *, void *);
3705 #endif
3706 printf("res1 = %d\n", __builtin_constant_p(1));
3707 printf("res2 = %d\n", __builtin_constant_p(1 + 2));
3708 printf("res3 = %d\n", __builtin_constant_p(&constant_p_var));
3709 printf("res4 = %d\n", __builtin_constant_p(constant_p_var));
3710 printf("res5 = %d\n", __builtin_constant_p(100000 / constant_p_var));
3711 #ifdef __clang__
3712 /* clang doesn't regard this as constant expression */
3713 printf("res6 = 1\n");
3714 #else
3715 printf("res6 = %d\n", __builtin_constant_p(i && 0));
3716 #endif
3717 printf("res7 = %d\n", __builtin_constant_p(i && 1));
3718 #ifdef __clang__
3719 /* clang doesn't regard this as constant expression */
3720 printf("res8 = 1\n");
3721 #else
3722 printf("res8 = %d\n", __builtin_constant_p(i && 0 ? i : 34));
3723 #endif
3724 printf("res9 = %d\n", __builtin_constant_p("hi"));
3725 printf("res10 = %d\n", __builtin_constant_p(func()));
3726 s = 1;
3727 ll = 2;
3728 i = __builtin_choose_expr (1 != 0, ll, s);
3729 printf("bce: %d\n", i);
3730 i = __builtin_choose_expr (1 != 1, ll, s);
3731 printf("bce: %d\n", i);
3732 i = sizeof (__builtin_choose_expr (1, ll, s));
3733 printf("bce: %d\n", i);
3734 i = sizeof (__builtin_choose_expr (0, ll, s));
3735 printf("bce: %d\n", i);
3737 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
3740 #ifdef _WIN32
3741 void weak_test(void) {}
3742 #else
3743 extern int __attribute__((weak)) weak_f1(void);
3744 extern int __attribute__((weak)) weak_f2(void);
3745 extern int weak_f3(void);
3746 extern int __attribute__((weak)) weak_v1;
3747 extern int __attribute__((weak)) weak_v2;
3748 extern int weak_v3;
3750 extern int (*weak_fpa)() __attribute__((weak));
3751 extern int __attribute__((weak)) (*weak_fpb)();
3752 extern __attribute__((weak)) int (*weak_fpc)();
3754 extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
3755 extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ;
3756 extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
3757 extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak));
3758 extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ;
3759 extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
3761 #ifndef __clang__
3762 static const size_t dummy = 0;
3763 extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy")));
3764 extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2;
3765 extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3;
3766 #endif
3768 int some_lib_func(void);
3769 int dummy_impl_of_slf(void) { return 444; }
3770 #ifndef __clang__
3771 int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf")));
3772 #endif
3774 int weak_toolate() __attribute__((weak));
3775 int weak_toolate() { return 0; }
3777 void __attribute__((weak)) weak_test(void)
3779 printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
3780 printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123);
3781 printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123);
3782 printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123);
3783 printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123);
3784 printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123);
3786 printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
3787 printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
3788 printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
3790 printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
3791 printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
3792 printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
3793 printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
3794 printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
3795 printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
3796 #ifdef __clang__
3797 printf("some_lib_func=444\n");
3798 #else
3799 printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
3800 #endif
3803 int __attribute__((weak)) weak_f2() { return 222; }
3804 int __attribute__((weak)) weak_f3() { return 333; }
3805 int __attribute__((weak)) weak_v2 = 222;
3806 int __attribute__((weak)) weak_v3 = 333;
3807 #endif
3809 void const_func(const int a)
3813 void const_warn_test(void)
3815 const_func(1);
3818 struct condstruct {
3819 int i;
3822 int getme (struct condstruct *s, int i)
3824 int i1 = (i == 0 ? 0 : s)->i;
3825 int i2 = (i == 0 ? s : 0)->i;
3826 int i3 = (i == 0 ? (void*)0 : s)->i;
3827 int i4 = (i == 0 ? s : (void*)0)->i;
3828 return i1 + i2 + i3 + i4;
3831 struct global_data
3833 int a[40];
3834 int *b[40];
3837 struct global_data global_data;
3839 int global_data_getstuff (int *, int);
3841 void global_data_callit (int i)
3843 *global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
3846 int global_data_getstuff (int *p, int i)
3848 return *p + i;
3851 void global_data_test (void)
3853 global_data.a[0] = 42;
3854 global_data.b[0] = &global_data.a[0];
3855 global_data_callit (0);
3856 printf ("%d\n", global_data.a[0]);
3859 struct cmpcmpS
3861 unsigned char fill : 3;
3862 unsigned char b1 : 1;
3863 unsigned char b2 : 1;
3864 unsigned char fill2 : 3;
3867 int glob1, glob2, glob3;
3869 void compare_comparisons (struct cmpcmpS *s)
3871 if (s->b1 != (glob1 == glob2)
3872 || (s->b2 != (glob1 == glob3)))
3873 printf ("comparing comparisons broken\n");
3876 void cmp_comparison_test(void)
3878 struct cmpcmpS s;
3879 s.b1 = 1;
3880 glob1 = 42; glob2 = 42;
3881 s.b2 = 0;
3882 glob3 = 43;
3883 compare_comparisons (&s);
3886 int fcompare (double a, double b, int code)
3888 switch (code) {
3889 case 0: return a == b;
3890 case 1: return a != b;
3891 case 2: return a < b;
3892 case 3: return a >= b;
3893 case 4: return a > b;
3894 case 5: return a <= b;
3896 return 0;
3899 void math_cmp_test(void)
3901 double nan = 0.0/0.0;
3902 double one = 1.0;
3903 double two = 2.0;
3904 int comp = 0;
3905 int v;
3906 #define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
3908 /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
3909 And it does this in various ways so that all code generation paths
3910 are checked (generating inverted tests, or non-inverted tests, or
3911 producing a 0/1 value without jumps (that's done in the fcompare
3912 function). */
3913 #define FCMP(a,b,op,iop,code) \
3914 if (fcompare (a,b,code)) \
3915 bug (a,b,op,iop,1); \
3916 if (a op b) \
3917 bug (a,b,op,iop,2); \
3918 if (a iop b) \
3920 else \
3921 bug (a,b,op,iop,3); \
3922 if ((a op b) || comp) \
3923 bug (a,b,op,iop,4); \
3924 if ((a iop b) || comp) \
3926 else \
3927 bug (a,b,op,iop,5); \
3928 if (v = !(a op b), !v) bug(a,b,op,iop,7);
3930 /* Equality tests. */
3931 FCMP(nan, nan, ==, !=, 0);
3932 FCMP(one, two, ==, !=, 0);
3933 FCMP(one, one, !=, ==, 1);
3934 /* Non-equality is a bit special. */
3935 if (!fcompare (nan, nan, 1))
3936 bug (nan, nan, !=, ==, 6);
3938 /* Relational tests on numbers. */
3939 FCMP(two, one, <, >=, 2);
3940 FCMP(one, two, >=, <, 3);
3941 FCMP(one, two, >, <=, 4);
3942 FCMP(two, one, <=, >, 5);
3944 /* Relational tests on NaNs. Note that the inverse op here is
3945 always !=, there's no operator in C that is equivalent to !(a < b),
3946 when NaNs are involved, same for the other relational ops. */
3947 FCMP(nan, nan, <, !=, 2);
3948 FCMP(nan, nan, >=, !=, 3);
3949 FCMP(nan, nan, >, !=, 4);
3950 FCMP(nan, nan, <=, !=, 5);
3953 double get100 () { return 100.0; }
3955 void callsave_test(void)
3957 #if defined __i386__ || defined __x86_64__ || defined __arm__
3958 int i, s; double *d; double t;
3959 s = sizeof (double);
3960 printf ("callsavetest: %d\n", s);
3961 d = alloca (sizeof(double));
3962 d[0] = 10.0;
3963 /* x86-64 had a bug were the next call to get100 would evict
3964 the lvalue &d[0] as VT_LLOCAL, and the reload would be done
3965 in int type, not pointer type. When alloca returns a pointer
3966 with the high 32 bit set (which is likely on x86-64) the access
3967 generates a segfault. */
3968 i = d[0] > get100 ();
3969 printf ("%d\n", i);
3970 #endif
3974 void bfa3(ptrdiff_t str_offset)
3976 printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
3978 void bfa2(ptrdiff_t str_offset)
3980 printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
3981 bfa3(str_offset);
3983 void bfa1(ptrdiff_t str_offset)
3985 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
3986 bfa2(str_offset);
3989 void builtin_frame_address_test(void)
3991 /* builtin_frame_address fails on ARM with gcc which make test3 fail */
3992 #ifndef __arm__
3993 char str[] = "__builtin_frame_address";
3994 char *fp0 = __builtin_frame_address(0);
3996 printf("str: %s\n", str);
3997 #ifndef __riscv
3998 bfa1(str-fp0);
3999 #endif
4000 #endif
4003 char via_volatile (char i)
4005 char volatile vi;
4006 vi = i;
4007 return vi;
4010 void volatile_test(void)
4012 if (via_volatile (42) != 42)
4013 printf (" broken\n");
4014 else
4015 printf (" ok\n");
4018 struct __attribute__((__packed__)) Spacked {
4019 char a;
4020 short b;
4021 int c;
4023 struct Spacked spacked;
4024 typedef struct __attribute__((__packed__)) {
4025 char a;
4026 short b;
4027 int c;
4028 } Spacked2;
4029 Spacked2 spacked2;
4030 typedef struct Spacked3_s {
4031 char a;
4032 short b;
4033 int c;
4034 } __attribute__((__packed__)) Spacked3;
4035 Spacked3 spacked3;
4036 struct gate_struct64 {
4037 unsigned short offset_low;
4038 unsigned short segment;
4039 unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
4040 unsigned short offset_middle;
4041 unsigned offset_high;
4042 unsigned zero1;
4043 } __attribute__((packed));
4044 typedef struct gate_struct64 gate_desc;
4045 gate_desc a_gate_desc;
4046 void attrib_test(void)
4048 #ifndef _WIN32
4049 printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
4050 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
4051 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
4052 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
4053 #endif
4055 extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
4056 strange_attrib_placement (void);
4058 void * __attribute__((__unused__)) get_void_ptr (void *a)
4060 return a;
4063 /* This part checks for a bug in TOK_GET (used for inline expansion),
4064 where the large long long constant left the the high bits set for
4065 the integer constant token. */
4066 static inline
4067 int __get_order(unsigned long long size)
4069 int order;
4070 size -= 0xffff880000000000ULL; // this const left high bits set in the token
4072 struct S { int i : 1; } s; // constructed for this '1'
4074 order = size;
4075 return order;
4078 /* This just forces the above inline function to be actually emitted. */
4079 int force_get_order(unsigned long s)
4081 return __get_order(s);
4084 #define pv(m) printf(sizeof (s->m + 0) == 8 ? "%016llx\n" : "%02x\n", s->m)
4086 /* Test failed when using bounds checking */
4087 void bounds_check1_test (void)
4089 struct s {
4090 int x;
4091 long long y;
4092 } _s, *s = &_s;
4093 s->x = 10;
4094 s->y = 20;
4095 pv(x);
4096 pv(y);
4099 /* gcc 2.95.3 does not handle correctly CR in strings or after strays */
4100 #define CORRECT_CR_HANDLING
4102 /* deprecated and no longer supported in gcc 3.3 */
4103 #ifdef __TINYC__
4104 # define ACCEPT_CR_IN_STRINGS
4105 #endif
4107 /* keep this as the last test because GCC messes up line-numbers
4108 with the ^L^K^M characters below */
4109 void whitespace_test(void)
4111 char *str;
4113 \f\v #if 1
4114 pri\
4115 ntf("whitspace:\n");\f\v
4116 #endif
4117 pf("N=%d\n", 2);
4119 #ifdef CORRECT_CR_HANDLING
4120 pri\
4121 ntf("aaa=%d\n", 3);
4122 #endif
4124 pri\
4126 ntf("min=%d\n", 4);
4128 #ifdef ACCEPT_CR_IN_STRINGS
4129 printf("len1=%d\n", strlen("
4130 "));
4131 #ifdef CORRECT_CR_HANDLING
4132 str = "
4134 printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
4135 #endif
4136 printf("len1=%d\n", strlen(" a
4137 "));
4138 #else
4139 printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n");
4140 #endif /* ACCEPT_CR_IN_STRINGS */
4142 #ifdef __LINE__
4143 printf("__LINE__ defined\n");
4144 #endif
4146 #if 0
4147 /* wrong with GCC */
4148 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4149 #line 1111
4150 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4151 #line 2222 "test"
4152 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4153 #endif
4156 #define RUN(test) puts("---- " #test " ----"), test(), puts("")
4158 int main(int argc, char **argv)
4160 RUN(whitespace_test);
4161 RUN(macro_test);
4162 RUN(recursive_macro_test);
4163 RUN(string_test);
4164 RUN(expr_test);
4165 RUN(scope_test);
4166 RUN(scope2_test);
4167 RUN(forward_test);
4168 RUN(funcptr_test);
4169 RUN(if_test);
4170 RUN(loop_test);
4171 RUN(switch_test);
4172 RUN(goto_test);
4173 RUN(enum_test);
4174 RUN(typedef_test);
4175 RUN(struct_test);
4176 RUN(array_test);
4177 RUN(expr_ptr_test);
4178 RUN(bool_test);
4179 RUN(optimize_out_test);
4180 RUN(expr2_test);
4181 RUN(constant_expr_test);
4182 RUN(expr_cmp_test);
4183 RUN(char_short_test);
4184 RUN(init_test);
4185 RUN(compound_literal_test);
4186 RUN(kr_test);
4187 RUN(struct_assign_test);
4188 RUN(cast_test);
4189 RUN(bitfield_test);
4190 RUN(c99_bool_test);
4191 RUN(float_test);
4192 RUN(longlong_test);
4193 RUN(manyarg_test);
4194 RUN(stdarg_test);
4195 RUN(relocation_test);
4196 RUN(old_style_function_test);
4197 RUN(alloca_test);
4198 RUN(c99_vla_test);
4199 RUN(sizeof_test);
4200 RUN(typeof_test);
4201 RUN(statement_expr_test);
4202 RUN(local_label_test);
4203 RUN(asm_test);
4204 RUN(builtin_test);
4205 RUN(weak_test);
4206 RUN(global_data_test);
4207 RUN(cmp_comparison_test);
4208 RUN(math_cmp_test);
4209 RUN(callsave_test);
4210 RUN(builtin_frame_address_test);
4211 RUN(volatile_test);
4212 RUN(attrib_test);
4213 RUN(bounds_check1_test);
4215 return 0;