__builtin_/__bound_: A 'stay tiny' approach to the matter
[tinycc.git] / tests / tcctest.c
blob921b0ebafea79fdd07f2c72ed667384820fed475
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 if_test(void)
468 if1t(1, 0, 0, 0);
469 if1t(2, 0, 3, 0);
470 if1t(3, 2, 0, 0);
471 if1t(4, 2, 3, 0);
472 if2t();
475 void loop_test()
477 int i;
478 i = 0;
479 while (i < 10)
480 printf("%d", i++);
481 printf("\n");
482 for(i = 0; i < 10;i++)
483 printf("%d", i);
484 printf("\n");
485 i = 0;
486 do {
487 printf("%d", i++);
488 } while (i < 10);
489 printf("\n");
491 char count = 123;
492 /* c99 for loop init test */
493 for (size_t count = 1; count < 3; count++)
494 printf("count=%d\n", count);
495 printf("count = %d\n", count);
497 /* break/continue tests */
498 i = 0;
499 while (1) {
500 if (i == 6)
501 break;
502 i++;
503 if (i == 3)
504 continue;
505 printf("%d", i);
507 printf("\n");
509 /* break/continue tests */
510 i = 0;
511 do {
512 if (i == 6)
513 break;
514 i++;
515 if (i == 3)
516 continue;
517 printf("%d", i);
518 } while(1);
519 printf("\n");
521 for(i = 0;i < 10;i++) {
522 if (i == 3)
523 continue;
524 printf("%d", i);
526 printf("\n");
529 typedef int typedef_and_label;
531 void goto_test()
533 int i;
534 static void *label_table[3] = { &&label1, &&label2, &&label3 };
536 printf("\ngoto:\n");
537 i = 0;
538 /* This needs to parse as label, not as start of decl. */
539 typedef_and_label x;
540 typedef_and_label:
541 s_loop:
542 if (i >= 10)
543 goto s_end;
544 printf("%d", i);
545 i++;
546 goto s_loop;
547 s_end:
548 printf("\n");
550 /* we also test computed gotos (GCC extension) */
551 for(i=0;i<3;i++) {
552 goto *label_table[i];
553 label1:
554 printf("label1\n");
555 goto next;
556 label2:
557 printf("label2\n");
558 goto next;
559 label3:
560 printf("label3\n");
561 next: ;
565 enum {
567 E1 = 2,
568 E2 = 4,
573 enum test {
574 E5 = 1000,
577 struct S_enum {
578 enum {E6 = 42, E7, E8} e:8;
581 enum ELong {
582 /* This is either 0 on L32 machines, or a large number
583 on L64 machines. We should be able to store this. */
584 EL_large = ((unsigned long)0xf000 << 31) << 1,
587 enum { BIASU = -1U<<31 };
588 enum { BIASS = -1 << 31 };
590 static int getint(int i)
592 if (i)
593 return 0;
594 else
595 return (int)(-1U << 31);
598 void enum_test()
600 enum test b1;
601 /* The following should give no warning */
602 unsigned *p = &b1;
603 struct S_enum s = {E7};
604 printf("%d %d %d %d %d %d %d\n", s.e,
605 E0, E1, E2, E3, E4, E5);
606 b1 = 1;
607 printf("b1=%d\n", b1);
608 printf("enum large: %ld\n", EL_large);
610 if (getint(0) == BIASU)
611 printf("enum unsigned: ok\n");
612 else
613 printf("enum unsigned: wrong\n");
614 if (getint(0) == BIASS)
615 printf("enum unsigned: ok\n");
616 else
617 printf("enum unsigned: wrong\n");
620 typedef int *my_ptr;
622 typedef int mytype1;
623 typedef int mytype2;
625 void typedef_test()
627 my_ptr a;
628 mytype1 mytype2;
629 int b;
631 a = &b;
632 *a = 1234;
633 printf("a=%d\n", *a);
634 mytype2 = 2;
635 printf("mytype2=%d\n", mytype2);
638 void forward_test()
640 forward_ref();
641 forward_ref();
645 void forward_ref(void)
647 printf("forward ok\n");
650 typedef struct struct1 {
651 int f1;
652 int f2, f3;
653 union union1 {
654 int v1;
655 int v2;
656 } u;
657 char str[3];
658 } struct1;
660 struct struct2 {
661 int a;
662 char b;
665 union union2 {
666 int w1;
667 int w2;
670 struct struct1 st1, st2;
672 struct empty_mem {
673 /* nothing */ ;
674 int x;
677 int tab[3];
678 int tab2[3][2];
680 int g;
682 void f1(g)
684 printf("g1=%d\n", g);
687 void scope_test()
689 g = 2;
690 f1(1);
691 printf("g2=%d\n", g);
693 int g;
694 g = 3;
695 printf("g3=%d\n", g);
697 int g;
698 g = 4;
699 printf("g4=%d\n", g);
702 printf("g5=%d\n", g);
705 int st2_i;
706 int *st2_p = &st2_i;
707 void scope2_test()
709 char a[50];
710 st2_i = 42;
711 for (int st2_i = 1; st2_i < 10; st2_i++) {
712 extern int st2_i;
713 st2_i++;
714 printf("exloc: %d\n", st2_i);
716 printf("exloc: %d\n", *st2_p);
719 /* C has tentative definition, and they may be repeated. */
720 extern int st_global1;
721 int st_global1=42;
722 extern int st_global1;
723 int st_global1;
724 extern int st_global2;
725 int st_global2;
726 extern int st_global2;
727 int st_global2;
729 void array_test()
731 int i, j, a[4];
733 printf("sizeof(a) = %d\n", sizeof(a));
734 printf("sizeof(\"a\") = %d\n", sizeof("a"));
735 #ifdef C99_MACROS
736 printf("sizeof(__func__) = %d\n", sizeof(__func__));
737 #endif
738 printf("sizeof tab %d\n", sizeof(tab));
739 printf("sizeof tab2 %d\n", sizeof tab2);
740 tab[0] = 1;
741 tab[1] = 2;
742 tab[2] = 3;
743 printf("%d %d %d\n", tab[0], tab[1], tab[2]);
744 for(i=0;i<3;i++)
745 for(j=0;j<2;j++)
746 tab2[i][j] = 10 * i + j;
747 for(i=0;i<3*2;i++) {
748 printf(" %3d", ((int *)tab2)[i]);
750 printf("\n");
751 printf("sizeof(size_t)=%d\n", sizeof(size_t));
752 printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
755 void expr_test()
757 int a, b;
758 a = 0;
759 printf("%d\n", a += 1);
760 printf("%d\n", a -= 2);
761 printf("%d\n", a *= 31232132);
762 printf("%d\n", a /= 4);
763 printf("%d\n", a %= 20);
764 printf("%d\n", a &= 6);
765 printf("%d\n", a ^= 7);
766 printf("%d\n", a |= 8);
767 printf("%d\n", a >>= 3);
768 printf("%d\n", a <<= 4);
770 a = 22321;
771 b = -22321;
772 printf("%d\n", a + 1);
773 printf("%d\n", a - 2);
774 printf("%d\n", a * 312);
775 printf("%d\n", a / 4);
776 printf("%d\n", b / 4);
777 printf("%d\n", (unsigned)b / 4);
778 printf("%d\n", a % 20);
779 printf("%d\n", b % 20);
780 printf("%d\n", (unsigned)b % 20);
781 printf("%d\n", a & 6);
782 printf("%d\n", a ^ 7);
783 printf("%d\n", a | 8);
784 printf("%d\n", a >> 3);
785 printf("%d\n", b >> 3);
786 printf("%d\n", (unsigned)b >> 3);
787 printf("%d\n", a << 4);
788 printf("%d\n", ~a);
789 printf("%d\n", -a);
790 printf("%d\n", +a);
792 printf("%d\n", 12 + 1);
793 printf("%d\n", 12 - 2);
794 printf("%d\n", 12 * 312);
795 printf("%d\n", 12 / 4);
796 printf("%d\n", 12 % 20);
797 printf("%d\n", 12 & 6);
798 printf("%d\n", 12 ^ 7);
799 printf("%d\n", 12 | 8);
800 printf("%d\n", 12 >> 2);
801 printf("%d\n", 12 << 4);
802 printf("%d\n", ~12);
803 printf("%d\n", -12);
804 printf("%d\n", +12);
805 printf("%d %d %d %d\n",
806 isid('a'),
807 isid('g'),
808 isid('T'),
809 isid('('));
812 int isid(int c)
814 return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
817 /**********************/
819 int vstack[10], *vstack_ptr;
821 void vpush(int vt, int vc)
823 *vstack_ptr++ = vt;
824 *vstack_ptr++ = vc;
827 void vpop(int *ft, int *fc)
829 *fc = *--vstack_ptr;
830 *ft = *--vstack_ptr;
833 void expr2_test()
835 int a, b;
837 vstack_ptr = vstack;
838 vpush(1432432, 2);
839 vstack_ptr[-2] &= ~0xffffff80;
840 vpop(&a, &b);
841 printf("res= %d %d\n", a, b);
844 int const_len_ar[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */
846 void constant_expr_test()
848 int a;
849 a = 3;
850 printf("%d\n", a * 16);
851 printf("%d\n", a * 1);
852 printf("%d\n", a + 0);
853 printf("%d\n", sizeof(const_len_ar));
856 int tab4[10];
858 void expr_ptr_test()
860 int *p, *q;
861 int i = -1;
863 p = tab4;
864 q = tab4 + 10;
865 printf("diff=%d\n", q - p);
866 p++;
867 printf("inc=%d\n", p - tab4);
868 p--;
869 printf("dec=%d\n", p - tab4);
870 ++p;
871 printf("inc=%d\n", p - tab4);
872 --p;
873 printf("dec=%d\n", p - tab4);
874 printf("add=%d\n", p + 3 - tab4);
875 printf("add=%d\n", 3 + p - tab4);
877 /* check if 64bit support is ok */
878 q = p = 0;
879 q += i;
880 printf("%p %p %ld\n", q, p, p-q);
881 printf("%d %d %d %d %d %d\n",
882 p == q, p != q, p < q, p <= q, p >= q, p > q);
883 i = 0xf0000000;
884 p += i;
885 printf("%p %p %ld\n", q, p, p-q);
886 printf("%d %d %d %d %d %d\n",
887 p == q, p != q, p < q, p <= q, p >= q, p > q);
888 p = (int *)((char *)p + 0xf0000000);
889 printf("%p %p %ld\n", q, p, p-q);
890 printf("%d %d %d %d %d %d\n",
891 p == q, p != q, p < q, p <= q, p >= q, p > q);
892 p += 0xf0000000;
893 printf("%p %p %ld\n", q, p, p-q);
894 printf("%d %d %d %d %d %d\n",
895 p == q, p != q, p < q, p <= q, p >= q, p > q);
897 struct size12 {
898 int i, j, k;
900 struct size12 s[2], *sp = s;
901 int i, j;
902 sp->i = 42;
903 sp++;
904 j = -1;
905 printf("%d\n", sp[j].i);
907 #ifdef __LP64__
908 i = 1;
909 p = (int*)0x100000000UL + i;
910 i = ((long)p) >> 32;
911 printf("largeptr: %p %d\n", p, i);
912 #endif
915 void expr_cmp_test()
917 int a, b;
918 a = -1;
919 b = 1;
920 printf("%d\n", a == a);
921 printf("%d\n", a != a);
923 printf("%d\n", a < b);
924 printf("%d\n", a <= b);
925 printf("%d\n", a <= a);
926 printf("%d\n", b >= a);
927 printf("%d\n", a >= a);
928 printf("%d\n", b > a);
930 printf("%d\n", (unsigned)a < b);
931 printf("%d\n", (unsigned)a <= b);
932 printf("%d\n", (unsigned)a <= a);
933 printf("%d\n", (unsigned)b >= a);
934 printf("%d\n", (unsigned)a >= a);
935 printf("%d\n", (unsigned)b > a);
938 struct empty {
941 struct aligntest1 {
942 char a[10];
945 struct aligntest2 {
946 int a;
947 char b[10];
950 struct aligntest3 {
951 double a, b;
954 struct aligntest4 {
955 double a[0];
958 struct __attribute__((aligned(16))) aligntest5
960 int i;
962 struct aligntest6
964 int i;
965 } __attribute__((aligned(16)));
966 struct aligntest7
968 int i;
970 struct aligntest5 altest5[2];
971 struct aligntest6 altest6[2];
972 int pad1;
973 /* altest7 is correctly aligned to 16 bytes also with TCC,
974 but __alignof__ returns the wrong result (4) because we
975 can't store the alignment yet when specified on symbols
976 directly (it's stored in the type so we'd need to make
977 a copy of it). -- FIXED */
978 struct aligntest7 altest7[2] __attribute__((aligned(16)));
980 struct aligntest8
982 int i;
983 } __attribute__((aligned(4096)));
985 struct Large {
986 unsigned long flags;
987 union {
988 void *u1;
989 int *u2;
992 struct {
993 union {
994 unsigned long index;
995 void *freelist;
997 union {
998 unsigned long counters;
999 struct {
1000 int bla;
1005 union {
1006 struct {
1007 long u3;
1008 long u4;
1010 void *u5;
1011 struct {
1012 unsigned long compound_head;
1013 unsigned int compound_dtor;
1014 unsigned int compound_order;
1017 } __attribute__((aligned(2 * sizeof(long))));
1019 typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
1021 struct aligntest9 {
1022 unsigned int buf_nr;
1023 unaligned_u64 start_lba;
1026 struct aligntest10 {
1027 unsigned int buf_nr;
1028 unsigned long long start_lba;
1031 void struct_test()
1033 struct1 *s;
1034 union union2 u;
1035 struct Large ls;
1037 printf("sizes: %d %d %d %d\n",
1038 sizeof(struct struct1),
1039 sizeof(struct struct2),
1040 sizeof(union union1),
1041 sizeof(union union2));
1042 printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
1043 st1.f1 = 1;
1044 st1.f2 = 2;
1045 st1.f3 = 3;
1046 printf("st1: %d %d %d\n",
1047 st1.f1, st1.f2, st1.f3);
1048 st1.u.v1 = 1;
1049 st1.u.v2 = 2;
1050 printf("union1: %d\n", st1.u.v1);
1051 u.w1 = 1;
1052 u.w2 = 2;
1053 printf("union2: %d\n", u.w1);
1054 s = &st2;
1055 s->f1 = 3;
1056 s->f2 = 2;
1057 s->f3 = 1;
1058 printf("st2: %d %d %d\n",
1059 s->f1, s->f2, s->f3);
1060 printf("str_addr=%x\n", (int)(uintptr_t)st1.str - (int)(uintptr_t)&st1.f1);
1062 /* align / size tests */
1063 printf("aligntest1 sizeof=%d alignof=%d\n",
1064 sizeof(struct aligntest1), __alignof__(struct aligntest1));
1065 printf("aligntest2 sizeof=%d alignof=%d\n",
1066 sizeof(struct aligntest2), __alignof__(struct aligntest2));
1067 printf("aligntest3 sizeof=%d alignof=%d\n",
1068 sizeof(struct aligntest3), __alignof__(struct aligntest3));
1069 printf("aligntest4 sizeof=%d alignof=%d\n",
1070 sizeof(struct aligntest4), __alignof__(struct aligntest4));
1071 printf("aligntest5 sizeof=%d alignof=%d\n",
1072 sizeof(struct aligntest5), __alignof__(struct aligntest5));
1073 printf("aligntest6 sizeof=%d alignof=%d\n",
1074 sizeof(struct aligntest6), __alignof__(struct aligntest6));
1075 printf("aligntest7 sizeof=%d alignof=%d\n",
1076 sizeof(struct aligntest7), __alignof__(struct aligntest7));
1077 printf("aligntest8 sizeof=%d alignof=%d\n",
1078 sizeof(struct aligntest8), __alignof__(struct aligntest8));
1079 printf("aligntest9 sizeof=%d alignof=%d\n",
1080 sizeof(struct aligntest9), __alignof__(struct aligntest9));
1081 printf("aligntest10 sizeof=%d alignof=%d\n",
1082 sizeof(struct aligntest10), __alignof__(struct aligntest10));
1083 printf("altest5 sizeof=%d alignof=%d\n",
1084 sizeof(altest5), __alignof__(altest5));
1085 printf("altest6 sizeof=%d alignof=%d\n",
1086 sizeof(altest6), __alignof__(altest6));
1087 printf("altest7 sizeof=%d alignof=%d\n",
1088 sizeof(altest7), __alignof__(altest7));
1090 /* empty structures (GCC extension) */
1091 printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
1092 printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
1094 printf("Large: sizeof=%d\n", sizeof(ls));
1095 memset(&ls, 0, sizeof(ls));
1096 ls.compound_head = 42;
1097 printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
1100 /* simulate char/short return value with undefined upper bits */
1101 static int __csf(int x) { return x; }
1102 static void *_csf = __csf;
1103 #define csf(t,n) ((t(*)(int))_csf)(n)
1105 /* XXX: depend on endianness */
1106 void char_short_test()
1108 int var1, var2;
1109 signed char var3;
1110 long long var4;
1112 var1 = 0x01020304;
1113 var2 = 0xfffefdfc;
1114 printf("s8=%d %d\n",
1115 *(signed char *)&var1, *(signed char *)&var2);
1116 printf("u8=%d %d\n",
1117 *(unsigned char *)&var1, *(unsigned char *)&var2);
1118 printf("s16=%d %d\n",
1119 *(short *)&var1, *(short *)&var2);
1120 printf("u16=%d %d\n",
1121 *(unsigned short *)&var1, *(unsigned short *)&var2);
1122 printf("s32=%d %d\n",
1123 *(int *)&var1, *(int *)&var2);
1124 printf("u32=%d %d\n",
1125 *(unsigned int *)&var1, *(unsigned int *)&var2);
1126 *(signed char *)&var1 = 0x08;
1127 printf("var1=%x\n", var1);
1128 *(short *)&var1 = 0x0809;
1129 printf("var1=%x\n", var1);
1130 *(int *)&var1 = 0x08090a0b;
1131 printf("var1=%x\n", var1);
1133 var1 = 0x778899aa;
1134 var4 = 0x11223344aa998877ULL;
1135 var1 = var3 = var1 + 1;
1136 var4 = var3 = var4 + 1;
1137 printf("promote char/short assign %d "LONG_LONG_FORMAT"\n", var1, var4);
1138 var1 = 0x778899aa;
1139 var4 = 0x11223344aa998877ULL;
1140 printf("promote char/short assign VA %d %d\n", var3 = var1 + 1, var3 = var4 + 1);
1141 printf("promote char/short cast VA %d %d\n", (signed char)(var1 + 1), (signed char)(var4 + 1));
1142 #if !defined(__arm__)
1143 /* We can't really express GCC behaviour of return type promotion in
1144 the presence of undefined behaviour (like __csf is). */
1145 var1 = csf(unsigned char,0x89898989);
1146 var4 = csf(signed char,0xabababab);
1147 printf("promote char/short funcret %d "LONG_LONG_FORMAT"\n", var1, var4);
1148 printf("promote char/short fumcret VA %d %d %d %d\n",
1149 csf(unsigned short,0xcdcdcdcd),
1150 csf(short,0xefefefef),
1151 csf(_Bool,0x33221100),
1152 csf(_Bool,0x33221101));
1153 #endif
1154 var3 = -10;
1155 var1 = (signed char)(unsigned char)(var3 + 1);
1156 var4 = (signed char)(unsigned char)(var3 + 1);
1157 printf("promote multicast (char)(unsigned char) %d "LONG_LONG_FORMAT"\n", var1, var4);
1158 var4 = 0x11223344aa998877ULL;
1159 var4 = (unsigned)(int)(var4 + 1);
1160 printf("promote multicast (unsigned)(int) "LONG_LONG_FORMAT"\n", var4);
1161 var4 = 0x11223344bbaa9988ULL;
1162 var4 = (unsigned)(signed char)(var4 + 1);
1163 printf("promote multicast (unsigned)(char) "LONG_LONG_FORMAT"\n", var4);
1166 /******************/
1168 typedef struct Sym {
1169 int v;
1170 int t;
1171 int c;
1172 struct Sym *next;
1173 struct Sym *prev;
1174 } Sym;
1176 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
1177 #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
1179 static int toupper1(int a)
1181 return TOUPPER(a);
1184 static unsigned int calc_vm_flags(unsigned int prot)
1186 unsigned int prot_bits;
1187 /* This used to segfault in some revisions: */
1188 prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
1189 return prot_bits;
1192 void bool_test()
1194 int *s, a, b, t, f, i;
1196 a = 0;
1197 s = (void*)0;
1198 printf("!s=%d\n", !s);
1200 if (!s || !s[0])
1201 a = 1;
1202 printf("a=%d\n", a);
1204 printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
1205 printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
1206 printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
1207 #if 1 && 1
1208 printf("a1\n");
1209 #endif
1210 #if 1 || 0
1211 printf("a2\n");
1212 #endif
1213 #if 1 ? 0 : 1
1214 printf("a3\n");
1215 #endif
1216 #if 0 ? 0 : 1
1217 printf("a4\n");
1218 #endif
1220 a = 4;
1221 printf("b=%d\n", a + (0 ? 1 : a / 2));
1223 /* test register spilling */
1224 a = 10;
1225 b = 10;
1226 a = (a + b) * ((a < b) ?
1227 ((b - a) * (a - b)): a + b);
1228 printf("a=%d\n", a);
1230 /* test complex || or && expressions */
1231 t = 1;
1232 f = 0;
1233 a = 32;
1234 printf("exp=%d\n", f == (32 <= a && a <= 3));
1235 printf("r=%d\n", (t || f) + (t && f));
1237 /* test ? : cast */
1239 int aspect_on;
1240 int aspect_native = 65536;
1241 double bfu_aspect = 1.0;
1242 int aspect;
1243 for(aspect_on = 0; aspect_on < 2; aspect_on++) {
1244 aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
1245 printf("aspect=%d\n", aspect);
1249 /* test ? : GCC extension */
1251 static int v1 = 34 ? : -1; /* constant case */
1252 static int v2 = 0 ? : -1; /* constant case */
1253 int a = 30;
1255 printf("%d %d\n", v1, v2);
1256 printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
1259 /* again complex expression */
1260 for(i=0;i<256;i++) {
1261 if (toupper1 (i) != TOUPPER (i))
1262 printf("error %d\n", i);
1264 printf ("bits = 0x%x\n", calc_vm_flags (0x1));
1267 extern int undefined_function(void);
1268 extern int defined_function(void);
1270 #ifdef __clang__
1271 int undefined_function(void) {}
1272 #endif
1274 static inline void refer_to_undefined(void)
1276 undefined_function();
1279 void optimize_out_test(void)
1281 int i = 0 ? undefined_function() : defined_function();
1282 printf ("oo:%d\n", i);
1283 int j = 1 ? defined_function() : undefined_function();
1284 printf ("oo:%d\n", j);
1285 if (0)
1286 printf("oo:%d\n", undefined_function());
1287 else
1288 printf("oo:%d\n", defined_function());
1289 if (1)
1290 printf("oo:%d\n", defined_function());
1291 else
1292 printf("oo:%d\n", undefined_function());
1293 while (1) {
1294 printf("oow:%d\n", defined_function());
1295 break;
1296 printf("oow:%d\n", undefined_function());
1298 j = 1;
1299 /* Following is a switch without {} block intentionally. */
1300 switch (j)
1301 case 1: break;
1302 printf ("oos:%d\n", defined_function());
1303 /* The following break shouldn't lead to disabled code after
1304 the while. */
1305 while (1)
1306 break;
1307 printf ("ool1:%d\n", defined_function());
1308 /* Same for the other types of loops. */
1310 break;
1311 while (1);
1312 printf ("ool2:%d\n", defined_function());
1313 for (;;)
1314 break;
1315 printf ("ool3:%d\n", defined_function());
1316 /* Normal {} blocks without controlling statements
1317 shouldn't reactivate code emission */
1318 while (1) {
1320 break;
1322 printf ("ool4:%d\n", undefined_function());
1324 j = 1;
1325 while (j) {
1326 if (j == 0)
1327 break; /* this break shouldn't disable code outside the if. */
1328 printf("ool5:%d\n", defined_function());
1329 j--;
1332 j = 1;
1333 while (j) {
1334 if (1)
1335 j--;
1336 else
1337 breakhere: break;
1338 printf("ool6:%d\n", defined_function());
1339 goto breakhere;
1341 j = 1;
1342 while (j) {
1343 j--;
1344 continue;
1345 printf("ool7:%d\n", undefined_function());
1348 /* Test that constants in logical && are optimized: */
1349 i = 0 && undefined_function();
1350 i = defined_function() && 0 && undefined_function();
1351 if (0 && undefined_function())
1352 undefined_function();
1353 if (defined_function() && 0)
1354 undefined_function();
1355 if (0 && 0)
1356 undefined_function();
1357 if (defined_function() && 0 && undefined_function())
1358 undefined_function();
1359 /* The same for || : */
1360 i = 1 || undefined_function();
1361 i = defined_function() || 1 || undefined_function();
1362 if (1 || undefined_function())
1364 else
1365 undefined_function();
1366 if (defined_function() || 1)
1368 else
1369 undefined_function();
1370 if (1 || 1)
1372 else
1373 undefined_function();
1374 if (defined_function() || 1 || undefined_function())
1376 else
1377 undefined_function();
1379 if (defined_function() && 0)
1380 refer_to_undefined();
1382 if (0) {
1383 (void)sizeof( ({
1384 do { } while (0);
1386 }) );
1387 undefined_function();
1390 /* Leave the "if(1)return; printf()" in this order and last in the function */
1391 if (1)
1392 return;
1393 printf ("oor:%d\n", undefined_function());
1396 int defined_function(void)
1398 static int i = 40;
1399 return i++;
1402 /* GCC accepts that */
1403 static int tab_reinit[];
1404 static int tab_reinit[10];
1406 static int tentative_ar[];
1407 static int tentative_ar[] = {1,2,3};
1409 //int cinit1; /* a global variable can be defined several times without error ! */
1410 int cinit1;
1411 int cinit1;
1412 int cinit1 = 0;
1413 int *cinit2 = (int []){3, 2, 1};
1415 void compound_literal_test(void)
1417 int *p, i;
1418 char *q, *q3;
1420 p = (int []){1, 2, 3};
1421 for(i=0;i<3;i++)
1422 printf(" %d", p[i]);
1423 printf("\n");
1425 for(i=0;i<3;i++)
1426 printf("%d", cinit2[i]);
1427 printf("\n");
1429 q = "tralala1";
1430 printf("q1=%s\n", q);
1432 q = (char *){ "tralala2" };
1433 printf("q2=%s\n", q);
1435 q3 = (char *){ q };
1436 printf("q3=%s\n", q3);
1438 q = (char []){ "tralala3" };
1439 printf("q4=%s\n", q);
1441 #ifdef ALL_ISOC99
1442 p = (int []){1, 2, cinit1 + 3};
1443 for(i=0;i<3;i++)
1444 printf(" %d", p[i]);
1445 printf("\n");
1447 for(i=0;i<3;i++) {
1448 p = (int []){1, 2, 4 + i};
1449 printf("%d %d %d\n",
1450 p[0],
1451 p[1],
1452 p[2]);
1454 #endif
1457 /* K & R protos */
1459 kr_func1(a, b)
1461 return a + b;
1464 int kr_func2(a, b)
1466 return a + b;
1469 kr_test()
1471 printf("func1=%d\n", kr_func1(3, 4));
1472 printf("func2=%d\n", kr_func2(3, 4));
1473 return 0;
1476 void num(int n)
1478 char *tab, *p;
1479 tab = (char*)malloc(20);
1480 p = tab;
1481 while (1) {
1482 *p = 48 + (n % 10);
1483 p++;
1484 n = n / 10;
1485 if (n == 0)
1486 break;
1488 while (p != tab) {
1489 p--;
1490 printf("%c", *p);
1492 printf("\n");
1493 free(tab);
1496 /* structure assignment tests */
1497 struct structa1 {
1498 int f1;
1499 char f2;
1502 struct structa1 ssta1;
1504 void struct_assign_test1(struct structa1 s1, int t, float f)
1506 printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
1509 struct structa1 struct_assign_test2(struct structa1 s1, int t)
1511 s1.f1 += t;
1512 s1.f2 -= t;
1513 return s1;
1516 void struct_assign_test(void)
1518 struct S {
1519 struct structa1 lsta1, lsta2;
1520 int i;
1521 } s, *ps;
1523 ps = &s;
1524 ps->i = 4;
1525 #if 0
1526 s.lsta1.f1 = 1;
1527 s.lsta1.f2 = 2;
1528 printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
1529 s.lsta2 = s.lsta1;
1530 printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
1531 #else
1532 s.lsta2.f1 = 1;
1533 s.lsta2.f2 = 2;
1534 #endif
1535 struct_assign_test1(ps->lsta2, 3, 4.5);
1537 printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
1538 ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
1539 printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
1541 static struct {
1542 void (*elem)();
1543 } t[] = {
1544 /* XXX: we should allow this even without braces */
1545 { struct_assign_test }
1547 printf("%d\n", struct_assign_test == t[0].elem);
1550 /* casts to short/char */
1552 void cast1(char a, short b, unsigned char c, unsigned short d)
1554 printf("%d %d %d %d\n", a, b, c, d);
1557 char bcast;
1558 short scast;
1560 void cast_test()
1562 int a;
1563 char c;
1564 char tab[10];
1565 unsigned b,d;
1566 short s;
1567 char *p = NULL;
1568 unsigned long ul = 0x80000000UL;
1569 p -= 0x700000000042;
1571 a = 0xfffff;
1572 cast1(a, a, a, a);
1573 a = 0xffffe;
1574 printf("%d %d %d %d\n",
1575 (char)(a + 1),
1576 (short)(a + 1),
1577 (unsigned char)(a + 1),
1578 (unsigned short)(a + 1));
1579 printf("%d %d %d %d\n",
1580 (char)0xfffff,
1581 (short)0xfffff,
1582 (unsigned char)0xfffff,
1583 (unsigned short)0xfffff);
1585 a = (bcast = 128) + 1;
1586 printf("%d\n", a);
1587 a = (scast = 65536) + 1;
1588 printf("%d\n", a);
1590 printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
1592 /* test cast from unsigned to signed short to int */
1593 b = 0xf000;
1594 d = (short)b;
1595 printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
1596 b = 0xf0f0;
1597 d = (char)b;
1598 printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
1600 /* test implicit int casting for array accesses */
1601 c = 0;
1602 tab[1] = 2;
1603 tab[c] = 1;
1604 printf("%d %d\n", tab[0], tab[1]);
1606 /* test implicit casting on some operators */
1607 printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
1608 printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
1609 printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
1611 #if CC_NAME != CC_clang /* clang doesn't support non-portable conversions */
1612 /* from pointer to integer types */
1613 printf("%d %d %ld %ld %lld %lld\n",
1614 (int)p, (unsigned int)p,
1615 (long)p, (unsigned long)p,
1616 (long long)p, (unsigned long long)p);
1617 #endif
1619 /* from integers to pointers */
1620 printf("%p %p %p %p\n",
1621 (void *)a, (void *)b, (void *)c, (void *)d);
1623 /* int to int with sign set */
1624 printf("0x%lx\n", (unsigned long)(int)ul);
1627 /* initializers tests */
1628 struct structinit1 {
1629 int f1;
1630 char f2;
1631 short f3;
1632 int farray[3];
1635 int sinit1 = 2;
1636 int sinit2 = { 3 };
1637 int sinit3[3] = { 1, 2, {{3}}, };
1638 int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1639 int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
1640 int sinit6[] = { 1, 2, 3 };
1641 int sinit7[] = { [2] = 3, [0] = 1, 2 };
1642 char sinit8[] = "hello" "trala";
1644 struct structinit1 sinit9 = { 1, 2, 3 };
1645 struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
1646 struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
1647 #ifdef ALL_ISOC99
1648 .farray[0] = 10,
1649 .farray[1] = 11,
1650 .farray[2] = 12,
1651 #endif
1654 char *sinit12 = "hello world";
1655 char *sinit13[] = {
1656 "test1",
1657 "test2",
1658 "test3",
1660 char sinit14[10] = { "abc" };
1661 int sinit15[3] = { sizeof(sinit15), 1, 2 };
1663 struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
1665 struct bar {
1666 char *s;
1667 int len;
1668 } sinit17[] = {
1669 "a1", 4,
1670 "a2", 1
1673 int sinit18[10] = {
1674 [2 ... 5] = 20,
1676 [8] = 10,
1679 struct complexinit0 {
1680 int a;
1681 int b;
1684 struct complexinit {
1685 int a;
1686 const struct complexinit0 *b;
1689 const static struct complexinit cix[] = {
1690 [0] = {
1691 .a = 2000,
1692 .b = (const struct complexinit0[]) {
1693 { 2001, 2002 },
1694 { 2003, 2003 },
1700 struct complexinit2 {
1701 int a;
1702 int b[];
1705 struct complexinit2 cix20;
1707 struct complexinit2 cix21 = {
1708 .a = 3000,
1709 .b = { 3001, 3002, 3003 }
1712 struct complexinit2 cix22 = {
1713 .a = 4000,
1714 .b = { 4001, 4002, 4003, 4004, 4005, 4006 }
1717 typedef int arrtype1[];
1718 arrtype1 sinit19 = {1};
1719 arrtype1 sinit20 = {2,3};
1720 typedef int arrtype2[3];
1721 arrtype2 sinit21 = {4};
1722 arrtype2 sinit22 = {5,6,7};
1724 /* Address comparisons of non-weak symbols with zero can be const-folded */
1725 int sinit23[2] = { "astring" ? sizeof("astring") : -1,
1726 &sinit23 ? 42 : -1 };
1728 int sinit24 = 2 || 1 / 0; /* exception in constant but unevaluated context */
1730 extern int external_inited = 42;
1732 void init_test(void)
1734 int linit1 = 2;
1735 int linit2 = { 3 };
1736 int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1737 int linit6[] = { 1, 2, 3 };
1738 int i, j;
1739 char linit8[] = "hello" "trala";
1740 int linit12[10] = { 1, 2 };
1741 int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
1742 char linit14[10] = "abc";
1743 int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
1744 struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
1745 int linit17 = sizeof(linit17);
1746 int zero = 0;
1747 /* Addresses on non-weak symbols are non-zero, but not the access itself */
1748 int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
1750 printf("sinit1=%d\n", sinit1);
1751 printf("sinit2=%d\n", sinit2);
1752 printf("sinit3=%d %d %d %d\n",
1753 sizeof(sinit3),
1754 sinit3[0],
1755 sinit3[1],
1756 sinit3[2]
1758 printf("sinit6=%d\n", sizeof(sinit6));
1759 printf("sinit7=%d %d %d %d\n",
1760 sizeof(sinit7),
1761 sinit7[0],
1762 sinit7[1],
1763 sinit7[2]
1765 printf("sinit8=%s\n", sinit8);
1766 printf("sinit9=%d %d %d\n",
1767 sinit9.f1,
1768 sinit9.f2,
1769 sinit9.f3
1771 printf("sinit10=%d %d %d\n",
1772 sinit10.f1,
1773 sinit10.f2,
1774 sinit10.f3
1776 printf("sinit11=%d %d %d %d %d %d\n",
1777 sinit11.f1,
1778 sinit11.f2,
1779 sinit11.f3,
1780 sinit11.farray[0],
1781 sinit11.farray[1],
1782 sinit11.farray[2]
1785 for(i=0;i<3;i++)
1786 for(j=0;j<2;j++)
1787 printf("[%d][%d] = %d %d %d\n",
1788 i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
1789 printf("linit1=%d\n", linit1);
1790 printf("linit2=%d\n", linit2);
1791 printf("linit6=%d\n", sizeof(linit6));
1792 printf("linit8=%d %s\n", sizeof(linit8), linit8);
1794 printf("sinit12=%s\n", sinit12);
1795 printf("sinit13=%d %s %s %s\n",
1796 sizeof(sinit13),
1797 sinit13[0],
1798 sinit13[1],
1799 sinit13[2]);
1800 printf("sinit14=%s\n", sinit14);
1802 for(i=0;i<10;i++) printf(" %d", linit12[i]);
1803 printf("\n");
1804 for(i=0;i<10;i++) printf(" %d", linit13[i]);
1805 printf("\n");
1806 for(i=0;i<10;i++) printf(" %d", linit14[i]);
1807 printf("\n");
1808 for(i=0;i<10;i++) printf(" %d", linit15[i]);
1809 printf("\n");
1810 printf("%d %d %d %d\n",
1811 linit16.a1,
1812 linit16.a2,
1813 linit16.a3,
1814 linit16.a4);
1815 /* test that initialisation is done after variable declare */
1816 printf("linit17=%d\n", linit17);
1817 printf("sinit15=%d\n", sinit15[0]);
1818 printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
1819 printf("sinit17=%s %d %s %d\n",
1820 sinit17[0].s, sinit17[0].len,
1821 sinit17[1].s, sinit17[1].len);
1822 for(i=0;i<10;i++)
1823 printf("%x ", sinit18[i]);
1824 printf("\n");
1825 /* complex init check */
1826 printf("cix: %d %d %d %d %d %d %d\n",
1827 cix[0].a,
1828 cix[0].b[0].a, cix[0].b[0].b,
1829 cix[0].b[1].a, cix[0].b[1].b,
1830 cix[0].b[2].a, cix[0].b[2].b);
1831 printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
1832 printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
1834 printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
1835 printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
1836 printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
1837 printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
1838 printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
1839 printf("arrtype6: %d\n", sizeof(arrtype2));
1841 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
1842 printf("sinit24=%d\n", sinit24);
1843 printf("linit18= %d %d\n", linit18[0], linit18[1]);
1846 void switch_uc(unsigned char uc)
1848 switch (uc) {
1849 case 0xfb ... 0xfe:
1850 printf("ucsw:1\n");
1851 break;
1852 case 0xff:
1853 printf("ucsw:2\n");
1854 break;
1855 case 0 ... 5:
1856 printf("ucsw:3\n");
1857 break;
1858 default:
1859 printf("ucsw: broken!\n");
1863 void switch_sc(signed char sc)
1865 switch (sc) {
1866 case -5 ... -2:
1867 printf("scsw:1\n");
1868 break;
1869 case -1:
1870 printf("scsw:2\n");
1871 break;
1872 case 0 ... 5:
1873 printf("scsw:3\n");
1874 break;
1875 default:
1876 printf("scsw: broken!\n");
1880 void switch_test()
1882 int i;
1883 unsigned long long ull;
1884 long long ll;
1886 for(i=0;i<15;i++) {
1887 switch(i) {
1888 case 0:
1889 case 1:
1890 printf("a");
1891 break;
1892 default:
1893 printf("%d", i);
1894 break;
1895 case 8 ... 12:
1896 printf("c");
1897 break;
1898 case 3:
1899 printf("b");
1900 break;
1901 case 0xc33c6b9fU:
1902 case 0x7c9eeeb9U:
1903 break;
1906 printf("\n");
1908 for (i = 1; i <= 5; i++) {
1909 ull = (unsigned long long)i << 61;
1910 switch (ull) {
1911 case 1ULL << 61:
1912 printf("ullsw:1\n");
1913 break;
1914 case 2ULL << 61:
1915 printf("ullsw:2\n");
1916 break;
1917 case 3ULL << 61:
1918 printf("ullsw:3\n");
1919 break;
1920 case 4ULL << 61:
1921 printf("ullsw:4\n");
1922 break;
1923 case 5ULL << 61:
1924 printf("ullsw:5\n");
1925 break;
1926 default:
1927 printf("ullsw: broken!\n");
1931 for (i = 1; i <= 5; i++) {
1932 ll = (long long)i << 61;
1933 switch (ll) {
1934 case 1LL << 61:
1935 printf("llsw:1\n");
1936 break;
1937 case 2LL << 61:
1938 printf("llsw:2\n");
1939 break;
1940 case 3LL << 61:
1941 printf("llsw:3\n");
1942 break;
1943 case 4LL << 61:
1944 printf("llsw:4\n");
1945 break;
1946 case 5LL << 61:
1947 printf("llsw:5\n");
1948 break;
1949 default:
1950 printf("llsw: broken!\n");
1954 for (i = -5; i <= 5; i++) {
1955 switch_uc((unsigned char)i);
1958 for (i = -5; i <= 5; i++) {
1959 switch_sc ((signed char)i);
1963 /* ISOC99 _Bool type */
1964 void c99_bool_test(void)
1966 #ifdef BOOL_ISOC99
1967 int a;
1968 _Bool b, b2;
1970 printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
1971 a = 3;
1972 printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
1973 b = 3;
1974 printf("b = %d\n", b);
1975 b++;
1976 printf("b = %d\n", b);
1977 b2 = 0;
1978 printf("sizeof(x ? _Bool : _Bool) = %d (should be sizeof int)\n",
1979 sizeof((volatile)a ? b : b2));
1980 #endif
1983 void bitfield_test(void)
1985 int a;
1986 short sa;
1987 unsigned char ca;
1988 struct sbf1 {
1989 int f1 : 3;
1990 int : 2;
1991 int f2 : 1;
1992 int : 0;
1993 int f3 : 5;
1994 int f4 : 7;
1995 unsigned int f5 : 7;
1996 } st1;
1997 printf("sizeof(st1) = %d\n", sizeof(st1));
1999 st1.f1 = 3;
2000 st1.f2 = 1;
2001 st1.f3 = 15;
2002 a = 120;
2003 st1.f4 = a;
2004 st1.f5 = a;
2005 st1.f5++;
2006 printf("%d %d %d %d %d\n",
2007 st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
2008 sa = st1.f5;
2009 ca = st1.f5;
2010 printf("%d %d\n", sa, ca);
2012 st1.f1 = 7;
2013 if (st1.f1 == -1)
2014 printf("st1.f1 == -1\n");
2015 else
2016 printf("st1.f1 != -1\n");
2017 if (st1.f2 == -1)
2018 printf("st1.f2 == -1\n");
2019 else
2020 printf("st1.f2 != -1\n");
2022 struct sbf2 {
2023 long long f1 : 45;
2024 long long : 2;
2025 long long f2 : 35;
2026 unsigned long long f3 : 38;
2027 } st2;
2028 st2.f1 = 0x123456789ULL;
2029 a = 120;
2030 st2.f2 = (long long)a << 25;
2031 st2.f3 = a;
2032 st2.f2++;
2033 printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
2035 #if 0
2036 Disabled for now until further clarification re GCC compatibility
2037 struct sbf3 {
2038 int f1 : 7;
2039 int f2 : 1;
2040 char f3;
2041 int f4 : 8;
2042 int f5 : 1;
2043 int f6 : 16;
2044 } st3;
2045 printf("sizeof(st3) = %d\n", sizeof(st3));
2046 #endif
2048 struct sbf4 {
2049 int x : 31;
2050 char y : 2;
2051 } st4;
2052 st4.y = 1;
2053 printf("st4.y == %d\n", st4.y);
2054 struct sbf5 {
2055 int a;
2056 char b;
2057 int x : 12, y : 4, : 0, : 4, z : 3;
2058 char c;
2059 } st5 = { 1, 2, 3, 4, -3, 6 };
2060 printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
2061 struct sbf6 {
2062 short x : 12;
2063 unsigned char y : 2;
2064 } st6;
2065 st6.y = 1;
2066 printf("st6.y == %d\n", st6.y);
2069 #ifdef __x86_64__
2070 #define FLOAT_FMT "%f\n"
2071 #else
2072 /* x86's float isn't compatible with GCC */
2073 #define FLOAT_FMT "%.5f\n"
2074 #endif
2076 /* declare strto* functions as they are C99 */
2077 double strtod(const char *nptr, char **endptr);
2079 #if defined(_WIN32)
2080 float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
2081 LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
2082 #else
2083 float strtof(const char *nptr, char **endptr);
2084 LONG_DOUBLE strtold(const char *nptr, char **endptr);
2085 #endif
2087 #define FTEST(prefix, typename, type, fmt)\
2088 void prefix ## cmp(type a, type b)\
2090 printf("%d %d %d %d %d %d\n",\
2091 a == b,\
2092 a != b,\
2093 a < b,\
2094 a > b,\
2095 a >= b,\
2096 a <= b);\
2097 printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
2100 a + b,\
2101 a - b,\
2102 a * b,\
2103 a / b,\
2104 -a);\
2105 printf(fmt "\n", ++a);\
2106 printf(fmt "\n", a++);\
2107 printf(fmt "\n", a);\
2108 b = 0;\
2109 printf("%d %d\n", !a, !b);\
2111 void prefix ## fcast(type a)\
2113 float fa;\
2114 double da;\
2115 LONG_DOUBLE la;\
2116 int ia;\
2117 long long llia;\
2118 unsigned int ua;\
2119 unsigned long long llua;\
2120 type b;\
2121 fa = a;\
2122 da = a;\
2123 la = a;\
2124 printf("ftof: %f %f %Lf\n", fa, da, la);\
2125 ia = (int)a;\
2126 llia = (long long)a;\
2127 a = (a >= 0) ? a : -a;\
2128 ua = (unsigned int)a;\
2129 llua = (unsigned long long)a;\
2130 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
2131 ia = -1234;\
2132 ua = 0x81234500;\
2133 llia = -0x123456789012345LL;\
2134 llua = 0xf123456789012345LLU;\
2135 b = ia;\
2136 printf("itof: " fmt "\n", b);\
2137 b = ua;\
2138 printf("utof: " fmt "\n", b);\
2139 b = llia;\
2140 printf("lltof: " fmt "\n", b);\
2141 b = llua;\
2142 printf("ulltof: " fmt "\n", b);\
2145 float prefix ## retf(type a) { return a; }\
2146 double prefix ## retd(type a) { return a; }\
2147 LONG_DOUBLE prefix ## retld(type a) { return a; }\
2149 void prefix ## call(void)\
2151 printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
2152 printf("double: %f\n", prefix ## retd(42.123456789));\
2153 printf("long double: %Lf\n", prefix ## retld(42.123456789));\
2154 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
2157 void prefix ## signed_zeros(void) \
2159 type x = 0.0, y = -0.0, n, p;\
2160 if (x == y)\
2161 printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\
2162 1.0 / x != 1.0 / y);\
2163 else\
2164 printf ("x != y; this is wrong!\n");\
2166 n = -x;\
2167 if (x == n)\
2168 printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
2169 1.0 / x != 1.0 / n);\
2170 else\
2171 printf ("x != -x; this is wrong!\n");\
2173 p = +y;\
2174 if (x == p)\
2175 printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
2176 1.0 / x != 1.0 / p);\
2177 else\
2178 printf ("x != +y; this is wrong!\n");\
2179 p = -y;\
2180 if (x == p)\
2181 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
2182 1.0 / x != 1.0 / p);\
2183 else\
2184 printf ("x != -y; this is wrong!\n");\
2186 void prefix ## test(void)\
2188 printf("testing '%s'\n", #typename);\
2189 prefix ## cmp(1, 2.5);\
2190 prefix ## cmp(2, 1.5);\
2191 prefix ## cmp(1, 1);\
2192 prefix ## fcast(234.6);\
2193 prefix ## fcast(-2334.6);\
2194 prefix ## call();\
2195 prefix ## signed_zeros();\
2198 FTEST(f, float, float, "%f")
2199 FTEST(d, double, double, "%f")
2200 FTEST(ld, long double, LONG_DOUBLE, "%Lf")
2202 double ftab1[3] = { 1.2, 3.4, -5.6 };
2205 void float_test(void)
2207 #if !defined(__arm__) || defined(__ARM_PCS_VFP)
2208 float fa, fb;
2209 double da, db;
2210 int a;
2211 unsigned int b;
2212 static double nan2 = 0.0/0.0;
2213 static double inf1 = 1.0/0.0;
2214 static double inf2 = 1e5000;
2216 printf("sizeof(float) = %d\n", sizeof(float));
2217 printf("sizeof(double) = %d\n", sizeof(double));
2218 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
2219 ftest();
2220 dtest();
2221 ldtest();
2222 printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
2223 printf("%f %f %f\n", 2.12, .5, 2.3e10);
2224 // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
2225 da = 123;
2226 printf("da=%f\n", da);
2227 fa = 123;
2228 printf("fa=%f\n", fa);
2229 a = 4000000000;
2230 da = a;
2231 printf("da = %f\n", da);
2232 b = 4000000000;
2233 db = b;
2234 printf("db = %f\n", db);
2235 printf("nan != nan = %d, inf1 = %f, inf2 = %f\n", nan2 != nan2, inf1, inf2);
2236 #endif
2239 int fib(int n)
2241 if (n <= 2)
2242 return 1;
2243 else
2244 return fib(n-1) + fib(n-2);
2247 #if __GNUC__ == 3
2248 # define aligned_function 0
2249 #else
2250 void __attribute__((aligned(16))) aligned_function(int i) {}
2251 #endif
2253 void funcptr_test()
2255 void (*func)(int);
2256 int a;
2257 struct {
2258 int dummy;
2259 void (*func)(int);
2260 } st1;
2261 long diff;
2263 func = &num;
2264 (*func)(12345);
2265 func = num;
2266 a = 1;
2267 a = 1;
2268 func(12345);
2269 /* more complicated pointer computation */
2270 st1.func = num;
2271 st1.func(12346);
2272 printf("sizeof1 = %d\n", sizeof(funcptr_test));
2273 printf("sizeof2 = %d\n", sizeof funcptr_test);
2274 printf("sizeof3 = %d\n", sizeof(&funcptr_test));
2275 printf("sizeof4 = %d\n", sizeof &funcptr_test);
2276 a = 0;
2277 func = num + a;
2278 diff = func - num;
2279 func(42);
2280 (func + diff)(42);
2281 (num + a)(43);
2283 /* Check that we can align functions */
2284 func = aligned_function;
2285 printf("aligned_function (should be zero): %d\n", ((int)(uintptr_t)func) & 15);
2288 void lloptest(long long a, long long b)
2290 unsigned long long ua, ub;
2292 ua = a;
2293 ub = b;
2294 /* arith */
2295 printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2296 a + b,
2297 a - b,
2298 a * b);
2300 if (b != 0) {
2301 printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2302 a / b,
2303 a % b);
2306 /* binary */
2307 printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2308 a & b,
2309 a | b,
2310 a ^ b);
2312 /* tests */
2313 printf("test: %d %d %d %d %d %d\n",
2314 a == b,
2315 a != b,
2316 a < b,
2317 a > b,
2318 a >= b,
2319 a <= b);
2321 printf("utest: %d %d %d %d %d %d\n",
2322 ua == ub,
2323 ua != ub,
2324 ua < ub,
2325 ua > ub,
2326 ua >= ub,
2327 ua <= ub);
2329 /* arith2 */
2330 a++;
2331 b++;
2332 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2333 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
2334 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
2335 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2336 b = ub = 0;
2337 printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
2340 void llshift(long long a, int b)
2342 printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2343 (unsigned long long)a >> b,
2344 a >> b,
2345 a << b);
2346 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2347 (unsigned long long)a >> 3,
2348 a >> 3,
2349 a << 3);
2350 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2351 (unsigned long long)a >> 35,
2352 a >> 35,
2353 a << 35);
2356 void llfloat(void)
2358 float fa;
2359 double da;
2360 LONG_DOUBLE lda;
2361 long long la, lb, lc;
2362 unsigned long long ula, ulb, ulc;
2363 la = 0x12345678;
2364 ula = 0x72345678;
2365 la = (la << 20) | 0x12345;
2366 ula = ula << 33;
2367 printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
2369 fa = la;
2370 da = la;
2371 lda = la;
2372 printf("lltof: %f %f %Lf\n", fa, da, lda);
2374 la = fa;
2375 lb = da;
2376 lc = lda;
2377 printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
2379 fa = ula;
2380 da = ula;
2381 lda = ula;
2382 printf("ulltof: %f %f %Lf\n", fa, da, lda);
2384 ula = fa;
2385 ulb = da;
2386 ulc = lda;
2387 printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
2390 long long llfunc1(int a)
2392 return a * 2;
2395 struct S {
2396 int id;
2397 char item;
2400 long long int value(struct S *v)
2402 return ((long long int)v->item);
2405 long long llfunc2(long long x, long long y, int z)
2407 return x * y * z;
2410 void check_opl_save_regs(char *a, long long b, int c)
2412 *a = b < 0 && !c;
2415 void longlong_test(void)
2417 long long a, b, c;
2418 int ia;
2419 unsigned int ua;
2420 printf("sizeof(long long) = %d\n", sizeof(long long));
2421 ia = -1;
2422 ua = -2;
2423 a = ia;
2424 b = ua;
2425 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2426 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
2427 (long long)1,
2428 (long long)-2,
2429 1LL,
2430 0x1234567812345679);
2431 a = llfunc1(-3);
2432 printf(LONG_LONG_FORMAT "\n", a);
2434 lloptest(1000, 23);
2435 lloptest(0xff, 0x1234);
2436 b = 0x72345678 << 10;
2437 lloptest(-3, b);
2438 llshift(0x123, 5);
2439 llshift(-23, 5);
2440 b = 0x72345678LL << 10;
2441 llshift(b, 47);
2443 llfloat();
2444 #if 1
2445 b = 0x12345678;
2446 a = -1;
2447 c = a + b;
2448 printf("%Lx\n", c);
2449 #endif
2451 /* long long reg spill test */
2453 struct S a;
2455 a.item = 3;
2456 printf("%lld\n", value(&a));
2458 lloptest(0x80000000, 0);
2461 long long *p, v, **pp;
2462 v = 1;
2463 p = &v;
2464 p[0]++;
2465 printf("another long long spill test : %lld\n", *p);
2466 pp = &p;
2468 v = llfunc2(**pp, **pp, ia);
2469 printf("a long long function (arm-)reg-args test : %lld\n", v);
2471 a = 68719476720LL;
2472 b = 4294967295LL;
2473 printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
2475 printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
2477 /* long long pointer deref in argument passing test */
2478 a = 0x123;
2479 long long *p = &a;
2480 llshift(*p, 5);
2482 /* shortening followed by widening */
2483 unsigned long long u = 0x8000000000000001ULL;
2484 u = (unsigned)(u + 1);
2485 printf("long long u=" ULONG_LONG_FORMAT "\n", u);
2486 u = 0x11223344aa998877ULL;
2487 u = (unsigned)(int)(u + 1);
2488 printf("long long u=" ULONG_LONG_FORMAT "\n", u);
2490 /* was a problem with missing save_regs in gen_opl on 32-bit platforms */
2491 char cc = 78;
2492 check_opl_save_regs(&cc, -1, 0);
2493 printf("check_opl_save_regs: %d\n", cc);
2496 void manyarg_test(void)
2498 LONG_DOUBLE ld = 1234567891234LL;
2499 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2500 1, 2, 3, 4, 5, 6, 7, 8,
2501 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2502 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2503 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2504 1, 2, 3, 4, 5, 6, 7, 8,
2505 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2506 1234567891234LL, 987654321986LL,
2507 42.0, 43.0);
2508 printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2509 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2510 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2511 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2512 1234567891234LL, 987654321986LL,
2513 42.0, 43.0);
2514 printf("%d %d %d %d %d %d %d %d %Lf\n",
2515 1, 2, 3, 4, 5, 6, 7, 8, ld);
2516 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2517 LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
2518 1, 2, 3, 4, 5, 6, 7, 8,
2519 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2520 1234567891234LL, 987654321986LL,
2521 42.0, 43.0, ld);
2522 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2523 "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
2524 1, 2, 3, 4, 5, 6, 7, 8,
2525 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2526 ld, 1234567891234LL, 987654321986LL,
2527 42.0, 43.0, ld);
2530 void*
2531 va_arg_with_struct_ptr(va_list ap) {
2533 * This was a BUG identified with FFTW-3.3.8 on arm64.
2534 * The test case only checks it compiles on all supported
2535 * architectures. This function is not currently called.
2537 struct X { int _x; };
2538 struct X *x = va_arg(ap, struct X *);
2539 return x;
2542 void vprintf1(const char *fmt, ...)
2544 va_list ap, aq;
2545 const char *p;
2546 int c, i;
2547 double d;
2548 long long ll;
2549 LONG_DOUBLE ld;
2551 va_start(aq, fmt);
2552 va_copy(ap, aq);
2554 p = fmt;
2555 for(;;) {
2556 c = *p;
2557 if (c == '\0')
2558 break;
2559 p++;
2560 if (c == '%') {
2561 c = *p;
2562 switch(c) {
2563 case '\0':
2564 goto the_end;
2565 case 'd':
2566 i = va_arg(ap, int);
2567 printf("%d", i);
2568 break;
2569 case 'f':
2570 d = va_arg(ap, double);
2571 printf("%f", d);
2572 break;
2573 case 'l':
2574 ll = va_arg(ap, long long);
2575 printf(LONG_LONG_FORMAT, ll);
2576 break;
2577 case 'F':
2578 ld = va_arg(ap, LONG_DOUBLE);
2579 printf("%Lf", ld);
2580 break;
2582 p++;
2583 } else {
2584 putchar(c);
2587 the_end:
2588 va_end(aq);
2589 va_end(ap);
2592 struct myspace {
2593 short int profile;
2596 void stdarg_for_struct(struct myspace bob, ...)
2598 struct myspace george, bill;
2599 va_list ap;
2600 short int validate;
2602 va_start(ap, bob);
2603 bill = va_arg(ap, struct myspace);
2604 george = va_arg(ap, struct myspace);
2605 validate = va_arg(ap, int);
2606 printf("stdarg_for_struct: %d %d %d %d\n",
2607 bob.profile, bill.profile, george.profile, validate);
2608 va_end(ap);
2611 void stdarg_for_libc(const char *fmt, ...)
2613 va_list args;
2614 va_start(args, fmt);
2615 vprintf(fmt, args);
2616 va_end(args);
2619 void stdarg_syntax(int n, ...)
2621 int i;
2622 va_list ap;
2623 if (1)
2624 va_start(ap, n);
2625 else
2627 i = va_arg(ap, int);
2628 printf("stdarg_void_expr: %d\n", i);
2629 (va_end(ap));
2632 void stdarg_test(void)
2634 LONG_DOUBLE ld = 1234567891234LL;
2635 struct myspace bob;
2637 vprintf1("%d %d %d\n", 1, 2, 3);
2638 vprintf1("%f %d %f\n", 1.0, 2, 3.0);
2639 vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
2640 vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
2641 vprintf1("%d %f %l %F %d %f %l %F\n",
2642 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
2643 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
2644 1, 2, 3, 4, 5, 6, 7, 8,
2645 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
2646 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2647 1, 2, 3, 4, 5, 6, 7, 8,
2648 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2649 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2650 "%l %l %f %f\n",
2651 1, 2, 3, 4, 5, 6, 7, 8,
2652 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2653 1234567891234LL, 987654321986LL,
2654 42.0, 43.0);
2655 vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2656 "%l %l %f %f\n",
2657 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2658 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2659 1234567891234LL, 987654321986LL,
2660 42.0, 43.0);
2661 vprintf1("%d %d %d %d %d %d %d %d %F\n",
2662 1, 2, 3, 4, 5, 6, 7, 8, ld);
2663 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2664 "%l %l %f %f %F\n",
2665 1, 2, 3, 4, 5, 6, 7, 8,
2666 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2667 1234567891234LL, 987654321986LL,
2668 42.0, 43.0, ld);
2669 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2670 "%F %l %l %f %f %F\n",
2671 1, 2, 3, 4, 5, 6, 7, 8,
2672 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2673 ld, 1234567891234LL, 987654321986LL,
2674 42.0, 43.0, ld);
2676 bob.profile = 42;
2677 stdarg_for_struct(bob, bob, bob, bob.profile);
2678 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
2679 stdarg_syntax(1, 17);
2682 int reltab[3] = { 1, 2, 3 };
2684 int *rel1 = &reltab[1];
2685 int *rel2 = &reltab[2];
2687 #ifdef _WIN64
2688 void relocation_test(void) {}
2689 #else
2690 void getmyaddress(void)
2692 printf("in getmyaddress\n");
2695 #ifdef __LP64__
2696 long __pa_symbol(void)
2698 /* This 64bit constant was handled incorrectly, it was used as addend
2699 (which can hold 64bit just fine) in connection with a symbol,
2700 and TCC generates wrong code for that (displacements are 32bit only).
2701 This effectively is "+ 0x80000000", and if addresses of globals
2702 are below 2GB the result should be a number without high 32 bits set. */
2703 return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
2705 #endif
2707 unsigned long theaddress = (unsigned long)getmyaddress;
2708 void relocation_test(void)
2710 void (*fptr)(void) = (void (*)(void))theaddress;
2711 printf("*rel1=%d\n", *rel1);
2712 printf("*rel2=%d\n", *rel2);
2713 fptr();
2714 #ifdef __LP64__
2715 printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
2716 #endif
2718 #endif
2720 void old_style_f(a,b,c)
2721 int a, b;
2722 double c;
2724 printf("a=%d b=%d b=%f\n", a, b, c);
2727 void decl_func1(int cmpfn())
2729 printf("cmpfn=%lx\n", (long)cmpfn);
2732 void decl_func2(cmpfn)
2733 int cmpfn();
2735 printf("cmpfn=%lx\n", (long)cmpfn);
2738 void old_style_function_test(void)
2740 old_style_f((void *)1, 2, 3.0);
2741 decl_func1(NULL);
2742 decl_func2(NULL);
2745 void alloca_test()
2747 #if defined __i386__ || defined __x86_64__ || defined __arm__
2748 char *p = alloca(16);
2749 strcpy(p,"123456789012345");
2750 printf("alloca: p is %s\n", p);
2751 char *demo = "This is only a test.\n";
2752 /* Test alloca embedded in a larger expression */
2753 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
2754 #endif
2757 void *bounds_checking_is_enabled()
2759 char ca[10], *cp = ca-1;
2760 return (ca != cp + 1) ? cp : NULL;
2763 typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
2765 void c99_vla_test_1(int size1, int size2)
2767 #if defined __i386__ || defined __x86_64__
2768 int size = size1 * size2;
2769 int tab1[size][2], tab2[10][2];
2770 void *tab1_ptr, *tab2_ptr, *bad_ptr;
2772 /* "size" should have been 'captured' at tab1 declaration,
2773 so modifying it should have no effect on VLA behaviour. */
2774 size = size-1;
2776 printf("Test C99 VLA 1 (sizeof): ");
2777 printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
2778 tab1_ptr = tab1;
2779 tab2_ptr = tab2;
2780 printf("Test C99 VLA 2 (ptrs subtract): ");
2781 printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
2782 printf("Test C99 VLA 3 (ptr add): ");
2783 printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
2784 printf("Test C99 VLA 4 (ptr access): ");
2785 tab1[size1][1] = 42;
2786 printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
2788 printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
2789 if (bad_ptr = bounds_checking_is_enabled()) {
2790 int *t1 = &tab1[size1 * size2 - 1][3];
2791 int *t2 = &tab2[9][3];
2792 printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED");
2793 printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED");
2795 char*c1 = 1 + sizeof(tab1) + (char*)tab1;
2796 char*c2 = 1 + sizeof(tab2) + (char*)tab2;
2797 printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED");
2798 printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED");
2800 int *i1 = tab1[-1];
2801 int *i2 = tab2[-1];
2802 printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED");
2803 printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED");
2805 int *x1 = tab1[size1 * size2 + 1];
2806 int *x2 = tab2[10 + 1];
2807 printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED");
2808 printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED");
2809 } else {
2810 printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
2812 printf("\n");
2813 #endif
2816 void c99_vla_test(void)
2818 c99_vla_test_1(5, 2);
2822 void sizeof_test(void)
2824 int a;
2825 int **ptr;
2827 printf("sizeof(int) = %d\n", sizeof(int));
2828 printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
2829 printf("sizeof(long) = %d\n", sizeof(long));
2830 printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
2831 printf("sizeof(short) = %d\n", sizeof(short));
2832 printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
2833 printf("sizeof(char) = %d\n", sizeof(char));
2834 printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
2835 printf("sizeof(func) = %d\n", sizeof sizeof_test());
2836 a = 1;
2837 printf("sizeof(a++) = %d\n", sizeof a++);
2838 printf("a=%d\n", a);
2839 ptr = NULL;
2840 printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
2842 /* The type of sizeof should be as large as a pointer, actually
2843 it should be size_t. */
2844 printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
2845 uintptr_t t = 1;
2846 uintptr_t t2;
2847 /* Effectively <<32, but defined also on 32bit machines. */
2848 t <<= 16;
2849 t <<= 16;
2850 t++;
2851 /* This checks that sizeof really can be used to manipulate
2852 uintptr_t objects, without truncation. */
2853 t2 = t & -sizeof(uintptr_t);
2854 printf ("%lu %lu\n", t, t2);
2856 /* some alignof tests */
2857 printf("__alignof__(int) = %d\n", __alignof__(int));
2858 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
2859 printf("__alignof__(short) = %d\n", __alignof__(short));
2860 printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
2861 printf("__alignof__(char) = %d\n", __alignof__(char));
2862 printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
2863 printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
2865 /* sizes of VLAs need to be evaluated even inside sizeof: */
2866 a = 2;
2867 printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
2868 /* And checking if sizeof compound literal works. Parenthesized: */
2869 printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
2870 sizeof( (struct {int i; int j;}){4,5} ));
2871 /* And as direct sizeof argument (as unary expression): */
2872 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
2873 sizeof (struct {short i; short j;}){4,5} );
2875 /* sizeof(x && y) should be sizeof(int), even if constant
2876 evaluating is possible. */
2877 printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
2878 printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
2879 printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
2880 printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
2883 void typeof_test(void)
2885 double a;
2886 typeof(a) b;
2887 typeof(float) c;
2889 a = 1.5;
2890 b = 2.5;
2891 c = 3.5;
2892 printf("a=%f b=%f c=%f\n", a, b, c);
2896 struct hlist_node;
2897 struct hlist_head {
2898 struct hlist_node *first, *last;
2901 void consume_ulong (unsigned long i)
2903 i = 0;
2906 void statement_expr_test(void)
2908 int a, i;
2910 /* Basic stmt expr test */
2911 a = 0;
2912 for(i=0;i<10;i++) {
2913 a += 1 +
2914 ( { int b, j;
2915 b = 0;
2916 for(j=0;j<5;j++)
2917 b += j; b;
2918 } );
2920 printf("a=%d\n", a);
2922 /* Test that symbols aren't freed prematurely.
2923 With SYM_DEBUG valgrind will show a read from a freed
2924 symbol, and tcc will show an (invalid) warning on the initialization
2925 of 'ptr' below, if symbols are popped after the stmt expr. */
2926 void *v = (void*)39;
2927 typeof(({
2928 (struct hlist_node *)v;
2929 })) x;
2930 typeof (x)
2931 ptr = (struct hlist_node *)v;
2933 /* This part used to segfault when symbols were popped prematurely.
2934 The symbols for the static local would be overwritten with
2935 helper symbols from the pre-processor expansions in between. */
2936 #define some_attr __attribute__((aligned(1)))
2937 #define tps(str) ({ \
2938 static const char *t some_attr = str; \
2939 t; \
2941 printf ("stmtexpr: %s %s\n",
2942 tps("somerandomlongstring"),
2943 tps("anotherlongstring"));
2945 /* Test that the three decls of 't' don't interact. */
2946 int t = 40;
2947 int b = ({ int t = 41; t; });
2948 int c = ({ int t = 42; t; });
2950 /* Test that aggregate return values work. */
2951 struct hlist_head h
2952 = ({
2953 typedef struct hlist_head T;
2954 long pre = 48;
2955 T t = { (void*)43, (void*)44 };
2956 long post = 49;
2959 printf ("stmtexpr: %d %d %d\n", t, b, c);
2960 printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
2962 /* Test that we can give out addresses of local labels. */
2963 consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
2965 /* Test interaction between local and global label stacks and the
2966 need to defer popping symbol from them when within statement
2967 expressions. Note how the labels are both named LBL. */
2968 i = 0;
2971 __label__ LBL;
2972 LBL: if (i++ == 0) goto LBL;
2974 /* jump to a classical label out of an expr-stmt that had previously
2975 overshadowed that classical label */
2976 goto LBL;
2978 LBL:
2979 printf("stmtexpr: %d should be 2\n", i);
2982 void local_label_test(void)
2984 int a;
2985 goto l1;
2987 a = 1 + ({
2988 __label__ l1, l2, l3, l4;
2989 goto l1;
2991 printf("aa1\n");
2992 goto l3;
2994 printf("aa3\n");
2995 goto l4;
2997 printf("aa2\n");
2998 goto l2;
2999 l3:;
3002 printf("a=%d\n", a);
3003 return;
3005 printf("bb1\n");
3006 goto l2;
3008 printf("bb2\n");
3009 goto l4;
3012 /* inline assembler test */
3013 #if defined(__i386__) || defined(__x86_64__)
3015 /* from linux kernel */
3016 static char * strncat1(char * dest,const char * src,size_t count)
3018 long d0, d1, d2, d3;
3019 __asm__ __volatile__(
3020 "repne\n\t"
3021 "scasb\n\t"
3022 "dec %1\n\t"
3023 "mov %8,%3\n"
3024 "1:\tdec %3\n\t"
3025 "js 2f\n\t"
3026 "lodsb\n\t"
3027 "stosb\n\t"
3028 "testb %%al,%%al\n\t"
3029 "jne 1b\n"
3030 "2:\txor %2,%2\n\t"
3031 "stosb"
3032 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3033 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3034 : "memory");
3035 return dest;
3038 static char * strncat2(char * dest,const char * src,size_t count)
3040 long d0, d1, d2, d3;
3041 __asm__ __volatile__(
3042 "repne scasb\n\t" /* one-line repne prefix + string op */
3043 "dec %1\n\t"
3044 "mov %8,%3\n"
3045 "1:\tdec %3\n\t"
3046 "js 2f\n\t"
3047 "lodsb\n\t"
3048 "stosb\n\t"
3049 "testb %%al,%%al\n\t"
3050 "jne 1b\n"
3051 "2:\txor %2,%2\n\t"
3052 "stosb"
3053 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3054 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3055 : "memory");
3056 return dest;
3059 static inline void * memcpy1(void * to, const void * from, size_t n)
3061 long d0, d1, d2;
3062 __asm__ __volatile__(
3063 "rep ; movsl\n\t"
3064 "testb $2,%b4\n\t"
3065 "je 1f\n\t"
3066 "movsw\n"
3067 "1:\ttestb $1,%b4\n\t"
3068 "je 2f\n\t"
3069 "movsb\n"
3070 "2:"
3071 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3072 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3073 : "memory");
3074 return (to);
3077 static inline void * memcpy2(void * to, const void * from, size_t n)
3079 long d0, d1, d2;
3080 __asm__ __volatile__(
3081 "rep movsl\n\t" /* one-line rep prefix + string op */
3082 "testb $2,%b4\n\t"
3083 "je 1f\n\t"
3084 "movsw\n"
3085 "1:\ttestb $1,%b4\n\t"
3086 "je 2f\n\t"
3087 "movsb\n"
3088 "2:"
3089 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3090 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3091 : "memory");
3092 return (to);
3095 static __inline__ void sigaddset1(unsigned int *set, int _sig)
3097 __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
3100 static __inline__ void sigdelset1(unsigned int *set, int _sig)
3102 asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
3105 #ifndef __APPLE__
3106 /* clang's inline asm is uncapable of 'xchgb %b0,%h0' */
3107 static __inline__ __const__ unsigned int swab32(unsigned int x)
3109 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
3110 "rorl $16,%0\n\t" /* swap words */
3111 "xchgb %b0,%h0" /* swap higher bytes */
3112 :"=" "q" (x)
3113 : "0" (x));
3114 return x;
3116 #endif
3118 static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
3120 unsigned long long res;
3121 #ifdef __x86_64__
3122 /* Using the A constraint is wrong (it means rdx:rax, which is too large)
3123 but still test the 32bit->64bit mull. */
3124 unsigned int resh, resl;
3125 __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
3126 res = ((unsigned long long)resh << 32) | resl;
3127 #else
3128 __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
3129 #endif
3130 return res;
3133 static __inline__ unsigned long long inc64(unsigned long long a)
3135 unsigned long long res;
3136 #ifdef __x86_64__
3137 /* Using the A constraint is wrong, and increments are tested
3138 elsewhere. */
3139 res = a + 1;
3140 #else
3141 __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
3142 #endif
3143 return res;
3146 struct struct123 {
3147 int a;
3148 int b;
3150 struct struct1231 {
3151 unsigned long addr;
3154 unsigned long mconstraint_test(struct struct1231 *r)
3156 unsigned long ret;
3157 unsigned int a[2];
3158 a[0] = 0;
3159 __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
3160 : "=&r" (ret), "=m" (a)
3161 : "m" (*(struct struct123 *)r->addr));
3162 return ret + a[0];
3165 #ifdef __x86_64__
3166 int fls64(unsigned long long x)
3168 int bitpos = -1;
3169 asm("bsrq %1,%q0"
3170 : "+r" (bitpos)
3171 : "rm" (x));
3172 return bitpos + 1;
3174 #endif
3176 void other_constraints_test(void)
3178 unsigned long ret;
3179 int var;
3180 #ifndef _WIN64
3181 __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
3182 printf ("oc1: %d\n", ret == (unsigned long)&var);
3183 #endif
3186 #ifndef _WIN32
3187 /* Test global asm blocks playing with aliases. */
3188 void base_func(void)
3190 printf ("asmc: base\n");
3193 #ifndef __APPLE__
3194 extern void override_func1 (void);
3195 extern void override_func2 (void);
3197 asm(".weak override_func1\n.set override_func1, base_func");
3198 asm(".set override_func1, base_func");
3199 asm(".set override_func2, base_func");
3201 void override_func2 (void)
3203 printf ("asmc: override2\n");
3206 /* This checks a construct used by the linux kernel to encode
3207 references to strings by PC relative references. */
3208 extern int bug_table[] __attribute__((section("__bug_table")));
3209 char * get_asm_string (void)
3211 /* On i386 when -fPIC is enabled this would cause a compile error with GCC,
3212 the problem being the "i" constraint used with a symbolic operand
3213 resolving to a local label. That check is overly zealous as the code
3214 within the asm makes sure to use it only in PIC-possible contexts,
3215 but all GCC versions behave like so. We arrange for PIC to be disabled
3216 for compiling tcctest.c in the Makefile.
3218 Additionally the usage of 'c' in "%c0" in the template is actually wrong,
3219 as that would expect an operand that is a condition code. The operand
3220 as is (a local label) is accepted by GCC in non-PIC mode, and on x86-64.
3221 What the linux kernel really wanted is 'p' to disable the addition of '$'
3222 to the printed operand (as in "$.LC0" where the template only wants the
3223 bare operand ".LC0"). But the code below is what the linux kernel
3224 happens to use and as such is the one we want to test. */
3225 #ifndef __clang__
3226 extern int some_symbol;
3227 asm volatile (".globl some_symbol\n"
3228 "jmp .+6\n"
3229 "1:\n"
3230 "some_symbol: .long 0\n"
3231 ".pushsection __bug_table, \"a\"\n"
3232 ".globl bug_table\n"
3233 "bug_table:\n"
3234 /* The first entry (1b-2b) is unused in this test,
3235 but we include it to check if cross-section
3236 PC-relative references work. */
3237 "2:\t.long 1b - 2b, %c0 - 2b\n"
3238 ".popsection\n" : : "i" ("A string"));
3239 char * str = ((char*)bug_table) + bug_table[1];
3240 return str;
3241 #else
3242 return (char *) "A string";
3243 #endif
3246 /* This checks another constructs with local labels. */
3247 extern unsigned char alld_stuff[];
3248 asm(".data\n"
3249 ".byte 41\n"
3250 "alld_stuff:\n"
3251 "661:\n"
3252 ".byte 42\n"
3253 "662:\n"
3254 ".pushsection .data.ignore\n"
3255 ".long 661b - .\n" /* This reference to 661 generates an external sym
3256 which shouldn't somehow overwrite the offset that's
3257 already determined for it. */
3258 ".popsection\n"
3259 ".byte 662b - 661b\n" /* So that this value is undeniably 1. */);
3261 void asm_local_label_diff (void)
3263 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
3265 #endif
3267 /* This checks that static local variables are available from assembler. */
3268 void asm_local_statics (void)
3270 static int localint = 41;
3271 asm("incl %0" : "+m" (localint));
3272 printf ("asm_local_statics: %d\n", localint);
3274 #endif
3276 static
3277 unsigned int set;
3279 void fancy_copy (unsigned *in, unsigned *out)
3281 asm volatile ("" : "=r" (*out) : "0" (*in));
3284 void fancy_copy2 (unsigned *in, unsigned *out)
3286 asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
3289 #if defined __x86_64__ && !defined _WIN64
3290 void clobber_r12(void)
3292 asm volatile("mov $1, %%r12" ::: "r12");
3294 #endif
3296 void test_high_clobbers_really(void)
3298 #if defined __x86_64__ && !defined _WIN64
3299 register long val asm("r12");
3300 long val2;
3301 /* This tests if asm clobbers correctly save/restore callee saved
3302 registers if they are clobbered and if it's the high 8 x86-64
3303 registers. This is fragile for GCC as the constraints do not
3304 correctly capture the data flow, but good enough for us. */
3305 asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
3306 clobber_r12();
3307 asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
3308 printf("asmhc: 0x%x\n", val2);
3309 #endif
3312 void test_high_clobbers(void)
3314 #if defined __x86_64__ && !defined _WIN64
3315 long x1, x2;
3316 asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */
3317 test_high_clobbers_really();
3318 asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */
3319 asm volatile("mov %0,%%r12" :: "m" (x1)); /* restore r12 */
3320 /* should be 0 but tcc doesn't save r12 automatically, which has
3321 bad effects when gcc helds TCCState *s in r12 in tcc.c:main */
3322 //printf("r12-clobber-diff: %lx\n", x2 - x1);
3323 #endif
3326 static long cpu_number;
3327 void trace_console(long len, long len2)
3329 #ifdef __x86_64__
3330 /* This generated invalid code when the emission of the switch
3331 table isn't disabled. The asms are necessary to show the bug,
3332 normal statements don't work (they need to generate some code
3333 even under nocode_wanted, which normal statements don't do,
3334 but asms do). Also at least these number of cases is necessary
3335 to generate enough "random" bytes. They ultimately are enough
3336 to create invalid instruction patterns to which the first
3337 skip-to-decision-table jump jumps. If decision table emission
3338 is disabled all of this is no problem.
3340 It also is necessary that the switches are in a statement expression
3341 (which has the property of not being enterable from outside. no
3342 matter what). */
3343 if (0
3346 long pscr_ret__;
3347 switch(len) {
3348 case 4:
3350 long pfo_ret__;
3351 switch (len2) {
3352 case 8: printf("bla"); pfo_ret__ = 42; break;
3354 pscr_ret__ = pfo_ret__;
3356 break;
3357 case 8:
3359 long pfo_ret__;
3360 switch (len2) {
3361 case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3362 case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3363 case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3364 case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3365 default: printf("impossible\n");
3367 pscr_ret__ = pfo_ret__;
3369 break;
3371 pscr_ret__;
3374 printf("huh?\n");
3376 #endif
3379 void test_asm_dead_code(void)
3381 long rdi;
3382 /* Try to make sure that xdi contains a zero, and hence will
3383 lead to a segfault if the next asm is evaluated without
3384 arguments being set up. */
3385 asm volatile ("" : "=D" (rdi) : "0" (0));
3386 (void)sizeof (({
3387 int var;
3388 /* This shouldn't trigger a segfault, either the argument
3389 registers need to be set up and the asm emitted despite
3390 this being in an unevaluated context, or both the argument
3391 setup _and_ the asm emission need to be suppressed. The latter
3392 is better. Disabling asm code gen when suppression is on
3393 also fixes the above trace_console bug, but that came earlier
3394 than asm suppression. */
3395 asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
3396 var;
3397 }));
3400 void test_asm_call(void)
3402 #if defined __x86_64__ && !defined _WIN64
3403 static char str[] = "PATH";
3404 char *s;
3405 /* This tests if a reference to an undefined symbol from an asm
3406 block, which isn't otherwise referenced in this file, is correctly
3407 regarded as global symbol, so that it's resolved by other object files
3408 or libraries. We chose getenv here, which isn't used anywhere else
3409 in this file. (If we used e.g. printf, which is used we already
3410 would have a global symbol entry, not triggering the bug which is
3411 tested here). */
3412 /* two pushes so stack remains aligned */
3413 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
3414 #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) && !defined(__APPLE__)
3415 "call getenv@plt;"
3416 #elif defined(__APPLE__)
3417 "call _getenv;"
3418 #else
3419 "call getenv;"
3420 #endif
3421 "pop %%rdi; pop %%rdi"
3422 : "=a" (s) : "r" (str));
3423 printf("asmd: %s\n", s);
3424 #endif
3427 #if defined __x86_64__
3428 # define RX "(%rip)"
3429 #else
3430 # define RX
3431 #endif
3433 void asm_dot_test(void)
3435 #ifndef __APPLE__
3436 int x;
3437 for (x = 1;; ++x) {
3438 int r = x;
3439 switch (x) {
3440 case 1:
3441 asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
3442 case 2:
3443 #ifndef __clang__
3444 /* clangs internal assembler is broken */
3445 asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
3446 #else
3447 asm(".text; mov $123, %eax; jmp p0");
3448 #endif
3449 case 3:
3450 #if !defined(_WIN32) && !defined(__clang__)
3451 asm(".pushsection \".data\"; Y=.; .int 999; X=Y; .int 456; X=.-4; .popsection");
3452 #else
3453 asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4; .text");
3454 #endif
3455 asm(".text; mov X"RX",%eax; jmp p0");
3456 case 4:
3457 #ifdef __clang__
3458 /* Bah! Clang! Doesn't want to redefine 'X' */
3459 asm(".text; mov $789,%eax; jmp p0");
3460 #else
3461 #ifndef _WIN32
3462 asm(".data; X=.; .int 789; Y=.; .int 999; .previous");
3463 #else
3464 asm(".data; X=.; .int 789; Y=.; .int 999; .text");
3465 #endif
3466 asm(".text; mov X"RX",%eax; X=Y; jmp p0");
3467 #endif
3468 case 0:
3469 asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
3471 if (r == x)
3472 break;
3473 printf("asm_dot_test %d: %d\n", x, r);
3475 #endif
3478 void asm_test(void)
3480 char buf[128];
3481 unsigned int val, val2;
3482 struct struct123 s1;
3483 struct struct1231 s2 = { (unsigned long)&s1 };
3484 /* Hide the outer base_func, but check later that the inline
3485 asm block gets the outer one. */
3486 int base_func = 42;
3487 void override_func3 (void);
3488 unsigned long asmret;
3489 #ifdef BOOL_ISOC99
3490 _Bool somebool;
3491 #endif
3492 register int regvar asm("%esi");
3494 // parse 0x1E-1 as 3 tokens in asm mode
3495 asm volatile ("mov $0x1E-1,%eax");
3497 /* test the no operand case */
3498 asm volatile ("xorl %eax, %eax");
3500 memcpy1(buf, "hello", 6);
3501 strncat1(buf, " worldXXXXX", 3);
3502 printf("%s\n", buf);
3504 memcpy2(buf, "hello", 6);
3505 strncat2(buf, " worldXXXXX", 3);
3506 printf("%s\n", buf);
3508 /* 'A' constraint test */
3509 printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
3510 printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
3512 s1.a = 42;
3513 s1.b = 43;
3514 printf("mconstraint: %d", mconstraint_test(&s2));
3515 printf(" %d %d\n", s1.a, s1.b);
3516 other_constraints_test();
3517 set = 0xff;
3518 sigdelset1(&set, 2);
3519 sigaddset1(&set, 16);
3520 /* NOTE: we test here if C labels are correctly restored after the
3521 asm statement */
3522 goto label1;
3523 label2:
3524 __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
3525 printf("set=0x%x\n", set);
3526 val = 0x01020304;
3527 #ifndef __APPLE__
3528 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
3529 #endif
3530 #ifndef _WIN32
3531 #ifndef __APPLE__
3532 override_func1();
3533 override_func2();
3534 /* The base_func ref from the following inline asm should find
3535 the global one, not the local decl from this function. */
3536 asm volatile(".weak override_func3\n.set override_func3, base_func");
3537 override_func3();
3538 printf("asmstr: %s\n", get_asm_string());
3539 asm_local_label_diff();
3540 #endif
3541 asm_local_statics();
3542 #endif
3543 #ifndef __clang__
3544 /* clang can't deal with the type change */
3545 /* Check that we can also load structs of appropriate layout
3546 into registers. */
3547 asm volatile("" : "=r" (asmret) : "0"(s2));
3548 if (asmret != s2.addr)
3549 printf("asmstr: failed\n");
3550 #endif
3551 #ifdef BOOL_ISOC99
3552 /* Check that the typesize correctly sets the register size to
3553 8 bit. */
3554 asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
3555 if (!somebool)
3556 printf("asmbool: failed\n");
3557 #endif
3558 val = 43;
3559 fancy_copy (&val, &val2);
3560 printf ("fancycpy(%d)=%d\n", val, val2);
3561 val = 44;
3562 fancy_copy2 (&val, &val2);
3563 printf ("fancycpy2(%d)=%d\n", val, val2);
3564 asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
3565 printf ("regvar=%x\n", regvar);
3566 test_high_clobbers();
3567 trace_console(8, 8);
3568 test_asm_dead_code();
3569 test_asm_call();
3570 asm_dot_test();
3571 return;
3572 label1:
3573 goto label2;
3576 #else
3578 void asm_test(void)
3582 #endif
3584 #define COMPAT_TYPE(type1, type2) \
3586 printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
3587 __builtin_types_compatible_p (type1, type2));\
3590 int constant_p_var;
3592 void builtin_test(void)
3594 short s;
3595 int i;
3596 long long ll;
3597 #if GCC_MAJOR >= 3
3598 COMPAT_TYPE(int, int);
3599 COMPAT_TYPE(int, unsigned int);
3600 COMPAT_TYPE(int, char);
3601 COMPAT_TYPE(int, const int);
3602 COMPAT_TYPE(int, volatile int);
3603 COMPAT_TYPE(int *, int *);
3604 COMPAT_TYPE(int *, void *);
3605 COMPAT_TYPE(int *, const int *);
3606 COMPAT_TYPE(char *, unsigned char *);
3607 COMPAT_TYPE(char *, signed char *);
3608 COMPAT_TYPE(char *, char *);
3609 /* space is needed because tcc preprocessor introduces a space between each token */
3610 COMPAT_TYPE(char * *, void *);
3611 #endif
3612 printf("res1 = %d\n", __builtin_constant_p(1));
3613 printf("res2 = %d\n", __builtin_constant_p(1 + 2));
3614 printf("res3 = %d\n", __builtin_constant_p(&constant_p_var));
3615 printf("res4 = %d\n", __builtin_constant_p(constant_p_var));
3616 printf("res5 = %d\n", __builtin_constant_p(100000 / constant_p_var));
3617 #ifdef __clang__
3618 /* clang doesn't regard this as constant expression */
3619 printf("res6 = 1\n");
3620 #else
3621 printf("res6 = %d\n", __builtin_constant_p(i && 0));
3622 #endif
3623 printf("res7 = %d\n", __builtin_constant_p(i && 1));
3624 #ifdef __clang__
3625 /* clang doesn't regard this as constant expression */
3626 printf("res8 = 1\n");
3627 #else
3628 printf("res8 = %d\n", __builtin_constant_p(i && 0 ? i : 34));
3629 #endif
3630 s = 1;
3631 ll = 2;
3632 i = __builtin_choose_expr (1 != 0, ll, s);
3633 printf("bce: %d\n", i);
3634 i = __builtin_choose_expr (1 != 1, ll, s);
3635 printf("bce: %d\n", i);
3636 i = sizeof (__builtin_choose_expr (1, ll, s));
3637 printf("bce: %d\n", i);
3638 i = sizeof (__builtin_choose_expr (0, ll, s));
3639 printf("bce: %d\n", i);
3641 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
3644 #ifdef _WIN32
3645 void weak_test(void) {}
3646 #else
3647 extern int __attribute__((weak)) weak_f1(void);
3648 extern int __attribute__((weak)) weak_f2(void);
3649 extern int weak_f3(void);
3650 extern int __attribute__((weak)) weak_v1;
3651 extern int __attribute__((weak)) weak_v2;
3652 extern int weak_v3;
3654 extern int (*weak_fpa)() __attribute__((weak));
3655 extern int __attribute__((weak)) (*weak_fpb)();
3656 extern __attribute__((weak)) int (*weak_fpc)();
3658 extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
3659 extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ;
3660 extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
3661 extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak));
3662 extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ;
3663 extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
3665 #ifndef __clang__
3666 static const size_t dummy = 0;
3667 extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy")));
3668 extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2;
3669 extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3;
3670 #endif
3672 int some_lib_func(void);
3673 int dummy_impl_of_slf(void) { return 444; }
3674 #ifndef __clang__
3675 int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf")));
3676 #endif
3678 int weak_toolate() __attribute__((weak));
3679 int weak_toolate() { return 0; }
3681 void __attribute__((weak)) weak_test(void)
3683 printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
3684 printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123);
3685 printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123);
3686 printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123);
3687 printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123);
3688 printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123);
3690 printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
3691 printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
3692 printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
3694 printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
3695 printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
3696 printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
3697 printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
3698 printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
3699 printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
3700 #ifdef __clang__
3701 printf("some_lib_func=444\n");
3702 #else
3703 printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
3704 #endif
3707 int __attribute__((weak)) weak_f2() { return 222; }
3708 int __attribute__((weak)) weak_f3() { return 333; }
3709 int __attribute__((weak)) weak_v2 = 222;
3710 int __attribute__((weak)) weak_v3 = 333;
3711 #endif
3713 void const_func(const int a)
3717 void const_warn_test(void)
3719 const_func(1);
3722 struct condstruct {
3723 int i;
3726 int getme (struct condstruct *s, int i)
3728 int i1 = (i == 0 ? 0 : s)->i;
3729 int i2 = (i == 0 ? s : 0)->i;
3730 int i3 = (i == 0 ? (void*)0 : s)->i;
3731 int i4 = (i == 0 ? s : (void*)0)->i;
3732 return i1 + i2 + i3 + i4;
3735 struct global_data
3737 int a[40];
3738 int *b[40];
3741 struct global_data global_data;
3743 int global_data_getstuff (int *, int);
3745 void global_data_callit (int i)
3747 *global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
3750 int global_data_getstuff (int *p, int i)
3752 return *p + i;
3755 void global_data_test (void)
3757 global_data.a[0] = 42;
3758 global_data.b[0] = &global_data.a[0];
3759 global_data_callit (0);
3760 printf ("%d\n", global_data.a[0]);
3763 struct cmpcmpS
3765 unsigned char fill : 3;
3766 unsigned char b1 : 1;
3767 unsigned char b2 : 1;
3768 unsigned char fill2 : 3;
3771 int glob1, glob2, glob3;
3773 void compare_comparisons (struct cmpcmpS *s)
3775 if (s->b1 != (glob1 == glob2)
3776 || (s->b2 != (glob1 == glob3)))
3777 printf ("comparing comparisons broken\n");
3780 void cmp_comparison_test(void)
3782 struct cmpcmpS s;
3783 s.b1 = 1;
3784 glob1 = 42; glob2 = 42;
3785 s.b2 = 0;
3786 glob3 = 43;
3787 compare_comparisons (&s);
3790 int fcompare (double a, double b, int code)
3792 switch (code) {
3793 case 0: return a == b;
3794 case 1: return a != b;
3795 case 2: return a < b;
3796 case 3: return a >= b;
3797 case 4: return a > b;
3798 case 5: return a <= b;
3800 return 0;
3803 void math_cmp_test(void)
3805 double nan = 0.0/0.0;
3806 double one = 1.0;
3807 double two = 2.0;
3808 int comp = 0;
3809 int v;
3810 #define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
3812 /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
3813 And it does this in various ways so that all code generation paths
3814 are checked (generating inverted tests, or non-inverted tests, or
3815 producing a 0/1 value without jumps (that's done in the fcompare
3816 function). */
3817 #define FCMP(a,b,op,iop,code) \
3818 if (fcompare (a,b,code)) \
3819 bug (a,b,op,iop,1); \
3820 if (a op b) \
3821 bug (a,b,op,iop,2); \
3822 if (a iop b) \
3824 else \
3825 bug (a,b,op,iop,3); \
3826 if ((a op b) || comp) \
3827 bug (a,b,op,iop,4); \
3828 if ((a iop b) || comp) \
3830 else \
3831 bug (a,b,op,iop,5); \
3832 if (v = !(a op b), !v) bug(a,b,op,iop,7);
3834 /* Equality tests. */
3835 FCMP(nan, nan, ==, !=, 0);
3836 FCMP(one, two, ==, !=, 0);
3837 FCMP(one, one, !=, ==, 1);
3838 /* Non-equality is a bit special. */
3839 if (!fcompare (nan, nan, 1))
3840 bug (nan, nan, !=, ==, 6);
3842 /* Relational tests on numbers. */
3843 FCMP(two, one, <, >=, 2);
3844 FCMP(one, two, >=, <, 3);
3845 FCMP(one, two, >, <=, 4);
3846 FCMP(two, one, <=, >, 5);
3848 /* Relational tests on NaNs. Note that the inverse op here is
3849 always !=, there's no operator in C that is equivalent to !(a < b),
3850 when NaNs are involved, same for the other relational ops. */
3851 FCMP(nan, nan, <, !=, 2);
3852 FCMP(nan, nan, >=, !=, 3);
3853 FCMP(nan, nan, >, !=, 4);
3854 FCMP(nan, nan, <=, !=, 5);
3857 double get100 () { return 100.0; }
3859 void callsave_test(void)
3861 #if defined __i386__ || defined __x86_64__ || defined __arm__
3862 int i, s; double *d; double t;
3863 s = sizeof (double);
3864 printf ("callsavetest: %d\n", s);
3865 d = alloca (sizeof(double));
3866 d[0] = 10.0;
3867 /* x86-64 had a bug were the next call to get100 would evict
3868 the lvalue &d[0] as VT_LLOCAL, and the reload would be done
3869 in int type, not pointer type. When alloca returns a pointer
3870 with the high 32 bit set (which is likely on x86-64) the access
3871 generates a segfault. */
3872 i = d[0] > get100 ();
3873 printf ("%d\n", i);
3874 #endif
3878 void bfa3(ptrdiff_t str_offset)
3880 printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
3882 void bfa2(ptrdiff_t str_offset)
3884 printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
3885 bfa3(str_offset);
3887 void bfa1(ptrdiff_t str_offset)
3889 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
3890 bfa2(str_offset);
3893 void builtin_frame_address_test(void)
3895 /* builtin_frame_address fails on ARM with gcc which make test3 fail */
3896 #ifndef __arm__
3897 char str[] = "__builtin_frame_address";
3898 char *fp0 = __builtin_frame_address(0);
3900 printf("str: %s\n", str);
3901 #ifndef __riscv
3902 bfa1(str-fp0);
3903 #endif
3904 #endif
3907 char via_volatile (char i)
3909 char volatile vi;
3910 vi = i;
3911 return vi;
3914 void volatile_test(void)
3916 if (via_volatile (42) != 42)
3917 printf (" broken\n");
3918 else
3919 printf (" ok\n");
3922 struct __attribute__((__packed__)) Spacked {
3923 char a;
3924 short b;
3925 int c;
3927 struct Spacked spacked;
3928 typedef struct __attribute__((__packed__)) {
3929 char a;
3930 short b;
3931 int c;
3932 } Spacked2;
3933 Spacked2 spacked2;
3934 typedef struct Spacked3_s {
3935 char a;
3936 short b;
3937 int c;
3938 } __attribute__((__packed__)) Spacked3;
3939 Spacked3 spacked3;
3940 struct gate_struct64 {
3941 unsigned short offset_low;
3942 unsigned short segment;
3943 unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
3944 unsigned short offset_middle;
3945 unsigned offset_high;
3946 unsigned zero1;
3947 } __attribute__((packed));
3948 typedef struct gate_struct64 gate_desc;
3949 gate_desc a_gate_desc;
3950 void attrib_test(void)
3952 #ifndef _WIN32
3953 printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
3954 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
3955 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
3956 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
3957 #endif
3959 extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
3960 strange_attrib_placement (void);
3962 void * __attribute__((__unused__)) get_void_ptr (void *a)
3964 return a;
3967 /* This part checks for a bug in TOK_GET (used for inline expansion),
3968 where the large long long constant left the the high bits set for
3969 the integer constant token. */
3970 static inline
3971 int __get_order(unsigned long long size)
3973 int order;
3974 size -= 0xffff880000000000ULL; // this const left high bits set in the token
3976 struct S { int i : 1; } s; // constructed for this '1'
3978 order = size;
3979 return order;
3982 /* This just forces the above inline function to be actually emitted. */
3983 int force_get_order(unsigned long s)
3985 return __get_order(s);
3988 #define pv(m) printf(sizeof (s->m + 0) == 8 ? "%016llx\n" : "%02x\n", s->m)
3990 /* Test failed when using bounds checking */
3991 void bounds_check1_test (void)
3993 struct s {
3994 int x;
3995 long long y;
3996 } _s, *s = &_s;
3997 s->x = 10;
3998 s->y = 20;
3999 pv(x);
4000 pv(y);
4003 /* gcc 2.95.3 does not handle correctly CR in strings or after strays */
4004 #define CORRECT_CR_HANDLING
4006 /* deprecated and no longer supported in gcc 3.3 */
4007 #ifdef __TINYC__
4008 # define ACCEPT_CR_IN_STRINGS
4009 #endif
4011 /* keep this as the last test because GCC messes up line-numbers
4012 with the ^L^K^M characters below */
4013 void whitespace_test(void)
4015 char *str;
4017 \f\v #if 1
4018 pri\
4019 ntf("whitspace:\n");\f\v
4020 #endif
4021 pf("N=%d\n", 2);
4023 #ifdef CORRECT_CR_HANDLING
4024 pri\
4025 ntf("aaa=%d\n", 3);
4026 #endif
4028 pri\
4030 ntf("min=%d\n", 4);
4032 #ifdef ACCEPT_CR_IN_STRINGS
4033 printf("len1=%d\n", strlen("
4034 "));
4035 #ifdef CORRECT_CR_HANDLING
4036 str = "
4038 printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
4039 #endif
4040 printf("len1=%d\n", strlen(" a
4041 "));
4042 #else
4043 printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n");
4044 #endif /* ACCEPT_CR_IN_STRINGS */
4046 #ifdef __LINE__
4047 printf("__LINE__ defined\n");
4048 #endif
4050 #if 0
4051 /* wrong with GCC */
4052 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4053 #line 1111
4054 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4055 #line 2222 "test"
4056 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
4057 #endif
4060 #define RUN(test) puts("---- " #test " ----"), test(), puts("")
4062 int main(int argc, char **argv)
4064 RUN(whitespace_test);
4065 RUN(macro_test);
4066 RUN(recursive_macro_test);
4067 RUN(string_test);
4068 RUN(expr_test);
4069 RUN(scope_test);
4070 RUN(scope2_test);
4071 RUN(forward_test);
4072 RUN(funcptr_test);
4073 RUN(if_test);
4074 RUN(loop_test);
4075 RUN(switch_test);
4076 RUN(goto_test);
4077 RUN(enum_test);
4078 RUN(typedef_test);
4079 RUN(struct_test);
4080 RUN(array_test);
4081 RUN(expr_ptr_test);
4082 RUN(bool_test);
4083 RUN(optimize_out_test);
4084 RUN(expr2_test);
4085 RUN(constant_expr_test);
4086 RUN(expr_cmp_test);
4087 RUN(char_short_test);
4088 RUN(init_test);
4089 RUN(compound_literal_test);
4090 RUN(kr_test);
4091 RUN(struct_assign_test);
4092 RUN(cast_test);
4093 RUN(bitfield_test);
4094 RUN(c99_bool_test);
4095 RUN(float_test);
4096 RUN(longlong_test);
4097 RUN(manyarg_test);
4098 RUN(stdarg_test);
4099 RUN(relocation_test);
4100 RUN(old_style_function_test);
4101 RUN(alloca_test);
4102 RUN(c99_vla_test);
4103 RUN(sizeof_test);
4104 RUN(typeof_test);
4105 RUN(statement_expr_test);
4106 RUN(local_label_test);
4107 RUN(asm_test);
4108 RUN(builtin_test);
4109 RUN(weak_test);
4110 RUN(global_data_test);
4111 RUN(cmp_comparison_test);
4112 RUN(math_cmp_test);
4113 RUN(callsave_test);
4114 RUN(builtin_frame_address_test);
4115 RUN(volatile_test);
4116 RUN(attrib_test);
4117 RUN(bounds_check1_test);
4119 return 0;