2 * TCC auto test program
6 /* identify the configured reference compiler in use */
11 /* Unfortunately, gcc version < 3 does not handle that! */
14 /* only gcc 3 handles _Bool correctly */
17 /* __VA_ARGS__ and __func__ support */
21 typedef __SIZE_TYPE__
uintptr_t;
24 #if defined(_WIN32) || \
25 (defined(__arm__) && \
26 (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)))
27 #define LONG_LONG_FORMAT "%lld"
28 #define ULONG_LONG_FORMAT "%llu"
30 #define LONG_LONG_FORMAT "%Ld"
31 #define ULONG_LONG_FORMAT "%Lu"
34 // MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
35 #if defined(_WIN32) && defined(__GNUC__)
36 #define LONG_DOUBLE double
37 #define LONG_DOUBLE_LITERAL(x) x
39 #define LONG_DOUBLE long double
40 #define LONG_DOUBLE_LITERAL(x) x ## L
43 /* test various include syntaxes */
45 #define TCCLIB_INC <tcclib.h>
46 #define TCCLIB_INC1 <tcclib
47 #define TCCLIB_INC2 h>
48 #define TCCLIB_INC3 "tcclib.h"
52 #include TCCLIB_INC1.TCCLIB_INC2
54 #include TCCLIB_INC1.h>
64 /* Test two more ways to include a file named like a pp-number */
65 #define INC(name) <tests/name.h>
66 #define funnyname 42test.h
69 /* clang's preprocessor is broken in this regard and adds spaces
70 to the tokens 'incdir' and 'funnyname' when expanding */
71 #define incname <tests/42test.h>
73 #define incname < incdir funnyname >
75 #define __stringify(x) #x
76 #define stringify(x) __stringify(x)
79 #include stringify(funnyname)
83 void forward_ref(void);
86 /* Line joining happens before tokenization, so the following
87 must be parsed as ellipsis. */
88 void funny_line_continuation (int, ..\
94 #define M1(a, b) (a) + (b)
98 #define glue(a, b) a ## b
99 #define xglue(a, b) glue(a, b)
100 #define HIGHLOW "hello"
101 #define LOW LOW ", world"
103 static int onetwothree
= 123;
104 #define onetwothree4 onetwothree
105 #define onetwothree xglue(onetwothree,4)
107 #define min(a, b) ((a) < (b) ? (a) : (b))
110 #define dprintf(level,...) printf(__VA_ARGS__)
113 /* gcc vararg macros */
114 #define dprintf1(level, fmt, args...) printf(fmt, ## args)
116 #define MACRO_NOARGS()
133 /* We try to handle this syntax. Make at least sure it doesn't segfault. */
134 char invalid_function_def()[] {return 0;}
137 #define __INT64_C(c) c ## LL
138 #define INT64_MIN (-__INT64_C(9223372036854775807)-1)
146 #define spin_lock(lock) do { } while (0)
147 #define wq_spin_lock spin_lock
148 #define TEST2() wq_spin_lock(a)
150 void macro_test(void)
153 printf("aaa=%d\n", AAA
);
155 printf("min=%d\n", min(1, min(2, -1)));
157 printf("s1=%s\n", glue(HIGH
, LOW
));
158 printf("s2=%s\n", xglue(HIGH
, LOW
));
159 printf("s3=%s\n", str("c"));
160 printf("s4=%s\n", str(a1
));
161 printf("B3=%d\n", B3
);
163 printf("onetwothree=%d\n", onetwothree
);
166 printf("A defined\n");
169 printf("B defined\n");
172 printf("A defined\n");
174 printf("A not defined\n");
177 printf("B defined\n");
179 printf("B not defined\n");
183 printf("A defined\n");
185 printf("B1 defined\n");
187 printf("B1 not defined\n");
190 printf("A not defined\n");
192 printf("B2 defined\n");
194 printf("B2 not defined\n");
199 printf("test true1\n");
202 printf("test true2\n");
205 printf("test true3\n");
208 printf("test trueA\n");
211 printf("test trueB\n");
226 /* not strictly preprocessor, but we test it there */
228 printf("__func__ = %s\n", __func__
);
229 dprintf(1, "vaarg=%d\n", 1);
231 dprintf1(1, "vaarg1\n");
232 dprintf1(1, "vaarg1=%d\n", 2);
233 dprintf1(1, "vaarg1=%d %d\n", 1, 2);
236 printf("func='%s'\n", __FUNCTION__
);
238 /* complicated macros in glibc */
239 printf("INT64_MIN=" LONG_LONG_FORMAT
"\n", INT64_MIN
);
249 /* macro function with argument outside the macro string */
250 #define MF_s MF_hello
251 #define MF_hello(msg) printf("%s\n",msg)
253 #define MF_t printf("tralala\n"); MF_hello
258 /* test macro substitution inside args (should not eat stream) */
259 printf("qq=%d\n", qq(qq
)(2));
261 /* test zero argument case. NOTE: gcc 2.95.x does not accept a
262 null argument without a space. gcc 3.2 fixes that. */
265 printf("qq1=%d\n", qq1( ));
267 /* comment with stray handling *\
269 /* this is a valid *\/ comment */
270 /* this is a valid comment *\*/
274 /* test function macro substitution when the function name is
278 /* And again when the name and parentheses are separated by a
280 TEST2
/* the comment */ ();
282 printf("basefromheader %s\n", get_basefile_from_header());
283 printf("base %s\n", __BASE_FILE__
);
285 /* Some compilers (clang) prepend './' to __FILE__ from included
287 const char *fn
= get_file_from_header();
288 if (fn
[0] == '.' && fn
[1] == '/')
290 printf("filefromheader %s\n", fn
);
292 printf("file %s\n", __FILE__
);
294 /* Check that funnily named include was in fact included */
295 have_included_42test_h
= 1;
296 have_included_42test_h_second
= 1;
297 have_included_42test_h_third
= 1;
299 /* Check that we don't complain about stray \ here */
300 printf("print a backslash: %s\n", stringify(\\));
304 static void print_num(char *fn
, int line
, int num
) {
305 printf("fn %s, line %d, num %d\n", fn
, line
, num
);
308 void recursive_macro_test(void)
311 #define ELF32_ST_TYPE(val) ((val) & 0xf)
312 #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
313 #define STB_WEAK 2 /* Weak symbol */
314 #define ELFW(type) ELF##32##_##type
315 printf("%d\n", ELFW(ST_INFO
)(STB_WEAK
, ELFW(ST_TYPE
)(123)));
319 #define print_num(x) print_num(__FILE__,__LINE__,x)
321 WRAP(print_num(123));
322 WRAP(WRAP(print_num(123)));
324 static struct recursive_macro
{ int rm_field
; } G
;
325 #define rm_field (G.rm_field)
326 printf("rm_field = %d\n", rm_field
);
327 printf("rm_field = %d\n", WRAP(rm_field
));
328 WRAP((printf("rm_field = %d %d\n", rm_field
, WRAP(rm_field
))));
345 #if !defined(__TINYC__) && (__GNUC__ >= 8)
346 /* Old GCCs don't regard "foo"[1] as constant, even in GNU dialect. */
347 #define CONSTANTINDEXEDSTRLIT
349 char str_ag1
[] = "b";
350 char str_ag2
[] = { "b" };
351 /*char str_bg1[] = ("cccc"); GCC accepts this with pedantic warning, TCC not */
352 #ifdef CONSTANTINDEXEDSTRLIT
353 char str_ag3
[] = { "ab"[1], 0 };
354 char str_x
[2] = { "xy" "z"[2], 0 };
356 char *str_ar
[] = { "one", "two" };
357 struct str_SS
{unsigned char a
[3], b
; };
358 struct str_SS str_sinit15
= { "r" };
359 struct str_SS str_sinit16
[] = { { "q" }, 2 };
361 static void string_test2()
364 char a3
[2] = { "p" };
365 char a4
[2] = { "ab" "c"[2], 0 };
366 char *pa1
= "def" + 1;
367 char *pa2
= { "xyz" + 1 };
369 struct str_SS ss
= { { [0 ... 1] = 'a' }, 0 };
370 #ifndef CONSTANTINDEXEDSTRLIT
371 char str_ag3
[] = { "ab"[1], 0 };
372 char str_x
[2] = { "xy" "z"[2], 0 };
374 puts("string_test2");
381 puts(str_sinit16
[0].a
);
386 printf("%s\n", "bla");
390 puts(i
>= 0 ? "one" : "two");
395 void ps(const char *s
)
407 const char foo1_string
[] = "\
416 printf("\141\1423\143\n");/* dezdez test */
417 printf("\x41\x42\x43\x3a\n");
418 printf("c=%c\n", 'r');
419 printf("wc=%C 0x%lx %C\n", L
'a', L
'\x1234', L
'c');
420 printf("foo1_string='%s'\n", foo1_string
);
422 printf("wstring=%S\n", L
"abc");
423 printf("wstring=%S\n", L
"abc" L
"def" "ghi");
424 printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
425 printf("L'\\377'=%d L'\\xff'=%d\n", L
'\377', L
'\xff');
429 while ((b
= b
+ 1) < 96) {
433 printf("fib=%d\n", fib(33));
435 while (b
!= 0x80000000) {
443 void if1t(int n
, int a
, int b
, int c
)
445 if (a
&& b
) printf("if1t: %d 1 %d %d\n", n
, a
, b
);
446 if (a
&& !b
) printf("if1t: %d 2 %d %d\n", n
, a
, b
);
447 if (!a
&& b
) printf("if1t: %d 3 %d %d\n", n
, a
, b
);
448 if (!a
&& !b
) printf("if1t: %d 4 %d %d\n", n
, a
, b
);
449 if (a
|| b
) printf("if1t: %d 5 %d %d\n", n
, a
, b
);
450 if (a
|| !b
) printf("if1t: %d 6 %d %d\n", n
, a
, b
);
451 if (!a
|| b
) printf("if1t: %d 7 %d %d\n", n
, a
, b
);
452 if (!a
|| !b
) printf("if1t: %d 8 %d %d\n", n
, a
, b
);
453 if (a
&& b
|| c
) printf("if1t: %d 9 %d %d %d\n", n
, a
, b
, c
);
454 if (a
|| b
&& c
) printf("if1t: %d 10 %d %d %d\n", n
, a
, b
, c
);
455 if (a
> b
- 1 && c
) printf("if1t: %d 11 %d %d %d\n", n
, a
, b
, c
);
456 if (a
> b
- 1 || c
) printf("if1t: %d 12 %d %d %d\n", n
, a
, b
, c
);
457 if (a
> 0 && 1) printf("if1t: %d 13 %d %d %d\n", n
, a
, b
, c
);
458 if (a
> 0 || 0) printf("if1t: %d 14 %d %d %d\n", n
, a
, b
, c
);
463 if (0 && 1 || printf("if2t:ok\n") || 1)
464 printf("if2t:ok2\n");
465 printf("if2t:ok3\n");
470 volatile long long i
= 1;
471 if (i
<= 18446744073709551615ULL)
474 printf ("if3t:wrong 1\n");
494 for(i
= 0; i
< 10;i
++)
504 /* c99 for loop init test */
505 for (size_t count
= 1; count
< 3; count
++)
506 printf("count=%d\n", count
);
507 printf("count = %d\n", count
);
509 /* break/continue tests */
521 /* break/continue tests */
533 for(i
= 0;i
< 10;i
++) {
541 typedef int typedef_and_label
;
546 static void *label_table
[3] = { &&label1
, &&label2
, &&label3
};
550 /* This needs to parse as label, not as start of decl. */
562 /* we also test computed gotos (GCC extension) */
564 goto *label_table
[i
];
590 enum {E6
= 42, E7
, E8
} e
:8;
594 /* This is either 0 on L32 machines, or a large number
595 on L64 machines. We should be able to store this. */
596 EL_large
= ((unsigned long)0xf000 << 31) << 1,
599 enum { BIASU
= -1U<<31 };
600 enum { BIASS
= -1 << 31 };
602 static int getint(int i
)
607 return (int)(-1U << 31);
613 /* The following should give no warning */
615 struct S_enum s
= {E7
};
616 printf("%d %d %d %d %d %d %d\n", s
.e
,
617 E0
, E1
, E2
, E3
, E4
, E5
);
619 printf("b1=%d\n", b1
);
620 printf("enum large: %ld\n", EL_large
);
622 if (getint(0) == BIASU
)
623 printf("enum unsigned: ok\n");
625 printf("enum unsigned: wrong\n");
626 if (getint(0) == BIASS
)
627 printf("enum unsigned: ok\n");
629 printf("enum unsigned: wrong\n");
645 printf("a=%d\n", *a
);
647 printf("mytype2=%d\n", mytype2
);
657 void forward_ref(void)
659 printf("forward ok\n");
662 typedef struct struct1
{
682 struct struct1 st1
, st2
;
696 printf("g1=%d\n", g
);
703 printf("g2=%d\n", g
);
707 printf("g3=%d\n", g
);
711 printf("g4=%d\n", g
);
714 printf("g5=%d\n", g
);
723 for (int st2_i
= 1; st2_i
< 10; st2_i
++) {
726 printf("exloc: %d\n", st2_i
);
728 printf("exloc: %d\n", *st2_p
);
731 /* C has tentative definition, and they may be repeated. */
732 extern int st_global1
;
734 extern int st_global1
;
736 extern int st_global2
;
738 extern int st_global2
;
745 printf("sizeof(a) = %d\n", sizeof(a
));
746 printf("sizeof(\"a\") = %d\n", sizeof("a"));
748 printf("sizeof(__func__) = %d\n", sizeof(__func__
));
750 printf("sizeof tab %d\n", sizeof(tab
));
751 printf("sizeof tab2 %d\n", sizeof tab2
);
755 printf("%d %d %d\n", tab
[0], tab
[1], tab
[2]);
758 tab2
[i
][j
] = 10 * i
+ j
;
760 printf(" %3d", ((int *)tab2
)[i
]);
763 printf("sizeof(size_t)=%d\n", sizeof(size_t));
764 printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
771 printf("%d\n", a
+= 1);
772 printf("%d\n", a
-= 2);
773 printf("%d\n", a
*= 31232132);
774 printf("%d\n", a
/= 4);
775 printf("%d\n", a
%= 20);
776 printf("%d\n", a
&= 6);
777 printf("%d\n", a
^= 7);
778 printf("%d\n", a
|= 8);
779 printf("%d\n", a
>>= 3);
780 printf("%d\n", a
<<= 4);
784 printf("%d\n", a
+ 1);
785 printf("%d\n", a
- 2);
786 printf("%d\n", a
* 312);
787 printf("%d\n", a
/ 4);
788 printf("%d\n", b
/ 4);
789 printf("%d\n", (unsigned)b
/ 4);
790 printf("%d\n", a
% 20);
791 printf("%d\n", b
% 20);
792 printf("%d\n", (unsigned)b
% 20);
793 printf("%d\n", a
& 6);
794 printf("%d\n", a
^ 7);
795 printf("%d\n", a
| 8);
796 printf("%d\n", a
>> 3);
797 printf("%d\n", b
>> 3);
798 printf("%d\n", (unsigned)b
>> 3);
799 printf("%d\n", a
<< 4);
804 printf("%d\n", 12 + 1);
805 printf("%d\n", 12 - 2);
806 printf("%d\n", 12 * 312);
807 printf("%d\n", 12 / 4);
808 printf("%d\n", 12 % 20);
809 printf("%d\n", 12 & 6);
810 printf("%d\n", 12 ^ 7);
811 printf("%d\n", 12 | 8);
812 printf("%d\n", 12 >> 2);
813 printf("%d\n", 12 << 4);
817 printf("%d %d %d %d\n",
826 return (c
>= 'a' & c
<= 'z') | (c
>= 'A' & c
<= 'Z') | c
== '_';
829 /**********************/
831 int vstack
[10], *vstack_ptr
;
833 void vpush(int vt
, int vc
)
839 void vpop(int *ft
, int *fc
)
851 vstack_ptr
[-2] &= ~0xffffff80;
853 printf("res= %d %d\n", a
, b
);
856 int const_len_ar
[sizeof(1/0)]; /* div-by-zero, but in unevaluated context */
858 void constant_expr_test()
862 printf("%d\n", a
* 16);
863 printf("%d\n", a
* 1);
864 printf("%d\n", a
+ 0);
865 printf("%d\n", sizeof(const_len_ar
));
877 printf("diff=%d\n", q
- p
);
879 printf("inc=%d\n", p
- tab4
);
881 printf("dec=%d\n", p
- tab4
);
883 printf("inc=%d\n", p
- tab4
);
885 printf("dec=%d\n", p
- tab4
);
886 printf("add=%d\n", p
+ 3 - tab4
);
887 printf("add=%d\n", 3 + p
- tab4
);
889 /* check if 64bit support is ok */
892 printf("%p %p %ld\n", q
, p
, p
-q
);
893 printf("%d %d %d %d %d %d\n",
894 p
== q
, p
!= q
, p
< q
, p
<= q
, p
>= q
, p
> q
);
897 printf("%p %p %ld\n", q
, p
, p
-q
);
898 printf("%d %d %d %d %d %d\n",
899 p
== q
, p
!= q
, p
< q
, p
<= q
, p
>= q
, p
> q
);
900 p
= (int *)((char *)p
+ 0xf0000000);
901 printf("%p %p %ld\n", q
, p
, p
-q
);
902 printf("%d %d %d %d %d %d\n",
903 p
== q
, p
!= q
, p
< q
, p
<= q
, p
>= q
, p
> q
);
905 printf("%p %p %ld\n", q
, p
, p
-q
);
906 printf("%d %d %d %d %d %d\n",
907 p
== q
, p
!= q
, p
< q
, p
<= q
, p
>= q
, p
> q
);
912 struct size12 s
[2], *sp
= s
;
917 printf("%d\n", sp
[j
].i
);
921 p
= (int*)0x100000000UL
+ i
;
923 printf("largeptr: %p %d\n", p
, i
);
932 printf("%d\n", a
== a
);
933 printf("%d\n", a
!= a
);
935 printf("%d\n", a
< b
);
936 printf("%d\n", a
<= b
);
937 printf("%d\n", a
<= a
);
938 printf("%d\n", b
>= a
);
939 printf("%d\n", a
>= a
);
940 printf("%d\n", b
> a
);
942 printf("%d\n", (unsigned)a
< b
);
943 printf("%d\n", (unsigned)a
<= b
);
944 printf("%d\n", (unsigned)a
<= a
);
945 printf("%d\n", (unsigned)b
>= a
);
946 printf("%d\n", (unsigned)a
>= a
);
947 printf("%d\n", (unsigned)b
> a
);
970 struct __attribute__((aligned(16))) aligntest5
977 } __attribute__((aligned(16)));
982 struct aligntest5 altest5
[2];
983 struct aligntest6 altest6
[2];
985 /* altest7 is correctly aligned to 16 bytes also with TCC,
986 but __alignof__ returns the wrong result (4) because we
987 can't store the alignment yet when specified on symbols
988 directly (it's stored in the type so we'd need to make
989 a copy of it). -- FIXED */
990 struct aligntest7 altest7
[2] __attribute__((aligned(16)));
995 } __attribute__((aligned(4096)));
1006 unsigned long index
;
1010 unsigned long counters
;
1024 unsigned long compound_head
;
1025 unsigned int compound_dtor
;
1026 unsigned int compound_order
;
1029 } __attribute__((aligned(2 * sizeof(long))));
1031 typedef unsigned long long __attribute__((aligned(4))) unaligned_u64
;
1034 unsigned int buf_nr
;
1035 unaligned_u64 start_lba
;
1038 struct aligntest10
{
1039 unsigned int buf_nr
;
1040 unsigned long long start_lba
;
1049 printf("sizes: %d %d %d %d\n",
1050 sizeof(struct struct1
),
1051 sizeof(struct struct2
),
1052 sizeof(union union1
),
1053 sizeof(union union2
));
1054 printf("offsets: %d\n", (int)((char*)&st1
.u
.v1
- (char*)&st1
));
1058 printf("st1: %d %d %d\n",
1059 st1
.f1
, st1
.f2
, st1
.f3
);
1062 printf("union1: %d\n", st1
.u
.v1
);
1065 printf("union2: %d\n", u
.w1
);
1070 printf("st2: %d %d %d\n",
1071 s
->f1
, s
->f2
, s
->f3
);
1072 printf("str_addr=%x\n", (int)(uintptr_t)st1
.str
- (int)(uintptr_t)&st1
.f1
);
1074 /* align / size tests */
1075 printf("aligntest1 sizeof=%d alignof=%d\n",
1076 sizeof(struct aligntest1
), __alignof__(struct aligntest1
));
1077 printf("aligntest2 sizeof=%d alignof=%d\n",
1078 sizeof(struct aligntest2
), __alignof__(struct aligntest2
));
1079 printf("aligntest3 sizeof=%d alignof=%d\n",
1080 sizeof(struct aligntest3
), __alignof__(struct aligntest3
));
1081 printf("aligntest4 sizeof=%d alignof=%d\n",
1082 sizeof(struct aligntest4
), __alignof__(struct aligntest4
));
1083 printf("aligntest5 sizeof=%d alignof=%d\n",
1084 sizeof(struct aligntest5
), __alignof__(struct aligntest5
));
1085 printf("aligntest6 sizeof=%d alignof=%d\n",
1086 sizeof(struct aligntest6
), __alignof__(struct aligntest6
));
1087 printf("aligntest7 sizeof=%d alignof=%d\n",
1088 sizeof(struct aligntest7
), __alignof__(struct aligntest7
));
1089 printf("aligntest8 sizeof=%d alignof=%d\n",
1090 sizeof(struct aligntest8
), __alignof__(struct aligntest8
));
1091 printf("aligntest9 sizeof=%d alignof=%d\n",
1092 sizeof(struct aligntest9
), __alignof__(struct aligntest9
));
1093 printf("aligntest10 sizeof=%d alignof=%d\n",
1094 sizeof(struct aligntest10
), __alignof__(struct aligntest10
));
1095 printf("altest5 sizeof=%d alignof=%d\n",
1096 sizeof(altest5
), __alignof__(altest5
));
1097 printf("altest6 sizeof=%d alignof=%d\n",
1098 sizeof(altest6
), __alignof__(altest6
));
1099 printf("altest7 sizeof=%d alignof=%d\n",
1100 sizeof(altest7
), __alignof__(altest7
));
1102 /* empty structures (GCC extension) */
1103 printf("sizeof(struct empty) = %d\n", sizeof(struct empty
));
1104 printf("alignof(struct empty) = %d\n", __alignof__(struct empty
));
1106 printf("Large: sizeof=%d\n", sizeof(ls
));
1107 memset(&ls
, 0, sizeof(ls
));
1108 ls
.compound_head
= 42;
1109 printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls
.compound_head
- (char*)&ls
));
1112 /* simulate char/short return value with undefined upper bits */
1113 static int __csf(int x
) { return x
; }
1114 static void *_csf
= __csf
;
1115 #define csf(t,n) ((t(*)(int))_csf)(n)
1117 /* XXX: depend on endianness */
1118 void char_short_test()
1126 printf("s8=%d %d\n",
1127 *(signed char *)&var1
, *(signed char *)&var2
);
1128 printf("u8=%d %d\n",
1129 *(unsigned char *)&var1
, *(unsigned char *)&var2
);
1130 printf("s16=%d %d\n",
1131 *(short *)&var1
, *(short *)&var2
);
1132 printf("u16=%d %d\n",
1133 *(unsigned short *)&var1
, *(unsigned short *)&var2
);
1134 printf("s32=%d %d\n",
1135 *(int *)&var1
, *(int *)&var2
);
1136 printf("u32=%d %d\n",
1137 *(unsigned int *)&var1
, *(unsigned int *)&var2
);
1138 *(signed char *)&var1
= 0x08;
1139 printf("var1=%x\n", var1
);
1140 *(short *)&var1
= 0x0809;
1141 printf("var1=%x\n", var1
);
1142 *(int *)&var1
= 0x08090a0b;
1143 printf("var1=%x\n", var1
);
1146 var4
= 0x11223344aa998877ULL
;
1147 var1
= var3
= var1
+ 1;
1148 var4
= var3
= var4
+ 1;
1149 printf("promote char/short assign %d "LONG_LONG_FORMAT
"\n", var1
, var4
);
1151 var4
= 0x11223344aa998877ULL
;
1152 printf("promote char/short assign VA %d %d\n", var3
= var1
+ 1, var3
= var4
+ 1);
1153 printf("promote char/short cast VA %d %d\n", (signed char)(var1
+ 1), (signed char)(var4
+ 1));
1154 #if !defined(__arm__)
1155 /* We can't really express GCC behaviour of return type promotion in
1156 the presence of undefined behaviour (like __csf is). */
1157 var1
= csf(unsigned char,0x89898989);
1158 var4
= csf(signed char,0xabababab);
1159 printf("promote char/short funcret %d "LONG_LONG_FORMAT
"\n", var1
, var4
);
1160 printf("promote char/short fumcret VA %d %d %d %d\n",
1161 csf(unsigned short,0xcdcdcdcd),
1162 csf(short,0xefefefef),
1163 csf(_Bool
,0x33221100),
1164 csf(_Bool
,0x33221101));
1167 var1
= (signed char)(unsigned char)(var3
+ 1);
1168 var4
= (signed char)(unsigned char)(var3
+ 1);
1169 printf("promote multicast (char)(unsigned char) %d "LONG_LONG_FORMAT
"\n", var1
, var4
);
1170 var4
= 0x11223344aa998877ULL
;
1171 var4
= (unsigned)(int)(var4
+ 1);
1172 printf("promote multicast (unsigned)(int) "LONG_LONG_FORMAT
"\n", var4
);
1173 var4
= 0x11223344bbaa9988ULL
;
1174 var4
= (unsigned)(signed char)(var4
+ 1);
1175 printf("promote multicast (unsigned)(char) "LONG_LONG_FORMAT
"\n", var4
);
1178 /******************/
1180 typedef struct Sym
{
1188 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
1189 #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
1191 static int toupper1(int a
)
1196 static unsigned int calc_vm_flags(unsigned int prot
)
1198 unsigned int prot_bits
;
1199 /* This used to segfault in some revisions: */
1200 prot_bits
= ((0x1==0x00000001)?(prot
&0x1):(prot
&0x1)?0x00000001:0);
1206 int *s
, a
, b
, t
, f
, i
;
1210 printf("!s=%d\n", !s
);
1214 printf("a=%d\n", a
);
1216 printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
1217 printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
1218 printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
1233 printf("b=%d\n", a
+ (0 ? 1 : a
/ 2));
1235 /* test register spilling */
1238 a
= (a
+ b
) * ((a
< b
) ?
1239 ((b
- a
) * (a
- b
)): a
+ b
);
1240 printf("a=%d\n", a
);
1242 /* test complex || or && expressions */
1246 printf("exp=%d\n", f
== (32 <= a
&& a
<= 3));
1247 printf("r=%d\n", (t
|| f
) + (t
&& f
));
1252 int aspect_native
= 65536;
1253 double bfu_aspect
= 1.0;
1255 for(aspect_on
= 0; aspect_on
< 2; aspect_on
++) {
1256 aspect
=aspect_on
?(aspect_native
*bfu_aspect
+0.5):65535UL;
1257 printf("aspect=%d\n", aspect
);
1261 /* test ? : GCC extension */
1263 static int v1
= 34 ? : -1; /* constant case */
1264 static int v2
= 0 ? : -1; /* constant case */
1267 printf("%d %d\n", v1
, v2
);
1268 printf("%d %d\n", a
- 30 ? : a
* 2, a
+ 1 ? : a
* 2);
1271 /* again complex expression */
1272 for(i
=0;i
<256;i
++) {
1273 if (toupper1 (i
) != TOUPPER (i
))
1274 printf("error %d\n", i
);
1276 printf ("bits = 0x%x\n", calc_vm_flags (0x1));
1279 extern int undefined_function(void);
1280 extern int defined_function(void);
1283 int undefined_function(void) {}
1286 static inline void refer_to_undefined(void)
1288 undefined_function();
1291 void optimize_out_test(void)
1293 int i
= 0 ? undefined_function() : defined_function();
1294 printf ("oo:%d\n", i
);
1295 int j
= 1 ? defined_function() : undefined_function();
1296 printf ("oo:%d\n", j
);
1298 printf("oo:%d\n", undefined_function());
1300 printf("oo:%d\n", defined_function());
1302 printf("oo:%d\n", defined_function());
1304 printf("oo:%d\n", undefined_function());
1306 printf("oow:%d\n", defined_function());
1308 printf("oow:%d\n", undefined_function());
1311 /* Following is a switch without {} block intentionally. */
1314 printf ("oos:%d\n", defined_function());
1315 /* The following break shouldn't lead to disabled code after
1319 printf ("ool1:%d\n", defined_function());
1320 /* Same for the other types of loops. */
1324 printf ("ool2:%d\n", defined_function());
1327 printf ("ool3:%d\n", defined_function());
1328 /* Normal {} blocks without controlling statements
1329 shouldn't reactivate code emission */
1334 printf ("ool4:%d\n", undefined_function());
1339 break; /* this break shouldn't disable code outside the if. */
1340 printf("ool5:%d\n", defined_function());
1350 printf("ool6:%d\n", defined_function());
1357 printf("ool7:%d\n", undefined_function());
1360 /* Test that constants in logical && are optimized: */
1361 i
= 0 && undefined_function();
1362 i
= defined_function() && 0 && undefined_function();
1363 if (0 && undefined_function())
1364 undefined_function();
1365 if (defined_function() && 0)
1366 undefined_function();
1368 undefined_function();
1369 if (defined_function() && 0 && undefined_function())
1370 undefined_function();
1371 /* The same for || : */
1372 i
= 1 || undefined_function();
1373 i
= defined_function() || 1 || undefined_function();
1374 if (1 || undefined_function())
1377 undefined_function();
1378 if (defined_function() || 1)
1381 undefined_function();
1385 undefined_function();
1386 if (defined_function() || 1 || undefined_function())
1389 undefined_function();
1391 if (defined_function() && 0)
1392 refer_to_undefined();
1399 undefined_function();
1402 /* Leave the "if(1)return; printf()" in this order and last in the function */
1405 printf ("oor:%d\n", undefined_function());
1408 int defined_function(void)
1414 /* GCC accepts that */
1415 static int tab_reinit
[];
1416 static int tab_reinit
[10];
1418 static int tentative_ar
[];
1419 static int tentative_ar
[] = {1,2,3};
1421 //int cinit1; /* a global variable can be defined several times without error ! */
1425 int *cinit2
= (int []){3, 2, 1};
1427 void compound_literal_test(void)
1432 p
= (int []){1, 2, 3};
1434 printf(" %d", p
[i
]);
1438 printf("%d", cinit2
[i
]);
1442 printf("q1=%s\n", q
);
1444 q
= (char *){ "tralala2" };
1445 printf("q2=%s\n", q
);
1448 printf("q3=%s\n", q3
);
1450 q
= (char []){ "tralala3" };
1451 printf("q4=%s\n", q
);
1454 p
= (int []){1, 2, cinit1
+ 3};
1456 printf(" %d", p
[i
]);
1460 p
= (int []){1, 2, 4 + i
};
1461 printf("%d %d %d\n",
1483 printf("func1=%d\n", kr_func1(3, 4));
1484 printf("func2=%d\n", kr_func2(3, 4));
1491 tab
= (char*)malloc(20);
1508 /* structure assignment tests */
1514 struct structa1 ssta1
;
1516 void struct_assign_test1(struct structa1 s1
, int t
, float f
)
1518 printf("%d %d %d %f\n", s1
.f1
, s1
.f2
, t
, f
);
1521 struct structa1
struct_assign_test2(struct structa1 s1
, int t
)
1528 void struct_assign_test(void)
1531 struct structa1 lsta1
, lsta2
;
1540 printf("%d %d\n", s
.lsta1
.f1
, s
.lsta1
.f2
);
1542 printf("%d %d\n", s
.lsta2
.f1
, s
.lsta2
.f2
);
1547 struct_assign_test1(ps
->lsta2
, 3, 4.5);
1549 printf("before call: %d %d\n", s
.lsta2
.f1
, s
.lsta2
.f2
);
1550 ps
->lsta2
= struct_assign_test2(ps
->lsta2
, ps
->i
);
1551 printf("after call: %d %d\n", ps
->lsta2
.f1
, ps
->lsta2
.f2
);
1556 /* XXX: we should allow this even without braces */
1557 { struct_assign_test
}
1559 printf("%d\n", struct_assign_test
== t
[0].elem
);
1562 /* casts to short/char */
1564 void cast1(char a
, short b
, unsigned char c
, unsigned short d
)
1566 printf("%d %d %d %d\n", a
, b
, c
, d
);
1580 unsigned long ul
= 0x80000000UL
;
1581 p
-= 0x700000000042;
1586 printf("%d %d %d %d\n",
1589 (unsigned char)(a
+ 1),
1590 (unsigned short)(a
+ 1));
1591 printf("%d %d %d %d\n",
1594 (unsigned char)0xfffff,
1595 (unsigned short)0xfffff);
1597 a
= (bcast
= 128) + 1;
1599 a
= (scast
= 65536) + 1;
1602 printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c
), sizeof((int)c
));
1604 /* test cast from unsigned to signed short to int */
1607 printf("((unsigned)(short)0x%08x) = 0x%08x\n", b
, d
);
1610 printf("((unsigned)(char)0x%08x) = 0x%08x\n", b
, d
);
1612 /* test implicit int casting for array accesses */
1616 printf("%d %d\n", tab
[0], tab
[1]);
1618 /* test implicit casting on some operators */
1619 printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
1620 printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
1621 printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
1623 #if CC_NAME != CC_clang /* clang doesn't support non-portable conversions */
1624 /* from pointer to integer types */
1625 printf("%d %d %ld %ld %lld %lld\n",
1626 (int)p
, (unsigned int)p
,
1627 (long)p
, (unsigned long)p
,
1628 (long long)p
, (unsigned long long)p
);
1631 /* from integers to pointers */
1632 printf("%p %p %p %p\n",
1633 (void *)a
, (void *)b
, (void *)c
, (void *)d
);
1635 /* int to int with sign set */
1636 printf("0x%lx\n", (unsigned long)(int)ul
);
1639 /* initializers tests */
1640 struct structinit1
{
1649 int sinit3
[3] = { 1, 2, {{3}}, };
1650 int sinit4
[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1651 int sinit5
[3][2] = { 1, 2, 3, 4, 5, 6 };
1652 int sinit6
[] = { 1, 2, 3 };
1653 int sinit7
[] = { [2] = 3, [0] = 1, 2 };
1654 char sinit8
[] = "hello" "trala";
1656 struct structinit1 sinit9
= { 1, 2, 3 };
1657 struct structinit1 sinit10
= { .f2
= 2, 3, .f1
= 1 };
1658 struct structinit1 sinit11
= { .f2
= 2, 3, .f1
= 1,
1666 char *sinit12
= "hello world";
1672 char sinit14
[10] = { "abc" };
1673 int sinit15
[3] = { sizeof(sinit15
), 1, 2 };
1675 struct { int a
[3], b
; } sinit16
[] = { { 1 }, 2 };
1691 struct complexinit0
{
1696 struct complexinit
{
1698 const struct complexinit0
*b
;
1701 const static struct complexinit cix
[] = {
1704 .b
= (const struct complexinit0
[]) {
1712 struct complexinit2
{
1717 struct complexinit2 cix20
;
1719 struct complexinit2 cix21
= {
1721 .b
= { 3001, 3002, 3003 }
1724 struct complexinit2 cix22
= {
1726 .b
= { 4001, 4002, 4003, 4004, 4005, 4006 }
1729 typedef int arrtype1
[];
1730 arrtype1 sinit19
= {1};
1731 arrtype1 sinit20
= {2,3};
1732 typedef int arrtype2
[3];
1733 arrtype2 sinit21
= {4};
1734 arrtype2 sinit22
= {5,6,7};
1736 /* Address comparisons of non-weak symbols with zero can be const-folded */
1737 int sinit23
[2] = { "astring" ? sizeof("astring") : -1,
1738 &sinit23
? 42 : -1 };
1740 int sinit24
= 2 || 1 / 0; /* exception in constant but unevaluated context */
1743 struct bf_SS
{unsigned int bit
:1,bits31
:31; };
1744 struct bf_SS bf_init
= { .bit
= 1 };
1745 struct bfn_SS
{int a
,b
; struct bf_SS c
; int d
,e
; };
1746 struct bfn_SS bfn_init
= { .c
.bit
= 1 };
1747 struct bfa_SS
{int a
,b
; struct bf_SS c
[3]; int d
,e
; };
1748 struct bfa_SS bfa_init
= { .c
[1].bit
= 1 };
1749 struct bf_SS bfaa_init
[3] = { [1].bit
= 1 };
1750 struct bf_SS bfaa_vinit
[] = { [2].bit
= 1 };
1751 struct b2_SS
{long long int field
: 52; long long int pad
: 12; };
1752 struct b2_SS bf_init2
= {0xFFF000FFF000FLL
, 0x123};
1754 extern int external_inited
= 42;
1756 void init_test(void)
1760 int linit4
[3][2] = { {1, 2}, {3, 4}, {5, 6} };
1761 int linit6
[] = { 1, 2, 3 };
1763 char linit8
[] = "hello" "trala";
1764 int linit12
[10] = { 1, 2 };
1765 int linit13
[10] = { 1, 2, [7] = 3, [3] = 4, };
1766 char linit14
[10] = "abc";
1767 int linit15
[10] = { linit1
, linit1
+ 1, [6] = linit1
+ 2, };
1768 struct linit16
{ int a1
, a2
, a3
, a4
; } linit16
= { 1, .a3
= 2 };
1769 int linit17
= sizeof(linit17
);
1771 /* Addresses on non-weak symbols are non-zero, but not the access itself */
1772 int linit18
[2] = {&zero
? 1 : -1, zero
? -1 : 1 };
1773 struct bf_SS bf_finit
= { .bit
= 1 };
1774 struct bfn_SS bfn_finit
= { .c
.bit
= 1 };
1775 struct bfa_SS bfa_finit
= { .c
[1].bit
= 1 };
1776 struct bf_SS bfaa_finit
[3] = { [1].bit
= 1 };
1777 struct bf_SS bfaa_fvinit
[] = { [2].bit
= 1 };
1778 struct b2_SS bf_finit2
= {0xFFF000FFF000FLL
, 0x123};
1780 printf("sinit1=%d\n", sinit1
);
1781 printf("sinit2=%d\n", sinit2
);
1782 printf("sinit3=%d %d %d %d\n",
1788 printf("sinit6=%d\n", sizeof(sinit6
));
1789 printf("sinit7=%d %d %d %d\n",
1795 printf("sinit8=%s\n", sinit8
);
1796 printf("sinit9=%d %d %d\n",
1801 printf("sinit10=%d %d %d\n",
1806 printf("sinit11=%d %d %d %d %d %d\n",
1817 printf("[%d][%d] = %d %d %d\n",
1818 i
, j
, sinit4
[i
][j
], sinit5
[i
][j
], linit4
[i
][j
]);
1819 printf("linit1=%d\n", linit1
);
1820 printf("linit2=%d\n", linit2
);
1821 printf("linit6=%d\n", sizeof(linit6
));
1822 printf("linit8=%d %s\n", sizeof(linit8
), linit8
);
1824 printf("sinit12=%s\n", sinit12
);
1825 printf("sinit13=%d %s %s %s\n",
1830 printf("sinit14=%s\n", sinit14
);
1832 for(i
=0;i
<10;i
++) printf(" %d", linit12
[i
]);
1834 for(i
=0;i
<10;i
++) printf(" %d", linit13
[i
]);
1836 for(i
=0;i
<10;i
++) printf(" %d", linit14
[i
]);
1838 for(i
=0;i
<10;i
++) printf(" %d", linit15
[i
]);
1840 printf("%d %d %d %d\n",
1845 /* test that initialisation is done after variable declare */
1846 printf("linit17=%d\n", linit17
);
1847 printf("sinit15=%d\n", sinit15
[0]);
1848 printf("sinit16=%d %d\n", sinit16
[0].a
[0], sinit16
[1].a
[0]);
1849 printf("sinit17=%s %d %s %d\n",
1850 sinit17
[0].s
, sinit17
[0].len
,
1851 sinit17
[1].s
, sinit17
[1].len
);
1853 printf("%x ", sinit18
[i
]);
1855 /* complex init check */
1856 printf("cix: %d %d %d %d %d %d %d\n",
1858 cix
[0].b
[0].a
, cix
[0].b
[0].b
,
1859 cix
[0].b
[1].a
, cix
[0].b
[1].b
,
1860 cix
[0].b
[2].a
, cix
[0].b
[2].b
);
1861 printf("cix2: %d %d\n", cix21
.b
[2], cix22
.b
[5]);
1862 printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20
, sizeof cix21
, sizeof cix22
);
1864 printf("arrtype1: %d %d %d\n", sinit19
[0], sinit20
[0], sinit20
[1]);
1865 printf("arrtype2: %d %d\n", sizeof(sinit19
), sizeof(sinit20
));
1866 printf("arrtype3: %d %d %d\n", sinit21
[0], sinit21
[1], sinit21
[2]);
1867 printf("arrtype4: %d %d %d\n", sinit22
[0], sinit22
[1], sinit22
[2]);
1868 printf("arrtype5: %d %d\n", sizeof(sinit21
), sizeof(sinit22
));
1869 printf("arrtype6: %d\n", sizeof(arrtype2
));
1871 printf("sinit23= %d %d\n", sinit23
[0], sinit23
[1]);
1872 printf("sinit24=%d\n", sinit24
);
1873 printf("linit18= %d %d\n", linit18
[0], linit18
[1]);
1874 printf ("bf1: %u %u\n", bf_init
.bit
, bf_init
.bits31
);
1875 printf ("bf2: %u %u\n", bf_finit
.bit
, bf_finit
.bits31
);
1876 printf ("bf3: %u %u\n", bfn_init
.c
.bit
, bfn_init
.c
.bits31
);
1877 printf ("bf4: %u %u\n", bfn_finit
.c
.bit
, bfn_finit
.c
.bits31
);
1878 for (i
= 0; i
< 3; i
++)
1879 printf ("bf5[%d]: %u %u\n", i
, bfa_init
.c
[i
].bit
, bfa_init
.c
[i
].bits31
);
1880 for (i
= 0; i
< 3; i
++)
1881 printf ("bf6[%d]: %u %u\n", i
, bfa_finit
.c
[i
].bit
, bfa_finit
.c
[i
].bits31
);
1882 for (i
= 0; i
< 3; i
++)
1883 printf ("bf7[%d]: %u %u\n", i
, bfaa_init
[i
].bit
, bfaa_init
[i
].bits31
);
1884 for (i
= 0; i
< 3; i
++)
1885 printf ("bf8[%d]: %u %u\n", i
, bfaa_finit
[i
].bit
, bfaa_finit
[i
].bits31
);
1886 for (i
= 0; i
< 3; i
++)
1887 printf ("bf9[%d]: %u %u\n", i
, bfaa_vinit
[i
].bit
, bfaa_vinit
[i
].bits31
);
1888 for (i
= 0; i
< 3; i
++)
1889 printf ("bf10[%d]: %u %u\n", i
, bfaa_fvinit
[i
].bit
, bfaa_fvinit
[i
].bits31
);
1892 void switch_uc(unsigned char uc
)
1905 printf("ucsw: broken!\n");
1909 void switch_sc(signed char sc
)
1922 printf("scsw: broken!\n");
1929 unsigned long long ull
;
1954 for (i
= 1; i
<= 5; i
++) {
1955 ull
= (unsigned long long)i
<< 61;
1958 printf("ullsw:1\n");
1961 printf("ullsw:2\n");
1964 printf("ullsw:3\n");
1967 printf("ullsw:4\n");
1970 printf("ullsw:5\n");
1973 printf("ullsw: broken!\n");
1977 for (i
= 1; i
<= 5; i
++) {
1978 ll
= (long long)i
<< 61;
1996 printf("llsw: broken!\n");
2000 for (i
= -5; i
<= 5; i
++) {
2001 switch_uc((unsigned char)i
);
2004 for (i
= -5; i
<= 5; i
++) {
2005 switch_sc ((signed char)i
);
2009 /* ISOC99 _Bool type */
2010 void c99_bool_test(void)
2016 printf("sizeof(_Bool) = %d\n", sizeof(_Bool
));
2018 printf("cast: %d %d %d\n", (_Bool
)10, (_Bool
)0, (_Bool
)a
);
2020 printf("b = %d\n", b
);
2022 printf("b = %d\n", b
);
2024 printf("sizeof(x ? _Bool : _Bool) = %d (should be sizeof int)\n",
2025 sizeof((volatile)a
? b
: b2
));
2029 void bitfield_test(void)
2041 unsigned int f5
: 7;
2043 printf("sizeof(st1) = %d\n", sizeof(st1
));
2052 printf("%d %d %d %d %d\n",
2053 st1
.f1
, st1
.f2
, st1
.f3
, st1
.f4
, st1
.f5
);
2056 printf("%d %d\n", sa
, ca
);
2060 printf("st1.f1 == -1\n");
2062 printf("st1.f1 != -1\n");
2064 printf("st1.f2 == -1\n");
2066 printf("st1.f2 != -1\n");
2072 unsigned long long f3
: 38;
2074 st2
.f1
= 0x123456789ULL
;
2076 st2
.f2
= (long long)a
<< 25;
2079 printf("%lld %lld %lld\n", st2
.f1
, st2
.f2
, st2
.f3
);
2082 Disabled
for now until further clarification re GCC compatibility
2091 printf("sizeof(st3) = %d\n", sizeof(st3
));
2099 printf("st4.y == %d\n", st4
.y
);
2103 int x
: 12, y
: 4, : 0, : 4, z
: 3;
2105 } st5
= { 1, 2, 3, 4, -3, 6 };
2106 printf("st5 = %d %d %d %d %d %d\n", st5
.a
, st5
.b
, st5
.x
, st5
.y
, st5
.z
, st5
.c
);
2109 unsigned char y
: 2;
2112 printf("st6.y == %d\n", st6
.y
);
2116 #define FLOAT_FMT "%f\n"
2118 /* x86's float isn't compatible with GCC */
2119 #define FLOAT_FMT "%.5f\n"
2122 /* declare strto* functions as they are C99 */
2123 double strtod(const char *nptr
, char **endptr
);
2126 float strtof(const char *nptr
, char **endptr
) {return (float)strtod(nptr
, endptr
);}
2127 LONG_DOUBLE
strtold(const char *nptr
, char **endptr
) {return (LONG_DOUBLE
)strtod(nptr
, endptr
);}
2129 float strtof(const char *nptr
, char **endptr
);
2130 LONG_DOUBLE
strtold(const char *nptr
, char **endptr
);
2133 #if CC_NAME == CC_clang
2134 /* In clang 0.0/0.0 is nan and not -nan.
2135 Also some older clang version do v=-v
2137 static char enable_nan_test
= 0;
2139 static char enable_nan_test
= 1;
2142 #define FTEST(prefix, typename, type, fmt)\
2143 void prefix ## cmp(type a, type b)\
2145 printf("%d %d %d %d %d %d\n",\
2152 printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
2160 printf(fmt "\n", ++a);\
2161 printf(fmt "\n", a++);\
2162 printf(fmt "\n", a);\
2164 printf("%d %d\n", !a, !b);\
2166 void prefix ## fcast(type a)\
2174 unsigned long long llua;\
2179 printf("ftof: %f %f %Lf\n", fa, da, la);\
2181 llia = (long long)a;\
2182 a = (a >= 0) ? a : -a;\
2183 ua = (unsigned int)a;\
2184 llua = (unsigned long long)a;\
2185 printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
2188 llia = -0x123456789012345LL;\
2189 llua = 0xf123456789012345LLU;\
2191 printf("itof: " fmt "\n", b);\
2193 printf("utof: " fmt "\n", b);\
2195 printf("lltof: " fmt "\n", b);\
2197 printf("ulltof: " fmt "\n", b);\
2200 float prefix ## retf(type a) { return a; }\
2201 double prefix ## retd(type a) { return a; }\
2202 LONG_DOUBLE prefix ## retld(type a) { return a; }\
2204 void prefix ## call(void)\
2206 printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
2207 printf("double: %f\n", prefix ## retd(42.123456789));\
2208 printf("long double: %Lf\n", prefix ## retld(42.123456789));\
2209 printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
2212 void prefix ## signed_zeros(void) \
2214 type x = 0.0, y = -0.0, n, p;\
2216 printf ("Test 1.0 / x != 1.0 / y returns %d (should be 1).\n",\
2217 1.0 / x != 1.0 / y);\
2219 printf ("x != y; this is wrong!\n");\
2223 printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
2224 1.0 / x != 1.0 / n);\
2226 printf ("x != -x; this is wrong!\n");\
2230 printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
2231 1.0 / x != 1.0 / p);\
2233 printf ("x != +y; this is wrong!\n");\
2236 printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
2237 1.0 / x != 1.0 / p);\
2239 printf ("x != -y; this is wrong!\n");\
2241 void prefix ## nan(void)\
2243 type nan = 0.0/0.0;\
2245 printf("nantest: " fmt " " fmt "\n", nan, nnan);\
2247 void prefix ## test(void)\
2249 printf("testing '%s'\n", #typename);\
2250 prefix ## cmp(1, 2.5);\
2251 prefix ## cmp(2, 1.5);\
2252 prefix ## cmp(1, 1);\
2253 prefix ## fcast(234.6);\
2254 prefix ## fcast(-2334.6);\
2256 prefix ## signed_zeros();\
2257 if (enable_nan_test) prefix ## nan();\
2260 FTEST(f
, float, float, "%f")
2261 FTEST(d
, double, double, "%f")
2262 FTEST(ld
, long double, LONG_DOUBLE
, "%Lf")
2264 double ftab1
[3] = { 1.2, 3.4, -5.6 };
2267 void float_test(void)
2269 #if !defined(__arm__) || defined(__ARM_PCS_VFP)
2270 volatile float fa
, fb
;
2271 volatile double da
, db
;
2274 static double nan2
= 0.0/0.0;
2275 static double inf1
= 1.0/0.0;
2276 static double inf2
= 1e5000
;
2277 volatile LONG_DOUBLE la
;
2279 printf("sizeof(float) = %d\n", sizeof(float));
2280 printf("sizeof(double) = %d\n", sizeof(double));
2281 printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE
));
2285 printf("%f %f %f\n", ftab1
[0], ftab1
[1], ftab1
[2]);
2286 printf("%f %f %f\n", 2.12, .5, 2.3e10
);
2287 // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
2289 printf("da=%f\n", da
);
2291 printf("fa=%f\n", fa
);
2294 printf("da = %f\n", da
);
2297 printf("db = %f\n", db
);
2298 printf("nan != nan = %d, inf1 = %f, inf2 = %f\n", nan2
!= nan2
, inf1
, inf2
);
2299 da
= 0x0.88p
-1022; /* a subnormal */
2301 printf ("da subnormal = %a\n", da
);
2302 printf ("da subnormal = %.40g\n", da
);
2303 printf ("la subnormal = %La\n", la
);
2304 printf ("la subnormal = %.40Lg\n", la
);
2307 printf ("da/2 subnormal = %a\n", da
);
2308 printf ("da/2 subnormal = %.40g\n", da
);
2309 printf ("la/2 subnormal = %La\n", la
);
2310 printf ("la/2 subnormal = %.40Lg\n", la
);
2311 fa
= 0x0.88p
-126f
; /* a subnormal */
2313 printf ("fa subnormal = %a\n", fa
);
2314 printf ("fa subnormal = %.40g\n", fa
);
2315 printf ("la subnormal = %La\n", la
);
2316 printf ("la subnormal = %.40Lg\n", la
);
2319 printf ("fa/2 subnormal = %a\n", fa
);
2320 printf ("fa/2 subnormal = %.40g\n", fa
);
2321 printf ("la/2 subnormal = %La\n", la
);
2322 printf ("la/2 subnormal = %.40Lg\n", la
);
2331 return fib(n
-1) + fib(n
-2);
2334 #if __GNUC__ == 3 || __GNUC__ == 4
2335 # define aligned_function 0
2337 void __attribute__((aligned(16))) aligned_function(int i
) {}
2356 /* more complicated pointer computation */
2359 printf("sizeof1 = %d\n", sizeof(funcptr_test
));
2360 printf("sizeof2 = %d\n", sizeof funcptr_test
);
2361 printf("sizeof3 = %d\n", sizeof(&funcptr_test
));
2362 printf("sizeof4 = %d\n", sizeof &funcptr_test
);
2370 /* Check that we can align functions */
2371 func
= aligned_function
;
2372 printf("aligned_function (should be zero): %d\n", ((int)(uintptr_t)func
) & 15);
2375 void lloptest(long long a
, long long b
)
2377 unsigned long long ua
, ub
;
2382 printf("arith: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n",
2388 printf("arith1: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n",
2394 printf("bin: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n",
2400 printf("test: %d %d %d %d %d %d\n",
2408 printf("utest: %d %d %d %d %d %d\n",
2419 printf("arith2: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n", a
, b
);
2420 printf("arith2: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n", a
++, b
++);
2421 printf("arith2: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n", --a
, --b
);
2422 printf("arith2: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n", a
, b
);
2424 printf("not: %d %d %d %d\n", !a
, !ua
, !b
, !ub
);
2427 void llshift(long long a
, int b
)
2429 printf("shift: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n",
2430 (unsigned long long)a
>> b
,
2433 printf("shiftc: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n",
2434 (unsigned long long)a
>> 3,
2437 printf("shiftc: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n",
2438 (unsigned long long)a
>> 35,
2448 long long la
, lb
, lc
;
2449 unsigned long long ula
, ulb
, ulc
;
2452 la
= (la
<< 20) | 0x12345;
2454 printf("la=" LONG_LONG_FORMAT
" ula=" ULONG_LONG_FORMAT
"\n", la
, ula
);
2459 printf("lltof: %f %f %Lf\n", fa
, da
, lda
);
2464 printf("ftoll: " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n", la
, lb
, lc
);
2469 printf("ulltof: %f %f %Lf\n", fa
, da
, lda
);
2474 printf("ftoull: " ULONG_LONG_FORMAT
" " ULONG_LONG_FORMAT
" " ULONG_LONG_FORMAT
"\n", ula
, ulb
, ulc
);
2477 long long llfunc1(int a
)
2487 long long int value(struct S
*v
)
2489 return ((long long int)v
->item
);
2492 long long llfunc2(long long x
, long long y
, int z
)
2497 void check_opl_save_regs(char *a
, long long b
, int c
)
2502 void longlong_test(void)
2507 printf("sizeof(long long) = %d\n", sizeof(long long));
2512 printf(LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"\n", a
, b
);
2513 printf(LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" %Lx\n",
2517 0x1234567812345679);
2519 printf(LONG_LONG_FORMAT
"\n", a
);
2522 lloptest(0xff, 0x1234);
2523 b
= 0x72345678 << 10;
2527 b
= 0x72345678LL
<< 10;
2538 /* long long reg spill test */
2543 printf("%lld\n", value(&a
));
2545 lloptest(0x80000000, 0);
2548 long long *p
, v
, **pp
;
2552 printf("another long long spill test : %lld\n", *p
);
2555 v
= llfunc2(**pp
, **pp
, ia
);
2556 printf("a long long function (arm-)reg-args test : %lld\n", v
);
2560 printf("%d %d %d %d\n", a
> b
, a
< b
, a
>= b
, a
<= b
);
2562 printf(LONG_LONG_FORMAT
"\n", 0x123456789LLU
);
2564 /* long long pointer deref in argument passing test */
2569 /* shortening followed by widening */
2570 unsigned long long u
= 0x8000000000000001ULL
;
2571 u
= (unsigned)(u
+ 1);
2572 printf("long long u=" ULONG_LONG_FORMAT
"\n", u
);
2573 u
= 0x11223344aa998877ULL
;
2574 u
= (unsigned)(int)(u
+ 1);
2575 printf("long long u=" ULONG_LONG_FORMAT
"\n", u
);
2577 /* was a problem with missing save_regs in gen_opl on 32-bit platforms */
2579 check_opl_save_regs(&cc
, -1, 0);
2580 printf("check_opl_save_regs: %d\n", cc
);
2583 void manyarg_test(void)
2585 LONG_DOUBLE ld
= 1234567891234LL;
2586 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2587 1, 2, 3, 4, 5, 6, 7, 8,
2588 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2589 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2590 LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" %f %f\n",
2591 1, 2, 3, 4, 5, 6, 7, 8,
2592 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2593 1234567891234LL, 987654321986LL,
2595 printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2596 LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" %f %f\n",
2597 ld
, 1, 2, 3, 4, 5, 6, 7, 8,
2598 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2599 1234567891234LL, 987654321986LL,
2601 printf("%d %d %d %d %d %d %d %d %Lf\n",
2602 1, 2, 3, 4, 5, 6, 7, 8, ld
);
2603 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2604 LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
"%f %f %Lf\n",
2605 1, 2, 3, 4, 5, 6, 7, 8,
2606 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2607 1234567891234LL, 987654321986LL,
2609 printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2610 "%Lf " LONG_LONG_FORMAT
" " LONG_LONG_FORMAT
" %f %f %Lf\n",
2611 1, 2, 3, 4, 5, 6, 7, 8,
2612 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2613 ld
, 1234567891234LL, 987654321986LL,
2618 va_arg_with_struct_ptr(va_list ap
) {
2620 * This was a BUG identified with FFTW-3.3.8 on arm64.
2621 * The test case only checks it compiles on all supported
2622 * architectures. This function is not currently called.
2624 struct X
{ int _x
; };
2625 struct X
*x
= va_arg(ap
, struct X
*);
2629 void vprintf1(const char *fmt
, ...)
2653 i
= va_arg(ap
, int);
2657 d
= va_arg(ap
, double);
2661 ll
= va_arg(ap
, long long);
2662 printf(LONG_LONG_FORMAT
, ll
);
2665 ld
= va_arg(ap
, LONG_DOUBLE
);
2683 #if CC_NAME == CC_clang /* clang7 doesn't support zero sized structs */
2696 void stdarg_for_struct(struct myspace bob
, ...)
2698 struct myspace george
, bill
;
2699 struct myspace2 alex1
;
2700 struct myspace3 alex2
;
2701 struct myspace4 alex3
;
2706 alex1
= va_arg(ap
, struct myspace2
);
2707 alex2
= va_arg(ap
, struct myspace3
);
2708 alex3
= va_arg(ap
, struct myspace4
);
2709 bill
= va_arg(ap
, struct myspace
);
2710 george
= va_arg(ap
, struct myspace
);
2711 validate
= va_arg(ap
, int);
2712 printf("stdarg_for_struct: %d %d %d %d %d %d %d\n",
2713 alex2
.a
[0], alex3
.a
[0], alex3
.a
[1],
2714 bob
.profile
, bill
.profile
, george
.profile
, validate
);
2718 void stdarg_for_libc(const char *fmt
, ...)
2721 va_start(args
, fmt
);
2726 void stdarg_syntax(int n
, ...)
2734 i
= va_arg(ap
, int);
2735 printf("stdarg_void_expr: %d\n", i
);
2742 point pts
[]={{1.0,2.0},{3.0,4.0},{5.0,6.0},{7.0,8.0},{9.0,10.0},{11.0,12.0}};
2744 static void stdarg_double_struct(int nargs
, int posd
,...)
2751 printf ("stdarg_double_struct: %d\n", posd
);
2752 va_start(args
,posd
);
2753 for(i
= 0; i
< nargs
; i
++) {
2755 d
= va_arg (args
, double);
2756 printf ("d %d = %g\n", i
, d
);
2759 pi
= va_arg (args
, point
);
2760 printf ("pts[%d] = %g %g\n", i
, pi
.x
, pi
.y
);
2766 void stdarg_test(void)
2768 LONG_DOUBLE ld
= 1234567891234LL;
2770 struct myspace2 bob2
;
2771 struct myspace3 bob3
;
2772 struct myspace4 bob4
;
2774 vprintf1("%d %d %d\n", 1, 2, 3);
2775 vprintf1("%f %d %f\n", 1.0, 2, 3.0);
2776 vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
2777 vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
2778 vprintf1("%d %f %l %F %d %f %l %F\n",
2779 1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
2780 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
2781 1, 2, 3, 4, 5, 6, 7, 8,
2782 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
2783 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
2784 1, 2, 3, 4, 5, 6, 7, 8,
2785 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
2786 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2788 1, 2, 3, 4, 5, 6, 7, 8,
2789 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2790 1234567891234LL, 987654321986LL,
2792 vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2794 ld
, 1, 2, 3, 4, 5, 6, 7, 8,
2795 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2796 1234567891234LL, 987654321986LL,
2798 vprintf1("%d %d %d %d %d %d %d %d %F\n",
2799 1, 2, 3, 4, 5, 6, 7, 8, ld
);
2800 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2802 1, 2, 3, 4, 5, 6, 7, 8,
2803 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2804 1234567891234LL, 987654321986LL,
2806 vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
2807 "%F %l %l %f %f %F\n",
2808 1, 2, 3, 4, 5, 6, 7, 8,
2809 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
2810 ld
, 1234567891234LL, 987654321986LL,
2817 stdarg_for_struct(bob
, bob2
, bob3
, bob4
, bob
, bob
, bob
.profile
);
2818 stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
2819 stdarg_syntax(1, 17);
2820 stdarg_double_struct(6,-1,pts
[0],pts
[1],pts
[2],pts
[3],pts
[4],pts
[5]);
2821 stdarg_double_struct(7,1,pts
[0],-1.0,pts
[1],pts
[2],pts
[3],pts
[4],pts
[5]);
2822 stdarg_double_struct(7,2,pts
[0],pts
[1],-1.0,pts
[2],pts
[3],pts
[4],pts
[5]);
2823 stdarg_double_struct(7,3,pts
[0],pts
[1],pts
[2],-1.0,pts
[3],pts
[4],pts
[5]);
2824 stdarg_double_struct(7,4,pts
[0],pts
[1],pts
[2],pts
[3],-1.0,pts
[4],pts
[5]);
2825 stdarg_double_struct(7,5,pts
[0],pts
[1],pts
[2],pts
[3],pts
[4],-1.0,pts
[5]);
2828 int reltab
[3] = { 1, 2, 3 };
2830 int *rel1
= &reltab
[1];
2831 int *rel2
= &reltab
[2];
2834 void relocation_test(void) {}
2836 void getmyaddress(void)
2838 printf("in getmyaddress\n");
2842 long __pa_symbol(void)
2844 /* This 64bit constant was handled incorrectly, it was used as addend
2845 (which can hold 64bit just fine) in connection with a symbol,
2846 and TCC generates wrong code for that (displacements are 32bit only).
2847 This effectively is "+ 0x80000000", and if addresses of globals
2848 are below 2GB the result should be a number without high 32 bits set. */
2849 return ((long)(((unsigned long)(&rel1
))) - (0xffffffff80000000UL
));
2853 unsigned long theaddress
= (unsigned long)getmyaddress
;
2854 void relocation_test(void)
2856 void (*fptr
)(void) = (void (*)(void))theaddress
;
2857 printf("*rel1=%d\n", *rel1
);
2858 printf("*rel2=%d\n", *rel2
);
2861 printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
2866 void old_style_f(a
,b
,c
)
2870 printf("a=%d b=%d b=%f\n", a
, b
, c
);
2873 void decl_func1(int cmpfn())
2875 printf("cmpfn=%lx\n", (long)cmpfn
);
2878 void decl_func2(cmpfn
)
2881 printf("cmpfn=%lx\n", (long)cmpfn
);
2884 void old_style_function_test(void)
2886 old_style_f((void *)1, 2, 3.0);
2893 #if defined __i386__ || defined __x86_64__ || defined __arm__
2894 char *p
= alloca(16);
2895 strcpy(p
,"123456789012345");
2896 printf("alloca: p is %s\n", p
);
2897 char *demo
= "This is only a test.\n";
2898 /* Test alloca embedded in a larger expression */
2899 printf("alloca: %s\n", strcpy(alloca(strlen(demo
)+1),demo
) );
2903 void *bounds_checking_is_enabled()
2905 char ca
[10], *cp
= ca
-1;
2906 return (ca
!= cp
+ 1) ? cp
: NULL
;
2909 typedef int constant_negative_array_size_as_compile_time_assertion_idiom
[(1 ? 2 : 0) - 1];
2911 void c99_vla_test_1(int size1
, int size2
)
2913 #if defined __i386__ || defined __x86_64__
2914 int size
= size1
* size2
;
2915 int tab1
[size
][2], tab2
[10][2];
2916 void *tab1_ptr
, *tab2_ptr
, *bad_ptr
;
2918 /* "size" should have been 'captured' at tab1 declaration,
2919 so modifying it should have no effect on VLA behaviour. */
2922 printf("Test C99 VLA 1 (sizeof): ");
2923 printf("%s\n", (sizeof tab1
== size1
* size2
* 2 * sizeof(int)) ? "PASSED" : "FAILED");
2926 printf("Test C99 VLA 2 (ptrs subtract): ");
2927 printf("%s\n", (tab2
- tab1
== (tab2_ptr
- tab1_ptr
) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
2928 printf("Test C99 VLA 3 (ptr add): ");
2929 printf("%s\n", &tab1
[5][1] == (tab1_ptr
+ (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
2930 printf("Test C99 VLA 4 (ptr access): ");
2931 tab1
[size1
][1] = 42;
2932 printf("%s\n", (*((int *) (tab1_ptr
+ (size1
* 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
2934 printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
2935 if (bad_ptr
= bounds_checking_is_enabled()) {
2936 int *t1
= &tab1
[size1
* size2
- 1][3];
2937 int *t2
= &tab2
[9][3];
2938 printf("%s ", bad_ptr
== t1
? "PASSED" : "FAILED");
2939 printf("%s ", bad_ptr
== t2
? "PASSED" : "FAILED");
2941 char*c1
= 1 + sizeof(tab1
) + (char*)tab1
;
2942 char*c2
= 1 + sizeof(tab2
) + (char*)tab2
;
2943 printf("%s ", bad_ptr
== c1
? "PASSED" : "FAILED");
2944 printf("%s ", bad_ptr
== c2
? "PASSED" : "FAILED");
2948 printf("%s ", bad_ptr
== i1
? "PASSED" : "FAILED");
2949 printf("%s ", bad_ptr
== i2
? "PASSED" : "FAILED");
2951 int *x1
= tab1
[size1
* size2
+ 1];
2952 int *x2
= tab2
[10 + 1];
2953 printf("%s ", bad_ptr
== x1
? "PASSED" : "FAILED");
2954 printf("%s ", bad_ptr
== x2
? "PASSED" : "FAILED");
2956 printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
2962 void c99_vla_test(void)
2964 c99_vla_test_1(5, 2);
2968 void sizeof_test(void)
2973 printf("sizeof(int) = %d\n", sizeof(int));
2974 printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
2975 printf("sizeof(long) = %d\n", sizeof(long));
2976 printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
2977 printf("sizeof(short) = %d\n", sizeof(short));
2978 printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
2979 printf("sizeof(char) = %d\n", sizeof(char));
2980 printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
2981 printf("sizeof(func) = %d\n", sizeof sizeof_test());
2983 printf("sizeof(a++) = %d\n", sizeof a
++);
2984 printf("a=%d\n", a
);
2986 printf("sizeof(**ptr) = %d\n", sizeof (**ptr
));
2988 /* The type of sizeof should be as large as a pointer, actually
2989 it should be size_t. */
2990 printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
2993 /* Effectively <<32, but defined also on 32bit machines. */
2997 /* This checks that sizeof really can be used to manipulate
2998 uintptr_t objects, without truncation. */
2999 t2
= t
& -sizeof(uintptr_t);
3000 printf ("%lu %lu\n", t
, t2
);
3002 /* some alignof tests */
3003 printf("__alignof__(int) = %d\n", __alignof__(int));
3004 printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
3005 printf("__alignof__(short) = %d\n", __alignof__(short));
3006 printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
3007 printf("__alignof__(char) = %d\n", __alignof__(char));
3008 printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
3009 printf("__alignof__(func) = %d\n", __alignof__
sizeof_test());
3011 /* sizes of VLAs need to be evaluated even inside sizeof: */
3013 printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a
]));
3014 /* And checking if sizeof compound literal works. Parenthesized: */
3015 printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
3016 sizeof( (struct {int i
; int j
;}){4,5} ));
3017 /* And as direct sizeof argument (as unary expression): */
3018 printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
3019 sizeof (struct {short i
; short j
;}){4,5} );
3021 /* sizeof(x && y) should be sizeof(int), even if constant
3022 evaluating is possible. */
3023 printf("sizeof(t && 0) = %d\n", sizeof(t
&& 0));
3024 printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
3025 printf("sizeof(t || 1) = %d\n", sizeof(t
|| 1));
3026 printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
3029 void typeof_test(void)
3038 printf("a=%f b=%f c=%f\n", a
, b
, c
);
3044 struct hlist_node
*first
, *last
;
3047 void consume_ulong (unsigned long i
)
3052 void statement_expr_test(void)
3056 /* Basic stmt expr test */
3066 printf("a=%d\n", a
);
3068 /* Test that symbols aren't freed prematurely.
3069 With SYM_DEBUG valgrind will show a read from a freed
3070 symbol, and tcc will show an (invalid) warning on the initialization
3071 of 'ptr' below, if symbols are popped after the stmt expr. */
3072 void *v
= (void*)39;
3074 (struct hlist_node
*)v
;
3077 ptr
= (struct hlist_node
*)v
;
3079 /* This part used to segfault when symbols were popped prematurely.
3080 The symbols for the static local would be overwritten with
3081 helper symbols from the pre-processor expansions in between. */
3082 #define some_attr __attribute__((aligned(1)))
3083 #define tps(str) ({ \
3084 static const char *t some_attr = str; \
3087 printf ("stmtexpr: %s %s\n",
3088 tps("somerandomlongstring"),
3089 tps("anotherlongstring"));
3091 /* Test that the three decls of 't' don't interact. */
3093 int b
= ({ int t
= 41; t
; });
3094 int c
= ({ int t
= 42; t
; });
3096 /* Test that aggregate return values work. */
3099 typedef struct hlist_head T
;
3101 T t
= { (void*)43, (void*)44 };
3105 printf ("stmtexpr: %d %d %d\n", t
, b
, c
);
3106 printf ("stmtexpr: %ld %ld\n", (long)h
.first
, (long)h
.last
);
3108 /* Test that we can give out addresses of local labels. */
3109 consume_ulong(({ __label__ __here
; __here
: (unsigned long)&&__here
; }));
3111 /* Test interaction between local and global label stacks and the
3112 need to defer popping symbol from them when within statement
3113 expressions. Note how the labels are both named LBL. */
3118 LBL
: if (i
++ == 0) goto LBL
;
3120 /* jump to a classical label out of an expr-stmt that had previously
3121 overshadowed that classical label */
3125 printf("stmtexpr: %d should be 2\n", i
);
3128 void local_label_test(void)
3134 __label__ l1
, l2
, l3
, l4
;
3148 printf("a=%d\n", a
);
3158 /* inline assembler test */
3159 #if defined(__i386__) || defined(__x86_64__)
3161 /* from linux kernel */
3162 static char * strncat1(char * dest
,const char * src
,size_t count
)
3164 long d0
, d1
, d2
, d3
;
3165 __asm__
__volatile__(
3174 "testb %%al,%%al\n\t"
3178 : "=&S" (d0
), "=&D" (d1
), "=&a" (d2
), "=&c" (d3
)
3179 : "0" (src
),"1" (dest
),"2" (0),"3" (0xffffffff), "g" (count
)
3184 static char * strncat2(char * dest
,const char * src
,size_t count
)
3186 long d0
, d1
, d2
, d3
;
3187 __asm__
__volatile__(
3188 "repne scasb\n\t" /* one-line repne prefix + string op */
3195 "testb %%al,%%al\n\t"
3199 : "=&S" (d0
), "=&D" (d1
), "=&a" (d2
), "=&c" (d3
)
3200 : "0" (src
),"1" (dest
),"2" (0),"3" (0xffffffff), "g" (count
)
3205 static inline void * memcpy1(void * to
, const void * from
, size_t n
)
3208 __asm__
__volatile__(
3213 "1:\ttestb $1,%b4\n\t"
3217 : "=&c" (d0
), "=&D" (d1
), "=&S" (d2
)
3218 :"0" (n
/4), "q" (n
),"1" ((long) to
),"2" ((long) from
)
3223 static inline void * memcpy2(void * to
, const void * from
, size_t n
)
3226 __asm__
__volatile__(
3227 "rep movsl\n\t" /* one-line rep prefix + string op */
3231 "1:\ttestb $1,%b4\n\t"
3235 : "=&c" (d0
), "=&D" (d1
), "=&S" (d2
)
3236 :"0" (n
/4), "q" (n
),"1" ((long) to
),"2" ((long) from
)
3241 static __inline__
void sigaddset1(unsigned int *set
, int _sig
)
3243 __asm__("btsl %1,%0" : "=m"(*set
) : "Ir"(_sig
- 1) : "cc");
3246 static __inline__
void sigdelset1(unsigned int *set
, int _sig
)
3248 asm("btrl %1,%0" : "=m"(*set
) : "Ir"(_sig
- 1) : "cc", "flags");
3252 /* clang's inline asm is uncapable of 'xchgb %b0,%h0' */
3253 static __inline__ __const__
unsigned int swab32(unsigned int x
)
3255 return ((x
>> 24) & 0xff) |
3256 ((x
>> 8) & 0xff00) |
3257 ((x
<< 8) & 0xff0000) |
3258 ((x
<< 24) & 0xff000000);
3261 static __inline__ __const__
unsigned int swab32(unsigned int x
)
3263 __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
3264 "rorl $16,%0\n\t" /* swap words */
3265 "xchgb %b0,%h0" /* swap higher bytes */
3272 static __inline__
unsigned long long mul64(unsigned int a
, unsigned int b
)
3274 unsigned long long res
;
3276 /* Using the A constraint is wrong (it means rdx:rax, which is too large)
3277 but still test the 32bit->64bit mull. */
3278 unsigned int resh
, resl
;
3279 __asm__("mull %2" : "=a" (resl
), "=d" (resh
) : "a" (a
), "r" (b
));
3280 res
= ((unsigned long long)resh
<< 32) | resl
;
3282 __asm__("mull %2" : "=A" (res
) : "a" (a
), "r" (b
));
3287 static __inline__
unsigned long long inc64(unsigned long long a
)
3289 unsigned long long res
;
3291 /* Using the A constraint is wrong, and increments are tested
3295 __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res
) : "A" (a
));
3308 unsigned long mconstraint_test(struct struct1231
*r
)
3313 __asm__
volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
3314 : "=&r" (ret
), "=m" (a
)
3315 : "m" (*(struct struct123
*)r
->addr
));
3320 int fls64(unsigned long long x
)
3330 void other_constraints_test(void)
3335 __asm__
volatile ("mov %P1,%0" : "=r" (ret
) : "p" (&var
));
3336 printf ("oc1: %d\n", ret
== (unsigned long)&var
);
3341 /* Test global asm blocks playing with aliases. */
3342 void base_func(void)
3344 printf ("asmc: base\n");
3348 extern void override_func1 (void);
3349 extern void override_func2 (void);
3351 asm(".weak override_func1\n.set override_func1, base_func");
3352 asm(".set override_func1, base_func");
3353 asm(".set override_func2, base_func");
3355 void override_func2 (void)
3357 printf ("asmc: override2\n");
3360 /* This checks a construct used by the linux kernel to encode
3361 references to strings by PC relative references. */
3362 extern int bug_table
[] __attribute__((section("__bug_table")));
3363 char * get_asm_string (void)
3365 /* On i386 when -fPIC is enabled this would cause a compile error with GCC,
3366 the problem being the "i" constraint used with a symbolic operand
3367 resolving to a local label. That check is overly zealous as the code
3368 within the asm makes sure to use it only in PIC-possible contexts,
3369 but all GCC versions behave like so. We arrange for PIC to be disabled
3370 for compiling tcctest.c in the Makefile.
3372 Additionally the usage of 'c' in "%c0" in the template is actually wrong,
3373 as that would expect an operand that is a condition code. The operand
3374 as is (a local label) is accepted by GCC in non-PIC mode, and on x86-64.
3375 What the linux kernel really wanted is 'p' to disable the addition of '$'
3376 to the printed operand (as in "$.LC0" where the template only wants the
3377 bare operand ".LC0"). But the code below is what the linux kernel
3378 happens to use and as such is the one we want to test. */
3380 extern int some_symbol
;
3381 asm volatile (".globl some_symbol\n"
3384 "some_symbol: .long 0\n"
3385 ".pushsection __bug_table, \"a\"\n"
3386 ".globl bug_table\n"
3388 /* The first entry (1b-2b) is unused in this test,
3389 but we include it to check if cross-section
3390 PC-relative references work. */
3391 "2:\t.long 1b - 2b, %c0 - 2b\n"
3392 ".popsection\n" : : "i" ("A string"));
3393 char * str
= ((char*)bug_table
) + bug_table
[1];
3396 return (char *) "A string";
3400 /* This checks another constructs with local labels. */
3401 extern unsigned char alld_stuff
[];
3408 ".pushsection .data.ignore\n"
3409 ".long 661b - .\n" /* This reference to 661 generates an external sym
3410 which shouldn't somehow overwrite the offset that's
3411 already determined for it. */
3413 ".byte 662b - 661b\n" /* So that this value is undeniably 1. */);
3415 void asm_local_label_diff (void)
3417 printf ("asm_local_label_diff: %d %d\n", alld_stuff
[0], alld_stuff
[1]);
3421 /* This checks that static local variables are available from assembler. */
3422 void asm_local_statics (void)
3424 static int localint
= 41;
3425 asm("incl %0" : "+m" (localint
));
3426 printf ("asm_local_statics: %d\n", localint
);
3433 void fancy_copy (unsigned *in
, unsigned *out
)
3435 asm volatile ("" : "=r" (*out
) : "0" (*in
));
3438 void fancy_copy2 (unsigned *in
, unsigned *out
)
3440 asm volatile ("mov %0,(%1)" : : "r" (*in
), "r" (out
) : "memory");
3443 #if defined __x86_64__ && !defined _WIN64
3444 void clobber_r12(void)
3446 asm volatile("mov $1, %%r12" ::: "r12");
3450 void test_high_clobbers_really(void)
3452 #if defined __x86_64__ && !defined _WIN64
3453 register long val
asm("r12");
3455 /* This tests if asm clobbers correctly save/restore callee saved
3456 registers if they are clobbered and if it's the high 8 x86-64
3457 registers. This is fragile for GCC as the constraints do not
3458 correctly capture the data flow, but good enough for us. */
3459 asm volatile("mov $0x4542, %%r12" : "=r" (val
):: "memory");
3461 asm volatile("mov %%r12, %0" : "=r" (val2
) : "r" (val
): "memory");
3462 printf("asmhc: 0x%x\n", val2
);
3466 void test_high_clobbers(void)
3468 #if defined __x86_64__ && !defined _WIN64
3470 asm volatile("mov %%r12,%0" :: "m" (x1
)); /* save r12 */
3471 test_high_clobbers_really();
3472 asm volatile("mov %%r12,%0" :: "m" (x2
)); /* new r12 */
3473 asm volatile("mov %0,%%r12" :: "m" (x1
)); /* restore r12 */
3474 /* should be 0 but tcc doesn't save r12 automatically, which has
3475 bad effects when gcc helds TCCState *s in r12 in tcc.c:main */
3476 //printf("r12-clobber-diff: %lx\n", x2 - x1);
3480 static long cpu_number
;
3481 void trace_console(long len
, long len2
)
3484 /* This generated invalid code when the emission of the switch
3485 table isn't disabled. The asms are necessary to show the bug,
3486 normal statements don't work (they need to generate some code
3487 even under nocode_wanted, which normal statements don't do,
3488 but asms do). Also at least these number of cases is necessary
3489 to generate enough "random" bytes. They ultimately are enough
3490 to create invalid instruction patterns to which the first
3491 skip-to-decision-table jump jumps. If decision table emission
3492 is disabled all of this is no problem.
3494 It also is necessary that the switches are in a statement expression
3495 (which has the property of not being enterable from outside. no
3506 case 8: printf("bla"); pfo_ret__
= 42; break;
3508 pscr_ret__
= pfo_ret__
;
3515 case 1:asm("movq %1,%0": "=r" (pfo_ret__
) : "m" (cpu_number
)); break;
3516 case 2:asm("movq %1,%0": "=r" (pfo_ret__
) : "m" (cpu_number
)); break;
3517 case 4:asm("movq %1,%0": "=r" (pfo_ret__
) : "m" (cpu_number
)); break;
3518 case 8:asm("movq %1,%0": "=r" (pfo_ret__
) : "m" (cpu_number
)); break;
3519 default: printf("impossible\n");
3521 pscr_ret__
= pfo_ret__
;
3533 void test_asm_dead_code(void)
3536 /* Try to make sure that xdi contains a zero, and hence will
3537 lead to a segfault if the next asm is evaluated without
3538 arguments being set up. */
3539 asm volatile ("" : "=D" (rdi
) : "0" (0));
3542 /* This shouldn't trigger a segfault, either the argument
3543 registers need to be set up and the asm emitted despite
3544 this being in an unevaluated context, or both the argument
3545 setup _and_ the asm emission need to be suppressed. The latter
3546 is better. Disabling asm code gen when suppression is on
3547 also fixes the above trace_console bug, but that came earlier
3548 than asm suppression. */
3549 asm volatile ("movl $0,(%0)" : : "D" (&var
) : "memory");
3554 void test_asm_call(void)
3556 #if defined __x86_64__ && !defined _WIN64
3557 static char str
[] = "PATH";
3559 /* This tests if a reference to an undefined symbol from an asm
3560 block, which isn't otherwise referenced in this file, is correctly
3561 regarded as global symbol, so that it's resolved by other object files
3562 or libraries. We chose getenv here, which isn't used anywhere else
3563 in this file. (If we used e.g. printf, which is used we already
3564 would have a global symbol entry, not triggering the bug which is
3566 /* two pushes so stack remains aligned */
3567 asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
3568 #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) && !defined(__APPLE__)
3570 #elif defined(__APPLE__)
3575 "pop %%rdi; pop %%rdi"
3576 : "=a" (s
) : "r" (str
));
3577 printf("asmd: %s\n", s
);
3581 #if defined __x86_64__
3582 # define RX "(%rip)"
3587 void asm_dot_test(void)
3595 asm(".text; lea S"RX
",%eax; lea ."RX
",%ecx; sub %ecx,%eax; S=.; jmp p0");
3598 /* clangs internal assembler is broken */
3599 asm(".text; jmp .+6; .int 123; mov .-4"RX
",%eax; jmp p0");
3601 asm(".text; mov $123, %eax; jmp p0");
3604 #if !defined(_WIN32) && !defined(__clang__)
3605 asm(".pushsection \".data\"; Y=.; .int 999; X=Y; .int 456; X=.-4; .popsection");
3607 asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4; .text");
3609 asm(".text; mov X"RX
",%eax; jmp p0");
3612 /* Bah! Clang! Doesn't want to redefine 'X' */
3613 asm(".text; mov $789,%eax; jmp p0");
3616 asm(".data; X=.; .int 789; Y=.; .int 999; .previous");
3618 asm(".data; X=.; .int 789; Y=.; .int 999; .text");
3620 asm(".text; mov X"RX
",%eax; X=Y; jmp p0");
3623 asm(".text; p0=.; mov %%eax,%0;" : "=m"(r
)); break;
3627 printf("asm_dot_test %d: %d\n", x
, r
);
3635 unsigned int val
, val2
;
3636 struct struct123 s1
;
3637 struct struct1231 s2
= { (unsigned long)&s1
};
3638 /* Hide the outer base_func, but check later that the inline
3639 asm block gets the outer one. */
3641 void override_func3 (void);
3642 unsigned long asmret
;
3646 register int regvar
asm("%esi");
3648 // parse 0x1E-1 as 3 tokens in asm mode
3649 asm volatile ("mov $0x1E-1,%eax");
3651 /* test the no operand case */
3652 asm volatile ("xorl %eax, %eax");
3654 memcpy1(buf
, "hello", 6);
3655 strncat1(buf
, " worldXXXXX", 3);
3656 printf("%s\n", buf
);
3658 memcpy2(buf
, "hello", 6);
3659 strncat2(buf
, " worldXXXXX", 3);
3660 printf("%s\n", buf
);
3662 /* 'A' constraint test */
3663 printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
3664 printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
3668 printf("mconstraint: %d", mconstraint_test(&s2
));
3669 printf(" %d %d\n", s1
.a
, s1
.b
);
3670 other_constraints_test();
3672 sigdelset1(&set
, 2);
3673 sigaddset1(&set
, 16);
3674 /* NOTE: we test here if C labels are correctly restored after the
3678 __asm__("btsl %1,%0" : "=m"(set
) : "Ir"(20) : "cc");
3679 printf("set=0x%x\n", set
);
3681 printf("swab32(0x%08x) = 0x%0x\n", val
, swab32(val
));
3686 /* The base_func ref from the following inline asm should find
3687 the global one, not the local decl from this function. */
3688 asm volatile(".weak override_func3\n.set override_func3, base_func");
3690 printf("asmstr: %s\n", get_asm_string());
3691 asm_local_label_diff();
3693 asm_local_statics();
3696 /* clang can't deal with the type change */
3697 /* Check that we can also load structs of appropriate layout
3699 asm volatile("" : "=r" (asmret
) : "0"(s2
));
3700 if (asmret
!= s2
.addr
)
3701 printf("asmstr: failed\n");
3704 /* Check that the typesize correctly sets the register size to
3706 asm volatile("cmp %1,%2; sete %0" : "=a"(somebool
) : "r"(1), "r"(2));
3708 printf("asmbool: failed\n");
3711 fancy_copy (&val
, &val2
);
3712 printf ("fancycpy(%d)=%d\n", val
, val2
);
3714 fancy_copy2 (&val
, &val2
);
3715 printf ("fancycpy2(%d)=%d\n", val
, val2
);
3716 asm volatile ("mov $0x4243, %%esi" : "=r" (regvar
));
3717 printf ("regvar=%x\n", regvar
);
3718 test_high_clobbers();
3719 trace_console(8, 8);
3720 test_asm_dead_code();
3736 #define COMPAT_TYPE(type1, type2) \
3738 printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
3739 __builtin_types_compatible_p (type1, type2));\
3746 void builtin_test(void)
3752 COMPAT_TYPE(int, int);
3753 COMPAT_TYPE(int, unsigned int);
3754 COMPAT_TYPE(int, char);
3755 COMPAT_TYPE(int, const int);
3756 COMPAT_TYPE(int, volatile int);
3757 COMPAT_TYPE(int *, int *);
3758 COMPAT_TYPE(int *, void *);
3759 COMPAT_TYPE(int *, const int *);
3760 COMPAT_TYPE(char *, unsigned char *);
3761 COMPAT_TYPE(char *, signed char *);
3762 COMPAT_TYPE(char *, char *);
3763 /* space is needed because tcc preprocessor introduces a space between each token */
3764 COMPAT_TYPE(char * *, void *);
3766 printf("res1 = %d\n", __builtin_constant_p(1));
3767 printf("res2 = %d\n", __builtin_constant_p(1 + 2));
3768 printf("res3 = %d\n", __builtin_constant_p(&constant_p_var
));
3769 printf("res4 = %d\n", __builtin_constant_p(constant_p_var
));
3770 printf("res5 = %d\n", __builtin_constant_p(100000 / constant_p_var
));
3772 /* clang doesn't regard this as constant expression */
3773 printf("res6 = 1\n");
3775 printf("res6 = %d\n", __builtin_constant_p(i
&& 0));
3777 printf("res7 = %d\n", __builtin_constant_p(i
&& 1));
3779 /* clang doesn't regard this as constant expression */
3780 printf("res8 = 1\n");
3782 printf("res8 = %d\n", __builtin_constant_p(i
&& 0 ? i
: 34));
3784 printf("res9 = %d\n", __builtin_constant_p("hi"));
3785 printf("res10 = %d\n", __builtin_constant_p(func()));
3788 i
= __builtin_choose_expr (1 != 0, ll
, s
);
3789 printf("bce: %d\n", i
);
3790 i
= __builtin_choose_expr (1 != 1, ll
, s
);
3791 printf("bce: %d\n", i
);
3792 i
= sizeof (__builtin_choose_expr (1, ll
, s
));
3793 printf("bce: %d\n", i
);
3794 i
= sizeof (__builtin_choose_expr (0, ll
, s
));
3795 printf("bce: %d\n", i
);
3797 //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
3801 void weak_test(void) {}
3803 extern int __attribute__((weak
)) weak_f1(void);
3804 extern int __attribute__((weak
)) weak_f2(void);
3805 extern int weak_f3(void);
3806 extern int __attribute__((weak
)) weak_v1
;
3807 extern int __attribute__((weak
)) weak_v2
;
3810 extern int (*weak_fpa
)() __attribute__((weak
));
3811 extern int __attribute__((weak
)) (*weak_fpb
)();
3812 extern __attribute__((weak
)) int (*weak_fpc
)();
3814 extern int weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak
));
3815 extern int __attribute((weak
)) weak_asm_f2(void) asm("weak_asm_f2x") ;
3816 extern int __attribute((weak
)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak
));
3817 extern int weak_asm_v1
asm("weak_asm_v1x") __attribute((weak
));
3818 extern int __attribute((weak
)) weak_asm_v2
asm("weak_asm_v2x") ;
3819 extern int __attribute((weak
)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak
));
3822 static const size_t dummy
= 0;
3823 extern __typeof(dummy
) weak_dummy1
__attribute__((weak
, alias("dummy")));
3824 extern __typeof(dummy
) __attribute__((weak
, alias("dummy"))) weak_dummy2
;
3825 extern __attribute__((weak
, alias("dummy"))) __typeof(dummy
) weak_dummy3
;
3828 int some_lib_func(void);
3829 int dummy_impl_of_slf(void) { return 444; }
3831 int some_lib_func(void) __attribute__((weak
, alias("dummy_impl_of_slf")));
3834 int weak_toolate() __attribute__((weak
));
3835 int weak_toolate() { return 0; }
3837 void __attribute__((weak
)) weak_test(void)
3839 printf("weak_f1=%d\n", weak_f1
? weak_f1() : 123);
3840 printf("weak_f2=%d\n", weak_f2
? weak_f2() : 123);
3841 printf("weak_f3=%d\n", weak_f3
? weak_f3() : 123);
3842 printf("weak_v1=%d\n",&weak_v1
? weak_v1
: 123);
3843 printf("weak_v2=%d\n",&weak_v2
? weak_v2
: 123);
3844 printf("weak_v3=%d\n",&weak_v3
? weak_v3
: 123);
3846 printf("weak_fpa=%d\n",&weak_fpa
? weak_fpa() : 123);
3847 printf("weak_fpb=%d\n",&weak_fpb
? weak_fpb() : 123);
3848 printf("weak_fpc=%d\n",&weak_fpc
? weak_fpc() : 123);
3850 printf("weak_asm_f1=%d\n", weak_asm_f1
!= NULL
);
3851 printf("weak_asm_f2=%d\n", weak_asm_f2
!= NULL
);
3852 printf("weak_asm_f3=%d\n", weak_asm_f3
!= NULL
);
3853 printf("weak_asm_v1=%d\n",&weak_asm_v1
!= NULL
);
3854 printf("weak_asm_v2=%d\n",&weak_asm_v2
!= NULL
);
3855 printf("weak_asm_v3=%d\n",&weak_asm_v3
!= NULL
);
3857 printf("some_lib_func=444\n");
3859 printf("some_lib_func=%d\n", &some_lib_func
? some_lib_func() : 0);
3863 int __attribute__((weak
)) weak_f2() { return 222; }
3864 int __attribute__((weak
)) weak_f3() { return 333; }
3865 int __attribute__((weak
)) weak_v2
= 222;
3866 int __attribute__((weak
)) weak_v3
= 333;
3869 void const_func(const int a
)
3873 void const_warn_test(void)
3882 int getme (struct condstruct
*s
, int i
)
3884 int i1
= (i
== 0 ? 0 : s
)->i
;
3885 int i2
= (i
== 0 ? s
: 0)->i
;
3886 int i3
= (i
== 0 ? (void*)0 : s
)->i
;
3887 int i4
= (i
== 0 ? s
: (void*)0)->i
;
3888 return i1
+ i2
+ i3
+ i4
;
3897 struct global_data global_data
;
3899 int global_data_getstuff (int *, int);
3901 void global_data_callit (int i
)
3903 *global_data
.b
[i
] = global_data_getstuff (global_data
.b
[i
], 1);
3906 int global_data_getstuff (int *p
, int i
)
3911 void global_data_test (void)
3913 global_data
.a
[0] = 42;
3914 global_data
.b
[0] = &global_data
.a
[0];
3915 global_data_callit (0);
3916 printf ("%d\n", global_data
.a
[0]);
3921 unsigned char fill
: 3;
3922 unsigned char b1
: 1;
3923 unsigned char b2
: 1;
3924 unsigned char fill2
: 3;
3927 int glob1
, glob2
, glob3
;
3929 void compare_comparisons (struct cmpcmpS
*s
)
3931 if (s
->b1
!= (glob1
== glob2
)
3932 || (s
->b2
!= (glob1
== glob3
)))
3933 printf ("comparing comparisons broken\n");
3936 void cmp_comparison_test(void)
3940 glob1
= 42; glob2
= 42;
3943 compare_comparisons (&s
);
3946 int fcompare (double a
, double b
, int code
)
3949 case 0: return a
== b
;
3950 case 1: return a
!= b
;
3951 case 2: return a
< b
;
3952 case 3: return a
>= b
;
3953 case 4: return a
> b
;
3954 case 5: return a
<= b
;
3959 void math_cmp_test(void)
3961 double nan
= 0.0/0.0;
3966 #define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
3968 /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
3969 And it does this in various ways so that all code generation paths
3970 are checked (generating inverted tests, or non-inverted tests, or
3971 producing a 0/1 value without jumps (that's done in the fcompare
3973 #define FCMP(a,b,op,iop,code) \
3974 if (fcompare (a,b,code)) \
3975 bug (a,b,op,iop,1); \
3977 bug (a,b,op,iop,2); \
3981 bug (a,b,op,iop,3); \
3982 if ((a op b) || comp) \
3983 bug (a,b,op,iop,4); \
3984 if ((a iop b) || comp) \
3987 bug (a,b,op,iop,5); \
3988 if (v = !(a op b), !v) bug(a,b,op,iop,7);
3990 /* Equality tests. */
3991 FCMP(nan
, nan
, ==, !=, 0);
3992 FCMP(one
, two
, ==, !=, 0);
3993 FCMP(one
, one
, !=, ==, 1);
3994 /* Non-equality is a bit special. */
3995 if (!fcompare (nan
, nan
, 1))
3996 bug (nan
, nan
, !=, ==, 6);
3998 /* Relational tests on numbers. */
3999 FCMP(two
, one
, <, >=, 2);
4000 FCMP(one
, two
, >=, <, 3);
4001 FCMP(one
, two
, >, <=, 4);
4002 FCMP(two
, one
, <=, >, 5);
4004 /* Relational tests on NaNs. Note that the inverse op here is
4005 always !=, there's no operator in C that is equivalent to !(a < b),
4006 when NaNs are involved, same for the other relational ops. */
4007 FCMP(nan
, nan
, <, !=, 2);
4008 FCMP(nan
, nan
, >=, !=, 3);
4009 FCMP(nan
, nan
, >, !=, 4);
4010 FCMP(nan
, nan
, <=, !=, 5);
4013 double get100 () { return 100.0; }
4015 void callsave_test(void)
4017 #if defined __i386__ || defined __x86_64__ || defined __arm__
4018 int i
, s
; double *d
; double t
;
4019 s
= sizeof (double);
4020 printf ("callsavetest: %d\n", s
);
4021 d
= alloca (sizeof(double));
4023 /* x86-64 had a bug were the next call to get100 would evict
4024 the lvalue &d[0] as VT_LLOCAL, and the reload would be done
4025 in int type, not pointer type. When alloca returns a pointer
4026 with the high 32 bit set (which is likely on x86-64) the access
4027 generates a segfault. */
4028 i
= d
[0] > get100 ();
4034 void bfa3(ptrdiff_t str_offset
)
4036 printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset
);
4038 void bfa2(ptrdiff_t str_offset
)
4040 printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset
);
4043 void bfa1(ptrdiff_t str_offset
)
4045 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset
);
4049 void builtin_frame_address_test(void)
4051 /* builtin_frame_address fails on ARM with gcc which make test3 fail */
4053 char str
[] = "__builtin_frame_address";
4054 char *fp0
= __builtin_frame_address(0);
4056 printf("str: %s\n", str
);
4057 #ifndef __riscv // gcc dumps core. tcc, clang work
4063 char via_volatile (char i
)
4070 void volatile_test(void)
4072 if (via_volatile (42) != 42)
4073 printf (" broken\n");
4078 struct __attribute__((__packed__
)) Spacked
{
4083 struct Spacked spacked
;
4084 typedef struct __attribute__((__packed__
)) {
4090 typedef struct Spacked3_s
{
4094 } __attribute__((__packed__
)) Spacked3
;
4096 struct gate_struct64
{
4097 unsigned short offset_low
;
4098 unsigned short segment
;
4099 unsigned ist
: 3, zero0
: 5, type
: 5, dpl
: 2, p
: 1;
4100 unsigned short offset_middle
;
4101 unsigned offset_high
;
4103 } __attribute__((packed
));
4104 typedef struct gate_struct64 gate_desc
;
4105 gate_desc a_gate_desc
;
4106 void attrib_test(void)
4109 printf("attr: %d %d %d %d\n", sizeof(struct Spacked
),
4110 sizeof(spacked
), sizeof(Spacked2
), sizeof(spacked2
));
4111 printf("attr: %d %d\n", sizeof(Spacked3
), sizeof(spacked3
));
4112 printf("attr: %d %d\n", sizeof(gate_desc
), sizeof(a_gate_desc
));
4115 extern __attribute__((__unused__
)) char * __attribute__((__unused__
)) *
4116 strange_attrib_placement (void);
4118 void * __attribute__((__unused__
)) get_void_ptr (void *a
)
4123 /* This part checks for a bug in TOK_GET (used for inline expansion),
4124 where the large long long constant left the the high bits set for
4125 the integer constant token. */
4127 int __get_order(unsigned long long size
)
4130 size
-= 0xffff880000000000ULL
; // this const left high bits set in the token
4132 struct S
{ int i
: 1; } s
; // constructed for this '1'
4138 /* This just forces the above inline function to be actually emitted. */
4139 int force_get_order(unsigned long s
)
4141 return __get_order(s
);
4144 #define pv(m) printf(sizeof (s->m + 0) == 8 ? "%016llx\n" : "%02x\n", s->m)
4146 /* Test failed when using bounds checking */
4147 void bounds_check1_test (void)
4159 /* gcc 2.95.3 does not handle correctly CR in strings or after strays */
4160 #define CORRECT_CR_HANDLING
4162 /* deprecated and no longer supported in gcc 3.3 */
4164 # define ACCEPT_CR_IN_STRINGS
4167 /* keep this as the last test because GCC messes up line-numbers
4168 with the ^L^K^M characters below */
4169 void whitespace_test(void)
4175 ntf("whitspace:\n");\f\v
4179 #ifdef CORRECT_CR_HANDLING
4188 #ifdef ACCEPT_CR_IN_STRINGS
4189 printf("len1=%d\n", strlen("
4191 #ifdef CORRECT_CR_HANDLING
4194 printf("len1=%d str[0]=%d\n", strlen(str
), str
[0]);
4196 printf("len1=%d\n", strlen("
a
4199 printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n");
4200 #endif /* ACCEPT_CR_IN_STRINGS */
4203 printf("__LINE__ defined\n");
4207 /* wrong with GCC */
4208 printf("__LINE__=%d __FILE__=%s\n", __LINE__
, __FILE__
);
4210 printf("__LINE__=%d __FILE__=%s\n", __LINE__
, __FILE__
);
4212 printf("__LINE__=%d __FILE__=%s\n", __LINE__
, __FILE__
);
4216 #define RUN(test) puts("---- " #test " ----"), test(), puts("")
4218 int main(int argc
, char **argv
)
4220 RUN(whitespace_test
);
4222 RUN(recursive_macro_test
);
4239 RUN(optimize_out_test
);
4241 RUN(constant_expr_test
);
4243 RUN(char_short_test
);
4245 RUN(compound_literal_test
);
4247 RUN(struct_assign_test
);
4255 RUN(relocation_test
);
4256 RUN(old_style_function_test
);
4261 RUN(statement_expr_test
);
4262 RUN(local_label_test
);
4266 RUN(global_data_test
);
4267 RUN(cmp_comparison_test
);
4270 RUN(builtin_frame_address_test
);
4273 RUN(bounds_check1_test
);