| @@ -103,7 +103,8 @@ ST_INLN int is_float(int t) · 102 unmodified lines |
| 103 | /* XXX: endianness dependent */ | 103 | /* XXX: endianness dependent */ |
| 104 | ST_FUNC int ieee_finite(double d) | 104 | ST_FUNC int ieee_finite(double d) |
| 105 | { | 105 | { |
| 106 | int *p = (int *)&d; | 106 | int p[4]; |
| | 107 | memcpy(p, &d, sizeof(double)); |
| 107 | return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; | 108 | return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; |
| 108 | } | 109 | } |
| 109 | | 110 | |
| @@ -2172,7 +2173,7 @@ static int is_compatible_func(CType *type1, CType *type2) · 2062 unmodified lines |
| 2172 | if (!is_compatible_types(&s1->type, &s2->type)) | 2173 | if (!is_compatible_types(&s1->type, &s2->type)) |
| 2173 | return 0; | 2174 | return 0; |
| 2174 | /* check func_call */ | 2175 | /* check func_call */ |
| 2175 | if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r)) | 2176 | if (s1->a.func_call != s2->a.func_call) |
| 2176 | return 0; | 2177 | return 0; |
| 2177 | /* XXX: not complete */ | 2178 | /* XXX: not complete */ |
| 2178 | if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) | 2179 | if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) |
| @@ -2659,15 +2660,15 @@ static void parse_attribute(AttributeDef *ad) · 480 unmodified lines |
| 2659 | } else { | 2660 | } else { |
| 2660 | n = MAX_ALIGN; | 2661 | n = MAX_ALIGN; |
| 2661 | } | 2662 | } |
| 2662 | ad->aligned = n; | 2663 | ad->a.aligned = n; |
| 2663 | break; | 2664 | break; |
| 2664 | case TOK_PACKED1: | 2665 | case TOK_PACKED1: |
| 2665 | case TOK_PACKED2: | 2666 | case TOK_PACKED2: |
| 2666 | ad->packed = 1; | 2667 | ad->a.packed = 1; |
| 2667 | break; | 2668 | break; |
| 2668 | case TOK_WEAK1: | 2669 | case TOK_WEAK1: |
| 2669 | case TOK_WEAK2: | 2670 | case TOK_WEAK2: |
| 2670 | ad->weak = 1; | 2671 | ad->a.weak = 1; |
| 2671 | break; | 2672 | break; |
| 2672 | case TOK_UNUSED1: | 2673 | case TOK_UNUSED1: |
| 2673 | case TOK_UNUSED2: | 2674 | case TOK_UNUSED2: |
| @@ -2682,12 +2683,12 @@ static void parse_attribute(AttributeDef *ad) · 8 unmodified lines |
| 2682 | case TOK_CDECL1: | 2683 | case TOK_CDECL1: |
| 2683 | case TOK_CDECL2: | 2684 | case TOK_CDECL2: |
| 2684 | case TOK_CDECL3: | 2685 | case TOK_CDECL3: |
| 2685 | ad->func_call = FUNC_CDECL; | 2686 | ad->a.func_call = FUNC_CDECL; |
| 2686 | break; | 2687 | break; |
| 2687 | case TOK_STDCALL1: | 2688 | case TOK_STDCALL1: |
| 2688 | case TOK_STDCALL2: | 2689 | case TOK_STDCALL2: |
| 2689 | case TOK_STDCALL3: | 2690 | case TOK_STDCALL3: |
| 2690 | ad->func_call = FUNC_STDCALL; | 2691 | ad->a.func_call = FUNC_STDCALL; |
| 2691 | break; | 2692 | break; |
| 2692 | #ifdef TCC_TARGET_I386 | 2693 | #ifdef TCC_TARGET_I386 |
| 2693 | case TOK_REGPARM1: | 2694 | case TOK_REGPARM1: |
| @@ -2699,26 +2700,26 @@ static void parse_attribute(AttributeDef *ad) · 5 unmodified lines |
| 2699 | else if (n < 0) | 2700 | else if (n < 0) |
| 2700 | n = 0; | 2701 | n = 0; |
| 2701 | if (n > 0) | 2702 | if (n > 0) |
| 2702 | ad->func_call = FUNC_FASTCALL1 + n - 1; | 2703 | ad->a.func_call = FUNC_FASTCALL1 + n - 1; |
| 2703 | skip(')'); | 2704 | skip(')'); |
| 2704 | break; | 2705 | break; |
| 2705 | case TOK_FASTCALL1: | 2706 | case TOK_FASTCALL1: |
| 2706 | case TOK_FASTCALL2: | 2707 | case TOK_FASTCALL2: |
| 2707 | case TOK_FASTCALL3: | 2708 | case TOK_FASTCALL3: |
| 2708 | ad->func_call = FUNC_FASTCALLW; | 2709 | ad->a.func_call = FUNC_FASTCALLW; |
| 2709 | break; | 2710 | break; |
| 2710 | #endif | 2711 | #endif |
| 2711 | case TOK_MODE: | 2712 | case TOK_MODE: |
| 2712 | skip('('); | 2713 | skip('('); |
| 2713 | switch(tok) { | 2714 | switch(tok) { |
| 2714 | case TOK_MODE_DI: | 2715 | case TOK_MODE_DI: |
| 2715 | ad->mode = VT_LLONG + 1; | 2716 | ad->a.mode = VT_LLONG + 1; |
| 2716 | break; | 2717 | break; |
| 2717 | case TOK_MODE_HI: | 2718 | case TOK_MODE_HI: |
| 2718 | ad->mode = VT_SHORT + 1; | 2719 | ad->a.mode = VT_SHORT + 1; |
| 2719 | break; | 2720 | break; |
| 2720 | case TOK_MODE_SI: | 2721 | case TOK_MODE_SI: |
| 2721 | ad->mode = VT_INT + 1; | 2722 | ad->a.mode = VT_INT + 1; |
| 2722 | break; | 2723 | break; |
| 2723 | default: | 2724 | default: |
| 2724 | tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL)); | 2725 | tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL)); |
| @@ -2728,10 +2729,10 @@ static void parse_attribute(AttributeDef *ad) · 3 unmodified lines |
| 2728 | skip(')'); | 2729 | skip(')'); |
| 2729 | break; | 2730 | break; |
| 2730 | case TOK_DLLEXPORT: | 2731 | case TOK_DLLEXPORT: |
| 2731 | ad->func_export = 1; | 2732 | ad->a.func_export = 1; |
| 2732 | break; | 2733 | break; |
| 2733 | case TOK_DLLIMPORT: | 2734 | case TOK_DLLIMPORT: |
| 2734 | ad->func_import = 1; | 2735 | ad->a.func_import = 1; |
| 2735 | break; | 2736 | break; |
| 2736 | default: | 2737 | default: |
| 2737 | if (tcc_state->warn_unsupported) | 2738 | if (tcc_state->warn_unsupported) |
| @@ -2873,10 +2874,10 @@ static void struct_decl(CType *type, int u, int tdef) · 135 unmodified lines |
| 2873 | get_tok_str(v, NULL)); | 2874 | get_tok_str(v, NULL)); |
| 2874 | } | 2875 | } |
| 2875 | size = type_size(&type1, &align); | 2876 | size = type_size(&type1, &align); |
| 2876 | if (ad.aligned) { | 2877 | if (ad.a.aligned) { |
| 2877 | if (align < ad.aligned) | 2878 | if (align < ad.a.aligned) |
| 2878 | align = ad.aligned; | 2879 | align = ad.a.aligned; |
| 2879 | } else if (ad.packed) { | 2880 | } else if (ad.a.packed) { |
| 2880 | align = 1; | 2881 | align = 1; |
| 2881 | } else if (*tcc_state->pack_stack_ptr) { | 2882 | } else if (*tcc_state->pack_stack_ptr) { |
| 2882 | if (align > *tcc_state->pack_stack_ptr) | 2883 | if (align > *tcc_state->pack_stack_ptr) |
| @@ -3118,8 +3119,8 @@ static int parse_btype(CType *type, AttributeDef *ad) · 235 unmodified lines |
| 3118 | case TOK_ATTRIBUTE1: | 3119 | case TOK_ATTRIBUTE1: |
| 3119 | case TOK_ATTRIBUTE2: | 3120 | case TOK_ATTRIBUTE2: |
| 3120 | parse_attribute(ad); | 3121 | parse_attribute(ad); |
| 3121 | if (ad->mode) { | 3122 | if (ad->a.mode) { |
| 3122 | u = ad->mode -1; | 3123 | u = ad->a.mode -1; |
| 3123 | t = (t & ~VT_BTYPE) | u; | 3124 | t = (t & ~VT_BTYPE) | u; |
| 3124 | } | 3125 | } |
| 3125 | break; | 3126 | break; |
| @@ -3143,11 +3144,11 @@ static int parse_btype(CType *type, AttributeDef *ad) · 17 unmodified lines |
| 3143 | type->ref = s->type.ref; | 3144 | type->ref = s->type.ref; |
| 3144 | if (s->r) { | 3145 | if (s->r) { |
| 3145 | /* get attributes from typedef */ | 3146 | /* get attributes from typedef */ |
| 3146 | if (0 == ad->aligned) | 3147 | if (0 == ad->a.aligned) |
| 3147 | ad->aligned = FUNC_ALIGN(s->r); | 3148 | ad->a.aligned = s->a.aligned; |
| 3148 | if (0 == ad->func_call) | 3149 | if (0 == ad->a.func_call) |
| 3149 | ad->func_call = FUNC_CALL(s->r); | 3150 | ad->a.func_call = s->a.func_call; |
| 3150 | ad->packed |= FUNC_PACKED(s->r); | 3151 | ad->a.packed |= s->a.packed; |
| 3151 | } | 3152 | } |
| 3152 | next(); | 3153 | next(); |
| 3153 | typespec_found = 1; | 3154 | typespec_found = 1; |
| @@ -3287,8 +3288,9 @@ static void post_type(CType *type, AttributeDef *ad) · 133 unmodified lines |
| 3287 | type->t |= VT_PTR; | 3288 | type->t |= VT_PTR; |
| 3288 | } | 3289 | } |
| 3289 | /* we push a anonymous symbol which will contain the function prototype */ | 3290 | /* we push a anonymous symbol which will contain the function prototype */ |
| 3290 | ad->func_args = arg_size; | 3291 | ad->a.func_args = arg_size; |
| 3291 | s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); | 3292 | s = sym_push(SYM_FIELD, type, 0, l); |
| | 3293 | s->a = ad->a; |
| 3292 | s->next = first; | 3294 | s->next = first; |
| 3293 | type->t = VT_FUNC; | 3295 | type->t = VT_FUNC; |
| 3294 | type->ref = s; | 3296 | type->ref = s; |
| @@ -5484,10 +5486,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2189 unmodified lines |
| 5484 | if (flexible_array) | 5486 | if (flexible_array) |
| 5485 | size += flexible_array->type.ref->c * pointed_size(&flexible_array->type); | 5487 | size += flexible_array->type.ref->c * pointed_size(&flexible_array->type); |
| 5486 | /* take into account specified alignment if bigger */ | 5488 | /* take into account specified alignment if bigger */ |
| 5487 | if (ad->aligned) { | 5489 | if (ad->a.aligned) { |
| 5488 | if (ad->aligned > align) | 5490 | if (ad->a.aligned > align) |
| 5489 | align = ad->aligned; | 5491 | align = ad->a.aligned; |
| 5490 | } else if (ad->packed) { | 5492 | } else if (ad->a.packed) { |
| 5491 | align = 1; | 5493 | align = 1; |
| 5492 | } | 5494 | } |
| 5493 | if ((r & VT_VALMASK) == VT_LOCAL) { | 5495 | if ((r & VT_VALMASK) == VT_LOCAL) { |
| @@ -5869,12 +5871,12 @@ static int decl0(int l, int is_for_loop_init) · 375 unmodified lines |
| 5869 | parse_attribute(&ad); | 5871 | parse_attribute(&ad); |
| 5870 | } | 5872 | } |
| 5871 | | 5873 | |
| 5872 | if (ad.weak) | 5874 | if (ad.a.weak) |
| 5873 | type.t |= VT_WEAK; | 5875 | type.t |= VT_WEAK; |
| 5874 | #ifdef TCC_TARGET_PE | 5876 | #ifdef TCC_TARGET_PE |
| 5875 | if (ad.func_import) | 5877 | if (ad.a.func_import) |
| 5876 | type.t |= VT_IMPORT; | 5878 | type.t |= VT_IMPORT; |
| 5877 | if (ad.func_export) | 5879 | if (ad.a.func_export) |
| 5878 | type.t |= VT_EXPORT; | 5880 | type.t |= VT_EXPORT; |
| 5879 | #endif | 5881 | #endif |
| 5880 | if (tok == '{') { | 5882 | if (tok == '{') { |
| @@ -5895,22 +5897,22 @@ static int decl0(int l, int is_for_loop_init) · 14 unmodified lines |
| 5895 | | 5897 | |
| 5896 | sym = sym_find(v); | 5898 | sym = sym_find(v); |
| 5897 | if (sym) { | 5899 | if (sym) { |
| | 5900 | Sym *ref; |
| 5898 | if ((sym->type.t & VT_BTYPE) != VT_FUNC) | 5901 | if ((sym->type.t & VT_BTYPE) != VT_FUNC) |
| 5899 | goto func_error1; | 5902 | goto func_error1; |
| 5900 | | 5903 | |
| 5901 | r = sym->type.ref->r; | 5904 | ref = sym->type.ref; |
| 5902 | | 5905 | if (0 == ref->a.func_proto) |
| 5903 | if (!FUNC_PROTO(r)) | | |
| 5904 | tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); | 5906 | tcc_error("redefinition of '%s'", get_tok_str(v, NULL)); |
| 5905 | | 5907 | |
| 5906 | /* use func_call from prototype if not defined */ | 5908 | /* use func_call from prototype if not defined */ |
| 5907 | if (FUNC_CALL(r) != FUNC_CDECL | 5909 | if (ref->a.func_call != FUNC_CDECL |
| 5908 | && FUNC_CALL(type.ref->r) == FUNC_CDECL) | 5910 | && type.ref->a.func_call == FUNC_CDECL) |
| 5909 | FUNC_CALL(type.ref->r) = FUNC_CALL(r); | 5911 | type.ref->a.func_call = ref->a.func_call; |
| 5910 | | 5912 | |
| 5911 | /* use export from prototype */ | 5913 | /* use export from prototype */ |
| 5912 | if (FUNC_EXPORT(r)) | 5914 | if (ref->a.func_export) |
| 5913 | FUNC_EXPORT(type.ref->r) = 1; | 5915 | type.ref->a.func_export = 1; |
| 5914 | | 5916 | |
| 5915 | /* use static from prototype */ | 5917 | /* use static from prototype */ |
| 5916 | if (sym->type.t & VT_STATIC) | 5918 | if (sym->type.t & VT_STATIC) |
| @@ -5921,7 +5923,7 @@ static int decl0(int l, int is_for_loop_init) · 4 unmodified lines |
| 5921 | tcc_error("incompatible types for redefinition of '%s'", | 5923 | tcc_error("incompatible types for redefinition of '%s'", |
| 5922 | get_tok_str(v, NULL)); | 5924 | get_tok_str(v, NULL)); |
| 5923 | } | 5925 | } |
| 5924 | FUNC_PROTO(type.ref->r) = 0; | 5926 | type.ref->a.func_proto = 0; |
| 5925 | /* if symbol is already defined, then put complete type */ | 5927 | /* if symbol is already defined, then put complete type */ |
| 5926 | sym->type = type; | 5928 | sym->type = type; |
| 5927 | } else { | 5929 | } else { |
| @@ -5980,15 +5982,16 @@ static int decl0(int l, int is_for_loop_init) · 52 unmodified lines |
| 5980 | if (btype.t & VT_TYPEDEF) { | 5982 | if (btype.t & VT_TYPEDEF) { |
| 5981 | /* save typedefed type */ | 5983 | /* save typedefed type */ |
| 5982 | /* XXX: test storage specifiers ? */ | 5984 | /* XXX: test storage specifiers ? */ |
| 5983 | sym = sym_push(v, &type, INT_ATTR(&ad), 0); | 5985 | sym = sym_push(v, &type, 0, 0); |
| | 5986 | sym->a = ad.a; |
| 5984 | sym->type.t |= VT_TYPEDEF; | 5987 | sym->type.t |= VT_TYPEDEF; |
| 5985 | } else { | 5988 | } else { |
| 5986 | r = 0; | 5989 | r = 0; |
| 5987 | if ((type.t & VT_BTYPE) == VT_FUNC) { | 5990 | if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 5988 | /* external function definition */ | 5991 | /* external function definition */ |
| 5989 | /* specific case for func_call attribute */ | 5992 | /* specific case for func_call attribute */ |
| 5990 | ad.func_proto = 1; | 5993 | ad.a.func_proto = 1; |
| 5991 | type.ref->r = INT_ATTR(&ad); | 5994 | type.ref->a = ad.a; |
| 5992 | } else if (!(type.t & VT_ARRAY)) { | 5995 | } else if (!(type.t & VT_ARRAY)) { |
| 5993 | /* not lvalue if array */ | 5996 | /* not lvalue if array */ |
| 5994 | r |= lvalue_type(type.t); | 5997 | r |= lvalue_type(type.t); |
| @@ -6039,7 +6042,7 @@ static int decl0(int l, int is_for_loop_init) · 44 unmodified lines |
| 6039 | } | 6042 | } |
| 6040 | next(); | 6043 | next(); |
| 6041 | } | 6044 | } |
| 6042 | ad.aligned = 0; | 6045 | ad.a.aligned = 0; |
| 6043 | } | 6046 | } |
| 6044 | } | 6047 | } |
| 6045 | return 0; | 6048 | return 0; |