we need to disable or adjust some tests where clang behaves slightly different from GCC: * slight difference in __FILE__ behaviour * difference (to less useful vs GCC) in computed #include * difference in __builtin_constant_p * attribute(weak, alias) isn't supported by clang on MacOS (though it could be, as Mach-O has the capabilities for this) * the built-in assembler of clang is mediocre this was all checked with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Unified · Split
| @@ -64,7 +64,13 @@ typedef __SIZE_TYPE__ uintptr_t; · 63 unmodified lines | |||
| 64 | #define INC(name) <tests/name.h> | 64 | #define INC(name) <tests/name.h> |
| 65 | #define funnyname 42test.h | 65 | #define funnyname 42test.h |
| 66 | #define incdir tests/ | 66 | #define incdir tests/ |
| 67 | #ifdef __clang__ | ||
| 68 | /* clang's preprocessor is broken in this regard and adds spaces | ||
| 69 | to the tokens 'incdir' and 'funnyname' when expanding */ | ||
| 70 | #define incname <tests/42test.h> | ||
| 71 | #else | ||
| 67 | #define incname < incdir funnyname > | 72 | #define incname < incdir funnyname > |
| 73 | #endif | ||
| 68 | #define __stringify(x) #x | 74 | #define __stringify(x) #x |
| 69 | #define stringify(x) __stringify(x) | 75 | #define stringify(x) __stringify(x) |
| 70 | #include INC(42test) | 76 | #include INC(42test) |
| @@ -411,10 +417,17 @@ comment · 340 unmodified lines | |||
| 411 | comment. */ | 417 | comment. */ |
| 412 | TEST2 /* the comment */ (); | 418 | TEST2 /* the comment */ (); |
| 413 | 419 | ||
| 414 | printf("%s\n", get_basefile_from_header()); | 420 | printf("basefromheader %s\n", get_basefile_from_header()); |
| 415 | printf("%s\n", __BASE_FILE__); | 421 | printf("base %s\n", __BASE_FILE__); |
| 416 | printf("%s\n", get_file_from_header()); | 422 | { |
| 417 | printf("%s\n", __FILE__); | 423 | /* Some compilers (clang) prepend './' to __FILE__ from included |
| 424 | files. */ | ||
| 425 | const char *fn = get_file_from_header(); | ||
| 426 | if (fn[0] == '.' && fn[1] == '/') | ||
| 427 | fn += 2; | ||
| 428 | printf("filefromheader %s\n", fn); | ||
| 429 | } | ||
| 430 | printf("file %s\n", __FILE__); | ||
| 418 | 431 | ||
| 419 | /* Check that funnily named include was in fact included */ | 432 | /* Check that funnily named include was in fact included */ |
| 420 | have_included_42test_h = 1; | 433 | have_included_42test_h = 1; |
| @@ -3330,6 +3343,8 @@ static __inline__ void sigdelset1(unsigned int *set, int _sig) · 2909 unmodified lines | |||
| 3330 | asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags"); | 3343 | asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags"); |
| 3331 | } | 3344 | } |
| 3332 | 3345 | ||
| 3346 | #ifndef __APPLE__ | ||
| 3347 | /* clang's inline asm is uncapable of 'xchgb %b0,%h0' */ | ||
| 3333 | static __inline__ __const__ unsigned int swab32(unsigned int x) | 3348 | static __inline__ __const__ unsigned int swab32(unsigned int x) |
| 3334 | { | 3349 | { |
| 3335 | __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ | 3350 | __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ |
| @@ -3339,6 +3354,7 @@ static __inline__ __const__ unsigned int swab32(unsigned int x) · 3 unmodified lines | |||
| 3339 | : "0" (x)); | 3354 | : "0" (x)); |
| 3340 | return x; | 3355 | return x; |
| 3341 | } | 3356 | } |
| 3357 | #endif | ||
| 3342 | 3358 | ||
| 3343 | static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) | 3359 | static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) |
| 3344 | { | 3360 | { |
| @@ -3415,6 +3431,7 @@ void base_func(void) · 70 unmodified lines | |||
| 3415 | printf ("asmc: base\n"); | 3431 | printf ("asmc: base\n"); |
| 3416 | } | 3432 | } |
| 3417 | 3433 | ||
| 3434 | #ifndef __APPLE__ | ||
| 3418 | extern void override_func1 (void); | 3435 | extern void override_func1 (void); |
| 3419 | extern void override_func2 (void); | 3436 | extern void override_func2 (void); |
| 3420 | 3437 | ||
| @@ -3482,6 +3499,7 @@ void asm_local_label_diff (void) · 61 unmodified lines | |||
| 3482 | { | 3499 | { |
| 3483 | printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); | 3500 | printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); |
| 3484 | } | 3501 | } |
| 3502 | #endif | ||
| 3485 | 3503 | ||
| 3486 | /* This checks that static local variables are available from assembler. */ | 3504 | /* This checks that static local variables are available from assembler. */ |
| 3487 | void asm_local_statics (void) | 3505 | void asm_local_statics (void) |
| @@ -3630,8 +3648,10 @@ void test_asm_call(void) · 142 unmodified lines | |||
| 3630 | tested here). */ | 3648 | tested here). */ |
| 3631 | /* two pushes so stack remains aligned */ | 3649 | /* two pushes so stack remains aligned */ |
| 3632 | asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;" | 3650 | asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;" |
| 3633 | #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) | 3651 | #if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) && !defined(__APPLE__) |
| 3634 | "call getenv@plt;" | 3652 | "call getenv@plt;" |
| 3653 | #elif defined(__APPLE__) && !defined(__TINYC__) | ||
| 3654 | "call _getenv;" | ||
| 3635 | #else | 3655 | #else |
| 3636 | "call getenv;" | 3656 | "call getenv;" |
| 3637 | #endif | 3657 | #endif |
| @@ -3656,21 +3676,31 @@ void asm_dot_test(void) · 18 unmodified lines | |||
| 3656 | case 1: | 3676 | case 1: |
| 3657 | asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0"); | 3677 | asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0"); |
| 3658 | case 2: | 3678 | case 2: |
| 3679 | #ifndef __APPLE__ | ||
| 3680 | /* clangs internal assembler is broken */ | ||
| 3659 | asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0"); | 3681 | asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0"); |
| 3682 | #else | ||
| 3683 | asm(".text; mov $0, %eax; jmp p0"); | ||
| 3684 | #endif | ||
| 3660 | case 3: | 3685 | case 3: |
| 3661 | #ifndef _WIN32 | 3686 | #if !defined(_WIN32) && !defined(__APPLE__) |
| 3662 | asm(".pushsection \".data\"; Y=.; .int 999; X=Y; .int 456; X=.-4; .popsection"); | 3687 | asm(".pushsection \".data\"; Y=.; .int 999; X=Y; .int 456; X=.-4; .popsection"); |
| 3663 | #else | 3688 | #else |
| 3664 | asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4; .text"); | 3689 | asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4; .text"); |
| 3665 | #endif | 3690 | #endif |
| 3666 | asm(".text; mov X"RX",%eax; jmp p0"); | 3691 | asm(".text; mov X"RX",%eax; jmp p0"); |
| 3667 | case 4: | 3692 | case 4: |
| 3693 | #ifdef __APPLE__ | ||
| 3694 | /* Bah! Clang! Doesn't want to redefine 'X' */ | ||
| 3695 | asm(".text; mov $123,%eax; jmp p0"); | ||
| 3696 | #else | ||
| 3668 | #ifndef _WIN32 | 3697 | #ifndef _WIN32 |
| 3669 | asm(".data; X=.; .int 789; Y=.; .int 999; .previous"); | 3698 | asm(".data; X=.; .int 789; Y=.; .int 999; .previous"); |
| 3670 | #else | 3699 | #else |
| 3671 | asm(".data; X=.; .int 789; Y=.; .int 999; .text"); | 3700 | asm(".data; X=.; .int 789; Y=.; .int 999; .text"); |
| 3672 | #endif | 3701 | #endif |
| 3673 | asm(".text; mov X"RX",%eax; X=Y; jmp p0"); | 3702 | asm(".text; mov X"RX",%eax; X=Y; jmp p0"); |
| 3703 | #endif | ||
| 3674 | case 0: | 3704 | case 0: |
| 3675 | asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break; | 3705 | asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break; |
| 3676 | } | 3706 | } |
| @@ -3731,8 +3761,11 @@ void asm_test(void) · 54 unmodified lines | |||
| 3731 | __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc"); | 3761 | __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc"); |
| 3732 | printf("set=0x%x\n", set); | 3762 | printf("set=0x%x\n", set); |
| 3733 | val = 0x01020304; | 3763 | val = 0x01020304; |
| 3764 | #ifndef __APPLE__ | ||
| 3734 | printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); | 3765 | printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); |
| 3766 | #endif | ||
| 3735 | #ifndef _WIN32 | 3767 | #ifndef _WIN32 |
| 3768 | #ifndef __APPLE__ | ||
| 3736 | override_func1(); | 3769 | override_func1(); |
| 3737 | override_func2(); | 3770 | override_func2(); |
| 3738 | /* The base_func ref from the following inline asm should find | 3771 | /* The base_func ref from the following inline asm should find |
| @@ -3741,13 +3774,17 @@ void asm_test(void) · 2 unmodified lines | |||
| 3741 | override_func3(); | 3774 | override_func3(); |
| 3742 | printf("asmstr: %s\n", get_asm_string()); | 3775 | printf("asmstr: %s\n", get_asm_string()); |
| 3743 | asm_local_label_diff(); | 3776 | asm_local_label_diff(); |
| 3777 | #endif | ||
| 3744 | asm_local_statics(); | 3778 | asm_local_statics(); |
| 3745 | #endif | 3779 | #endif |
| 3780 | #ifndef __APPLE__ | ||
| 3781 | /* clang can't deal with the type change */ | ||
| 3746 | /* Check that we can also load structs of appropriate layout | 3782 | /* Check that we can also load structs of appropriate layout |
| 3747 | into registers. */ | 3783 | into registers. */ |
| 3748 | asm volatile("" : "=r" (asmret) : "0"(s2)); | 3784 | asm volatile("" : "=r" (asmret) : "0"(s2)); |
| 3749 | if (asmret != s2.addr) | 3785 | if (asmret != s2.addr) |
| 3750 | printf("asmstr: failed\n"); | 3786 | printf("asmstr: failed\n"); |
| 3787 | #endif | ||
| 3751 | #ifdef BOOL_ISOC99 | 3788 | #ifdef BOOL_ISOC99 |
| 3752 | /* Check that the typesize correctly sets the register size to | 3789 | /* Check that the typesize correctly sets the register size to |
| 3753 | 8 bit. */ | 3790 | 8 bit. */ |
| @@ -3809,14 +3846,19 @@ void builtin_test(void) · 55 unmodified lines | |||
| 3809 | /* space is needed because tcc preprocessor introduces a space between each token */ | 3846 | /* space is needed because tcc preprocessor introduces a space between each token */ |
| 3810 | COMPAT_TYPE(char * *, void *); | 3847 | COMPAT_TYPE(char * *, void *); |
| 3811 | #endif | 3848 | #endif |
| 3812 | printf("res = %d\n", __builtin_constant_p(1)); | 3849 | printf("res1 = %d\n", __builtin_constant_p(1)); |
| 3813 | printf("res = %d\n", __builtin_constant_p(1 + 2)); | 3850 | printf("res2 = %d\n", __builtin_constant_p(1 + 2)); |
| 3814 | printf("res = %d\n", __builtin_constant_p(&constant_p_var)); | 3851 | printf("res3 = %d\n", __builtin_constant_p(&constant_p_var)); |
| 3815 | printf("res = %d\n", __builtin_constant_p(constant_p_var)); | 3852 | printf("res4 = %d\n", __builtin_constant_p(constant_p_var)); |
| 3816 | printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var)); | 3853 | printf("res5 = %d\n", __builtin_constant_p(100000 / constant_p_var)); |
| 3817 | printf("res = %d\n", __builtin_constant_p(i && 0)); | 3854 | #ifndef __APPLE__ |
| 3818 | printf("res = %d\n", __builtin_constant_p(i && 1)); | 3855 | /* clang doesn't regard this as constant expression */ |
| 3819 | printf("res = %d\n", __builtin_constant_p(i && 0 ? i : 34)); | 3856 | printf("res6 = %d\n", __builtin_constant_p(i && 0)); |
| 3857 | #endif | ||
| 3858 | printf("res7 = %d\n", __builtin_constant_p(i && 1)); | ||
| 3859 | #ifndef __APPLE__ | ||
| 3860 | printf("res8 = %d\n", __builtin_constant_p(i && 0 ? i : 34)); | ||
| 3861 | #endif | ||
| 3820 | s = 1; | 3862 | s = 1; |
| 3821 | ll = 2; | 3863 | ll = 2; |
| 3822 | i = __builtin_choose_expr (1 != 0, ll, s); | 3864 | i = __builtin_choose_expr (1 != 0, ll, s); |
| @@ -3850,14 +3892,18 @@ extern int weak_asm_v1 asm("weak_asm_v1x") __attribute · 27 unmodified lines | |||
| 3850 | extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ; | 3892 | extern int __attribute((weak)) weak_asm_v2 asm("weak_asm_v2x") ; |
| 3851 | extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak)); | 3893 | extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak)); |
| 3852 | 3894 | ||
| 3895 | #ifndef __APPLE__ | ||
| 3853 | static const size_t dummy = 0; | 3896 | static const size_t dummy = 0; |
| 3854 | extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy"))); | 3897 | extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy"))); |
| 3855 | extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2; | 3898 | extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2; |
| 3856 | extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3; | 3899 | extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3; |
| 3900 | #endif | ||
| 3857 | 3901 | ||
| 3858 | int some_lib_func(void); | 3902 | int some_lib_func(void); |
| 3859 | int dummy_impl_of_slf(void) { return 444; } | 3903 | int dummy_impl_of_slf(void) { return 444; } |
| 3904 | #ifndef __APPLE__ | ||
| 3860 | int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf"))); | 3905 | int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf"))); |
| 3906 | #endif | ||
| 3861 | 3907 | ||
| 3862 | int weak_toolate() __attribute__((weak)); | 3908 | int weak_toolate() __attribute__((weak)); |
| 3863 | int weak_toolate() { return 0; } | 3909 | int weak_toolate() { return 0; } |
| @@ -3881,7 +3927,9 @@ void __attribute__((weak)) weak_test(void) · 17 unmodified lines | |||
| 3881 | printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL); | 3927 | printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL); |
| 3882 | printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); | 3928 | printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL); |
| 3883 | printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); | 3929 | printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL); |
| 3930 | #ifndef __APPLE__ | ||
| 3884 | printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0); | 3931 | printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0); |
| 3932 | #endif | ||
| 3885 | } | 3933 | } |
| 3886 | 3934 | ||
| 3887 | int __attribute__((weak)) weak_f2() { return 222; } | 3935 | int __attribute__((weak)) weak_f2() { return 222; } |