Bad assumption make bad things happen: long d3; asm(..."1:\tdec %3\n\t" : ... "=&c" (d3) Which wants 'dec RDI' but did 'dec EDI' on _WIN64. Also: - tcctest.c: enable more asm tests for win64 - configure: show errors if any with 'gcc conftest.c' - tccgen.c: remove decl0(x, y, z)
Unified · Split
| @@ -357,7 +357,7 @@ fi · 356 unmodified lines | |||
| 357 | 357 | ||
| 358 | if test -z "$cross_prefix" ; then | 358 | if test -z "$cross_prefix" ; then |
| 359 | CONFTEST=./conftest$EXESUF | 359 | CONFTEST=./conftest$EXESUF |
| 360 | if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then | 360 | if ! $cc -o $CONFTEST $source_path/conftest.c ; then |
| 361 | echo "configure: error: '$cc' failed to compile conftest.c." | 361 | echo "configure: error: '$cc' failed to compile conftest.c." |
| 362 | else | 362 | else |
| 363 | cc_name="$($CONFTEST compiler)" | 363 | cc_name="$($CONFTEST compiler)" |
| @@ -130,8 +130,7 @@ static void init_putv(init_params *p, CType *type, unsigned long c); · 129 unmodified lines | |||
| 130 | static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags); | 130 | static void decl_initializer(init_params *p, CType *type, unsigned long c, int flags); |
| 131 | static void block(int is_expr); | 131 | static void block(int is_expr); |
| 132 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); | 132 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope); |
| 133 | static void decl(int l); | 133 | static int decl(int l); |
| 134 | static int decl0(int l, int is_for_loop_init, Sym *); | ||
| 135 | static void expr_eq(void); | 134 | static void expr_eq(void); |
| 136 | static void vpush_type_size(CType *type, int *a); | 135 | static void vpush_type_size(CType *type, int *a); |
| 137 | static int is_compatible_unqualified_types(CType *type1, CType *type2); | 136 | static int is_compatible_unqualified_types(CType *type1, CType *type2); |
| @@ -6881,7 +6880,7 @@ again: · 6743 unmodified lines | |||
| 6881 | skip('('); | 6880 | skip('('); |
| 6882 | if (tok != ';') { | 6881 | if (tok != ';') { |
| 6883 | /* c99 for-loop init decl? */ | 6882 | /* c99 for-loop init decl? */ |
| 6884 | if (!decl0(VT_LOCAL, 1, NULL)) { | 6883 | if (!decl(VT_JMP)) { |
| 6885 | /* no, regular for-loop init expr */ | 6884 | /* no, regular for-loop init expr */ |
| 6886 | gexpr(); | 6885 | gexpr(); |
| 6887 | vpop(); | 6886 | vpop(); |
| @@ -7795,7 +7794,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f · 907 unmodified lines | |||
| 7795 | is put in the value stack. If 'has_init' is 2, a special parsing | 7794 | is put in the value stack. If 'has_init' is 2, a special parsing |
| 7796 | is done to handle string constants. */ | 7795 | is done to handle string constants. */ |
| 7797 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, | 7796 | static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, |
| 7798 | int has_init, int v, int scope) | 7797 | int has_init, int v, int global) |
| 7799 | { | 7798 | { |
| 7800 | int size, align, addr; | 7799 | int size, align, addr; |
| 7801 | TokenString *init_str = NULL; | 7800 | TokenString *init_str = NULL; |
| @@ -7932,7 +7931,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 130 unmodified lines | |||
| 7932 | } | 7931 | } |
| 7933 | } else { | 7932 | } else { |
| 7934 | sym = NULL; | 7933 | sym = NULL; |
| 7935 | if (v && scope == VT_CONST) { | 7934 | if (v && global) { |
| 7936 | /* see if the symbol was already defined */ | 7935 | /* see if the symbol was already defined */ |
| 7937 | sym = sym_find(v); | 7936 | sym = sym_find(v); |
| 7938 | if (sym) { | 7937 | if (sym) { |
| @@ -8198,9 +8197,10 @@ static void free_inline_functions(TCCState *s) · 259 unmodified lines | |||
| 8198 | dynarray_reset(&s->inline_fns, &s->nb_inline_fns); | 8197 | dynarray_reset(&s->inline_fns, &s->nb_inline_fns); |
| 8199 | } | 8198 | } |
| 8200 | 8199 | ||
| 8201 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP | 8200 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type |
| 8202 | if parsing old style parameter decl list (and FUNC_SYM is set then) */ | 8201 | or VT_CMP if parsing old style parameter list |
| 8203 | static int decl0(int l, int is_for_loop_init, Sym *func_sym) | 8202 | or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */ |
| 8203 | static int decl(int l) | ||
| 8204 | { | 8204 | { |
| 8205 | int v, has_init, r, oldint; | 8205 | int v, has_init, r, oldint; |
| 8206 | CType type, btype; | 8206 | CType type, btype; |
| @@ -8236,7 +8236,7 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 29 unmodified lines | |||
| 8236 | 8236 | ||
| 8237 | oldint = 0; | 8237 | oldint = 0; |
| 8238 | if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) { | 8238 | if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) { |
| 8239 | if (is_for_loop_init) | 8239 | if (l == VT_JMP) |
| 8240 | return 0; | 8240 | return 0; |
| 8241 | /* skip redundant ';' if not in old parameter decl scope */ | 8241 | /* skip redundant ';' if not in old parameter decl scope */ |
| 8242 | if (tok == ';' && l != VT_CMP) { | 8242 | if (tok == ';' && l != VT_CMP) { |
| @@ -8288,13 +8288,15 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 45 unmodified lines | |||
| 8288 | } | 8288 | } |
| 8289 | #endif | 8289 | #endif |
| 8290 | if ((type.t & VT_BTYPE) == VT_FUNC) { | 8290 | if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 8291 | if ((type.t & VT_STATIC) && (l == VT_LOCAL)) | 8291 | if ((type.t & VT_STATIC) && (l != VT_CONST)) |
| 8292 | tcc_error("function without file scope cannot be static"); | 8292 | tcc_error("function without file scope cannot be static"); |
| 8293 | /* if old style function prototype, we accept a | 8293 | /* if old style function prototype, we accept a |
| 8294 | declaration list */ | 8294 | declaration list */ |
| 8295 | sym = type.ref; | 8295 | sym = type.ref; |
| 8296 | if (sym->f.func_type == FUNC_OLD && l == VT_CONST) | 8296 | if (sym->f.func_type == FUNC_OLD && l == VT_CONST) { |
| 8297 | decl0(VT_CMP, 0, sym); | 8297 | func_vt = type; |
| 8298 | decl(VT_CMP); | ||
| 8299 | } | ||
| 8298 | #if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID | 8300 | #if defined TCC_TARGET_MACHO || defined TARGETOS_ANDROID |
| 8299 | if (sym->f.func_alwinl | 8301 | if (sym->f.func_alwinl |
| 8300 | && ((type.t & (VT_EXTERN | VT_INLINE)) | 8302 | && ((type.t & (VT_EXTERN | VT_INLINE)) |
| @@ -8388,12 +8390,12 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 87 unmodified lines | |||
| 8388 | } else { | 8390 | } else { |
| 8389 | if (l == VT_CMP) { | 8391 | if (l == VT_CMP) { |
| 8390 | /* find parameter in function parameter list */ | 8392 | /* find parameter in function parameter list */ |
| 8391 | for (sym = func_sym->next; sym; sym = sym->next) | 8393 | for (sym = func_vt.ref->next; sym; sym = sym->next) |
| 8392 | if ((sym->v & ~SYM_FIELD) == v) | 8394 | if ((sym->v & ~SYM_FIELD) == v) |
| 8393 | goto found; | 8395 | goto found; |
| 8394 | tcc_error("declaration for parameter '%s' but no such parameter", | 8396 | tcc_error("declaration for parameter '%s' but no such parameter", |
| 8395 | get_tok_str(v, NULL)); | 8397 | get_tok_str(v, NULL)); |
| 8396 | found: | 8398 | found: |
| 8397 | if (type.t & VT_STORAGE) /* 'register' is okay */ | 8399 | if (type.t & VT_STORAGE) /* 'register' is okay */ |
| 8398 | tcc_error("storage class specified for '%s'", | 8400 | tcc_error("storage class specified for '%s'", |
| 8399 | get_tok_str(v, NULL)); | 8401 | get_tok_str(v, NULL)); |
| @@ -8460,20 +8462,20 @@ found: · 60 unmodified lines | |||
| 8460 | esym->st_value, esym->st_size, 1); | 8462 | esym->st_value, esym->st_size, 1); |
| 8461 | } | 8463 | } |
| 8462 | } else { | 8464 | } else { |
| 8463 | if (type.t & VT_STATIC) | 8465 | if (l == VT_CONST || (type.t & VT_STATIC)) |
| 8464 | r |= VT_CONST; | 8466 | r |= VT_CONST; |
| 8465 | else | 8467 | else |
| 8466 | r |= l; | 8468 | r |= VT_LOCAL; |
| 8467 | if (has_init) | 8469 | if (has_init) |
| 8468 | next(); | 8470 | next(); |
| 8469 | else if (l == VT_CONST) | 8471 | else if (l == VT_CONST) |
| 8470 | /* uninitialized global variables may be overridden */ | 8472 | /* uninitialized global variables may be overridden */ |
| 8471 | type.t |= VT_EXTERN; | 8473 | type.t |= VT_EXTERN; |
| 8472 | decl_initializer_alloc(&type, &ad, r, has_init, v, l); | 8474 | decl_initializer_alloc(&type, &ad, r, has_init, v, l == VT_CONST); |
| 8473 | } | 8475 | } |
| 8474 | } | 8476 | } |
| 8475 | if (tok != ',') { | 8477 | if (tok != ',') { |
| 8476 | if (is_for_loop_init) | 8478 | if (l == VT_JMP) |
| 8477 | return 1; | 8479 | return 1; |
| 8478 | skip(';'); | 8480 | skip(';'); |
| 8479 | break; | 8481 | break; |
| @@ -8485,11 +8487,6 @@ found: · 5 unmodified lines | |||
| 8485 | return 0; | 8487 | return 0; |
| 8486 | } | 8488 | } |
| 8487 | 8489 | ||
| 8488 | static void decl(int l) | ||
| 8489 | { | ||
| 8490 | decl0(l, 0, NULL); | ||
| 8491 | } | ||
| 8492 | |||
| 8493 | /* ------------------------------------------------------------------------- */ | 8490 | /* ------------------------------------------------------------------------- */ |
| 8494 | #undef gjmp_addr | 8491 | #undef gjmp_addr |
| 8495 | #undef gjmp | 8492 | #undef gjmp |
| @@ -3251,10 +3251,12 @@ void local_label_test(void) · 3250 unmodified lines | |||
| 3251 | /* inline assembler test */ | 3251 | /* inline assembler test */ |
| 3252 | #if defined(__i386__) || defined(__x86_64__) | 3252 | #if defined(__i386__) || defined(__x86_64__) |
| 3253 | 3253 | ||
| 3254 | typedef __SIZE_TYPE__ word; | ||
| 3255 | |||
| 3254 | /* from linux kernel */ | 3256 | /* from linux kernel */ |
| 3255 | static char * strncat1(char * dest,const char * src,size_t count) | 3257 | static char * strncat1(char * dest,const char * src,size_t count) |
| 3256 | { | 3258 | { |
| 3257 | long d0, d1, d2, d3; | 3259 | word d0, d1, d2, d3; |
| 3258 | __asm__ __volatile__( | 3260 | __asm__ __volatile__( |
| 3259 | "repne\n\t" | 3261 | "repne\n\t" |
| 3260 | "scasb\n\t" | 3262 | "scasb\n\t" |
| @@ -3276,7 +3278,7 @@ return dest; · 15 unmodified lines | |||
| 3276 | 3278 | ||
| 3277 | static char * strncat2(char * dest,const char * src,size_t count) | 3279 | static char * strncat2(char * dest,const char * src,size_t count) |
| 3278 | { | 3280 | { |
| 3279 | long d0, d1, d2, d3; | 3281 | word d0, d1, d2, d3; |
| 3280 | __asm__ __volatile__( | 3282 | __asm__ __volatile__( |
| 3281 | "repne scasb\n\t" /* one-line repne prefix + string op */ | 3283 | "repne scasb\n\t" /* one-line repne prefix + string op */ |
| 3282 | "dec %1\n\t" | 3284 | "dec %1\n\t" |
| @@ -3297,7 +3299,7 @@ return dest; · 14 unmodified lines | |||
| 3297 | 3299 | ||
| 3298 | static inline void * memcpy1(void * to, const void * from, size_t n) | 3300 | static inline void * memcpy1(void * to, const void * from, size_t n) |
| 3299 | { | 3301 | { |
| 3300 | size_t d0, d1, d2; | 3302 | word d0, d1, d2; |
| 3301 | __asm__ __volatile__( | 3303 | __asm__ __volatile__( |
| 3302 | "rep ; movsl\n\t" | 3304 | "rep ; movsl\n\t" |
| 3303 | "testb $2,%b4\n\t" | 3305 | "testb $2,%b4\n\t" |
| @@ -3308,14 +3310,14 @@ __asm__ __volatile__( · 4 unmodified lines | |||
| 3308 | "movsb\n" | 3310 | "movsb\n" |
| 3309 | "2:" | 3311 | "2:" |
| 3310 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) | 3312 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) |
| 3311 | :"0" (n/4), "q" (n),"1" ((size_t) to),"2" ((size_t) from) | 3313 | :"0" (n/4), "q" (n),"1" ((word) to),"2" ((word) from) |
| 3312 | : "memory"); | 3314 | : "memory"); |
| 3313 | return (to); | 3315 | return (to); |
| 3314 | } | 3316 | } |
| 3315 | 3317 | ||
| 3316 | static inline void * memcpy2(void * to, const void * from, size_t n) | 3318 | static inline void * memcpy2(void * to, const void * from, size_t n) |
| 3317 | { | 3319 | { |
| 3318 | size_t d0, d1, d2; | 3320 | word d0, d1, d2; |
| 3319 | __asm__ __volatile__( | 3321 | __asm__ __volatile__( |
| 3320 | "rep movsl\n\t" /* one-line rep prefix + string op */ | 3322 | "rep movsl\n\t" /* one-line rep prefix + string op */ |
| 3321 | "testb $2,%b4\n\t" | 3323 | "testb $2,%b4\n\t" |
| @@ -3326,7 +3328,7 @@ __asm__ __volatile__( · 4 unmodified lines | |||
| 3326 | "movsb\n" | 3328 | "movsb\n" |
| 3327 | "2:" | 3329 | "2:" |
| 3328 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) | 3330 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) |
| 3329 | :"0" (n/4), "q" (n),"1" ((size_t) to),"2" ((size_t) from) | 3331 | :"0" (n/4), "q" (n),"1" ((word) to),"2" ((word) from) |
| 3330 | : "memory"); | 3332 | : "memory"); |
| 3331 | return (to); | 3333 | return (to); |
| 3332 | } | 3334 | } |
| @@ -3395,12 +3397,12 @@ struct struct123 { · 62 unmodified lines | |||
| 3395 | int b; | 3397 | int b; |
| 3396 | }; | 3398 | }; |
| 3397 | struct struct1231 { | 3399 | struct struct1231 { |
| 3398 | unsigned long addr; | 3400 | word addr; |
| 3399 | }; | 3401 | }; |
| 3400 | 3402 | ||
| 3401 | unsigned long mconstraint_test(struct struct1231 *r) | 3403 | word mconstraint_test(struct struct1231 *r) |
| 3402 | { | 3404 | { |
| 3403 | unsigned long ret; | 3405 | word ret; |
| 3404 | unsigned int a[2]; | 3406 | unsigned int a[2]; |
| 3405 | a[0] = 0; | 3407 | a[0] = 0; |
| 3406 | __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1" | 3408 | __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1" |
| @@ -3422,11 +3424,11 @@ int fls64(unsigned long long x) · 15 unmodified lines | |||
| 3422 | 3424 | ||
| 3423 | void other_constraints_test(void) | 3425 | void other_constraints_test(void) |
| 3424 | { | 3426 | { |
| 3425 | unsigned long ret; | 3427 | word ret; |
| 3426 | int var; | 3428 | int var; |
| 3427 | #if !defined(_WIN64) && CC_NAME != CC_clang | 3429 | #if CC_NAME != CC_clang |
| 3428 | __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); | 3430 | __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); |
| 3429 | printf ("oc1: %d\n", ret == (unsigned long)&var); | 3431 | printf ("oc1: %d\n", ret == (word)&var); |
| 3430 | #endif | 3432 | #endif |
| 3431 | } | 3433 | } |
| 3432 | 3434 | ||
| @@ -3510,6 +3512,7 @@ void asm_local_label_diff (void) · 77 unmodified lines | |||
| 3510 | printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); | 3512 | printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); |
| 3511 | } | 3513 | } |
| 3512 | #endif | 3514 | #endif |
| 3515 | #endif | ||
| 3513 | 3516 | ||
| 3514 | /* This checks that static local variables are available from assembler. */ | 3517 | /* This checks that static local variables are available from assembler. */ |
| 3515 | void asm_local_statics (void) | 3518 | void asm_local_statics (void) |
| @@ -3518,7 +3521,6 @@ void asm_local_statics (void) · 2 unmodified lines | |||
| 3518 | asm("incl %0" : "+m" (localint)); | 3521 | asm("incl %0" : "+m" (localint)); |
| 3519 | printf ("asm_local_statics: %d\n", localint); | 3522 | printf ("asm_local_statics: %d\n", localint); |
| 3520 | } | 3523 | } |
| 3521 | #endif | ||
| 3522 | 3524 | ||
| 3523 | static | 3525 | static |
| 3524 | unsigned int set; | 3526 | unsigned int set; |
| @@ -3533,7 +3535,7 @@ void fancy_copy2 (unsigned *in, unsigned *out) · 8 unmodified lines | |||
| 3533 | asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); | 3535 | asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); |
| 3534 | } | 3536 | } |
| 3535 | 3537 | ||
| 3536 | #if defined __x86_64__ && !defined _WIN64 | 3538 | #if defined __x86_64__ |
| 3537 | void clobber_r12(void) | 3539 | void clobber_r12(void) |
| 3538 | { | 3540 | { |
| 3539 | asm volatile("mov $1, %%r12" ::: "r12"); | 3541 | asm volatile("mov $1, %%r12" ::: "r12"); |
| @@ -3542,9 +3544,9 @@ void clobber_r12(void) · 2 unmodified lines | |||
| 3542 | 3544 | ||
| 3543 | void test_high_clobbers_really(void) | 3545 | void test_high_clobbers_really(void) |
| 3544 | { | 3546 | { |
| 3545 | #if defined __x86_64__ && !defined _WIN64 | 3547 | #if defined __x86_64__ |
| 3546 | register long val asm("r12"); | 3548 | register word val asm("r12"); |
| 3547 | long val2; | 3549 | word val2; |
| 3548 | /* This tests if asm clobbers correctly save/restore callee saved | 3550 | /* This tests if asm clobbers correctly save/restore callee saved |
| 3549 | registers if they are clobbered and if it's the high 8 x86-64 | 3551 | registers if they are clobbered and if it's the high 8 x86-64 |
| 3550 | registers. This is fragile for GCC as the constraints do not | 3552 | registers. This is fragile for GCC as the constraints do not |
| @@ -3558,8 +3560,8 @@ void test_high_clobbers_really(void) · 7 unmodified lines | |||
| 3558 | 3560 | ||
| 3559 | void test_high_clobbers(void) | 3561 | void test_high_clobbers(void) |
| 3560 | { | 3562 | { |
| 3561 | #if defined __x86_64__ && !defined _WIN64 | 3563 | #if defined __x86_64__ |
| 3562 | long x1, x2; | 3564 | word x1, x2; |
| 3563 | asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */ | 3565 | asm volatile("mov %%r12,%0" :: "m" (x1)); /* save r12 */ |
| 3564 | test_high_clobbers_really(); | 3566 | test_high_clobbers_really(); |
| 3565 | asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */ | 3567 | asm volatile("mov %%r12,%0" :: "m" (x2)); /* new r12 */ |
| @@ -3625,7 +3627,7 @@ void trace_console(long len, long len2) · 59 unmodified lines | |||
| 3625 | 3627 | ||
| 3626 | void test_asm_dead_code(void) | 3628 | void test_asm_dead_code(void) |
| 3627 | { | 3629 | { |
| 3628 | long rdi; | 3630 | word rdi; |
| 3629 | /* Try to make sure that xdi contains a zero, and hence will | 3631 | /* Try to make sure that xdi contains a zero, and hence will |
| 3630 | lead to a segfault if the next asm is evaluated without | 3632 | lead to a segfault if the next asm is evaluated without |
| 3631 | arguments being set up. */ | 3633 | arguments being set up. */ |
| @@ -3727,12 +3729,12 @@ void asm_test(void) · 95 unmodified lines | |||
| 3727 | char buf[128]; | 3729 | char buf[128]; |
| 3728 | unsigned int val, val2; | 3730 | unsigned int val, val2; |
| 3729 | struct struct123 s1; | 3731 | struct struct123 s1; |
| 3730 | struct struct1231 s2 = { (unsigned long)&s1 }; | 3732 | struct struct1231 s2 = { (word)&s1 }; |
| 3731 | /* Hide the outer base_func, but check later that the inline | 3733 | /* Hide the outer base_func, but check later that the inline |
| 3732 | asm block gets the outer one. */ | 3734 | asm block gets the outer one. */ |
| 3733 | int base_func = 42; | 3735 | int base_func = 42; |
| 3734 | void override_func3 (void); | 3736 | void override_func3 (void); |
| 3735 | unsigned long asmret; | 3737 | word asmret; |
| 3736 | #ifdef BOOL_ISOC99 | 3738 | #ifdef BOOL_ISOC99 |
| 3737 | _Bool somebool; | 3739 | _Bool somebool; |
| 3738 | #endif | 3740 | #endif |
| @@ -3783,8 +3785,8 @@ void asm_test(void) · 44 unmodified lines | |||
| 3783 | printf("asmstr: %s\n", get_asm_string()); | 3785 | printf("asmstr: %s\n", get_asm_string()); |
| 3784 | asm_local_label_diff(); | 3786 | asm_local_label_diff(); |
| 3785 | #endif | 3787 | #endif |
| 3786 | asm_local_statics(); | ||
| 3787 | #endif | 3788 | #endif |
| 3789 | asm_local_statics(); | ||
| 3788 | #ifndef __clang__ | 3790 | #ifndef __clang__ |
| 3789 | /* clang can't deal with the type change */ | 3791 | /* clang can't deal with the type change */ |
| 3790 | /* Check that we can also load structs of appropriate layout | 3792 | /* Check that we can also load structs of appropriate layout |