source: EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 91.7 KB
Line 
1/*
2 * TCC auto test program
3 */
4#include "config.h"
5
6#if GCC_MAJOR >= 3
7
8/* Unfortunately, gcc version < 3 does not handle that! */
9#define ALL_ISOC99
10
11/* only gcc 3 handles _Bool correctly */
12#define BOOL_ISOC99
13
14/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
15#define CORRECT_CR_HANDLING
16
17#endif
18
19#if defined(_WIN32)
20#define LONG_LONG_FORMAT "%lld"
21#define ULONG_LONG_FORMAT "%llu"
22#else
23#define LONG_LONG_FORMAT "%Ld"
24#define ULONG_LONG_FORMAT "%Lu"
25#endif
26
27// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
28#if defined(_WIN32) && defined(__GNUC__)
29#define LONG_DOUBLE double
30#define LONG_DOUBLE_LITERAL(x) x
31#else
32#define LONG_DOUBLE long double
33#define LONG_DOUBLE_LITERAL(x) x ## L
34#endif
35
36/* deprecated and no longer supported in gcc 3.3 */
37//#define ACCEPT_CR_IN_STRINGS
38
39/* __VA_ARGS__ and __func__ support */
40#define C99_MACROS
41
42/* test various include syntaxes */
43
44#define TCCLIB_INC <tcclib.h>
45#define TCCLIB_INC1 <tcclib
46#define TCCLIB_INC2 h>
47#define TCCLIB_INC3 "tcclib.h"
48
49#include TCCLIB_INC
50
51#include TCCLIB_INC1.TCCLIB_INC2
52
53#include TCCLIB_INC1.h>
54
55#include TCCLIB_INC3
56
57#include <tcclib.h>
58
59#include "tcclib.h"
60
61#include "tcctest.h"
62
63/* Test two more ways to include a file named like a pp-number */
64#define INC(name) <tests/name.h>
65#define funnyname 42test.h
66#define incdir tests/
67#define incname < incdir funnyname >
68#define __stringify(x) #x
69#define stringify(x) __stringify(x)
70#include INC(42test)
71#include incname
72#include stringify(funnyname)
73
74void intdiv_test();
75void string_test();
76void expr_test();
77void macro_test();
78void recursive_macro_test();
79void scope_test();
80void forward_test();
81void funcptr_test();
82void loop_test();
83void switch_test();
84void goto_test();
85void enum_test();
86void typedef_test();
87void struct_test();
88void array_test();
89void expr_ptr_test();
90void bool_test();
91void optimize_out();
92void expr2_test();
93void constant_expr_test();
94void expr_cmp_test();
95void char_short_test();
96void init_test(void);
97void compound_literal_test(void);
98int kr_test();
99void struct_assign_test(void);
100void cast_test(void);
101void bitfield_test(void);
102void c99_bool_test(void);
103void float_test(void);
104void longlong_test(void);
105void manyarg_test(void);
106void stdarg_test(void);
107void whitespace_test(void);
108void relocation_test(void);
109void old_style_function(void);
110void alloca_test(void);
111void c99_vla_test(int size1, int size2);
112void sizeof_test(void);
113void typeof_test(void);
114void local_label_test(void);
115void statement_expr_test(void);
116void asm_test(void);
117void builtin_test(void);
118void weak_test(void);
119void global_data_test(void);
120void cmp_comparison_test(void);
121void math_cmp_test(void);
122void callsave_test(void);
123void builtin_frame_address_test(void);
124void attrib_test(void);
125
126int fib(int n);
127void num(int n);
128void forward_ref(void);
129int isid(int c);
130
131/* Line joining happens before tokenization, so the following
132 must be parsed as ellipsis. */
133void funny_line_continuation (int, ..\
134. );
135
136char via_volatile (char);
137
138#define A 2
139#define N 1234 + A
140#define pf printf
141#define M1(a, b) (a) + (b)
142
143#define str\
144(s) # s
145#define glue(a, b) a ## b
146#define xglue(a, b) glue(a, b)
147#define HIGHLOW "hello"
148#define LOW LOW ", world"
149
150static int onetwothree = 123;
151#define onetwothree4 onetwothree
152#define onetwothree xglue(onetwothree,4)
153
154#define min(a, b) ((a) < (b) ? (a) : (b))
155
156#ifdef C99_MACROS
157#define dprintf(level,...) printf(__VA_ARGS__)
158#endif
159
160/* gcc vararg macros */
161#define dprintf1(level, fmt, args...) printf(fmt, ## args)
162
163#define MACRO_NOARGS()
164
165#define AAA 3
166#undef AAA
167#define AAA 4
168
169#if 1
170#define B3 1
171#elif 1
172#define B3 2
173#elif 0
174#define B3 3
175#else
176#define B3 4
177#endif
178
179#ifdef __TINYC__
180/* We try to handle this syntax. Make at least sure it doesn't segfault. */
181char invalid_function_def()[] {}
182#endif
183
184#define __INT64_C(c) c ## LL
185#define INT64_MIN (-__INT64_C(9223372036854775807)-1)
186
187int qq(int x)
188{
189 return x + 40;
190}
191#define qq(x) x
192
193#define spin_lock(lock) do { } while (0)
194#define wq_spin_lock spin_lock
195#define TEST2() wq_spin_lock(a)
196
197#define UINT_MAX ((unsigned) -1)
198
199void intdiv_test(void)
200{
201 printf("18/21=%u\n", 18/21);
202 printf("18%%21=%u\n", 18%21);
203 printf("41/21=%u\n", 41/21);
204 printf("41%%21=%u\n", 41%21);
205 printf("42/21=%u\n", 42/21);
206 printf("42%%21=%u\n", 42%21);
207 printf("43/21=%u\n", 43/21);
208 printf("43%%21=%u\n", 43%21);
209 printf("126/21=%u\n", 126/21);
210 printf("126%%21=%u\n", 126%21);
211 printf("131/21=%u\n", 131/21);
212 printf("131%%21=%u\n", 131%21);
213 printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
214 printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
215
216 printf("18/-21=%u\n", 18/-21);
217 printf("18%%-21=%u\n", 18%-21);
218 printf("41/-21=%u\n", 41/-21);
219 printf("41%%-21=%u\n", 41%-21);
220 printf("42/-21=%u\n", 42/-21);
221 printf("42%%-21=%u\n", 42%-21);
222 printf("43/-21=%u\n", 43/-21);
223 printf("43%%-21=%u\n", 43%-21);
224 printf("126/-21=%u\n", 126/-21);
225 printf("126%%-21=%u\n", 126%-21);
226 printf("131/-21=%u\n", 131/-21);
227 printf("131%%-21=%u\n", 131%-21);
228 printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
229 printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
230
231 printf("-18/21=%u\n", -18/21);
232 printf("-18%%21=%u\n", -18%21);
233 printf("-41/21=%u\n", -41/21);
234 printf("-41%%21=%u\n", -41%21);
235 printf("-42/21=%u\n", -42/21);
236 printf("-42%%21=%u\n", -42%21);
237 printf("-43/21=%u\n", -43/21);
238 printf("-43%%21=%u\n", -43%21);
239 printf("-126/21=%u\n", -126/21);
240 printf("-126%%21=%u\n", -126%21);
241 printf("-131/21=%u\n", -131/21);
242 printf("-131%%21=%u\n", -131%21);
243 printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
244 printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
245
246 printf("-18/-21=%u\n", -18/-21);
247 printf("-18%%-21=%u\n", -18%-21);
248 printf("-41/-21=%u\n", -41/-21);
249 printf("-41%%-21=%u\n", -41%-21);
250 printf("-42/-21=%u\n", -42/-21);
251 printf("-42%%-21=%u\n", -42%-21);
252 printf("-43/-21=%u\n", -43/-21);
253 printf("-43%%-21=%u\n", -43%-21);
254 printf("-126/-21=%u\n", -126/-21);
255 printf("-126%%-21=%u\n", -126%-21);
256 printf("-131/-21=%u\n", -131/-21);
257 printf("-131%%-21=%u\n", -131%-21);
258 printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
259 printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
260}
261
262void macro_test(void)
263{
264 printf("macro:\n");
265
266
267 pf("N=%d\n", N);
268 printf("aaa=%d\n", AAA);
269
270 printf("min=%d\n", min(1, min(2, -1)));
271
272 printf("s1=%s\n", glue(HIGH, LOW));
273 printf("s2=%s\n", xglue(HIGH, LOW));
274 printf("s3=%s\n", str("c"));
275 printf("s4=%s\n", str(a1));
276 printf("B3=%d\n", B3);
277
278 printf("onetwothree=%d\n", onetwothree);
279
280#ifdef A
281 printf("A defined\n");
282#endif
283#ifdef B
284 printf("B defined\n");
285#endif
286#ifdef A
287 printf("A defined\n");
288#else
289 printf("A not defined\n");
290#endif
291#ifdef B
292 printf("B defined\n");
293#else
294 printf("B not defined\n");
295#endif
296
297#ifdef A
298 printf("A defined\n");
299#ifdef B
300 printf("B1 defined\n");
301#else
302 printf("B1 not defined\n");
303#endif
304#else
305 printf("A not defined\n");
306#ifdef B
307 printf("B2 defined\n");
308#else
309 printf("B2 not defined\n");
310#endif
311#endif
312
313#if 1+1
314 printf("test true1\n");
315#endif
316#if 0
317 printf("test true2\n");
318#endif
319#if 1-1
320 printf("test true3\n");
321#endif
322#if defined(A)
323 printf("test trueA\n");
324#endif
325#if defined(B)
326 printf("test trueB\n");
327#endif
328
329#if 0
330 printf("test 0\n");
331#elif 0
332 printf("test 1\n");
333#elif 2
334 printf("test 2\n");
335#else
336 printf("test 3\n");
337#endif
338
339 MACRO_NOARGS();
340
341#ifdef __LINE__
342 printf("__LINE__ defined\n");
343#endif
344
345 printf("__LINE__=%d __FILE__=%s\n",
346 __LINE__, __FILE__);
347#if 0
348#line 200
349 printf("__LINE__=%d __FILE__=%s\n",
350 __LINE__, __FILE__);
351#line 203 "test"
352 printf("__LINE__=%d __FILE__=%s\n",
353 __LINE__, __FILE__);
354#line 227 "tcctest.c"
355#endif
356
357 /* not strictly preprocessor, but we test it there */
358#ifdef C99_MACROS
359 printf("__func__ = %s\n", __func__);
360 dprintf(1, "vaarg=%d\n", 1);
361#endif
362 dprintf1(1, "vaarg1\n");
363 dprintf1(1, "vaarg1=%d\n", 2);
364 dprintf1(1, "vaarg1=%d %d\n", 1, 2);
365
366 /* gcc extension */
367 printf("func='%s'\n", __FUNCTION__);
368
369 /* complicated macros in glibc */
370 printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
371 {
372 int a;
373 a = 1;
374 glue(a+, +);
375 printf("a=%d\n", a);
376 glue(a <, <= 2);
377 printf("a=%d\n", a);
378 }
379
380 /* macro function with argument outside the macro string */
381#define MF_s MF_hello
382#define MF_hello(msg) printf("%s\n",msg)
383
384#define MF_t printf("tralala\n"); MF_hello
385
386 MF_s("hi");
387 MF_t("hi");
388
389 /* test macro substitution inside args (should not eat stream) */
390 printf("qq=%d\n", qq(qq)(2));
391
392 /* test zero argument case. NOTE: gcc 2.95.x does not accept a
393 null argument without a space. gcc 3.2 fixes that. */
394
395#define qq1(x) 1
396 printf("qq1=%d\n", qq1( ));
397
398 /* comment with stray handling *\
399/
400 /* this is a valid *\/ comment */
401 /* this is a valid comment *\*/
402 // this is a valid\
403comment
404
405 /* test function macro substitution when the function name is
406 substituted */
407 TEST2();
408
409 /* And again when the name and parentheses are separated by a
410 comment. */
411 TEST2 /* the comment */ ();
412
413 printf("%s\n", get_basefile_from_header());
414 printf("%s\n", __BASE_FILE__);
415 printf("%s\n", get_file_from_header());
416 printf("%s\n", __FILE__);
417
418 /* Check that funnily named include was in fact included */
419 have_included_42test_h = 1;
420 have_included_42test_h_second = 1;
421 have_included_42test_h_third = 1;
422}
423
424
425static void print_num(char *fn, int line, int num) {
426 printf("fn %s, line %d, num %d\n", fn, line, num);
427}
428
429void recursive_macro_test(void)
430{
431
432#define ELF32_ST_TYPE(val) ((val) & 0xf)
433#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
434#define STB_WEAK 2 /* Weak symbol */
435#define ELFW(type) ELF##32##_##type
436 printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
437
438#define WRAP(x) x
439
440#define print_num(x) print_num(__FILE__,__LINE__,x)
441 print_num(123);
442 WRAP(print_num(123));
443 WRAP(WRAP(print_num(123)));
444
445static struct recursive_macro { int rm_field; } G;
446#define rm_field (G.rm_field)
447 printf("rm_field = %d\n", rm_field);
448 printf("rm_field = %d\n", WRAP(rm_field));
449 WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field))));
450}
451
452int op(a,b)
453{
454 return a / b;
455}
456
457int ret(a)
458{
459 if (a == 2)
460 return 1;
461 if (a == 3)
462 return 2;
463 return 0;
464}
465
466void ps(const char *s)
467{
468 int c;
469 while (1) {
470 c = *s;
471 if (c == 0)
472 break;
473 printf("%c", c);
474 s++;
475 }
476}
477
478const char foo1_string[] = "\
479bar\n\
480test\14\
4811";
482
483void string_test()
484{
485 unsigned int b;
486 printf("string:\n");
487 printf("\141\1423\143\n");/* dezdez test */
488 printf("\x41\x42\x43\x3a\n");
489 printf("c=%c\n", 'r');
490 printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c');
491 printf("foo1_string='%s'\n", foo1_string);
492#if 0
493 printf("wstring=%S\n", L"abc");
494 printf("wstring=%S\n", L"abc" L"def" "ghi");
495 printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
496 printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff');
497#endif
498 ps("test\n");
499 b = 32;
500 while ((b = b + 1) < 96) {
501 printf("%c", b);
502 }
503 printf("\n");
504 printf("fib=%d\n", fib(33));
505 b = 262144;
506 while (b != 0x80000000) {
507 num(b);
508 b = b * 2;
509 }
510}
511
512void loop_test()
513{
514 int i;
515 i = 0;
516 while (i < 10)
517 printf("%d", i++);
518 printf("\n");
519 for(i = 0; i < 10;i++)
520 printf("%d", i);
521 printf("\n");
522 i = 0;
523 do {
524 printf("%d", i++);
525 } while (i < 10);
526 printf("\n");
527
528 char count = 123;
529 /* c99 for loop init test */
530 for (size_t count = 1; count < 3; count++)
531 printf("count=%d\n", count);
532 printf("count = %d\n", count);
533
534 /* break/continue tests */
535 i = 0;
536 while (1) {
537 if (i == 6)
538 break;
539 i++;
540 if (i == 3)
541 continue;
542 printf("%d", i);
543 }
544 printf("\n");
545
546 /* break/continue tests */
547 i = 0;
548 do {
549 if (i == 6)
550 break;
551 i++;
552 if (i == 3)
553 continue;
554 printf("%d", i);
555 } while(1);
556 printf("\n");
557
558 for(i = 0;i < 10;i++) {
559 if (i == 3)
560 continue;
561 printf("%d", i);
562 }
563 printf("\n");
564}
565
566typedef int typedef_and_label;
567
568void goto_test()
569{
570 int i;
571 static void *label_table[3] = { &&label1, &&label2, &&label3 };
572
573 printf("goto:\n");
574 i = 0;
575 /* This needs to parse as label, not as start of decl. */
576 typedef_and_label:
577 s_loop:
578 if (i >= 10)
579 goto s_end;
580 printf("%d", i);
581 i++;
582 goto s_loop;
583 s_end:
584 printf("\n");
585
586 /* we also test computed gotos (GCC extension) */
587 for(i=0;i<3;i++) {
588 goto *label_table[i];
589 label1:
590 printf("label1\n");
591 goto next;
592 label2:
593 printf("label2\n");
594 goto next;
595 label3:
596 printf("label3\n");
597 next: ;
598 }
599}
600
601enum {
602 E0,
603 E1 = 2,
604 E2 = 4,
605 E3,
606 E4,
607};
608
609enum test {
610 E5 = 1000,
611};
612
613struct S_enum {
614 enum {E6 = 42, E7, E8} e:8;
615};
616
617enum ELong {
618 /* This is either 0 on L32 machines, or a large number
619 on L64 machines. We should be able to store this. */
620 EL_large = ((unsigned long)0xf000 << 31) << 1,
621};
622
623enum { BIASU = -1U<<31 };
624enum { BIASS = -1 << 31 };
625
626static int getint(int i)
627{
628 if (i)
629 return 0;
630 else
631 return (int)(-1U << 31);
632}
633
634void enum_test()
635{
636 enum test b1;
637 /* The following should give no warning */
638 unsigned *p = &b1;
639 struct S_enum s = {E7};
640 printf("enum: %d\n", s.e);
641 printf("enum:\n%d %d %d %d %d %d\n",
642 E0, E1, E2, E3, E4, E5);
643 b1 = 1;
644 printf("b1=%d\n", b1);
645 printf("enum large: %ld\n", EL_large);
646
647 if (getint(0) == BIASU)
648 printf("enum unsigned: ok\n");
649 else
650 printf("enum unsigned: wrong\n");
651 if (getint(0) == BIASS)
652 printf("enum unsigned: ok\n");
653 else
654 printf("enum unsigned: wrong\n");
655}
656
657typedef int *my_ptr;
658
659typedef int mytype1;
660typedef int mytype2;
661
662void typedef_test()
663{
664 my_ptr a;
665 mytype1 mytype2;
666 int b;
667
668 a = &b;
669 *a = 1234;
670 printf("typedef:\n");
671 printf("a=%d\n", *a);
672 mytype2 = 2;
673 printf("mytype2=%d\n", mytype2);
674}
675
676void forward_test()
677{
678 printf("forward:\n");
679 forward_ref();
680 forward_ref();
681}
682
683
684void forward_ref(void)
685{
686 printf("forward ok\n");
687}
688
689typedef struct struct1 {
690 int f1;
691 int f2, f3;
692 union union1 {
693 int v1;
694 int v2;
695 } u;
696 char str[3];
697} struct1;
698
699struct struct2 {
700 int a;
701 char b;
702};
703
704union union2 {
705 int w1;
706 int w2;
707};
708
709struct struct1 st1, st2;
710
711struct empty_mem {
712 /* nothing */ ;
713 int x;
714};
715
716int main(int argc, char **argv)
717{
718 string_test();
719 expr_test();
720 macro_test();
721 recursive_macro_test();
722 scope_test();
723 forward_test();
724 funcptr_test();
725 loop_test();
726 switch_test();
727 goto_test();
728 enum_test();
729 typedef_test();
730 struct_test();
731 array_test();
732 expr_ptr_test();
733 bool_test();
734 optimize_out();
735 expr2_test();
736 constant_expr_test();
737 expr_cmp_test();
738 char_short_test();
739 init_test();
740 compound_literal_test();
741 kr_test();
742 struct_assign_test();
743 cast_test();
744 bitfield_test();
745 c99_bool_test();
746 float_test();
747 longlong_test();
748 manyarg_test();
749 stdarg_test();
750 whitespace_test();
751 relocation_test();
752 old_style_function();
753 alloca_test();
754 c99_vla_test(5, 2);
755 sizeof_test();
756 typeof_test();
757 statement_expr_test();
758 local_label_test();
759 asm_test();
760 builtin_test();
761#ifndef _WIN32
762 weak_test();
763#endif
764 global_data_test();
765 cmp_comparison_test();
766 math_cmp_test();
767 callsave_test();
768 builtin_frame_address_test();
769 intdiv_test();
770 if (via_volatile (42) != 42)
771 printf ("via_volatile broken\n");
772 attrib_test();
773 return 0;
774}
775
776int tab[3];
777int tab2[3][2];
778
779int g;
780
781void f1(g)
782{
783 printf("g1=%d\n", g);
784}
785
786void scope_test()
787{
788 printf("scope:\n");
789 g = 2;
790 f1(1);
791 printf("g2=%d\n", g);
792 {
793 int g;
794 g = 3;
795 printf("g3=%d\n", g);
796 {
797 int g;
798 g = 4;
799 printf("g4=%d\n", g);
800 }
801 }
802 printf("g5=%d\n", g);
803}
804
805void array_test()
806{
807 int i, j, a[4];
808
809 printf("array:\n");
810 printf("sizeof(a) = %d\n", sizeof(a));
811 printf("sizeof(\"a\") = %d\n", sizeof("a"));
812#ifdef C99_MACROS
813 printf("sizeof(__func__) = %d\n", sizeof(__func__));
814#endif
815 printf("sizeof tab %d\n", sizeof(tab));
816 printf("sizeof tab2 %d\n", sizeof tab2);
817 tab[0] = 1;
818 tab[1] = 2;
819 tab[2] = 3;
820 printf("%d %d %d\n", tab[0], tab[1], tab[2]);
821 for(i=0;i<3;i++)
822 for(j=0;j<2;j++)
823 tab2[i][j] = 10 * i + j;
824 for(i=0;i<3*2;i++) {
825 printf(" %3d", ((int *)tab2)[i]);
826 }
827 printf("\n");
828 printf("sizeof(size_t)=%d\n", sizeof(size_t));
829 printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
830}
831
832void expr_test()
833{
834 int a, b;
835 a = 0;
836 printf("%d\n", a += 1);
837 printf("%d\n", a -= 2);
838 printf("%d\n", a *= 31232132);
839 printf("%d\n", a /= 4);
840 printf("%d\n", a %= 20);
841 printf("%d\n", a &= 6);
842 printf("%d\n", a ^= 7);
843 printf("%d\n", a |= 8);
844 printf("%d\n", a >>= 3);
845 printf("%d\n", a <<= 4);
846
847 a = 22321;
848 b = -22321;
849 printf("%d\n", a + 1);
850 printf("%d\n", a - 2);
851 printf("%d\n", a * 312);
852 printf("%d\n", a / 4);
853 printf("%d\n", b / 4);
854 printf("%d\n", (unsigned)b / 4);
855 printf("%d\n", a % 20);
856 printf("%d\n", b % 20);
857 printf("%d\n", (unsigned)b % 20);
858 printf("%d\n", a & 6);
859 printf("%d\n", a ^ 7);
860 printf("%d\n", a | 8);
861 printf("%d\n", a >> 3);
862 printf("%d\n", b >> 3);
863 printf("%d\n", (unsigned)b >> 3);
864 printf("%d\n", a << 4);
865 printf("%d\n", ~a);
866 printf("%d\n", -a);
867 printf("%d\n", +a);
868
869 printf("%d\n", 12 + 1);
870 printf("%d\n", 12 - 2);
871 printf("%d\n", 12 * 312);
872 printf("%d\n", 12 / 4);
873 printf("%d\n", 12 % 20);
874 printf("%d\n", 12 & 6);
875 printf("%d\n", 12 ^ 7);
876 printf("%d\n", 12 | 8);
877 printf("%d\n", 12 >> 2);
878 printf("%d\n", 12 << 4);
879 printf("%d\n", ~12);
880 printf("%d\n", -12);
881 printf("%d\n", +12);
882 printf("%d %d %d %d\n",
883 isid('a'),
884 isid('g'),
885 isid('T'),
886 isid('('));
887}
888
889int isid(int c)
890{
891 return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
892}
893
894/**********************/
895
896int vstack[10], *vstack_ptr;
897
898void vpush(int vt, int vc)
899{
900 *vstack_ptr++ = vt;
901 *vstack_ptr++ = vc;
902}
903
904void vpop(int *ft, int *fc)
905{
906 *fc = *--vstack_ptr;
907 *ft = *--vstack_ptr;
908}
909
910void expr2_test()
911{
912 int a, b;
913
914 printf("expr2:\n");
915 vstack_ptr = vstack;
916 vpush(1432432, 2);
917 vstack_ptr[-2] &= ~0xffffff80;
918 vpop(&a, &b);
919 printf("res= %d %d\n", a, b);
920}
921
922void constant_expr_test()
923{
924 int a;
925 printf("constant_expr:\n");
926 a = 3;
927 printf("%d\n", a * 16);
928 printf("%d\n", a * 1);
929 printf("%d\n", a + 0);
930}
931
932int tab4[10];
933
934void expr_ptr_test()
935{
936 int *p, *q;
937 int i = -1;
938
939 printf("expr_ptr:\n");
940 p = tab4;
941 q = tab4 + 10;
942 printf("diff=%d\n", q - p);
943 p++;
944 printf("inc=%d\n", p - tab4);
945 p--;
946 printf("dec=%d\n", p - tab4);
947 ++p;
948 printf("inc=%d\n", p - tab4);
949 --p;
950 printf("dec=%d\n", p - tab4);
951 printf("add=%d\n", p + 3 - tab4);
952 printf("add=%d\n", 3 + p - tab4);
953
954 /* check if 64bit support is ok */
955 q = p = 0;
956 q += i;
957 printf("%p %p %ld\n", q, p, p-q);
958 printf("%d %d %d %d %d %d\n",
959 p == q, p != q, p < q, p <= q, p >= q, p > q);
960 i = 0xf0000000;
961 p += i;
962 printf("%p %p %ld\n", q, p, p-q);
963 printf("%d %d %d %d %d %d\n",
964 p == q, p != q, p < q, p <= q, p >= q, p > q);
965 p = (int *)((char *)p + 0xf0000000);
966 printf("%p %p %ld\n", q, p, p-q);
967 printf("%d %d %d %d %d %d\n",
968 p == q, p != q, p < q, p <= q, p >= q, p > q);
969 p += 0xf0000000;
970 printf("%p %p %ld\n", q, p, p-q);
971 printf("%d %d %d %d %d %d\n",
972 p == q, p != q, p < q, p <= q, p >= q, p > q);
973 {
974 struct size12 {
975 int i, j, k;
976 };
977 struct size12 s[2], *sp = s;
978 int i, j;
979 sp->i = 42;
980 sp++;
981 j = -1;
982 printf("%d\n", sp[j].i);
983 }
984#ifdef __LP64__
985 i = 1;
986 p = (int*)0x100000000UL + i;
987 i = ((long)p) >> 32;
988 printf("largeptr: %p %d\n", p, i);
989#endif
990}
991
992void expr_cmp_test()
993{
994 int a, b;
995 printf("constant_expr:\n");
996 a = -1;
997 b = 1;
998 printf("%d\n", a == a);
999 printf("%d\n", a != a);
1000
1001 printf("%d\n", a < b);
1002 printf("%d\n", a <= b);
1003 printf("%d\n", a <= a);
1004 printf("%d\n", b >= a);
1005 printf("%d\n", a >= a);
1006 printf("%d\n", b > a);
1007
1008 printf("%d\n", (unsigned)a < b);
1009 printf("%d\n", (unsigned)a <= b);
1010 printf("%d\n", (unsigned)a <= a);
1011 printf("%d\n", (unsigned)b >= a);
1012 printf("%d\n", (unsigned)a >= a);
1013 printf("%d\n", (unsigned)b > a);
1014}
1015
1016struct empty {
1017};
1018
1019struct aligntest1 {
1020 char a[10];
1021};
1022
1023struct aligntest2 {
1024 int a;
1025 char b[10];
1026};
1027
1028struct aligntest3 {
1029 double a, b;
1030};
1031
1032struct aligntest4 {
1033 double a[0];
1034};
1035
1036struct __attribute__((aligned(16))) aligntest5
1037{
1038 int i;
1039};
1040struct aligntest6
1041{
1042 int i;
1043} __attribute__((aligned(16)));
1044struct aligntest7
1045{
1046 int i;
1047};
1048struct aligntest5 altest5[2];
1049struct aligntest6 altest6[2];
1050int pad1;
1051/* altest7 is correctly aligned to 16 bytes also with TCC,
1052 but __alignof__ returns the wrong result (4) because we
1053 can't store the alignment yet when specified on symbols
1054 directly (it's stored in the type so we'd need to make
1055 a copy of it). -- FIXED */
1056struct aligntest7 altest7[2] __attribute__((aligned(16)));
1057
1058struct aligntest8
1059{
1060 int i;
1061} __attribute__((aligned(4096)));
1062
1063struct Large {
1064 unsigned long flags;
1065 union {
1066 void *u1;
1067 int *u2;
1068 };
1069
1070 struct {
1071 union {
1072 unsigned long index;
1073 void *freelist;
1074 };
1075 union {
1076 unsigned long counters;
1077 struct {
1078 int bla;
1079 };
1080 };
1081 };
1082
1083 union {
1084 struct {
1085 long u3;
1086 long u4;
1087 };
1088 void *u5;
1089 struct {
1090 unsigned long compound_head;
1091 unsigned int compound_dtor;
1092 unsigned int compound_order;
1093 };
1094 };
1095} __attribute__((aligned(2 * sizeof(long))));
1096
1097typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
1098
1099struct aligntest9 {
1100 unsigned int buf_nr;
1101 unaligned_u64 start_lba;
1102};
1103
1104struct aligntest10 {
1105 unsigned int buf_nr;
1106 unsigned long long start_lba;
1107};
1108
1109void struct_test()
1110{
1111 struct1 *s;
1112 union union2 u;
1113 struct Large ls;
1114
1115 printf("struct:\n");
1116 printf("sizes: %d %d %d %d\n",
1117 sizeof(struct struct1),
1118 sizeof(struct struct2),
1119 sizeof(union union1),
1120 sizeof(union union2));
1121 printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
1122 st1.f1 = 1;
1123 st1.f2 = 2;
1124 st1.f3 = 3;
1125 printf("st1: %d %d %d\n",
1126 st1.f1, st1.f2, st1.f3);
1127 st1.u.v1 = 1;
1128 st1.u.v2 = 2;
1129 printf("union1: %d\n", st1.u.v1);
1130 u.w1 = 1;
1131 u.w2 = 2;
1132 printf("union2: %d\n", u.w1);
1133 s = &st2;
1134 s->f1 = 3;
1135 s->f2 = 2;
1136 s->f3 = 1;
1137 printf("st2: %d %d %d\n",
1138 s->f1, s->f2, s->f3);
1139 printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1);
1140
1141 /* align / size tests */
1142 printf("aligntest1 sizeof=%d alignof=%d\n",
1143 sizeof(struct aligntest1), __alignof__(struct aligntest1));
1144 printf("aligntest2 sizeof=%d alignof=%d\n",
1145 sizeof(struct aligntest2), __alignof__(struct aligntest2));
1146 printf("aligntest3 sizeof=%d alignof=%d\n",
1147 sizeof(struct aligntest3), __alignof__(struct aligntest3));
1148 printf("aligntest4 sizeof=%d alignof=%d\n",
1149 sizeof(struct aligntest4), __alignof__(struct aligntest4));
1150 printf("aligntest5 sizeof=%d alignof=%d\n",
1151 sizeof(struct aligntest5), __alignof__(struct aligntest5));
1152 printf("aligntest6 sizeof=%d alignof=%d\n",
1153 sizeof(struct aligntest6), __alignof__(struct aligntest6));
1154 printf("aligntest7 sizeof=%d alignof=%d\n",
1155 sizeof(struct aligntest7), __alignof__(struct aligntest7));
1156 printf("aligntest8 sizeof=%d alignof=%d\n",
1157 sizeof(struct aligntest8), __alignof__(struct aligntest8));
1158 printf("aligntest9 sizeof=%d alignof=%d\n",
1159 sizeof(struct aligntest9), __alignof__(struct aligntest9));
1160 printf("aligntest10 sizeof=%d alignof=%d\n",
1161 sizeof(struct aligntest10), __alignof__(struct aligntest10));
1162 printf("altest5 sizeof=%d alignof=%d\n",
1163 sizeof(altest5), __alignof__(altest5));
1164 printf("altest6 sizeof=%d alignof=%d\n",
1165 sizeof(altest6), __alignof__(altest6));
1166 printf("altest7 sizeof=%d alignof=%d\n",
1167 sizeof(altest7), __alignof__(altest7));
1168
1169 /* empty structures (GCC extension) */
1170 printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
1171 printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
1172
1173 printf("Large: sizeof=%d\n", sizeof(ls));
1174 memset(&ls, 0, sizeof(ls));
1175 ls.compound_head = 42;
1176 printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
1177}
1178
1179/* XXX: depend on endianness */
1180void char_short_test()
1181{
1182 int var1, var2;
1183
1184 printf("char_short:\n");
1185
1186 var1 = 0x01020304;
1187 var2 = 0xfffefdfc;
1188 printf("s8=%d %d\n",
1189 *(char *)&var1, *(char *)&var2);
1190 printf("u8=%d %d\n",
1191 *(unsigned char *)&var1, *(unsigned char *)&var2);
1192 printf("s16=%d %d\n",
1193 *(short *)&var1, *(short *)&var2);
1194 printf("u16=%d %d\n",
1195 *(unsigned short *)&var1, *(unsigned short *)&var2);
1196 printf("s32=%d %d\n",
1197 *(int *)&var1, *(int *)&var2);
1198 printf("u32=%d %d\n",
1199 *(unsigned int *)&var1, *(unsigned int *)&var2);
1200 *(char *)&var1 = 0x08;
1201 printf("var1=%x\n", var1);
1202 *(short *)&var1 = 0x0809;
1203 printf("var1=%x\n", var1);
1204 *(int *)&var1 = 0x08090a0b;
1205 printf("var1=%x\n", var1);
1206}
1207
1208/******************/
1209
1210typedef struct Sym {
1211 int v;
1212 int t;
1213 int c;
1214 struct Sym *next;
1215 struct Sym *prev;
1216} Sym;
1217
1218#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
1219#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
1220
1221static int toupper1(int a)
1222{
1223 return TOUPPER(a);
1224}
1225
1226static unsigned int calc_vm_flags(unsigned int prot)
1227{
1228 unsigned int prot_bits;
1229 /* This used to segfault in some revisions: */
1230 prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
1231 return prot_bits;
1232}
1233
1234void bool_test()
1235{
1236 int *s, a, b, t, f, i;
1237
1238 a = 0;
1239 s = (void*)0;
1240 printf("!s=%d\n", !s);
1241
1242 if (!s || !s[0])
1243 a = 1;
1244 printf("a=%d\n", a);
1245
1246 printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
1247 printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
1248 printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
1249#if 1 && 1
1250 printf("a1\n");
1251#endif
1252#if 1 || 0
1253 printf("a2\n");
1254#endif
1255#if 1 ? 0 : 1
1256 printf("a3\n");
1257#endif
1258#if 0 ? 0 : 1
1259 printf("a4\n");
1260#endif
1261
1262 a = 4;
1263 printf("b=%d\n", a + (0 ? 1 : a / 2));
1264
1265 /* test register spilling */
1266 a = 10;
1267 b = 10;
1268 a = (a + b) * ((a < b) ?
1269 ((b - a) * (a - b)): a + b);
1270 printf("a=%d\n", a);
1271
1272 /* test complex || or && expressions */
1273 t = 1;
1274 f = 0;
1275 a = 32;
1276 printf("exp=%d\n", f == (32 <= a && a <= 3));
1277 printf("r=%d\n", (t || f) + (t && f));
1278
1279 /* test ? : cast */
1280 {
1281 int aspect_on;
1282 int aspect_native = 65536;
1283 double bfu_aspect = 1.0;
1284 int aspect;
1285 for(aspect_on = 0; aspect_on < 2; aspect_on++) {
1286 aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
1287 printf("aspect=%d\n", aspect);
1288 }
1289 }
1290
1291 /* test ? : GCC extension */
1292 {
1293 static int v1 = 34 ? : -1; /* constant case */
1294 static int v2 = 0 ? : -1; /* constant case */
1295 int a = 30;
1296
1297 printf("%d %d\n", v1, v2);
1298 printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
1299 }
1300
1301 /* again complex expression */
1302 for(i=0;i<256;i++) {
1303 if (toupper1 (i) != TOUPPER (i))
1304 printf("error %d\n", i);
1305 }
1306 printf ("bits = 0x%x\n", calc_vm_flags (0x1));
1307}
1308
1309extern int undefined_function(void);
1310extern int defined_function(void);
1311
1312static inline void refer_to_undefined(void)
1313{
1314 undefined_function();
1315}
1316
1317void optimize_out(void)
1318{
1319 int i = 0 ? undefined_function() : defined_function();
1320 printf ("oo:%d\n", i);
1321 int j = 1 ? defined_function() : undefined_function();
1322 printf ("oo:%d\n", j);
1323 if (0)
1324 printf("oo:%d\n", undefined_function());
1325 else
1326 printf("oo:%d\n", defined_function());
1327 if (1)
1328 printf("oo:%d\n", defined_function());
1329 else
1330 printf("oo:%d\n", undefined_function());
1331 while (1) {
1332 printf("oow:%d\n", defined_function());
1333 break;
1334 printf("oow:%d\n", undefined_function());
1335 }
1336 j = 1;
1337 /* Following is a switch without {} block intentionally. */
1338 switch (j)
1339 case 1: break;
1340 printf ("oos:%d\n", defined_function());
1341 /* The following break shouldn't lead to disabled code after
1342 the while. */
1343 while (1)
1344 break;
1345 printf ("ool1:%d\n", defined_function());
1346 /* Same for the other types of loops. */
1347 do
1348 break;
1349 while (1);
1350 printf ("ool2:%d\n", defined_function());
1351 for (;;)
1352 break;
1353 printf ("ool3:%d\n", defined_function());
1354 /* Normal {} blocks without controlling statements
1355 shouldn't reactivate code emission */
1356 while (1) {
1357 {
1358 break;
1359 }
1360 printf ("ool4:%d\n", undefined_function());
1361 }
1362 j = 1;
1363 while (j) {
1364 if (j == 0)
1365 break; /* this break shouldn't disable code outside the if. */
1366 printf("ool5:%d\n", defined_function());
1367 j--;
1368 }
1369
1370 j = 1;
1371 while (j) {
1372 if (1)
1373 j--;
1374 else
1375 breakhere: break;
1376 printf("ool6:%d\n", defined_function());
1377 goto breakhere;
1378 }
1379
1380 /* Test that constants in logical && are optimized: */
1381 i = 0 && undefined_function();
1382 i = defined_function() && 0 && undefined_function();
1383 if (0 && undefined_function())
1384 undefined_function();
1385 if (defined_function() && 0)
1386 undefined_function();
1387 if (0 && 0)
1388 undefined_function();
1389 if (defined_function() && 0 && undefined_function())
1390 undefined_function();
1391 /* The same for || : */
1392 i = 1 || undefined_function();
1393 i = defined_function() || 1 || undefined_function();
1394 if (1 || undefined_function())
1395 ;
1396 else
1397 undefined_function();
1398 if (defined_function() || 1)
1399 ;
1400 else
1401 undefined_function();
1402 if (1 || 1)
1403 ;
1404 else
1405 undefined_function();
1406 if (defined_function() || 1 || undefined_function())
1407 ;
1408 else
1409 undefined_function();
1410
1411 if (defined_function() && 0)
1412 refer_to_undefined();
1413
1414 if (0) {
1415 (void)sizeof( ({
1416 do { } while (0);
1417 0;
1418 }) );
1419 undefined_function();
1420 }
1421
1422 /* Leave the "if(1)return; printf()" in this order and last in the function */
1423 if (1)
1424 return;
1425 printf ("oor:%d\n", undefined_function());
1426}
1427
1428int defined_function(void)
1429{
1430 static int i = 40;
1431 return i++;
1432}
1433
1434/* GCC accepts that */
1435static int tab_reinit[];
1436static int tab_reinit[10];
1437
1438//int cinit1; /* a global variable can be defined several times without error ! */
1439int cinit1;
1440int cinit1;
1441int cinit1 = 0;
1442int *cinit2 = (int []){3, 2, 1};
1443
1444void compound_literal_test(void)
1445{
1446 int *p, i;
1447 char *q, *q3;
1448
1449 printf("compound_test:\n");
1450
1451 p = (int []){1, 2, 3};
1452 for(i=0;i<3;i++)
1453 printf(" %d", p[i]);
1454 printf("\n");
1455
1456 for(i=0;i<3;i++)
1457 printf("%d", cinit2[i]);
1458 printf("\n");
1459
1460 q = "tralala1";
1461 printf("q1=%s\n", q);
1462
1463 q = (char *){ "tralala2" };
1464 printf("q2=%s\n", q);
1465
1466 q3 = (char *){ q };
1467 printf("q3=%s\n", q3);
1468
1469 q = (char []){ "tralala3" };
1470 printf("q4=%s\n", q);
1471
1472#ifdef ALL_ISOC99
1473 p = (int []){1, 2, cinit1 + 3};
1474 for(i=0;i<3;i++)
1475 printf(" %d", p[i]);
1476 printf("\n");
1477
1478 for(i=0;i<3;i++) {
1479 p = (int []){1, 2, 4 + i};
1480 printf("%d %d %d\n",
1481 p[0],
1482 p[1],
1483 p[2]);
1484 }
1485#endif
1486}
1487
1488/* K & R protos */
1489
1490kr_func1(a, b)
1491{
1492 return a + b;
1493}
1494
1495int kr_func2(a, b)
1496{
1497 return a + b;
1498}
1499
1500kr_test()
1501{
1502 printf("kr_test:\n");
1503 printf("func1=%d\n", kr_func1(3, 4));
1504 printf("func2=%d\n", kr_func2(3, 4));
1505 return 0;
1506}
1507
1508void num(int n)
1509{
1510 char *tab, *p;
1511 tab = (char*)malloc(20);
1512 p = tab;
1513 while (1) {
1514 *p = 48 + (n % 10);
1515 p++;
1516 n = n / 10;
1517 if (n == 0)
1518 break;
1519 }
1520 while (p != tab) {
1521 p--;
1522 printf("%c", *p);
1523 }
1524 printf("\n");
1525 free(tab);
1526}
1527
1528/* structure assignment tests */
1529struct structa1 {
1530 int f1;
1531 char f2;
1532};
1533
1534struct structa1 ssta1;
1535
1536void struct_assign_test1(struct structa1 s1, int t, float f)
1537{
1538 printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
1539}
1540
1541struct structa1 struct_assign_test2(struct structa1 s1, int t)
1542{
1543 s1.f1 += t;
1544 s1.f2 -= t;
1545 return s1;
1546}
1547
1548void struct_assign_test(void)
1549{
1550 struct S {
1551 struct structa1 lsta1, lsta2;
1552 int i;
1553 } s, *ps;
1554
1555 ps = &s;
1556 ps->i = 4;
1557#if 0
1558 printf("struct_assign_test:\n");
1559
1560 s.lsta1.f1 = 1;
1561 s.lsta1.f2 = 2;
1562 printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
1563 s.lsta2 = s.lsta1;
1564 printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
1565#else
1566 s.lsta2.f1 = 1;
1567 s.lsta2.f2 = 2;
1568#endif
1569 struct_assign_test1(ps->lsta2, 3, 4.5);
1570
1571 printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
1572 ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
1573 printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
1574
1575 static struct {
1576 void (*elem)();
1577 } t[] = {
1578 /* XXX: we should allow this even without braces */
1579 { struct_assign_test }
1580 };
1581 printf("%d\n", struct_assign_test == t[0].elem);
1582}
1583
1584/* casts to short/char */
1585
1586void cast1(char a, short b, unsigned char c, unsigned short d)
1587{
1588 printf("%d %d %d %d\n", a, b, c, d);
1589}
1590
1591char bcast;
1592short scast;
1593
1594void cast_test()
1595{
1596 int a;
1597 char c;
1598 char tab[10];
1599 unsigned b,d;
1600 short s;
1601 char *p = NULL;
1602 p -= 0x700000000042;
1603
1604 printf("cast_test:\n");
1605 a = 0xfffff;
1606 cast1(a, a, a, a);
1607 a = 0xffffe;
1608 printf("%d %d %d %d\n",
1609 (char)(a + 1),
1610 (short)(a + 1),
1611 (unsigned char)(a + 1),
1612 (unsigned short)(a + 1));
1613 printf("%d %d %d %d\n",
1614 (char)0xfffff,
1615 (short)0xfffff,
1616 (unsigned char)0xfffff,
1617 (unsigned short)0xfffff);
1618
1619 a = (bcast = 128) + 1;
1620 printf("%d\n", a);
1621 a = (scast = 65536) + 1;
1622 printf("%d\n", a);
1623
1624 printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
1625
1626 /* test cast from unsigned to signed short to int */
1627 b = 0xf000;
1628 d = (short)b;
1629 printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
1630 b = 0xf0f0;
1631 d = (char)b;
1632 printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
1633
1634 /* test implicit int casting for array accesses */
1635 c = 0;
1636 tab[1] = 2;
1637 tab[c] = 1;
1638 printf("%d %d\n", tab[0], tab[1]);
1639
1640 /* test implicit casting on some operators */
1641 printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
1642 printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
1643 printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
1644
1645 /* from pointer to integer types */
1646 printf("%d %d %ld %ld %lld %lld\n",
1647 (int)p, (unsigned int)p,
1648 (long)p, (unsigned long)p,
1649 (long long)p, (unsigned long long)p);
1650
1651 /* from integers to pointers */
1652 printf("%p %p %p %p\n",
1653 (void *)a, (void *)b, (void *)c, (void *)d);
1654}
1655
1656/* initializers tests */
1657struct structinit1 {
1658 int f1;
1659 char f2;
1660 short f3;
1661 int farray[3];
1662};
1663
1664int sinit1 = 2;
1665int sinit2 = { 3 };
1666int sinit3[3] = { 1, 2, {{3}}, };
1667int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1668int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
1669int sinit6[] = { 1, 2, 3 };
1670int sinit7[] = { [2] = 3, [0] = 1, 2 };
1671char sinit8[] = "hello" "trala";
1672
1673struct structinit1 sinit9 = { 1, 2, 3 };
1674struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
1675struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
1676#ifdef ALL_ISOC99
1677 .farray[0] = 10,
1678 .farray[1] = 11,
1679 .farray[2] = 12,
1680#endif
1681};
1682
1683char *sinit12 = "hello world";
1684char *sinit13[] = {
1685 "test1",
1686 "test2",
1687 "test3",
1688};
1689char sinit14[10] = { "abc" };
1690int sinit15[3] = { sizeof(sinit15), 1, 2 };
1691
1692struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
1693
1694struct bar {
1695 char *s;
1696 int len;
1697} sinit17[] = {
1698 "a1", 4,
1699 "a2", 1
1700};
1701
1702int sinit18[10] = {
1703 [2 ... 5] = 20,
1704 2,
1705 [8] = 10,
1706};
1707
1708struct complexinit0 {
1709 int a;
1710 int b;
1711};
1712
1713struct complexinit {
1714 int a;
1715 const struct complexinit0 *b;
1716};
1717
1718const static struct complexinit cix[] = {
1719 [0] = {
1720 .a = 2000,
1721 .b = (const struct complexinit0[]) {
1722 { 2001, 2002 },
1723 { 2003, 2003 },
1724 {}
1725 }
1726 }
1727};
1728
1729struct complexinit2 {
1730 int a;
1731 int b[];
1732};
1733
1734struct complexinit2 cix20;
1735
1736struct complexinit2 cix21 = {
1737 .a = 3000,
1738 .b = { 3001, 3002, 3003 }
1739};
1740
1741struct complexinit2 cix22 = {
1742 .a = 4000,
1743 .b = { 4001, 4002, 4003, 4004, 4005, 4006 }
1744};
1745
1746typedef int arrtype1[];
1747arrtype1 sinit19 = {1};
1748arrtype1 sinit20 = {2,3};
1749typedef int arrtype2[3];
1750arrtype2 sinit21 = {4};
1751arrtype2 sinit22 = {5,6,7};
1752
1753/* Address comparisons of non-weak symbols with zero can be const-folded */
1754int sinit23[2] = { "astring" ? sizeof("astring") : -1,
1755 &sinit23 ? 42 : -1 };
1756
1757extern int external_inited = 42;
1758
1759void init_test(void)
1760{
1761 int linit1 = 2;
1762 int linit2 = { 3 };
1763 int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1764 int linit6[] = { 1, 2, 3 };
1765 int i, j;
1766 char linit8[] = "hello" "trala";
1767 int linit12[10] = { 1, 2 };
1768 int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
1769 char linit14[10] = "abc";
1770 int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
1771 struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
1772 int linit17 = sizeof(linit17);
1773 int zero = 0;
1774 /* Addresses on non-weak symbols are non-zero, but not the access itself */
1775 int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
1776
1777 printf("init_test:\n");
1778
1779 printf("sinit1=%d\n", sinit1);
1780 printf("sinit2=%d\n", sinit2);
1781 printf("sinit3=%d %d %d %d\n",
1782 sizeof(sinit3),
1783 sinit3[0],
1784 sinit3[1],
1785 sinit3[2]
1786 );
1787 printf("sinit6=%d\n", sizeof(sinit6));
1788 printf("sinit7=%d %d %d %d\n",
1789 sizeof(sinit7),
1790 sinit7[0],
1791 sinit7[1],
1792 sinit7[2]
1793 );
1794 printf("sinit8=%s\n", sinit8);
1795 printf("sinit9=%d %d %d\n",
1796 sinit9.f1,
1797 sinit9.f2,
1798 sinit9.f3
1799 );
1800 printf("sinit10=%d %d %d\n",
1801 sinit10.f1,
1802 sinit10.f2,
1803 sinit10.f3
1804 );
1805 printf("sinit11=%d %d %d %d %d %d\n",
1806 sinit11.f1,
1807 sinit11.f2,
1808 sinit11.f3,
1809 sinit11.farray[0],
1810 sinit11.farray[1],
1811 sinit11.farray[2]
1812 );
1813
1814 for(i=0;i<3;i++)
1815 for(j=0;j<2;j++)
1816 printf("[%d][%d] = %d %d %d\n",
1817 i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
1818 printf("linit1=%d\n", linit1);
1819 printf("linit2=%d\n", linit2);
1820 printf("linit6=%d\n", sizeof(linit6));
1821 printf("linit8=%d %s\n", sizeof(linit8), linit8);
1822
1823 printf("sinit12=%s\n", sinit12);
1824 printf("sinit13=%d %s %s %s\n",
1825 sizeof(sinit13),
1826 sinit13[0],
1827 sinit13[1],
1828 sinit13[2]);
1829 printf("sinit14=%s\n", sinit14);
1830
1831 for(i=0;i<10;i++) printf(" %d", linit12[i]);
1832 printf("\n");
1833 for(i=0;i<10;i++) printf(" %d", linit13[i]);
1834 printf("\n");
1835 for(i=0;i<10;i++) printf(" %d", linit14[i]);
1836 printf("\n");
1837 for(i=0;i<10;i++) printf(" %d", linit15[i]);
1838 printf("\n");
1839 printf("%d %d %d %d\n",
1840 linit16.a1,
1841 linit16.a2,
1842 linit16.a3,
1843 linit16.a4);
1844 /* test that initialisation is done after variable declare */
1845 printf("linit17=%d\n", linit17);
1846 printf("sinit15=%d\n", sinit15[0]);
1847 printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
1848 printf("sinit17=%s %d %s %d\n",
1849 sinit17[0].s, sinit17[0].len,
1850 sinit17[1].s, sinit17[1].len);
1851 for(i=0;i<10;i++)
1852 printf("%x ", sinit18[i]);
1853 printf("\n");
1854 /* complex init check */
1855 printf("cix: %d %d %d %d %d %d %d\n",
1856 cix[0].a,
1857 cix[0].b[0].a, cix[0].b[0].b,
1858 cix[0].b[1].a, cix[0].b[1].b,
1859 cix[0].b[2].a, cix[0].b[2].b);
1860 printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
1861 printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
1862
1863 printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
1864 printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
1865 printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
1866 printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
1867 printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
1868 printf("arrtype6: %d\n", sizeof(arrtype2));
1869
1870 printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
1871 printf("linit18= %d %d\n", linit18[0], linit18[1]);
1872}
1873
1874void switch_uc(unsigned char uc)
1875{
1876 switch (uc) {
1877 case 0xfb ... 0xfe:
1878 printf("ucsw:1\n");
1879 break;
1880 case 0xff:
1881 printf("ucsw:2\n");
1882 break;
1883 case 0 ... 5:
1884 printf("ucsw:3\n");
1885 break;
1886 default:
1887 printf("ucsw: broken!\n");
1888 }
1889}
1890
1891void switch_sc(signed char sc)
1892{
1893 switch (sc) {
1894 case -5 ... -2:
1895 printf("scsw:1\n");
1896 break;
1897 case -1:
1898 printf("scsw:2\n");
1899 break;
1900 case 0 ... 5:
1901 printf("scsw:3\n");
1902 break;
1903 default:
1904 printf("scsw: broken!\n");
1905 }
1906}
1907
1908void switch_test()
1909{
1910 int i;
1911 unsigned long long ull;
1912 long long ll;
1913
1914 for(i=0;i<15;i++) {
1915 switch(i) {
1916 case 0:
1917 case 1:
1918 printf("a");
1919 break;
1920 default:
1921 printf("%d", i);
1922 break;
1923 case 8 ... 12:
1924 printf("c");
1925 break;
1926 case 3:
1927 printf("b");
1928 break;
1929 case 0xc33c6b9fU:
1930 case 0x7c9eeeb9U:
1931 break;
1932 }
1933 }
1934 printf("\n");
1935
1936 for (i = 1; i <= 5; i++) {
1937 ull = (unsigned long long)i << 61;
1938 switch (ull) {
1939 case 1ULL << 61:
1940 printf("ullsw:1\n");
1941 break;
1942 case 2ULL << 61:
1943 printf("ullsw:2\n");
1944 break;
1945 case 3ULL << 61:
1946 printf("ullsw:3\n");
1947 break;
1948 case 4ULL << 61:
1949 printf("ullsw:4\n");
1950 break;
1951 case 5ULL << 61:
1952 printf("ullsw:5\n");
1953 break;
1954 default:
1955 printf("ullsw: broken!\n");
1956 }
1957 }
1958
1959 for (i = 1; i <= 5; i++) {
1960 ll = (long long)i << 61;
1961 switch (ll) {
1962 case 1LL << 61:
1963 printf("llsw:1\n");
1964 break;
1965 case 2LL << 61:
1966 printf("llsw:2\n");
1967 break;
1968 case 3LL << 61:
1969 printf("llsw:3\n");
1970 break;
1971 case 4LL << 61:
1972 printf("llsw:4\n");
1973 break;
1974 case 5LL << 61:
1975 printf("llsw:5\n");
1976 break;
1977 default:
1978 printf("llsw: broken!\n");
1979 }
1980 }
1981
1982 for (i = -5; i <= 5; i++) {
1983 switch_uc((unsigned char)i);
1984 }
1985
1986 for (i = -5; i <= 5; i++) {
1987 switch_sc ((signed char)i);
1988 }
1989}
1990
1991/* ISOC99 _Bool type */
1992void c99_bool_test(void)
1993{
1994#ifdef BOOL_ISOC99
1995 int a;
1996 _Bool b;
1997
1998 printf("bool_test:\n");
1999 printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
2000 a = 3;
2001 printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
2002 b = 3;
2003 printf("b = %d\n", b);
2004 b++;
2005 printf("b = %d\n", b);
2006#endif
2007}
2008
2009void bitfield_test(void)
2010{
2011 int a;
2012 short sa;
2013 unsigned char ca;
2014 struct sbf1 {
2015 int f1 : 3;
2016 int : 2;
2017 int f2 : 1;
2018 int : 0;
2019 int f3 : 5;
2020 int f4 : 7;
2021 unsigned int f5 : 7;
2022 } st1;
2023 printf("bitfield_test:");
2024 printf("sizeof(st1) = %d\n", sizeof(st1));
2025
2026 st1.f1 = 3;
2027 st1.f2 = 1;
2028 st1.f3 = 15;
2029 a = 120;
2030 st1.f4 = a;
2031 st1.f5 = a;
2032 st1.f5++;
2033 printf("%d %d %d %d %d\n",
2034 st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
2035 sa = st1.f5;
2036 ca = st1.f5;
2037 printf("%d %d\n", sa, ca);
2038
2039 st1.f1 = 7;
2040 if (st1.f1 == -1)
2041 printf("st1.f1 == -1\n");
2042 else
2043 printf("st1.f1 != -1\n");
2044 if (st1.f2 == -1)
2045 printf("st1.f2 == -1\n");
2046 else
2047 printf("st1.f2 != -1\n");
2048
2049 struct sbf2 {
2050 long long f1 : 45;
2051 long long : 2;
2052 long long f2 : 35;
2053 unsigned long long f3 : 38;
2054 } st2;
2055 st2.f1 = 0x123456789ULL;
2056 a = 120;
2057 st2.f2 = (long long)a << 25;
2058 st2.f3 = a;
2059 st2.f2++;
2060 printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
2061
2062#if 0
2063 Disabled for now until further clarification re GCC compatibility
2064 struct sbf3 {
2065 int f1 : 7;
2066 int f2 : 1;
2067 char f3;
2068 int f4 : 8;
2069 int f5 : 1;
2070 int f6 : 16;
2071 } st3;
2072 printf("sizeof(st3) = %d\n", sizeof(st3));
2073#endif
2074
2075 struct sbf4 {
2076 int x : 31;
2077 char y : 2;
2078 } st4;
2079 st4.y = 1;
2080 printf("st4.y == %d\n", st4.y);
2081 struct sbf5 {
2082 int a;
2083 char b;
2084 int x : 12, y : 4, : 0, : 4, z : 3;
2085 char c;
2086 } st5 = { 1, 2, 3, 4, -3, 6 };
2087 printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
2088 struct sbf6 {
2089 short x : 12;
2090 unsigned char y : 2;
2091 } st6;
2092 st6.y = 1;
2093 printf("st6.y == %d\n", st6.y);
2094}
2095
2096#ifdef __x86_64__
2097#define FLOAT_FMT "%f\n"
2098#else
2099/* x86's float isn't compatible with GCC */
2100#define FLOAT_FMT "%.5f\n"
2101#endif
2102
2103/* declare strto* functions as they are C99 */
2104double strtod(const char *nptr, char **endptr);
2105
2106#if defined(_WIN32)
2107float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
2108LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
2109#else
2110float strtof(const char *nptr, char **endptr);
2111LONG_DOUBLE strtold(const char *nptr, char **endptr);
2112#endif
2113
2114#define FTEST(prefix, typename, type, fmt)\
2115void prefix ## cmp(type a, type b)\
2116{\
2117 printf("%d %d %d %d %d %d\n",\
2118 a == b,\
2119 a != b,\
2120 a < b,\
2121 a > b,\
2122 a >= b,\
2123 a <= b);\
2124 printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
2125 a,\
2126 b,\
2127 a + b,\
2128 a - b,\
2129 a * b,\
2130 a / b,\
2131 -a);\
2132 printf(fmt "\n", ++a);\
2133 printf(fmt "\n", a++);\
2134 printf(fmt "\n", a);\
2135 b = 0;\
2136 printf("%d %d\n", !a, !b);\
2137}\
2138void prefix ## fcast(type a)\
2139{\
2140 float fa;\
2141 double da;\
2142 LONG_DOUBLE la;\
2143 int ia;\
2144 long long llia;\
2145 unsigned int ua;\
2146 unsigned long long llua;\
2147 type b;\
2148 fa = a;\
2149 da = a;\
2150 la = a;\
2151 printf("ftof: %f %f %Lf\n", fa, da, la);\
2152 ia = (int)a;\
2153 llia = (long long)a;\
2154 a = (a >= 0) ? a : -a;\
2155 ua = (unsigned int)a;\
2156 llua = (unsigned long long)a;\
2157 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
2158 ia = -1234;\
2159 ua = 0x81234500;\
2160 llia = -0x123456789012345LL;\
2161 llua = 0xf123456789012345LLU;\
2162 b = ia;\
2163 printf("itof: " fmt "\n", b);\
2164 b = ua;\
2165 printf("utof: " fmt "\n", b);\
2166 b = llia;\
2167 printf("lltof: " fmt "\n", b);\
2168 b = llua;\
2169 printf("ulltof: " fmt "\n", b);\
2170}\
2171\
2172float prefix ## retf(type a) { return a; }\
2173double prefix ## retd(type a) { return a; }\
2174LONG_DOUBLE prefix ## retld(type a) { return a; }\
2175\
2176void prefix ## call(void)\
2177{\
2178 printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
2179 printf("double: %f\n", prefix ## retd(42.123456789));\
2180 printf("long double: %Lf\n", prefix ## retld(42.123456789));\
2181 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
2182}\
2183\
2184void prefix ## signed_zeros(void) \
2185{\
2186 type x = 0.0, y = -0.0, n, p;\
2187 if (x == y)\
2188 printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\
2189 1.0 / x != 1.0 / y);\
2190 else\
2191 printf ("x != y; this is wrong!\n");\
2192\
2193 n = -x;\
2194 if (x == n)\
2195 printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
2196 1.0 / x != 1.0 / n);\
2197 else\
2198 printf ("x != -x; this is wrong!\n");\
2199\
2200 p = +y;\
2201 if (x == p)\
2202 printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
2203 1.0 / x != 1.0 / p);\
2204 else\
2205 printf ("x != +y; this is wrong!\n");\
2206 p = -y;\
2207 if (x == p)\
2208 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
2209 1.0 / x != 1.0 / p);\
2210 else\
2211 printf ("x != -y; this is wrong!\n");\
2212}\
2213void prefix ## test(void)\
2214{\
2215 printf("testing '%s'\n", #typename);\
2216 prefix ## cmp(1, 2.5);\
2217 prefix ## cmp(2, 1.5);\
2218 prefix ## cmp(1, 1);\
2219 prefix ## fcast(234.6);\
2220 prefix ## fcast(-2334.6);\
2221 prefix ## call();\
2222 prefix ## signed_zeros();\
2223}
2224
2225FTEST(f, float, float, "%f")
2226FTEST(d, double, double, "%f")
2227FTEST(ld, long double, LONG_DOUBLE, "%Lf")
2228
2229double ftab1[3] = { 1.2, 3.4, -5.6 };
2230
2231
2232void float_test(void)
2233{
2234#if !defined(__arm__) || defined(__ARM_PCS_VFP)
2235 float fa, fb;
2236 double da, db;
2237 int a;
2238 unsigned int b;
2239
2240 printf("float_test:\n");
2241 printf("sizeof(float) = %d\n", sizeof(float));
2242 printf("sizeof(double) = %d\n", sizeof(double));
2243 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
2244 ftest();
2245 dtest();
2246 ldtest();
2247 printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
2248 printf("%f %f %f\n", 2.12, .5, 2.3e10);
2249 // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
2250 da = 123;
2251 printf("da=%f\n", da);
2252 fa = 123;
2253 printf("fa=%f\n", fa);
2254 a = 4000000000;
2255 da = a;
2256 printf("da = %f\n", da);
2257 b = 4000000000;
2258 db = b;
2259 printf("db = %f\n", db);
2260#endif
2261}
2262
2263int fib(int n)
2264{
2265 if (n <= 2)
2266 return 1;
2267 else
2268 return fib(n-1) + fib(n-2);
2269}
2270
2271void funcptr_test()
2272{
2273 void (*func)(int);
2274 int a;
2275 struct {
2276 int dummy;
2277 void (*func)(int);
2278 } st1;
2279 long diff;
2280
2281 printf("funcptr:\n");
2282 func = &num;
2283 (*func)(12345);
2284 func = num;
2285 a = 1;
2286 a = 1;
2287 func(12345);
2288 /* more complicated pointer computation */
2289 st1.func = num;
2290 st1.func(12346);
2291 printf("sizeof1 = %d\n", sizeof(funcptr_test));
2292 printf("sizeof2 = %d\n", sizeof funcptr_test);
2293 printf("sizeof3 = %d\n", sizeof(&funcptr_test));
2294 printf("sizeof4 = %d\n", sizeof &funcptr_test);
2295 a = 0;
2296 func = num + a;
2297 diff = func - num;
2298 func(42);
2299 (func + diff)(42);
2300 (num + a)(43);
2301}
2302
2303void lloptest(long long a, long long b)
2304{
2305 unsigned long long ua, ub;
2306
2307 ua = a;
2308 ub = b;
2309 /* arith */
2310 printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2311 a + b,
2312 a - b,
2313 a * b);
2314
2315 if (b != 0) {
2316 printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2317 a / b,
2318 a % b);
2319 }
2320
2321 /* binary */
2322 printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2323 a & b,
2324 a | b,
2325 a ^ b);
2326
2327 /* tests */
2328 printf("test: %d %d %d %d %d %d\n",
2329 a == b,
2330 a != b,
2331 a < b,
2332 a > b,
2333 a >= b,
2334 a <= b);
2335
2336 printf("utest: %d %d %d %d %d %d\n",
2337 ua == ub,
2338 ua != ub,
2339 ua < ub,
2340 ua > ub,
2341 ua >= ub,
2342 ua <= ub);
2343
2344 /* arith2 */
2345 a++;
2346 b++;
2347 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2348 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
2349 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
2350 printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2351 b = ub = 0;
2352 printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
2353}
2354
2355void llshift(long long a, int b)
2356{
2357 printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2358 (unsigned long long)a >> b,
2359 a >> b,
2360 a << b);
2361 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2362 (unsigned long long)a >> 3,
2363 a >> 3,
2364 a << 3);
2365 printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
2366 (unsigned long long)a >> 35,
2367 a >> 35,
2368 a << 35);
2369}
2370
2371void llfloat(void)
2372{
2373 float fa;
2374 double da;
2375 LONG_DOUBLE lda;
2376 long long la, lb, lc;
2377 unsigned long long ula, ulb, ulc;
2378 la = 0x12345678;
2379 ula = 0x72345678;
2380 la = (la << 20) | 0x12345;
2381 ula = ula << 33;
2382 printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
2383
2384 fa = la;
2385 da = la;
2386 lda = la;
2387 printf("lltof: %f %f %Lf\n", fa, da, lda);
2388
2389 la = fa;
2390 lb = da;
2391 lc = lda;
2392 printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
2393
2394 fa = ula;
2395 da = ula;
2396 lda = ula;
2397 printf("ulltof: %f %f %Lf\n", fa, da, lda);
2398
2399 ula = fa;
2400 ulb = da;
2401 ulc = lda;
2402 printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
2403}
2404
2405long long llfunc1(int a)
2406{
2407 return a * 2;
2408}
2409
2410struct S {
2411 int id;
2412 char item;
2413};
2414
2415long long int value(struct S *v)
2416{
2417 return ((long long int)v->item);
2418}
2419
2420long long llfunc2(long long x, long long y, int z)
2421{
2422 return x * y * z;
2423}
2424
2425void longlong_test(void)
2426{
2427 long long a, b, c;
2428 int ia;
2429 unsigned int ua;
2430 printf("longlong_test:\n");
2431 printf("sizeof(long long) = %d\n", sizeof(long long));
2432 ia = -1;
2433 ua = -2;
2434 a = ia;
2435 b = ua;
2436 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
2437 printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
2438 (long long)1,
2439 (long long)-2,
2440 1LL,
2441 0x1234567812345679);
2442 a = llfunc1(-3);
2443 printf(LONG_LONG_FORMAT "\n", a);
2444
2445 lloptest(1000, 23);
2446 lloptest(0xff, 0x1234);
2447 b = 0x72345678 << 10;
2448 lloptest(-3, b);
2449 llshift(0x123, 5);
2450 llshift(-23, 5);
2451 b = 0x72345678LL << 10;
2452 llshift(b, 47);
2453
2454 llfloat();
2455#if 1
2456 b = 0x12345678;
2457 a = -1;
2458 c = a + b;
2459 printf("%Lx\n", c);
2460#endif
2461
2462 /* long long reg spill test */
2463 {
2464 struct S a;
2465
2466 a.item = 3;
2467 printf("%lld\n", value(&a));
2468 }
2469 lloptest(0x80000000, 0);
2470
2471 {
2472 long long *p, v, **pp;
2473 v = 1;
2474 p = &v;
2475 p[0]++;
2476 printf("another long long spill test : %lld\n", *p);
2477 pp = &p;
2478
2479 v = llfunc2(**pp, **pp, ia);
2480 printf("a long long function (arm-)reg-args test : %lld\n", v);
2481 }
2482 a = 68719476720LL;
2483 b = 4294967295LL;
2484 printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
2485
2486 printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
2487
2488 /* long long pointer deref in argument passing test */
2489 a = 0x123;
2490 long long *p = &a;
2491 llshift(*p, 5);
2492}
2493
2494void manyarg_test(void)
2495{
2496 LONG_DOUBLE ld = 1234567891234LL;
2497 printf("manyarg_test:\n");
2498 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2499 1, 2, 3, 4, 5, 6, 7, 8,
2500 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2501 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2502 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2503 1, 2, 3, 4, 5, 6, 7, 8,
2504 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2505 1234567891234LL, 987654321986LL,
2506 42.0, 43.0);
2507 printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2508 LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
2509 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2510 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2511 1234567891234LL, 987654321986LL,
2512 42.0, 43.0);
2513 printf("%d %d %d %d %d %d %d %d %Lf\n",
2514 1, 2, 3, 4, 5, 6, 7, 8, ld);
2515 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2516 LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
2517 1, 2, 3, 4, 5, 6, 7, 8,
2518 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2519 1234567891234LL, 987654321986LL,
2520 42.0, 43.0, ld);
2521 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2522 "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
2523 1, 2, 3, 4, 5, 6, 7, 8,
2524 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2525 ld, 1234567891234LL, 987654321986LL,
2526 42.0, 43.0, ld);
2527}
2528
2529void vprintf1(const char *fmt, ...)
2530{
2531 va_list ap, aq;
2532 const char *p;
2533 int c, i;
2534 double d;
2535 long long ll;
2536 LONG_DOUBLE ld;
2537
2538 va_start(aq, fmt);
2539 va_copy(ap, aq);
2540
2541 p = fmt;
2542 for(;;) {
2543 c = *p;
2544 if (c == '\0')
2545 break;
2546 p++;
2547 if (c == '%') {
2548 c = *p;
2549 switch(c) {
2550 case '\0':
2551 goto the_end;
2552 case 'd':
2553 i = va_arg(ap, int);
2554 printf("%d", i);
2555 break;
2556 case 'f':
2557 d = va_arg(ap, double);
2558 printf("%f", d);
2559 break;
2560 case 'l':
2561 ll = va_arg(ap, long long);
2562 printf(LONG_LONG_FORMAT, ll);
2563 break;
2564 case 'F':
2565 ld = va_arg(ap, LONG_DOUBLE);
2566 printf("%Lf", ld);
2567 break;
2568 }
2569 p++;
2570 } else {
2571 putchar(c);
2572 }
2573 }
2574 the_end:
2575 va_end(aq);
2576 va_end(ap);
2577}
2578
2579struct myspace {
2580 short int profile;
2581};
2582
2583void stdarg_for_struct(struct myspace bob, ...)
2584{
2585 struct myspace george, bill;
2586 va_list ap;
2587 short int validate;
2588
2589 va_start(ap, bob);
2590 bill = va_arg(ap, struct myspace);
2591 george = va_arg(ap, struct myspace);
2592 validate = va_arg(ap, int);
2593 printf("stdarg_for_struct: %d %d %d %d\n",
2594 bob.profile, bill.profile, george.profile, validate);
2595 va_end(ap);
2596}
2597
2598void stdarg_for_libc(const char *fmt, ...)
2599{
2600 va_list args;
2601 va_start(args, fmt);
2602 vprintf(fmt, args);
2603 va_end(args);
2604}
2605
2606void stdarg_test(void)
2607{
2608 LONG_DOUBLE ld = 1234567891234LL;
2609 struct myspace bob;
2610
2611 vprintf1("%d %d %d\n", 1, 2, 3);
2612 vprintf1("%f %d %f\n", 1.0, 2, 3.0);
2613 vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
2614 vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
2615 vprintf1("%d %f %l %F %d %f %l %F\n",
2616 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
2617 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
2618 1, 2, 3, 4, 5, 6, 7, 8,
2619 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
2620 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2621 1, 2, 3, 4, 5, 6, 7, 8,
2622 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2623 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2624 "%l %l %f %f\n",
2625 1, 2, 3, 4, 5, 6, 7, 8,
2626 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2627 1234567891234LL, 987654321986LL,
2628 42.0, 43.0);
2629 vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2630 "%l %l %f %f\n",
2631 ld, 1, 2, 3, 4, 5, 6, 7, 8,
2632 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2633 1234567891234LL, 987654321986LL,
2634 42.0, 43.0);
2635 vprintf1("%d %d %d %d %d %d %d %d %F\n",
2636 1, 2, 3, 4, 5, 6, 7, 8, ld);
2637 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2638 "%l %l %f %f %F\n",
2639 1, 2, 3, 4, 5, 6, 7, 8,
2640 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2641 1234567891234LL, 987654321986LL,
2642 42.0, 43.0, ld);
2643 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2644 "%F %l %l %f %f %F\n",
2645 1, 2, 3, 4, 5, 6, 7, 8,
2646 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2647 ld, 1234567891234LL, 987654321986LL,
2648 42.0, 43.0, ld);
2649
2650 bob.profile = 42;
2651 stdarg_for_struct(bob, bob, bob, bob.profile);
2652 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
2653}
2654
2655void whitespace_test(void)
2656{
2657 char *str;
2658
2659
2660
2661
2662#if 1
2663 pri\
2664ntf("whitspace:\n");
2665
2666
2667#endif
2668 pf("N=%d\n", 2);
2669
2670#ifdef CORRECT_CR_HANDLING
2671 pri\
2672ntf("aaa=%d\n", 3);
2673#endif
2674
2675 pri\
2676\
2677ntf("min=%d\n", 4);
2678
2679#ifdef ACCEPT_CR_IN_STRINGS
2680 printf("len1=%d\n", strlen("
2681"));
2682#ifdef CORRECT_CR_HANDLING
2683 str = "
2684";
2685 printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
2686#endif
2687 printf("len1=%d\n", strlen("
2688a
2689"));
2690#endif /* ACCEPT_CR_IN_STRINGS */
2691}
2692
2693int reltab[3] = { 1, 2, 3 };
2694
2695int *rel1 = &reltab[1];
2696int *rel2 = &reltab[2];
2697
2698#ifdef _WIN64
2699void relocation_test(void) {}
2700#else
2701void getmyaddress(void)
2702{
2703 printf("in getmyaddress\n");
2704}
2705
2706#ifdef __LP64__
2707long __pa_symbol(void)
2708{
2709 /* This 64bit constant was handled incorrectly, it was used as addend
2710 (which can hold 64bit just fine) in connection with a symbol,
2711 and TCC generates wrong code for that (displacements are 32bit only).
2712 This effectively is "+ 0x80000000", and if addresses of globals
2713 are below 2GB the result should be a number without high 32 bits set. */
2714 return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
2715}
2716#endif
2717
2718unsigned long theaddress = (unsigned long)getmyaddress;
2719void relocation_test(void)
2720{
2721 void (*fptr)(void) = (void (*)(void))theaddress;
2722 printf("*rel1=%d\n", *rel1);
2723 printf("*rel2=%d\n", *rel2);
2724 fptr();
2725#ifdef __LP64__
2726 printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
2727#endif
2728}
2729#endif
2730
2731void old_style_f(a,b,c)
2732 int a, b;
2733 double c;
2734{
2735 printf("a=%d b=%d b=%f\n", a, b, c);
2736}
2737
2738void decl_func1(int cmpfn())
2739{
2740 printf("cmpfn=%lx\n", (long)cmpfn);
2741}
2742
2743void decl_func2(cmpfn)
2744int cmpfn();
2745{
2746 printf("cmpfn=%lx\n", (long)cmpfn);
2747}
2748
2749void old_style_function(void)
2750{
2751 old_style_f((void *)1, 2, 3.0);
2752 decl_func1(NULL);
2753 decl_func2(NULL);
2754}
2755
2756void alloca_test()
2757{
2758#if defined __i386__ || defined __x86_64__ || defined __arm__
2759 char *p = alloca(16);
2760 strcpy(p,"123456789012345");
2761 printf("alloca: p is %s\n", p);
2762 char *demo = "This is only a test.\n";
2763 /* Test alloca embedded in a larger expression */
2764 printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
2765#endif
2766}
2767
2768void *bounds_checking_is_enabled()
2769{
2770 char ca[10], *cp = ca-1;
2771 return (ca != cp + 1) ? cp : NULL;
2772}
2773
2774typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
2775
2776void c99_vla_test(int size1, int size2)
2777{
2778#if defined __i386__ || defined __x86_64__
2779 int size = size1 * size2;
2780 int tab1[size][2], tab2[10][2];
2781 void *tab1_ptr, *tab2_ptr, *bad_ptr;
2782
2783 /* "size" should have been 'captured' at tab1 declaration,
2784 so modifying it should have no effect on VLA behaviour. */
2785 size = size-1;
2786
2787 printf("Test C99 VLA 1 (sizeof): ");
2788 printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
2789 tab1_ptr = tab1;
2790 tab2_ptr = tab2;
2791 printf("Test C99 VLA 2 (ptrs subtract): ");
2792 printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
2793 printf("Test C99 VLA 3 (ptr add): ");
2794 printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
2795 printf("Test C99 VLA 4 (ptr access): ");
2796 tab1[size1][1] = 42;
2797 printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
2798
2799 printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
2800 if (bad_ptr = bounds_checking_is_enabled()) {
2801 int *t1 = &tab1[size1 * size2 - 1][3];
2802 int *t2 = &tab2[9][3];
2803 printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED");
2804 printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED");
2805
2806 char*c1 = 1 + sizeof(tab1) + (char*)tab1;
2807 char*c2 = 1 + sizeof(tab2) + (char*)tab2;
2808 printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED");
2809 printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED");
2810
2811 int *i1 = tab1[-1];
2812 int *i2 = tab2[-1];
2813 printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED");
2814 printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED");
2815
2816 int *x1 = tab1[size1 * size2 + 1];
2817 int *x2 = tab2[10 + 1];
2818 printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED");
2819 printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED");
2820 } else {
2821 printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
2822 }
2823 printf("\n");
2824#endif
2825}
2826
2827#ifndef __TINYC__
2828typedef __SIZE_TYPE__ uintptr_t;
2829#endif
2830
2831void sizeof_test(void)
2832{
2833 int a;
2834 int **ptr;
2835
2836 printf("sizeof(int) = %d\n", sizeof(int));
2837 printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
2838 printf("sizeof(long) = %d\n", sizeof(long));
2839 printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
2840 printf("sizeof(short) = %d\n", sizeof(short));
2841 printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
2842 printf("sizeof(char) = %d\n", sizeof(char));
2843 printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
2844 printf("sizeof(func) = %d\n", sizeof sizeof_test());
2845 a = 1;
2846 printf("sizeof(a++) = %d\n", sizeof a++);
2847 printf("a=%d\n", a);
2848 ptr = NULL;
2849 printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
2850
2851 /* The type of sizeof should be as large as a pointer, actually
2852 it should be size_t. */
2853 printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
2854 uintptr_t t = 1;
2855 uintptr_t t2;
2856 /* Effectively <<32, but defined also on 32bit machines. */
2857 t <<= 16;
2858 t <<= 16;
2859 t++;
2860 /* This checks that sizeof really can be used to manipulate
2861 uintptr_t objects, without truncation. */
2862 t2 = t & -sizeof(uintptr_t);
2863 printf ("%lu %lu\n", t, t2);
2864
2865 /* some alignof tests */
2866 printf("__alignof__(int) = %d\n", __alignof__(int));
2867 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
2868 printf("__alignof__(short) = %d\n", __alignof__(short));
2869 printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
2870 printf("__alignof__(char) = %d\n", __alignof__(char));
2871 printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
2872 printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
2873
2874 /* sizes of VLAs need to be evaluated even inside sizeof: */
2875 a = 2;
2876 printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
2877 /* And checking if sizeof compound literal works. Parenthesized: */
2878 printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
2879 sizeof( (struct {int i; int j;}){4,5} ));
2880 /* And as direct sizeof argument (as unary expression): */
2881 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
2882 sizeof (struct {short i; short j;}){4,5} );
2883
2884 /* sizeof(x && y) should be sizeof(int), even if constant
2885 evaluating is possible. */
2886 printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
2887 printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
2888 printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
2889 printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
2890}
2891
2892void typeof_test(void)
2893{
2894 double a;
2895 typeof(a) b;
2896 typeof(float) c;
2897
2898 a = 1.5;
2899 b = 2.5;
2900 c = 3.5;
2901 printf("a=%f b=%f c=%f\n", a, b, c);
2902}
2903
2904
2905struct hlist_node;
2906struct hlist_head {
2907 struct hlist_node *first, *last;
2908};
2909
2910void consume_ulong (unsigned long i)
2911{
2912 i = 0;
2913}
2914
2915void statement_expr_test(void)
2916{
2917 int a, i;
2918
2919 /* Basic stmt expr test */
2920 a = 0;
2921 for(i=0;i<10;i++) {
2922 a += 1 +
2923 ( { int b, j;
2924 b = 0;
2925 for(j=0;j<5;j++)
2926 b += j; b;
2927 } );
2928 }
2929 printf("a=%d\n", a);
2930
2931 /* Test that symbols aren't freed prematurely.
2932 With SYM_DEBUG valgrind will show a read from a freed
2933 symbol, and tcc will show an (invalid) warning on the initialization
2934 of 'ptr' below, if symbols are popped after the stmt expr. */
2935 void *v = (void*)39;
2936 typeof(({
2937 (struct hlist_node *)v;
2938 })) x;
2939 typeof (x)
2940 ptr = (struct hlist_node *)v;
2941
2942 /* This part used to segfault when symbols were popped prematurely.
2943 The symbols for the static local would be overwritten with
2944 helper symbols from the pre-processor expansions in between. */
2945#define some_attr __attribute__((aligned(1)))
2946#define tps(str) ({ \
2947 static const char *t some_attr = str; \
2948 t; \
2949 })
2950 printf ("stmtexpr: %s %s\n",
2951 tps("somerandomlongstring"),
2952 tps("anotherlongstring"));
2953
2954 /* Test that the three decls of 't' don't interact. */
2955 int t = 40;
2956 int b = ({ int t = 41; t; });
2957 int c = ({ int t = 42; t; });
2958
2959 /* Test that aggregate return values work. */
2960 struct hlist_head h
2961 = ({
2962 typedef struct hlist_head T;
2963 long pre = 48;
2964 T t = { (void*)43, (void*)44 };
2965 long post = 49;
2966 t;
2967 });
2968 printf ("stmtexpr: %d %d %d\n", t, b, c);
2969 printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
2970
2971 /* Test that we can give out addresses of local labels. */
2972 consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
2973}
2974
2975void local_label_test(void)
2976{
2977 int a;
2978 goto l1;
2979 l2:
2980 a = 1 + ({
2981 __label__ l1, l2, l3, l4;
2982 goto l1;
2983 l4:
2984 printf("aa1\n");
2985 goto l3;
2986 l2:
2987 printf("aa3\n");
2988 goto l4;
2989 l1:
2990 printf("aa2\n");
2991 goto l2;
2992 l3:;
2993 1;
2994 });
2995 printf("a=%d\n", a);
2996 return;
2997 l4:
2998 printf("bb1\n");
2999 goto l2;
3000 l1:
3001 printf("bb2\n");
3002 goto l4;
3003}
3004
3005/* inline assembler test */
3006#if defined(__i386__) || defined(__x86_64__)
3007
3008/* from linux kernel */
3009static char * strncat1(char * dest,const char * src,size_t count)
3010{
3011long d0, d1, d2, d3;
3012__asm__ __volatile__(
3013 "repne\n\t"
3014 "scasb\n\t"
3015 "dec %1\n\t"
3016 "mov %8,%3\n"
3017 "1:\tdec %3\n\t"
3018 "js 2f\n\t"
3019 "lodsb\n\t"
3020 "stosb\n\t"
3021 "testb %%al,%%al\n\t"
3022 "jne 1b\n"
3023 "2:\txor %2,%2\n\t"
3024 "stosb"
3025 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3026 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3027 : "memory");
3028return dest;
3029}
3030
3031static char * strncat2(char * dest,const char * src,size_t count)
3032{
3033long d0, d1, d2, d3;
3034__asm__ __volatile__(
3035 "repne scasb\n\t" /* one-line repne prefix + string op */
3036 "dec %1\n\t"
3037 "mov %8,%3\n"
3038 "1:\tdec %3\n\t"
3039 "js 2f\n\t"
3040 "lodsb\n\t"
3041 "stosb\n\t"
3042 "testb %%al,%%al\n\t"
3043 "jne 1b\n"
3044 "2:\txor %2,%2\n\t"
3045 "stosb"
3046 : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
3047 : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
3048 : "memory");
3049return dest;
3050}
3051
3052static inline void * memcpy1(void * to, const void * from, size_t n)
3053{
3054long d0, d1, d2;
3055__asm__ __volatile__(
3056 "rep ; movsl\n\t"
3057 "testb $2,%b4\n\t"
3058 "je 1f\n\t"
3059 "movsw\n"
3060 "1:\ttestb $1,%b4\n\t"
3061 "je 2f\n\t"
3062 "movsb\n"
3063 "2:"
3064 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3065 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3066 : "memory");
3067return (to);
3068}
3069
3070static inline void * memcpy2(void * to, const void * from, size_t n)
3071{
3072long d0, d1, d2;
3073__asm__ __volatile__(
3074 "rep movsl\n\t" /* one-line rep prefix + string op */
3075 "testb $2,%b4\n\t"
3076 "je 1f\n\t"
3077 "movsw\n"
3078 "1:\ttestb $1,%b4\n\t"
3079 "je 2f\n\t"
3080 "movsb\n"
3081 "2:"
3082 : "=&c" (d0), "=&D" (d1), "=&S" (d2)
3083 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
3084 : "memory");
3085return (to);
3086}
3087
3088static __inline__ void sigaddset1(unsigned int *set, int _sig)
3089{
3090 __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
3091}
3092
3093static __inline__ void sigdelset1(unsigned int *set, int _sig)
3094{
3095 asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
3096}
3097
3098static __inline__ __const__ unsigned int swab32(unsigned int x)
3099{
3100 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
3101 "rorl $16,%0\n\t" /* swap words */
3102 "xchgb %b0,%h0" /* swap higher bytes */
3103 :"=" "q" (x)
3104 : "0" (x));
3105 return x;
3106}
3107
3108static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
3109{
3110 unsigned long long res;
3111#ifdef __x86_64__
3112 /* Using the A constraint is wrong (it means rdx:rax, which is too large)
3113 but still test the 32bit->64bit mull. */
3114 unsigned int resh, resl;
3115 __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
3116 res = ((unsigned long long)resh << 32) | resl;
3117#else
3118 __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
3119#endif
3120 return res;
3121}
3122
3123static __inline__ unsigned long long inc64(unsigned long long a)
3124{
3125 unsigned long long res;
3126#ifdef __x86_64__
3127 /* Using the A constraint is wrong, and increments are tested
3128 elsewhere. */
3129 res = a + 1;
3130#else
3131 __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
3132#endif
3133 return res;
3134}
3135
3136struct struct123 {
3137 int a;
3138 int b;
3139};
3140struct struct1231 {
3141 unsigned long addr;
3142};
3143
3144unsigned long mconstraint_test(struct struct1231 *r)
3145{
3146 unsigned long ret;
3147 unsigned int a[2];
3148 a[0] = 0;
3149 __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
3150 : "=&r" (ret), "=m" (a)
3151 : "m" (*(struct struct123 *)r->addr));
3152 return ret + a[0];
3153}
3154
3155#ifdef __x86_64__
3156int fls64(unsigned long long x)
3157{
3158 int bitpos = -1;
3159 asm("bsrq %1,%q0"
3160 : "+r" (bitpos)
3161 : "rm" (x));
3162 return bitpos + 1;
3163}
3164#endif
3165
3166void other_constraints_test(void)
3167{
3168 unsigned long ret;
3169 int var;
3170#ifndef _WIN64
3171 __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
3172 printf ("oc1: %d\n", ret == (unsigned long)&var);
3173#endif
3174}
3175
3176#ifndef _WIN32
3177/* Test global asm blocks playing with aliases. */
3178void base_func(void)
3179{
3180 printf ("asmc: base\n");
3181}
3182
3183extern void override_func1 (void);
3184extern void override_func2 (void);
3185
3186asm(".weak override_func1\n.set override_func1, base_func");
3187asm(".set override_func1, base_func");
3188asm(".set override_func2, base_func");
3189
3190void override_func2 (void)
3191{
3192 printf ("asmc: override2\n");
3193}
3194
3195/* This checks a construct used by the linux kernel to encode
3196 references to strings by PC relative references. */
3197extern int bug_table[] __attribute__((section("__bug_table")));
3198char * get_asm_string (void)
3199{
3200 extern int some_symbol;
3201 asm volatile (".globl some_symbol\n"
3202 "jmp .+6\n"
3203 "1:\n"
3204 "some_symbol: .long 0\n"
3205 ".pushsection __bug_table, \"a\"\n"
3206 ".globl bug_table\n"
3207 "bug_table:\n"
3208 /* The first entry (1b-2b) is unused in this test,
3209 but we include it to check if cross-section
3210 PC-relative references work. */
3211 "2:\t.long 1b - 2b, %c0 - 2b\n"
3212 ".popsection\n" : : "i" ("A string"));
3213 char * str = ((char*)bug_table) + bug_table[1];
3214 return str;
3215}
3216
3217/* This checks another constructs with local labels. */
3218extern unsigned char alld_stuff[];
3219asm(".data\n"
3220 ".byte 41\n"
3221 "alld_stuff:\n"
3222 "661:\n"
3223 ".byte 42\n"
3224 "662:\n"
3225 ".pushsection .data.ignore\n"
3226 ".long 661b - .\n" /* This reference to 661 generates an external sym
3227 which shouldn't somehow overwrite the offset that's
3228 already determined for it. */
3229 ".popsection\n"
3230 ".byte 662b - 661b\n" /* So that this value is undeniably 1. */);
3231
3232void asm_local_label_diff (void)
3233{
3234 printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
3235}
3236
3237/* This checks that static local variables are available from assembler. */
3238void asm_local_statics (void)
3239{
3240 static int localint = 41;
3241 asm("incl %0" : "+m" (localint));
3242 printf ("asm_local_statics: %d\n", localint);
3243}
3244#endif
3245
3246static
3247unsigned int set;
3248
3249void fancy_copy (unsigned *in, unsigned *out)
3250{
3251 asm volatile ("" : "=r" (*out) : "0" (*in));
3252}
3253
3254void fancy_copy2 (unsigned *in, unsigned *out)
3255{
3256 asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
3257}
3258
3259#if defined __x86_64__ && !defined _WIN64
3260void clobber_r12(void)
3261{
3262 asm volatile("mov $1, %%r12" ::: "r12");
3263}
3264#endif
3265
3266void test_high_clobbers(void)
3267{
3268#if defined __x86_64__ && !defined _WIN64
3269 register long val asm("r12");
3270 long val2;
3271 /* This tests if asm clobbers correctly save/restore callee saved
3272 registers if they are clobbered and if it's the high 8 x86-64
3273 registers. This is fragile for GCC as the constraints do not
3274 correctly capture the data flow, but good enough for us. */
3275 asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
3276 clobber_r12();
3277 asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
3278 printf("asmhc: 0x%x\n", val2);
3279#endif
3280}
3281
3282static long cpu_number;
3283void trace_console(long len, long len2)
3284{
3285#ifdef __x86_64__
3286 /* This generated invalid code when the emission of the switch
3287 table isn't disabled. The asms are necessary to show the bug,
3288 normal statements don't work (they need to generate some code
3289 even under nocode_wanted, which normal statements don't do,
3290 but asms do). Also at least these number of cases is necessary
3291 to generate enough "random" bytes. They ultimately are enough
3292 to create invalid instruction patterns to which the first
3293 skip-to-decision-table jump jumps. If decision table emission
3294 is disabled all of this is no problem.
3295
3296 It also is necessary that the switches are in a statement expression
3297 (which has the property of not being enterable from outside. no
3298 matter what). */
3299 if (0
3300 &&
3301 ({
3302 long pscr_ret__;
3303 switch(len) {
3304 case 4:
3305 {
3306 long pfo_ret__;
3307 switch (len2) {
3308 case 8: printf("bla"); pfo_ret__ = 42; break;
3309 }
3310 pscr_ret__ = pfo_ret__;
3311 }
3312 break;
3313 case 8:
3314 {
3315 long pfo_ret__;
3316 switch (len2) {
3317 case 1:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3318 case 2:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3319 case 4:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3320 case 8:asm("movq %1,%0": "=r" (pfo_ret__) : "m" (cpu_number)); break;
3321 default: printf("impossible\n");
3322 }
3323 pscr_ret__ = pfo_ret__;
3324 };
3325 break;
3326 }
3327 pscr_ret__;
3328 }))
3329 {
3330 printf("huh?\n");
3331 }
3332#endif
3333}
3334
3335void test_asm_dead_code(void)
3336{
3337 long rdi;
3338 /* Try to make sure that xdi contains a zero, and hence will
3339 lead to a segfault if the next asm is evaluated without
3340 arguments being set up. */
3341 asm volatile ("" : "=D" (rdi) : "0" (0));
3342 (void)sizeof (({
3343 int var;
3344 /* This shouldn't trigger a segfault, either the argument
3345 registers need to be set up and the asm emitted despite
3346 this being in an unevaluated context, or both the argument
3347 setup _and_ the asm emission need to be suppressed. The latter
3348 is better. Disabling asm code gen when suppression is on
3349 also fixes the above trace_console bug, but that came earlier
3350 than asm suppression. */
3351 asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
3352 var;
3353 }));
3354}
3355
3356void test_asm_call(void)
3357{
3358#if defined __x86_64__ && !defined _WIN64
3359 static char str[] = "PATH";
3360 char *s;
3361 /* This tests if a reference to an undefined symbol from an asm
3362 block, which isn't otherwise referenced in this file, is correctly
3363 regarded as global symbol, so that it's resolved by other object files
3364 or libraries. We chose getenv here, which isn't used anywhere else
3365 in this file. (If we used e.g. printf, which is used we already
3366 would have a global symbol entry, not triggering the bug which is
3367 tested here). */
3368 /* two pushes so stack remains aligned */
3369 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
3370#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__))
3371 "call getenv@plt;"
3372#else
3373 "call getenv;"
3374#endif
3375 "pop %%rdi; pop %%rdi"
3376 : "=a" (s) : "r" (str));
3377 printf("asmd: %s\n", s);
3378#endif
3379}
3380
3381#if defined __x86_64__
3382# define RX "(%rip)"
3383#else
3384# define RX
3385#endif
3386
3387void asm_dot_test(void)
3388{
3389 int x;
3390 for (x = 1;; ++x) {
3391 int r = x;
3392 switch (x) {
3393 case 1:
3394 asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
3395 case 2:
3396 asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
3397 case 3:
3398 asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4");
3399 asm(".text; mov X"RX",%eax; jmp p0");
3400 case 4:
3401 asm(".data; X=.; .int 789; Y=.; .int 999");
3402 asm(".text; mov X"RX",%eax; X=Y; jmp p0");
3403 case 0:
3404 asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
3405 }
3406 if (r == x)
3407 break;
3408 printf("asm_dot_test %d: %d\n", x, r);
3409 }
3410}
3411
3412void asm_test(void)
3413{
3414 char buf[128];
3415 unsigned int val, val2;
3416 struct struct123 s1;
3417 struct struct1231 s2 = { (unsigned long)&s1 };
3418 /* Hide the outer base_func, but check later that the inline
3419 asm block gets the outer one. */
3420 int base_func = 42;
3421 void override_func3 (void);
3422 unsigned long asmret;
3423#ifdef BOOL_ISOC99
3424 _Bool somebool;
3425#endif
3426 register int regvar asm("%esi");
3427
3428 printf("inline asm:\n");
3429
3430 // parse 0x1E-1 as 3 tokens in asm mode
3431 asm volatile ("mov $0x1E-1,%eax");
3432
3433 /* test the no operand case */
3434 asm volatile ("xorl %eax, %eax");
3435
3436 memcpy1(buf, "hello", 6);
3437 strncat1(buf, " worldXXXXX", 3);
3438 printf("%s\n", buf);
3439
3440 memcpy2(buf, "hello", 6);
3441 strncat2(buf, " worldXXXXX", 3);
3442 printf("%s\n", buf);
3443
3444 /* 'A' constraint test */
3445 printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
3446 printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
3447
3448 s1.a = 42;
3449 s1.b = 43;
3450 printf("mconstraint: %d", mconstraint_test(&s2));
3451 printf(" %d %d\n", s1.a, s1.b);
3452 other_constraints_test();
3453 set = 0xff;
3454 sigdelset1(&set, 2);
3455 sigaddset1(&set, 16);
3456 /* NOTE: we test here if C labels are correctly restored after the
3457 asm statement */
3458 goto label1;
3459 label2:
3460 __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
3461 printf("set=0x%x\n", set);
3462 val = 0x01020304;
3463 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
3464#ifndef _WIN32
3465 override_func1();
3466 override_func2();
3467 /* The base_func ref from the following inline asm should find
3468 the global one, not the local decl from this function. */
3469 asm volatile(".weak override_func3\n.set override_func3, base_func");
3470 override_func3();
3471 printf("asmstr: %s\n", get_asm_string());
3472 asm_local_label_diff();
3473 asm_local_statics();
3474#endif
3475 /* Check that we can also load structs of appropriate layout
3476 into registers. */
3477 asm volatile("" : "=r" (asmret) : "0"(s2));
3478 if (asmret != s2.addr)
3479 printf("asmstr: failed\n");
3480#ifdef BOOL_ISOC99
3481 /* Check that the typesize correctly sets the register size to
3482 8 bit. */
3483 asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
3484 if (!somebool)
3485 printf("asmbool: failed\n");
3486#endif
3487 val = 43;
3488 fancy_copy (&val, &val2);
3489 printf ("fancycpy(%d)=%d\n", val, val2);
3490 val = 44;
3491 fancy_copy2 (&val, &val2);
3492 printf ("fancycpy2(%d)=%d\n", val, val2);
3493 asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
3494 printf ("regvar=%x\n", regvar);
3495 test_high_clobbers();
3496 trace_console(8, 8);
3497 test_asm_dead_code();
3498 test_asm_call();
3499 asm_dot_test();
3500 return;
3501 label1:
3502 goto label2;
3503}
3504
3505#else
3506
3507void asm_test(void)
3508{
3509}
3510
3511#endif
3512
3513#define COMPAT_TYPE(type1, type2) \
3514{\
3515 printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
3516 __builtin_types_compatible_p (type1, type2));\
3517}
3518
3519int constant_p_var;
3520
3521void builtin_test(void)
3522{
3523 short s;
3524 int i;
3525 long long ll;
3526#if GCC_MAJOR >= 3
3527 COMPAT_TYPE(int, int);
3528 COMPAT_TYPE(int, unsigned int);
3529 COMPAT_TYPE(int, char);
3530 COMPAT_TYPE(int, const int);
3531 COMPAT_TYPE(int, volatile int);
3532 COMPAT_TYPE(int *, int *);
3533 COMPAT_TYPE(int *, void *);
3534 COMPAT_TYPE(int *, const int *);
3535 COMPAT_TYPE(char *, unsigned char *);
3536 COMPAT_TYPE(char *, signed char *);
3537 COMPAT_TYPE(char *, char *);
3538/* space is needed because tcc preprocessor introduces a space between each token */
3539 COMPAT_TYPE(char * *, void *);
3540#endif
3541 printf("res = %d\n", __builtin_constant_p(1));
3542 printf("res = %d\n", __builtin_constant_p(1 + 2));
3543 printf("res = %d\n", __builtin_constant_p(&constant_p_var));
3544 printf("res = %d\n", __builtin_constant_p(constant_p_var));
3545 printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
3546 s = 1;
3547 ll = 2;
3548 i = __builtin_choose_expr (1 != 0, ll, s);
3549 printf("bce: %d\n", i);
3550 i = __builtin_choose_expr (1 != 1, ll, s);
3551 printf("bce: %d\n", i);
3552 i = sizeof (__builtin_choose_expr (1, ll, s));
3553 printf("bce: %d\n", i);
3554 i = sizeof (__builtin_choose_expr (0, ll, s));
3555 printf("bce: %d\n", i);
3556
3557 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
3558}
3559
3560#ifndef _WIN32
3561extern int __attribute__((weak)) weak_f1(void);
3562extern int __attribute__((weak)) weak_f2(void);
3563extern int weak_f3(void);
3564extern int __attribute__((weak)) weak_v1;
3565extern int __attribute__((weak)) weak_v2;
3566extern int weak_v3;
3567
3568extern int (*weak_fpa)() __attribute__((weak));
3569extern int __attribute__((weak)) (*weak_fpb)();
3570extern __attribute__((weak)) int (*weak_fpc)();
3571
3572extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
3573extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x") ;
3574extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
3575extern int weak_asm_v1 asm("weak_asm_v1x") __attribute((weak));
3576extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ;
3577extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
3578
3579static const size_t dummy = 0;
3580extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy")));
3581extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2;
3582extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3;
3583
3584int some_lib_func(void);
3585int dummy_impl_of_slf(void) { return 444; }
3586int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf")));
3587
3588int weak_toolate() __attribute__((weak));
3589int weak_toolate() { return 0; }
3590
3591void __attribute__((weak)) weak_test(void)
3592{
3593 printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
3594 printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123);
3595 printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123);
3596 printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123);
3597 printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123);
3598 printf("weak_v3=%d\n",&weak_v3 ? weak_v3 : 123);
3599
3600 printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
3601 printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
3602 printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
3603
3604 printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
3605 printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
3606 printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
3607 printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
3608 printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
3609 printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
3610 printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
3611}
3612
3613int __attribute__((weak)) weak_f2() { return 222; }
3614int __attribute__((weak)) weak_f3() { return 333; }
3615int __attribute__((weak)) weak_v2 = 222;
3616int __attribute__((weak)) weak_v3 = 333;
3617#endif
3618
3619void const_func(const int a)
3620{
3621}
3622
3623void const_warn_test(void)
3624{
3625 const_func(1);
3626}
3627
3628struct condstruct {
3629 int i;
3630};
3631
3632int getme (struct condstruct *s, int i)
3633{
3634 int i1 = (i == 0 ? 0 : s)->i;
3635 int i2 = (i == 0 ? s : 0)->i;
3636 int i3 = (i == 0 ? (void*)0 : s)->i;
3637 int i4 = (i == 0 ? s : (void*)0)->i;
3638 return i1 + i2 + i3 + i4;
3639}
3640
3641struct global_data
3642{
3643 int a[40];
3644 int *b[40];
3645};
3646
3647struct global_data global_data;
3648
3649int global_data_getstuff (int *, int);
3650
3651void global_data_callit (int i)
3652{
3653 *global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
3654}
3655
3656int global_data_getstuff (int *p, int i)
3657{
3658 return *p + i;
3659}
3660
3661void global_data_test (void)
3662{
3663 global_data.a[0] = 42;
3664 global_data.b[0] = &global_data.a[0];
3665 global_data_callit (0);
3666 printf ("%d\n", global_data.a[0]);
3667}
3668
3669struct cmpcmpS
3670{
3671 unsigned char fill : 3;
3672 unsigned char b1 : 1;
3673 unsigned char b2 : 1;
3674 unsigned char fill2 : 3;
3675};
3676
3677int glob1, glob2, glob3;
3678
3679void compare_comparisons (struct cmpcmpS *s)
3680{
3681 if (s->b1 != (glob1 == glob2)
3682 || (s->b2 != (glob1 == glob3)))
3683 printf ("comparing comparisons broken\n");
3684}
3685
3686void cmp_comparison_test(void)
3687{
3688 struct cmpcmpS s;
3689 s.b1 = 1;
3690 glob1 = 42; glob2 = 42;
3691 s.b2 = 0;
3692 glob3 = 43;
3693 compare_comparisons (&s);
3694}
3695
3696int fcompare (double a, double b, int code)
3697{
3698 switch (code) {
3699 case 0: return a == b;
3700 case 1: return a != b;
3701 case 2: return a < b;
3702 case 3: return a >= b;
3703 case 4: return a > b;
3704 case 5: return a <= b;
3705 }
3706}
3707
3708void math_cmp_test(void)
3709{
3710 double nan = 0.0/0.0;
3711 double one = 1.0;
3712 double two = 2.0;
3713 int comp = 0;
3714#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
3715
3716 /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
3717 And it does this in various ways so that all code generation paths
3718 are checked (generating inverted tests, or non-inverted tests, or
3719 producing a 0/1 value without jumps (that's done in the fcompare
3720 function). */
3721#define FCMP(a,b,op,iop,code) \
3722 if (fcompare (a,b,code)) \
3723 bug (a,b,op,iop,1); \
3724 if (a op b) \
3725 bug (a,b,op,iop,2); \
3726 if (a iop b) \
3727 ; \
3728 else \
3729 bug (a,b,op,iop,3); \
3730 if ((a op b) || comp) \
3731 bug (a,b,op,iop,4); \
3732 if ((a iop b) || comp) \
3733 ; \
3734 else \
3735 bug (a,b,op,iop,5);
3736
3737 /* Equality tests. */
3738 FCMP(nan, nan, ==, !=, 0);
3739 FCMP(one, two, ==, !=, 0);
3740 FCMP(one, one, !=, ==, 1);
3741 /* Non-equality is a bit special. */
3742 if (!fcompare (nan, nan, 1))
3743 bug (nan, nan, !=, ==, 6);
3744
3745 /* Relational tests on numbers. */
3746 FCMP(two, one, <, >=, 2);
3747 FCMP(one, two, >=, <, 3);
3748 FCMP(one, two, >, <=, 4);
3749 FCMP(two, one, <=, >, 5);
3750
3751 /* Relational tests on NaNs. Note that the inverse op here is
3752 always !=, there's no operator in C that is equivalent to !(a < b),
3753 when NaNs are involved, same for the other relational ops. */
3754 FCMP(nan, nan, <, !=, 2);
3755 FCMP(nan, nan, >=, !=, 3);
3756 FCMP(nan, nan, >, !=, 4);
3757 FCMP(nan, nan, <=, !=, 5);
3758}
3759
3760double get100 () { return 100.0; }
3761
3762void callsave_test(void)
3763{
3764#if defined __i386__ || defined __x86_64__ || defined __arm__
3765 int i, s; double *d; double t;
3766 s = sizeof (double);
3767 printf ("callsavetest: %d\n", s);
3768 d = alloca (sizeof(double));
3769 d[0] = 10.0;
3770 /* x86-64 had a bug were the next call to get100 would evict
3771 the lvalue &d[0] as VT_LLOCAL, and the reload would be done
3772 in int type, not pointer type. When alloca returns a pointer
3773 with the high 32 bit set (which is likely on x86-64) the access
3774 generates a segfault. */
3775 i = d[0] > get100 ();
3776 printf ("%d\n", i);
3777#endif
3778}
3779
3780
3781void bfa3(ptrdiff_t str_offset)
3782{
3783 printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
3784}
3785void bfa2(ptrdiff_t str_offset)
3786{
3787 printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
3788 bfa3(str_offset);
3789}
3790void bfa1(ptrdiff_t str_offset)
3791{
3792 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
3793 bfa2(str_offset);
3794}
3795
3796void builtin_frame_address_test(void)
3797{
3798/* builtin_frame_address fails on ARM with gcc which make test3 fail */
3799#ifndef __arm__
3800 char str[] = "__builtin_frame_address";
3801 char *fp0 = __builtin_frame_address(0);
3802
3803 printf("str: %s\n", str);
3804 bfa1(str-fp0);
3805#endif
3806}
3807
3808char via_volatile (char i)
3809{
3810 char volatile vi;
3811 vi = i;
3812 return vi;
3813}
3814
3815struct __attribute__((__packed__)) Spacked {
3816 char a;
3817 short b;
3818 int c;
3819};
3820struct Spacked spacked;
3821typedef struct __attribute__((__packed__)) {
3822 char a;
3823 short b;
3824 int c;
3825} Spacked2;
3826Spacked2 spacked2;
3827typedef struct Spacked3_s {
3828 char a;
3829 short b;
3830 int c;
3831} __attribute__((__packed__)) Spacked3;
3832Spacked3 spacked3;
3833struct gate_struct64 {
3834 unsigned short offset_low;
3835 unsigned short segment;
3836 unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
3837 unsigned short offset_middle;
3838 unsigned offset_high;
3839 unsigned zero1;
3840} __attribute__((packed));
3841typedef struct gate_struct64 gate_desc;
3842gate_desc a_gate_desc;
3843void attrib_test(void)
3844{
3845#ifndef _WIN32
3846 printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
3847 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
3848 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
3849 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
3850#endif
3851}
3852extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
3853strange_attrib_placement (void);
3854
3855void * __attribute__((__unused__)) get_void_ptr (void *a)
3856{
3857 return a;
3858}
3859
3860/* This part checks for a bug in TOK_GET (used for inline expansion),
3861 where the large long long constant left the the high bits set for
3862 the integer constant token. */
3863static inline
3864int __get_order(unsigned long long size)
3865{
3866 int order;
3867 size -= 0xffff880000000000ULL; // this const left high bits set in the token
3868 {
3869 struct S { int i : 1; } s; // constructed for this '1'
3870 }
3871 order = size;
3872 return order;
3873}
3874
3875/* This just forces the above inline function to be actually emitted. */
3876int force_get_order(unsigned long s)
3877{
3878 return __get_order(s);
3879}
Note: See TracBrowser for help on using the repository browser.