If you're asking opinions.... I would rather the default is set -mms-bitfields if compiling on Windows, and -no-mms-bitfields (?) on Linux. That way there is no breaking change for some Windows users. Then the only impact would be to non MSVC users on Windows who are wanting to share objects and use bitfields.

Cheers
.Richard


David Mertens wrote:
Now this idea I like, a lot, in terms of forcing users to understand what they're dealing with. This would also give impetus to our Windows folks to update configure for more sensible the default selection behavior.

Thanks! Other thoughts?
David

On Tue, Nov 22, 2016 at 4:41 PM, Michael B. Smith <mich...@smithcons.com <mailto:mich...@smithcons.com>> wrote:

    Speaking only to my personal opinion – if you are compiling on
    Windows, and the –mms-bitfields is not set and –no-ms-bitfields is
    not set, then you should issue a warning to that effect.

    *From:* Tinycc-devel [mailto:tinycc-devel-bounces+michael
    <mailto:tinycc-devel-bounces%2Bmichael>=theessentialexchange....@nongnu.org
    <mailto:theessentialexchange....@nongnu.org>] *On Behalf Of *David
    Mertens
    *Sent:* Tuesday, November 22, 2016 4:32 PM
    *To:* tinycc-devel@nongnu.org <mailto:tinycc-devel@nongnu.org>
    *Subject:* [Tinycc-devel] Patch: add option -mms-bitfields

    Hello everyone,

    Per previous discussion, here is a patch to implement a
    command-line option, -mms-bitfields. This would alter tcc's
    bitfield alignment algorithm in a backwards-incompatible way to be
    a bit more consistent with gcc's algorithm. The old behavior is
    traditionally attributed to MSVC, and so (consistent with gcc) the
    command-line option to use the old behavior is -mms-bitfields. If
    this patch gets applied, Windows users would be encouraged to add
    -mms-bitfields to their Makefiles.

    I would appreciate comments, bug reports, etc. If you care, please
    give this a spin in the next 24 hours, or please tell me if you
    need more time. Any tests illustrating discrepancies between gcc
    and this algorithm would be especially appreciated!

    Thanks!

    David

    diff --git a/libtcc.c b/libtcc.c
    index f184502..b824c18 100644
    --- a/libtcc.c
    +++ b/libtcc.c
    @@ -752,6 +752,7 @@ LIBTCCAPI TCCState *tcc_new(void)
         s->alacarte_link = 1;
         s->nocommon = 1;
         s->warn_implicit_function_declaration = 1;
    +    s->ms_bitfields = 0;
