tccpp.c: * #pragma comment(option,"-some-option") to set commandline option from C code. May work only for some options. libtcc.c: * option "-d1..9": sets a 'g_debug' global variable. (for development) tests2/Makefile: * new make targets: tests2.37 / tests2.37+ run single test from tests2, optionally update .expect * new variable GEN-ALWAYS to always generate certain .expects * bitfields test tccgen.c: * bitfields: fix a bug and improve slightly more * _Generic: ignore "type match twice"
Unified · Split
| @@ -345,9 +345,12 @@ tar: tcc-doc.html · 344 unmodified lines | |||
| 345 | config.mak: | 345 | config.mak: |
| 346 | $(if $(wildcard $@),,@echo "Please run ./configure." && exit 1) | 346 | $(if $(wildcard $@),,@echo "Please run ./configure." && exit 1) |
| 347 | 347 | ||
| 348 | # in tests subdir | 348 | # run all tests |
| 349 | test: | 349 | test: |
| 350 | $(MAKE) -C tests | 350 | $(MAKE) -C tests |
| 351 | # run test(s) from tests2 subdir (see make help) | ||
| 352 | tests2.%: | ||
| 353 | $(MAKE) -C tests/tests2 $@ | ||
| 351 | 354 | ||
| 352 | clean: | 355 | clean: |
| 353 | rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod | 356 | rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod |
| @@ -389,8 +392,14 @@ help: · 35 unmodified lines | |||
| 389 | @echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include" | 392 | @echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include" |
| 390 | @echo " DEF-i386 += -D__linux__" | 393 | @echo " DEF-i386 += -D__linux__" |
| 391 | @echo "" | 394 | @echo "" |
| 395 | @echo "make test" | ||
| 396 | @echo " run all tests" | ||
| 397 | @echo "" | ||
| 398 | @echo "make tests2.all / make tests2.37 / make tests2.37+" | ||
| 399 | @echo " run all/single test(s) from tests2, optionally update .expect" | ||
| 400 | @echo "" | ||
| 392 | @echo "Other supported make targets:" | 401 | @echo "Other supported make targets:" |
| 393 | @echo " install install-strip test tags ETAGS tar clean distclean help" | 402 | @echo " install install-strip tags ETAGS tar clean distclean help" |
| 394 | @echo "" | 403 | @echo "" |
| 395 | 404 | ||
| 396 | # -------------------------------------------------------------------------- | 405 | # -------------------------------------------------------------------------- |
| @@ -1801,6 +1801,8 @@ reparse: · 1800 unmodified lines | |||
| 1801 | s->dflag = 3; | 1801 | s->dflag = 3; |
| 1802 | else if (*optarg == 'M') | 1802 | else if (*optarg == 'M') |
| 1803 | s->dflag = 7; | 1803 | s->dflag = 7; |
| 1804 | else if (isnum(*optarg)) | ||
| 1805 | g_debug = atoi(optarg); | ||
| 1804 | else | 1806 | else |
| 1805 | goto unsupported_option; | 1807 | goto unsupported_option; |
| 1806 | break; | 1808 | break; |
| @@ -1289,6 +1289,7 @@ ST_DATA int func_var; /* true if current function is variadic */ · 1288 unmodified lines | |||
| 1289 | ST_DATA int func_vc; | 1289 | ST_DATA int func_vc; |
| 1290 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ | 1290 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ |
| 1291 | ST_DATA const char *funcname; | 1291 | ST_DATA const char *funcname; |
| 1292 | ST_DATA int g_debug; | ||
| 1292 | 1293 | ||
| 1293 | ST_FUNC void tcc_debug_start(TCCState *s1); | 1294 | ST_FUNC void tcc_debug_start(TCCState *s1); |
| 1294 | ST_FUNC void tcc_debug_end(TCCState *s1); | 1295 | ST_FUNC void tcc_debug_end(TCCState *s1); |
| @@ -57,6 +57,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in · 56 unmodified lines | |||
| 57 | ST_DATA int func_vc; | 57 | ST_DATA int func_vc; |
| 58 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ | 58 | ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ |
| 59 | ST_DATA const char *funcname; | 59 | ST_DATA const char *funcname; |
| 60 | ST_DATA int g_debug; | ||
| 60 | 61 | ||
| 61 | ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; | 62 | ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; |
| 62 | 63 | ||
| @@ -1083,8 +1084,7 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size) · 1020 unmodified lines | |||
| 1083 | { | 1084 | { |
| 1084 | int n, o, bits; | 1085 | int n, o, bits; |
| 1085 | save_reg_upstack(vtop->r, 1); | 1086 | save_reg_upstack(vtop->r, 1); |
| 1086 | vpushi(0); // B X | 1087 | vpush64(type->t & VT_BTYPE, 0); // B X |
| 1087 | vtop->type.t |= type->t; | ||
| 1088 | bits = 0, o = bit_pos >> 3, bit_pos &= 7; | 1088 | bits = 0, o = bit_pos >> 3, bit_pos &= 7; |
| 1089 | do { | 1089 | do { |
| 1090 | vswap(); // X B | 1090 | vswap(); // X B |
| @@ -1113,7 +1113,7 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size) · 22 unmodified lines | |||
| 1113 | } | 1113 | } |
| 1114 | 1114 | ||
| 1115 | /* single-byte store mode for packed or otherwise unaligned bitfields */ | 1115 | /* single-byte store mode for packed or otherwise unaligned bitfields */ |
| 1116 | void store_packed_bf(int bit_pos, int bit_size) | 1116 | static void store_packed_bf(int bit_pos, int bit_size) |
| 1117 | { | 1117 | { |
| 1118 | int bits, n, o, m, c; | 1118 | int bits, n, o, m, c; |
| 1119 | 1119 | ||
| @@ -1148,7 +1148,7 @@ void store_packed_bf(int bit_pos, int bit_size) · 28 unmodified lines | |||
| 1148 | vpop(), vpop(); | 1148 | vpop(), vpop(); |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | int adjust_bf(SValue *sv, int bit_pos, int bit_size) | 1151 | static int adjust_bf(SValue *sv, int bit_pos, int bit_size) |
| 1152 | { | 1152 | { |
| 1153 | int t; | 1153 | int t; |
| 1154 | if (0 == sv->type.ref) | 1154 | if (0 == sv->type.ref) |
| @@ -2781,7 +2781,7 @@ static void type_to_str(char *buf, int buf_size, · 1626 unmodified lines | |||
| 2781 | pstrcat(buf, buf_size, "inline "); | 2781 | pstrcat(buf, buf_size, "inline "); |
| 2782 | buf_size -= strlen(buf); | 2782 | buf_size -= strlen(buf); |
| 2783 | buf += strlen(buf); | 2783 | buf += strlen(buf); |
| 2784 | if (IS_ENUM(type->t)) { | 2784 | if (IS_ENUM(t)) { |
| 2785 | tstr = "enum "; | 2785 | tstr = "enum "; |
| 2786 | goto tstruct; | 2786 | goto tstruct; |
| 2787 | } | 2787 | } |
| @@ -3405,9 +3405,12 @@ static void struct_layout(CType *type, AttributeDef *ad) · 617 unmodified lines | |||
| 3405 | //#define BF_DEBUG | 3405 | //#define BF_DEBUG |
| 3406 | 3406 | ||
| 3407 | for (f = type->ref->next; f; f = f->next) { | 3407 | for (f = type->ref->next; f; f = f->next) { |
| 3408 | if (f->type.t & VT_BITFIELD) | 3408 | if (f->type.t & VT_BITFIELD) { |
| 3409 | bit_size = BIT_SIZE(f->type.t); | 3409 | bit_size = BIT_SIZE(f->type.t); |
| 3410 | else | 3410 | /* in pcc mode, long long bitfields have type int if they fit */ |
| 3411 | if (pcc && (f->type.t & VT_BTYPE) == VT_LLONG && bit_size <= 32) | ||
| 3412 | f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT; | ||
| 3413 | } else | ||
| 3411 | bit_size = -1; | 3414 | bit_size = -1; |
| 3412 | size = type_size(&f->type, &align); | 3415 | size = type_size(&f->type, &align); |
| 3413 | a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0; | 3416 | a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0; |
| @@ -3476,16 +3479,10 @@ static void struct_layout(CType *type, AttributeDef *ad) · 62 unmodified lines | |||
| 3476 | goto new_field; | 3479 | goto new_field; |
| 3477 | } | 3480 | } |
| 3478 | 3481 | ||
| 3479 | /* in pcc mode, long long bitfields have type int if they fit */ | 3482 | while (bit_pos >= align * 8) |
| 3480 | if (size == 8 && bit_size <= 32) { | 3483 | c += align, bit_pos -= align * 8; |
| 3481 | f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT; | ||
| 3482 | size = 4; | ||
| 3483 | } | ||
| 3484 | if (bit_pos >= size * 8) { | ||
| 3485 | c += size; | ||
| 3486 | bit_pos -= size * 8; | ||
| 3487 | } | ||
| 3488 | offset = c; | 3484 | offset = c; |
| 3485 | |||
| 3489 | /* In PCC layout named bit-fields influence the alignment | 3486 | /* In PCC layout named bit-fields influence the alignment |
| 3490 | of the containing struct using the base types alignment, | 3487 | of the containing struct using the base types alignment, |
| 3491 | except for packed fields (which here have correct align). */ | 3488 | except for packed fields (which here have correct align). */ |
| @@ -3576,14 +3573,20 @@ static void struct_layout(CType *type, AttributeDef *ad) · 84 unmodified lines | |||
| 3576 | if (pcc) | 3573 | if (pcc) |
| 3577 | c += (bit_pos + 7) >> 3; | 3574 | c += (bit_pos + 7) >> 3; |
| 3578 | 3575 | ||
| 3579 | a = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 0; | 3576 | /* store size and alignment */ |
| 3577 | a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1; | ||
| 3580 | if (a < maxalign) | 3578 | if (a < maxalign) |
| 3581 | a = maxalign; | 3579 | a = maxalign; |
| 3580 | type->ref->r = a; | ||
| 3581 | if (pragma_pack && pragma_pack < maxalign) { | ||
| 3582 | /* can happen if individual align for some member was given. In | ||
| 3583 | this case MSVC ignores maxalign when aligning the size */ | ||
| 3584 | a = pragma_pack; | ||
| 3585 | if (a < bt) | ||
| 3586 | a = bt; | ||
| 3587 | } | ||
| 3582 | c = (c + a - 1) & -a; | 3588 | c = (c + a - 1) & -a; |
| 3583 | |||
| 3584 | /* store size and alignment */ | ||
| 3585 | type->ref->c = c; | 3589 | type->ref->c = c; |
| 3586 | type->ref->r = a; | ||
| 3587 | 3590 | ||
| 3588 | #ifdef BF_DEBUG | 3591 | #ifdef BF_DEBUG |
| 3589 | printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout); | 3592 | printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout); |
| @@ -3603,7 +3606,6 @@ static void struct_layout(CType *type, AttributeDef *ad) · 13 unmodified lines | |||
| 3603 | continue; | 3606 | continue; |
| 3604 | bit_pos = BIT_POS(f->type.t); | 3607 | bit_pos = BIT_POS(f->type.t); |
| 3605 | size = type_size(&f->type, &align); | 3608 | size = type_size(&f->type, &align); |
| 3606 | |||
| 3607 | if (bit_pos + bit_size <= size * 8 && f->c + size <= c) | 3609 | if (bit_pos + bit_size <= size * 8 && f->c + size <= c) |
| 3608 | continue; | 3610 | continue; |
| 3609 | 3611 | ||
| @@ -3637,19 +3639,20 @@ static void struct_layout(CType *type, AttributeDef *ad) · 27 unmodified lines | |||
| 3637 | | (bit_pos << VT_STRUCT_SHIFT); | 3639 | | (bit_pos << VT_STRUCT_SHIFT); |
| 3638 | if (s != size) | 3640 | if (s != size) |
| 3639 | f->auxtype = t.t; | 3641 | f->auxtype = t.t; |
| 3642 | #ifdef BF_DEBUG | ||
| 3643 | printf("FIX field %s offset %-2d size %-2d align %-2d " | ||
| 3644 | "pos %-2d bits %-2d\n", | ||
| 3645 | get_tok_str(f->v & ~SYM_FIELD, NULL), | ||
| 3646 | cx, s, align, px, bit_size); | ||
| 3647 | #endif | ||
| 3640 | } else { | 3648 | } else { |
| 3641 | /* fall back to load/store single-byte wise */ | 3649 | /* fall back to load/store single-byte wise */ |
| 3642 | f->auxtype = VT_STRUCT; | 3650 | f->auxtype = VT_STRUCT; |
| 3643 | } | ||
| 3644 | |||
| 3645 | #ifdef BF_DEBUG | 3651 | #ifdef BF_DEBUG |
| 3646 | printf("FIX field %s offset %-2d size %-2d align %-2d " | 3652 | printf("FIX field %s : load byte-wise\n", |
| 3647 | "pos %-2d bits %-2d %s\n", | 3653 | get_tok_str(f->v & ~SYM_FIELD, NULL)); |
| 3648 | get_tok_str(f->v & ~SYM_FIELD, NULL), | ||
| 3649 | cx, s, align, px, bit_size, | ||
| 3650 | f->auxtype == VT_PTR ? " byte-wise" : "" | ||
| 3651 | ); | ||
| 3652 | #endif | 3654 | #endif |
| 3655 | } | ||
| 3653 | } | 3656 | } |
| 3654 | } | 3657 | } |
| 3655 | 3658 | ||
| @@ -4915,9 +4918,9 @@ ST_FUNC void unary(void) · 1259 unmodified lines | |||
| 4915 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); | 4918 | type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); |
| 4916 | if (compare_types(&controlling_type, &cur_type, 0)) { | 4919 | if (compare_types(&controlling_type, &cur_type, 0)) { |
| 4917 | if (has_match) { | 4920 | if (has_match) { |
| 4918 | tcc_error("type march twice"); | 4921 | // tcc_error("type march twice"); |
| 4919 | } | 4922 | } |
| 4920 | if (has_default) | 4923 | if (str) |
| 4921 | tok_str_free(str); | 4924 | tok_str_free(str); |
| 4922 | has_match = 1; | 4925 | has_match = 1; |
| 4923 | learn = 1; | 4926 | learn = 1; |
| @@ -1658,24 +1658,28 @@ static void pragma_parse(TCCState *s1) · 1657 unmodified lines | |||
| 1658 | goto pragma_err; | 1658 | goto pragma_err; |
| 1659 | 1659 | ||
| 1660 | } else if (tok == TOK_comment) { | 1660 | } else if (tok == TOK_comment) { |
| 1661 | char *file; | 1661 | char *p; int t; |
| 1662 | next(); | 1662 | next(); |
| 1663 | skip('('); | 1663 | skip('('); |
| 1664 | if (tok != TOK_lib) | 1664 | t = tok; |
| 1665 | goto pragma_warn; | ||
| 1666 | next(); | 1665 | next(); |
| 1667 | skip(','); | 1666 | skip(','); |
| 1668 | if (tok != TOK_STR) | 1667 | if (tok != TOK_STR) |
| 1669 | goto pragma_err; | 1668 | goto pragma_err; |
| 1670 | file = tcc_strdup((char *)tokc.str.data); | 1669 | p = tcc_strdup((char *)tokc.str.data); |
| 1671 | dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, file); | ||
| 1672 | next(); | 1670 | next(); |
| 1673 | if (tok != ')') | 1671 | if (tok != ')') |
| 1674 | goto pragma_err; | 1672 | goto pragma_err; |
| 1675 | } else { | 1673 | if (t == TOK_lib) { |
| 1676 | pragma_warn: | 1674 | dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p); |
| 1677 | if (s1->warn_unsupported) | 1675 | } else { |
| 1678 | tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); | 1676 | if (t == TOK_option) |
| 1677 | tcc_set_options(s1, p); | ||
| 1678 | tcc_free(p); | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | } else if (s1->warn_unsupported) { | ||
| 1682 | tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); | ||
| 1679 | } | 1683 | } |
| 1680 | return; | 1684 | return; |
| 1681 | 1685 | ||
| @@ -167,6 +167,7 @@ · 166 unmodified lines | |||
| 167 | DEF(TOK_push_macro, "push_macro") | 167 | DEF(TOK_push_macro, "push_macro") |
| 168 | DEF(TOK_pop_macro, "pop_macro") | 168 | DEF(TOK_pop_macro, "pop_macro") |
| 169 | DEF(TOK_once, "once") | 169 | DEF(TOK_once, "once") |
| 170 | DEF(TOK_option, "option") | ||
| 170 | 171 | ||
| 171 | /* builtin functions or variables */ | 172 | /* builtin functions or variables */ |
| 172 | #ifndef TCC_ARM_EABI | 173 | #ifndef TCC_ARM_EABI |
| @@ -0,0 +1,215 @@ | |||
| 1 | /* ----------------------------------------------------------------------- */ | ||
| 2 | #if TEST == 1 | ||
| 3 | { | ||
| 4 | struct M P A __s | ||
| 5 | { | ||
| 6 | unsigned x : 12; | ||
| 7 | unsigned char y : 7; | ||
| 8 | unsigned z : 28; | ||
| 9 | unsigned a: 4; | ||
| 10 | unsigned b: 5; | ||
| 11 | }; | ||
| 12 | TEST_STRUCT(0x333,0x44,0x555555,6,7); | ||
| 13 | } | ||
| 14 | |||
| 15 | /* ----------------------------------------------------------------------- */ | ||
| 16 | #elif TEST == 2 | ||
| 17 | { | ||
| 18 | struct M P __s | ||
| 19 | { | ||
| 20 | int x: 12; | ||
| 21 | char y: 6; | ||
| 22 | long long z:63; | ||
| 23 | A char a:4; | ||
| 24 | long long b:2; | ||
| 25 | |||
| 26 | }; | ||
| 27 | TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2); | ||
| 28 | } | ||
| 29 | |||
| 30 | /* ----------------------------------------------------------------------- */ | ||
| 31 | #elif TEST == 3 | ||
| 32 | { | ||
| 33 | struct M P __s | ||
| 34 | { | ||
| 35 | unsigned x:5, y:5, :0, z:5; char a:5; A short b:5; | ||
| 36 | }; | ||
| 37 | TEST_STRUCT(21,23,25,6,14); | ||
| 38 | } | ||
| 39 | |||
| 40 | /* ----------------------------------------------------------------------- */ | ||
| 41 | #elif TEST == 4 | ||
| 42 | { | ||
| 43 | struct M P __s { | ||
| 44 | int x : 3; | ||
| 45 | int : 2; | ||
| 46 | int y : 1; | ||
| 47 | int : 0; | ||
| 48 | int z : 5; | ||
| 49 | int a : 7; | ||
| 50 | unsigned int b : 7; | ||
| 51 | }; | ||
| 52 | TEST_STRUCT(3,1,15,120,120); | ||
| 53 | } | ||
| 54 | |||
| 55 | /* ----------------------------------------------------------------------- */ | ||
| 56 | #elif TEST == 5 | ||
| 57 | { | ||
| 58 | struct M P __s { | ||
| 59 | long long x : 45; | ||
| 60 | long long : 2; | ||
| 61 | long long y : 35; | ||
| 62 | unsigned long long z : 38; | ||
| 63 | char a; short b; | ||
| 64 | }; | ||
| 65 | TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77); | ||
| 66 | } | ||
| 67 | |||
| 68 | /* ----------------------------------------------------------------------- */ | ||
| 69 | #elif TEST == 6 | ||
| 70 | { | ||
| 71 | struct M P __s { | ||
| 72 | int a; | ||
| 73 | char b; | ||
| 74 | int x : 12, y : 4, : 0, : 4, z : 3; | ||
| 75 | char d; | ||
| 76 | }; | ||
| 77 | TEST_STRUCT(1,2,3,4,-3); | ||
| 78 | } | ||
| 79 | |||
| 80 | /* ----------------------------------------------------------------------- */ | ||
| 81 | #elif defined PACK | ||
| 82 | |||
| 83 | #if PACK | ||
| 84 | # pragma pack(push,1) | ||
| 85 | # define P //_P | ||
| 86 | #else | ||
| 87 | # define P | ||
| 88 | #endif | ||
| 89 | |||
| 90 | #define TEST 1 | ||
| 91 | #include SELF | ||
| 92 | #define TEST 2 | ||
| 93 | #include SELF | ||
| 94 | #define TEST 3 | ||
| 95 | #include SELF | ||
| 96 | #define TEST 4 | ||
| 97 | #include SELF | ||
| 98 | #define TEST 5 | ||
| 99 | #include SELF | ||
| 100 | #define TEST 6 | ||
| 101 | #include SELF | ||
| 102 | printf("\n\n"); | ||
| 103 | |||
| 104 | #if PACK | ||
| 105 | # pragma pack(pop) | ||
| 106 | #endif | ||
| 107 | |||
| 108 | #undef P | ||
| 109 | #undef PACK | ||
| 110 | |||
| 111 | /* ----------------------------------------------------------------------- */ | ||
| 112 | #elif defined ALIGN | ||
| 113 | |||
| 114 | #if ALIGN | ||
| 115 | # define A _A(16) | ||
| 116 | #else | ||
| 117 | # define A | ||
| 118 | #endif | ||
| 119 | |||
| 120 | #define PACK 0 | ||
| 121 | #include SELF | ||
| 122 | #define PACK 1 | ||
| 123 | #include SELF | ||
| 124 | |||
| 125 | #undef A | ||
| 126 | #undef ALIGN | ||
| 127 | |||
| 128 | /* ----------------------------------------------------------------------- */ | ||
| 129 | #elif defined MS_BF | ||
| 130 | |||
| 131 | #if MS_BF | ||
| 132 | # ifdef __TINYC__ | ||
| 133 | # pragma comment(option, "-mms-bitfields") | ||
| 134 | # elif defined __GNUC__ | ||
| 135 | # define M __attribute__((ms_struct)) | ||
| 136 | # endif | ||
| 137 | #else | ||
| 138 | # ifdef __TINYC__ | ||
| 139 | # pragma comment(option, "-mno-ms-bitfields") | ||
| 140 | # elif defined __GNUC__ | ||
| 141 | # define M __attribute__((gcc_struct)) | ||
| 142 | # endif | ||
| 143 | #endif | ||
| 144 | #ifndef M | ||
| 145 | # define M | ||
| 146 | #endif | ||
| 147 | |||
| 148 | #define ALIGN 0 | ||
| 149 | #include SELF | ||
| 150 | #define ALIGN 1 | ||
| 151 | #include SELF | ||
| 152 | |||
| 153 | #undef M | ||
| 154 | #undef MS_BF | ||
| 155 | |||
| 156 | /* ----------------------------------------------------------------------- */ | ||
| 157 | #else | ||
| 158 | |||
| 159 | #include <stdio.h> | ||
| 160 | #include <string.h> | ||
| 161 | /* some gcc headers #define __attribute__ to empty if it's not gcc */ | ||
| 162 | #undef __attribute__ | ||
| 163 | |||
| 164 | void dump(void *p, int s) | ||
| 165 | { | ||
| 166 | int i; | ||
| 167 | for (i = s; --i >= 0;) | ||
| 168 | printf("%02X", ((unsigned char*)p)[i]); | ||
| 169 | printf("\n"); | ||
| 170 | } | ||
| 171 | |||
| 172 | #define pv(m) \ | ||
| 173 | printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m) | ||
| 174 | |||
| 175 | #define TEST_STRUCT(v1,v2,v3,v4,v5) { \ | ||
| 176 | struct __s _s, *s = & _s; \ | ||
| 177 | printf("---- TEST %d%s%s%s ----\n", \ | ||
| 178 | TEST, MS_BF?" - MS-BITFIELDS":"", \ | ||
| 179 | PACK?" - PACKED":"", \ | ||
| 180 | ALIGN?" - WITH ALIGN":""); \ | ||
| 181 | memset(s, 0, sizeof *s); \ | ||
| 182 | s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \ | ||
| 183 | printf("bits in use : "), dump(s, sizeof *s); \ | ||
| 184 | s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \ | ||
| 185 | printf("bits as set : "), dump(s, sizeof *s); \ | ||
| 186 | printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \ | ||
| 187 | printf("align/size : %d %d\n\n", alignof(struct __s),sizeof(struct __s)); \ | ||
| 188 | } | ||
| 189 | |||
| 190 | #ifdef _MSC_VER | ||
| 191 | # define _A(n) __declspec(align(n)) | ||
| 192 | # define _P | ||
| 193 | # define alignof(x) __alignof(x) | ||
| 194 | #else | ||
| 195 | # define _A(n) __attribute__((aligned(n))) | ||
| 196 | # define _P __attribute__((packed)) | ||
| 197 | # define alignof(x) __alignof__(x) | ||
| 198 | #endif | ||
| 199 | |||
| 200 | #ifndef MS_BITFIELDS | ||
| 201 | # define MS_BITFIELDS 0 | ||
| 202 | #endif | ||
| 203 | |||
| 204 | #define SELF "95_bitfields.c" | ||
| 205 | |||
| 206 | int main() | ||
| 207 | { | ||
| 208 | #define MS_BF MS_BITFIELDS | ||
| 209 | #include SELF | ||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | /* ----------------------------------------------------------------------- */ | ||
| 214 | #endif | ||
| 215 | #undef TEST | ||
| @@ -0,0 +1,2 @@ | |||
| 1 | #define MS_BITFIELDS 1 | ||
| 2 | #include "95_bitfields.c" | ||
| @@ -0,0 +1,152 @@ | |||
| 1 | ---- TEST 1 - MS-BITFIELDS ---- | ||
| 2 | bits in use : 0000001FFFFFFFFF0000007F00000FFF | ||
| 3 | bits as set : 00000007605555550000004400000333 | ||
| 4 | values : 333 44 555555 06 07 | ||
| 5 | align/size : 4 16 | ||
| 6 | |||
| 7 | ---- TEST 2 - MS-BITFIELDS ---- | ||
| 8 | bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF | ||
| 9 | bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 | ||
| 10 | values : 03 1e 123456789abcdef0 05 fffffffffffffffe | ||
| 11 | align/size : 8 32 | ||
| 12 | |||
| 13 | ---- TEST 3 - MS-BITFIELDS ---- | ||
| 14 | bits in use : 001F001F0000001F000003FF | ||
| 15 | bits as set : 000E000600000019000002F5 | ||
| 16 | values : 15 17 19 06 0e | ||
| 17 | align/size : 4 12 | ||
| 18 | |||
| 19 | ---- TEST 4 - MS-BITFIELDS ---- | ||
| 20 | bits in use : 0007FFFF00000027 | ||
| 21 | bits as set : 00078F0F00000023 | ||
| 22 | values : 03 ffffffff 0f fffffff8 78 | ||
| 23 | align/size : 4 8 | ||
| 24 | |||
| 25 | ---- TEST 5 - MS-BITFIELDS ---- | ||
| 26 | bits in use : 00000000FFFF00FF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF | ||
| 27 | bits as set : 0000000000770044000000000000007800000007F00000000000000123456789 | ||
| 28 | values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 | ||
| 29 | align/size : 8 32 | ||
| 30 | |||
| 31 | ---- TEST 6 - MS-BITFIELDS ---- | ||
| 32 | bits in use : 00000000000000700000FFFF000000FFFFFFFFFF | ||
| 33 | bits as set : 000000000000003000002001000000FD00000004 | ||
| 34 | values : 01 02 03 04 fffffffd | ||
| 35 | align/size : 4 20 | ||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | ---- TEST 1 - MS-BITFIELDS - PACKED ---- | ||
| 40 | bits in use : 0000001FFFFFFFFF7F00000FFF | ||
| 41 | bits as set : 00000007605555554400000333 | ||
| 42 | values : 333 44 555555 06 07 | ||
| 43 | align/size : 1 13 | ||
| 44 | |||
| 45 | ---- TEST 2 - MS-BITFIELDS - PACKED ---- | ||
| 46 | bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF | ||
| 47 | bits as set : 000000000000000205123456789ABCDEF01E00000003 | ||
| 48 | values : 03 1e 123456789abcdef0 05 fffffffffffffffe | ||
| 49 | align/size : 1 22 | ||
| 50 | |||
| 51 | ---- TEST 3 - MS-BITFIELDS - PACKED ---- | ||
| 52 | bits in use : 001F1F0000001F000003FF | ||
| 53 | bits as set : 000E0600000019000002F5 | ||
| 54 | values : 15 17 19 06 0e | ||
| 55 | align/size : 1 11 | ||
| 56 | |||
| 57 | ---- TEST 4 - MS-BITFIELDS - PACKED ---- | ||
| 58 | bits in use : 0007FFFF00000027 | ||
| 59 | bits as set : 00078F0F00000023 | ||
| 60 | values : 03 ffffffff 0f fffffff8 78 | ||
| 61 | align/size : 1 8 | ||
| 62 | |||
| 63 | ---- TEST 5 - MS-BITFIELDS - PACKED ---- | ||
| 64 | bits in use : FFFFFF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF | ||
| 65 | bits as set : 007744000000000000007800000007F00000000000000123456789 | ||
| 66 | values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 | ||
| 67 | align/size : 1 27 | ||
| 68 | |||
| 69 | ---- TEST 6 - MS-BITFIELDS - PACKED ---- | ||
| 70 | bits in use : 00000000700000FFFFFFFFFFFFFF | ||
| 71 | bits as set : 000000003000002001FD00000004 | ||
| 72 | values : 01 02 03 04 fffffffd | ||
| 73 | align/size : 1 14 | ||
| 74 | |||
| 75 | |||
| 76 | |||
| 77 | ---- TEST 1 - MS-BITFIELDS - WITH ALIGN ---- | ||
| 78 | bits in use : 0000001FFFFFFFFF0000007F00000FFF | ||
| 79 | bits as set : 00000007605555550000004400000333 | ||
| 80 | values : 333 44 555555 06 07 | ||
| 81 | align/size : 16 16 | ||
| 82 | |||
| 83 | ---- TEST 2 - MS-BITFIELDS - WITH ALIGN ---- | ||
| 84 | bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF | ||
| 85 | bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 | ||
| 86 | values : 03 1e 123456789abcdef0 05 fffffffffffffffe | ||
| 87 | align/size : 16 32 | ||
| 88 | |||
| 89 | ---- TEST 3 - MS-BITFIELDS - WITH ALIGN ---- | ||
| 90 | bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF | ||
| 91 | bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5 | ||
| 92 | values : 15 17 19 06 0e | ||
| 93 | align/size : 16 32 | ||
| 94 | |||
| 95 | ---- TEST 4 - MS-BITFIELDS - WITH ALIGN ---- | ||
| 96 | bits in use : 0007FFFF00000027 | ||
| 97 | bits as set : 00078F0F00000023 | ||
| 98 | values : 03 ffffffff 0f fffffff8 78 | ||
| 99 | align/size : 4 8 | ||
| 100 | |||
| 101 | ---- TEST 5 - MS-BITFIELDS - WITH ALIGN ---- | ||
| 102 | bits in use : 00000000FFFF00FF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF | ||
| 103 | bits as set : 0000000000770044000000000000007800000007F00000000000000123456789 | ||
| 104 | values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 | ||
| 105 | align/size : 8 32 | ||
| 106 | |||
| 107 | ---- TEST 6 - MS-BITFIELDS - WITH ALIGN ---- | ||
| 108 | bits in use : 00000000000000700000FFFF000000FFFFFFFFFF | ||
| 109 | bits as set : 000000000000003000002001000000FD00000004 | ||
| 110 | values : 01 02 03 04 fffffffd | ||
| 111 | align/size : 4 20 | ||
| 112 | |||
| 113 | |||
| 114 | |||
| 115 | ---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ---- | ||
| 116 | bits in use : 0000000000001FFFFFFFFF7F00000FFF | ||
| 117 | bits as set : 00000000000007605555554400000333 | ||
| 118 | values : 333 44 555555 06 07 | ||
| 119 | align/size : 16 16 | ||
| 120 | |||
| 121 | ---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ---- | ||
| 122 | bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF | ||
| 123 | bits as set : 000000000000000205000000123456789ABCDEF01E00000003 | ||
| 124 | values : 03 1e 123456789abcdef0 05 fffffffffffffffe | ||
| 125 | align/size : 16 25 | ||
| 126 | |||
| 127 | ---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ---- | ||
| 128 | bits in use : 001F000000000000001F0000001F000003FF | ||
| 129 | bits as set : 000E000000000000000600000019000002F5 | ||
| 130 | values : 15 17 19 06 0e | ||
| 131 | align/size : 16 18 | ||
| 132 | |||
| 133 | ---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ---- | ||
| 134 | bits in use : 0007FFFF00000027 | ||
| 135 | bits as set : 00078F0F00000023 | ||
| 136 | values : 03 ffffffff 0f fffffff8 78 | ||
| 137 | align/size : 1 8 | ||
| 138 | |||
| 139 | ---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ---- | ||
| 140 | bits in use : FFFFFF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF | ||
| 141 | bits as set : 007744000000000000007800000007F00000000000000123456789 | ||
| 142 | values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 | ||
| 143 | align/size : 1 27 | ||
| 144 | |||
| 145 | ---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ---- | ||
| 146 | bits in use : 00000000700000FFFFFFFFFFFFFF | ||
| 147 | bits as set : 000000003000002001FD00000004 | ||
| 148 | values : 01 02 03 04 fffffffd | ||
| 149 | align/size : 1 14 | ||
| 150 | |||
| 151 | |||
| 152 | |||
| @@ -18,6 +18,9 @@ NORUN = · 17 unmodified lines | |||
| 18 | FLAGS = | 18 | FLAGS = |
| 19 | 76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers | 19 | 76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers |
| 20 | 20 | ||
| 21 | # Always generate certain .expects (don't put these in the GIT), | ||
| 22 | GEN-ALWAYS = 95_bitfields.expect | ||
| 23 | |||
| 21 | # Filter source directory in warnings/errors (out-of-tree builds) | 24 | # Filter source directory in warnings/errors (out-of-tree builds) |
| 22 | FILTER = 2>&1 | sed 's,$(SRC)/,,g' | 25 | FILTER = 2>&1 | sed 's,$(SRC)/,,g' |
| 23 | # Filter some always-warning | 26 | # Filter some always-warning |
| @@ -40,26 +43,55 @@ endif · 16 unmodified lines | |||
| 40 | ifeq (,$(filter i386 x86_64,$(ARCH))) | 43 | ifeq (,$(filter i386 x86_64,$(ARCH))) |
| 41 | SKIP += 85_asm-outside-function.test | 44 | SKIP += 85_asm-outside-function.test |
| 42 | endif | 45 | endif |
| 46 | ifeq (-$(findstring gcc,$(CC)-)-,--) | ||
| 47 | SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) | ||
| 48 | endif | ||
| 49 | ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) | ||
| 50 | SKIP += 95_bitfields_ms.test # type_align is differnt on 32bit-non-windows | ||
| 51 | endif | ||
| 43 | 52 | ||
| 44 | all test: $(filter-out $(SKIP),$(TESTS)) | 53 | all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ; |
| 45 | 54 | ||
| 46 | %.test: %.c %.expect | 55 | %.test: %.c %.expect |
| 47 | @echo Test: $*... | 56 | @echo Test: $*... |
| 48 | # test -run | 57 | @$(if $(NORUN),\ |
| 49 | @if test -z "$(NORUN)"; then \ | 58 | ($(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)),\ |
| 50 | $(TCC) $(FLAGS) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \ | 59 | $(TCC) $(FLAGS) -run $< $(ARGS)\ |
| 51 | else \ | 60 | ) $(FILTER) >$*.output 2>&1 || true |
| 52 | $(TCC) $(FLAGS) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \ | 61 | @diff -Nbu $(filter %.expect,$^) $*.output \ |
| 53 | ./$*.exe $(ARGS) >>$*.output 2>&1 || true; \ | 62 | && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS)) |
| 54 | fi | 63 | |
| 55 | @diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output $*.exe | 64 | F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test) |
| 65 | F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" | ||
| 66 | |||
| 67 | # run single test and update .expect file, e.g. "make tests2.37+" | ||
| 68 | tests2.%+: | ||
| 69 | @$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory | ||
| 70 | |||
| 71 | # run single test, e.g. "make tests2.37" | ||
| 72 | tests2.%: | ||
| 73 | @$(MAKE) $(call F1,$*) --no-print-directory | ||
| 56 | 74 | ||
| 57 | # automatically generate .expect files with gcc: | 75 | # automatically generate .expect files with gcc: |
| 58 | %.expect : # %.c | 76 | %.expect : |
| 59 | (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) $(FILTER) >$*.expect 2>&1; rm -f a.exe | 77 | @echo Generating: $@ |
| 78 | @$(CC) -w -std=gnu99 $(FLAGS) $(SRC)/$*.c -o a.exe | ||
| 79 | @./a.exe $(ARGS) $(FILTER) >$@ 2>&1 | ||
| 80 | @rm -f a.exe | ||
| 81 | |||
| 82 | # using the ms compiler for the really ms-compatible bitfields | ||
| 83 | MS-CC = cl | ||
| 84 | 95_bitfields_ms.expect : | ||
| 85 | @echo Generating: $@ | ||
| 86 | @$(MS-CC) $(basename $@).c | ||
| 87 | @./$(basename $@).exe >$@ 2>&1 | ||
| 88 | @rm -f *.exe *.obj *.pdb | ||
| 60 | 89 | ||
| 61 | # tell make not to delete | 90 | # tell make not to delete |
| 62 | .PRECIOUS: %.expect | 91 | .PRECIOUS: %.expect |
| 63 | 92 | ||
| 93 | $(sort $(GEN-ALWAYS) $(UPDATE)) : force | ||
| 94 | force: | ||
| 95 | |||
| 64 | clean: | 96 | clean: |
| 65 | rm -f fred.txt *.output a.exe | 97 | rm -f fred.txt *.output a.exe $(GEN-ALWAYS) |