#ifdef CHAR_IS_UNSIGNED
         s->char_is_unsigned = 1;
    @@ -1508,6 +1509,7 @@ enum {
         TCC_OPTION_Wl,
         TCC_OPTION_W,
         TCC_OPTION_O,
    +    TCC_OPTION_mms_bitfields,
         TCC_OPTION_m,
         TCC_OPTION_f,
         TCC_OPTION_isystem,
    @@ -1571,6 +1573,7 @@ static const TCCOption tcc_options[] = {
         { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
         { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
         { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
    +    { "mms-bitfields", TCC_OPTION_mms_bitfields, 0}, /* must go
    before option 'm' */
         { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
         { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
         { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
    @@ -1854,6 +1857,9 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int
    argc, char **argv)
                 if (x > 0)
                     tcc_define_symbol(s, "__OPTIMIZE__", NULL);
                 break;
    +        case TCC_OPTION_mms_bitfields:
    +            s->ms_bitfields = 1;
    +            break;
             case TCC_OPTION_traditional:
             case TCC_OPTION_pedantic:
             case TCC_OPTION_pipe:
    diff --git a/tcc-doc.texi b/tcc-doc.texi
    index 5aab13c..9f136ed 100644
    --- a/tcc-doc.texi
    +++ b/tcc-doc.texi
    @@ -176,6 +176,10 @@ In a script, it gives the following header:
     #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
     @end example
+@item -mms-bitfields
    +Use an algorithm for bitfield alignment consistent with MSVC.
    Default is
    +gcc's algorithm.
    +
     @item -mfloat-abi (ARM only)
     Select the float ABI. Possible values: @code{softfp} and @code{hard}
diff --git a/tcc.c b/tcc.c
    index 28f3ae9..fbfbffa 100644
    --- a/tcc.c
    +++ b/tcc.c
    @@ -97,6 +97,7 @@ static void help(void)
                "  -o outfile  set output filename\n"
                "  -run        run compiled source\n"
                "  -fflag      set or reset (with 'no-' prefix) 'flag'
    (see man page)\n"
    +           "  -mms-bitfields  use bitfield alignment consistent
    with MSVC\n"
                "  -Wwarning   set or reset (with 'no-' prefix)
    'warning' (see man page)\n"
                "  -w          disable all warnings\n"
                "  -v          show version\n"
    diff --git a/tcc.h b/tcc.h
    index 180838d..cbdebd3 100644
    --- a/tcc.h
    +++ b/tcc.h
    @@ -605,6 +605,7 @@ struct TCCState {
         int old_struct_init_code;    /* use old algorithm to init
    array in struct when there is no '{' used.
                        Liuux 2.4.26 can't find initrd when compiled
    with a new algorithm */
         int dollars_in_identifiers;    /* allows '$' char in
    indentifiers */
    +    int ms_bitfields; /* if true, emulate MS algorithm for
    aligning bitfields */
/* warning switches */
         int warn_write_strings;
    diff --git a/tccgen.c b/tccgen.c
    index ba1757e..d064024 100644
    --- a/tccgen.c
    +++ b/tccgen.c
    @@ -3154,7 +3154,7 @@ static void parse_attribute(AttributeDef *ad)
     /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
     static void struct_decl(CType *type, AttributeDef *ad, int u)
     {
    -    int a, v, size, align, maxalign, c, offset, flexible;
    +    int a, v, size, align, maxalign, c, offset, flexible,
    extra_bytes;
         int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
         Sym *s, *ss, *ass, **ps;
         AttributeDef ad1;
    @@ -3235,6 +3235,7 @@ static void struct_decl(CType *type,
    AttributeDef *ad, int u)
                 while (tok != '}') {
                     parse_btype(&btype, &ad1);
                     while (1) {
    +                extra_bytes = 0;
                 if (flexible)
                     tcc_error("flexible array member '%s' not at the
    end of struct",
                                   get_tok_str(v, NULL));
    @@ -3310,9 +3311,9 @@ static void struct_decl(CType *type,
    AttributeDef *ad, int u)
                                 /* zero size: means to pad */
                                 bit_pos = 0;
                             } else {
    -                            /* we do not have enough room ?
    -                               did the type change?
    -                               is it a union? */
    +                            /* if type change, union, or will overrun
    +                             * allignment slot, start at a newly
    +                             * alligned slot */
                                 if ((bit_pos + bit_size) > bsize ||
                                     bt != prevbt || a == TOK_UNION)
                                     bit_pos = 0;
    @@ -3322,15 +3323,30 @@ static void struct_decl(CType *type,
    AttributeDef *ad, int u)
                                     (bit_pos << VT_STRUCT_SHIFT) |
                                     (bit_size << (VT_STRUCT_SHIFT + 6));
                                 bit_pos += bit_size;
    +                            /* without ms-bitfields, allocate the
    +                             * minimum number of bytes necessary,
    +                             * adding single bytes as needed */
    +                            if (!tcc_state->ms_bitfields) {
    +                                if (lbit_pos == 0)
    +                                    /* minimum bytes for new
    bitfield */
    +                                    size = (bit_size + 7) / 8;
    +                                else {
    +                                    /* enough spare bits already
    allocated? */
    +                                    bit_size = (lbit_pos - 1) % 8
    + 1 + bit_size;
    +                                    if (bit_size > 8) /* doesn't
    fit */
    +                                        extra_bytes = (bit_size -
    1) / 8;
    +                                }
    +                            }
                             }
                             prevbt = bt;
                         } else {
                             bit_pos = 0;
                         }
                         if (v != 0 || (type1.t & VT_BTYPE) ==
    VT_STRUCT) {
    -                        /* add new memory data only if starting
    -                           bit field */
    -                        if (lbit_pos == 0) {
    +                        /* add new memory data only if starting bit
    +                           field or adding bytes to existing bit
    field */
    +                        if (extra_bytes) c += extra_bytes;
    +                        else if (lbit_pos == 0) {
                                 if (a == TOK_STRUCT) {
                                     c = (c + align - 1) & -align;
                                     offset = c;
    diff --git a/tests/tcctest.c b/tests/tcctest.c
    index 5851fb4..b0fe8f3 100644
    --- a/tests/tcctest.c
    +++ b/tests/tcctest.c
    @@ -1634,6 +1634,15 @@ void bitfield_test(void)
         st2.f3 = a;
         st2.f2++;
         printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
    +    struct sbf3 {
    +        int f1 : 7;
    +        int f2 : 1;
    +        char f3;
    +        int f4 : 8;
    +        int f5 : 1;
    +        int f6 : 16;
    +    } st3;
    +    printf("sizeof(st3) = %d\n", sizeof(st3));
     }
#ifdef __x86_64__


    _______________________________________________
    Tinycc-devel mailing list
    Tinycc-devel@nongnu.org <mailto:Tinycc-devel@nongnu.org>
    https://lists.nongnu.org/mailman/listinfo/tinycc-devel
    <https://lists.nongnu.org/mailman/listinfo/tinycc-devel>




--
 "Debugging is twice as hard as writing the code in the first place.
  Therefore, if you write the code as cleverly as possible, you are,
  by definition, not smart enough to debug it." -- Brian Kernighan
------------------------------------------------------------------------

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to