Issue #100 resolved

Big endian regressions

Anonymous created an issue

0.7 introduced some test-failures on big-endian. Here's a sample from ppc:

============================= test session starts ==============================
platform linux2 -- Python 2.7.5 -- pytest-2.3.5
collected 1027 items

c/test_c.py .........s...............................................................................................................................s..................s.................
testing/test_cdata.py .
testing/test_ctypes.py ..................s...............s.s.s.......s.....................ssssss..s..s.....................ssssss.
testing/test_ffi_backend.py ..............................................................................s...s.................................s...........s..............FFFsFs..
testing/test_function.py .....s...........ss..ss..s
testing/test_model.py ............
testing/test_ownlib.py ..ss..
testing/test_parsing.py ..................s
testing/test_platform.py ....
testing/test_unicode_literals.py ............
testing/test_verify.py ..........s.............s......................................................s............s.......................
testing/test_verify2.py ..........s.............s......................................................s............s.......................
testing/test_version.py .....
testing/test_vgen.py ..........s.............s......................................................s............s.......................
testing/test_vgen2.py ..........s.............s......................................................s............s.......................
testing/test_zdistutils.py ......................................
testing/test_zintegration.py .......

=================================== FAILURES ===================================
_______________________ TestBitfield.test_bitfield_basic _______________________

self = <testing.test_ffi_backend.TestBitfield instance at 0x115ae738>

    def test_bitfield_basic(self):
>       self.check("int a; int b:9; int c:20; int y;", 8, 4, 12)

testing/test_ffi_backend.py:110: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x115ae738>
source = 'int a; int b:9; int c:20; int y;', expected_ofs_y = 8
expected_align = 4, expected_size = 12

    def check(self, source, expected_ofs_y, expected_align, expected_size):
        # NOTE: 'expected_*' is the numbers expected from GCC.
        # The numbers expected from MSVC are not explicitly written
        # in this file, and will just be taken from the compiler.
        ffi = FFI()
        ffi.cdef("struct s1 { %s };" % source)
        ctype = ffi.typeof("struct s1")
        # verify the information with gcc
        ffi1 = FFI()
        ffi1.cdef("""
                static const int Gofs_y, Galign, Gsize;
                struct s1 *try_with_value(int fieldnum, long long value);
            """)
        fnames = [name for name, cfield in ctype.fields
                       if name and cfield.bitsize > 0]
        setters = ['case %d: s.%s = value; break;' % iname
                   for iname in enumerate(fnames)]
        lib = ffi1.verify("""
                struct s1 { %s };
                struct sa { char a; struct s1 b; };
                #define Gofs_y  offsetof(struct s1, y)
                #define Galign  offsetof(struct sa, b)
                #define Gsize   sizeof(struct s1)
                struct s1 *try_with_value(int fieldnum, long long value)
                {
                    static struct s1 s;
                    memset(&s, 0, sizeof(s));
                    switch (fieldnum) { %s }
                    return &s;
                }
            """ % (source, ' '.join(setters)))
        if sys.platform == 'win32':
            expected_ofs_y = lib.Gofs_y
            expected_align = lib.Galign
            expected_size  = lib.Gsize
        else:
            assert (lib.Gofs_y, lib.Galign, lib.Gsize) == (
                expected_ofs_y, expected_align, expected_size)
        # the real test follows
        assert ffi.offsetof("struct s1", "y") == expected_ofs_y
        assert ffi.alignof("struct s1") == expected_align
        assert ffi.sizeof("struct s1") == expected_size
        # compare the actual storage of the two
        for name, cfield in ctype.fields:
            if cfield.bitsize < 0 or not name:
                continue
            if int(ffi.cast(cfield.type, -1)) == -1:   # signed
                min_value = -(1 << (cfield.bitsize-1))
                max_value = (1 << (cfield.bitsize-1)) - 1
            else:
                min_value = 0
                max_value = (1 << cfield.bitsize) - 1
            for t in [1, 2, 4, 8, 16, 128, 2813, 89728, 981729,
                     -1,-2,-4,-8,-16,-128,-2813,-89728,-981729]:
                if min_value <= t <= max_value:
>                   self._fieldcheck(ffi, lib, fnames, name, t)

testing/test_ffi_backend.py:98: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x115ae738>
ffi = <cffi.api.FFI object at 0x11a9d330>
lib = <cffi.vengine_cpy.FFILibrary object at 0x11f44590>, fnames = ['b', 'c']
name = 'b', value = 1

    def _fieldcheck(self, ffi, lib, fnames, name, value):
        s = ffi.new("struct s1 *")
        setattr(s, name, value)
        assert getattr(s, name) == value
        raw1 = ffi.buffer(s)[:]
        t = lib.try_with_value(fnames.index(name), value)
        raw2 = ffi.buffer(t, len(raw1))[:]
>       assert raw1 == raw2
E       assert '\x00\x00\x00...0\x00\x00\x00' == '\x00\x00\x00\...0\x00\x00\x00'
E         - 
E         + 

testing/test_ffi_backend.py:107: AssertionError
_______________ TestBitfield.test_bitfield_reuse_if_enough_space _______________

self = <testing.test_ffi_backend.TestBitfield instance at 0x117e6d50>

    def test_bitfield_reuse_if_enough_space(self):
>       self.check("int a:2; char y;", 1, 4, 4)

testing/test_ffi_backend.py:115: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x117e6d50>
source = 'int a:2; char y;', expected_ofs_y = 1, expected_align = 4
expected_size = 4

    def check(self, source, expected_ofs_y, expected_align, expected_size):
        # NOTE: 'expected_*' is the numbers expected from GCC.
        # The numbers expected from MSVC are not explicitly written
        # in this file, and will just be taken from the compiler.
        ffi = FFI()
        ffi.cdef("struct s1 { %s };" % source)
        ctype = ffi.typeof("struct s1")
        # verify the information with gcc
        ffi1 = FFI()
        ffi1.cdef("""
                static const int Gofs_y, Galign, Gsize;
                struct s1 *try_with_value(int fieldnum, long long value);
            """)
        fnames = [name for name, cfield in ctype.fields
                       if name and cfield.bitsize > 0]
        setters = ['case %d: s.%s = value; break;' % iname
                   for iname in enumerate(fnames)]
        lib = ffi1.verify("""
                struct s1 { %s };
                struct sa { char a; struct s1 b; };
                #define Gofs_y  offsetof(struct s1, y)
                #define Galign  offsetof(struct sa, b)
                #define Gsize   sizeof(struct s1)
                struct s1 *try_with_value(int fieldnum, long long value)
                {
                    static struct s1 s;
                    memset(&s, 0, sizeof(s));
                    switch (fieldnum) { %s }
                    return &s;
                }
            """ % (source, ' '.join(setters)))
        if sys.platform == 'win32':
            expected_ofs_y = lib.Gofs_y
            expected_align = lib.Galign
            expected_size  = lib.Gsize
        else:
            assert (lib.Gofs_y, lib.Galign, lib.Gsize) == (
                expected_ofs_y, expected_align, expected_size)
        # the real test follows
        assert ffi.offsetof("struct s1", "y") == expected_ofs_y
        assert ffi.alignof("struct s1") == expected_align
        assert ffi.sizeof("struct s1") == expected_size
        # compare the actual storage of the two
        for name, cfield in ctype.fields:
            if cfield.bitsize < 0 or not name:
                continue
            if int(ffi.cast(cfield.type, -1)) == -1:   # signed
                min_value = -(1 << (cfield.bitsize-1))
                max_value = (1 << (cfield.bitsize-1)) - 1
            else:
                min_value = 0
                max_value = (1 << cfield.bitsize) - 1
            for t in [1, 2, 4, 8, 16, 128, 2813, 89728, 981729,
                     -1,-2,-4,-8,-16,-128,-2813,-89728,-981729]:
                if min_value <= t <= max_value:
>                   self._fieldcheck(ffi, lib, fnames, name, t)

testing/test_ffi_backend.py:98: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x117e6d50>
ffi = <cffi.api.FFI object at 0x11f3d3f0>
lib = <cffi.vengine_cpy.FFILibrary object at 0x11f3dc90>, fnames = ['a']
name = 'a', value = 1

    def _fieldcheck(self, ffi, lib, fnames, name, value):
        s = ffi.new("struct s1 *")
        setattr(s, name, value)
        assert getattr(s, name) == value
        raw1 = ffi.buffer(s)[:]
        t = lib.try_with_value(fnames.index(name), value)
        raw2 = ffi.buffer(t, len(raw1))[:]
>       assert raw1 == raw2
E       assert '\x00\x00\x00\x01' == '@\x00\x00\x00'
E         - 
E         ?    -
E         + @
E         ? +

testing/test_ffi_backend.py:107: AssertionError
________________ TestBitfield.test_bitfield_anonymous_no_align _________________

self = <testing.test_ffi_backend.TestBitfield instance at 0x11863558>

    @pytest.mark.skipif("platform.machine().startswith('arm')")
    def test_bitfield_anonymous_no_align(self):
        L = FFI().alignof("long long")
        self.check("char y; int :1;", 0, 1, 2)
>       self.check("char x; int z:1; char y;", 2, 4, 4)

testing/test_ffi_backend.py:129: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x11863558>
source = 'char x; int z:1; char y;', expected_ofs_y = 2, expected_align = 4
expected_size = 4

    def check(self, source, expected_ofs_y, expected_align, expected_size):
        # NOTE: 'expected_*' is the numbers expected from GCC.
        # The numbers expected from MSVC are not explicitly written
        # in this file, and will just be taken from the compiler.
        ffi = FFI()
        ffi.cdef("struct s1 { %s };" % source)
        ctype = ffi.typeof("struct s1")
        # verify the information with gcc
        ffi1 = FFI()
        ffi1.cdef("""
                static const int Gofs_y, Galign, Gsize;
                struct s1 *try_with_value(int fieldnum, long long value);
            """)
        fnames = [name for name, cfield in ctype.fields
                       if name and cfield.bitsize > 0]
        setters = ['case %d: s.%s = value; break;' % iname
                   for iname in enumerate(fnames)]
        lib = ffi1.verify("""
                struct s1 { %s };
                struct sa { char a; struct s1 b; };
                #define Gofs_y  offsetof(struct s1, y)
                #define Galign  offsetof(struct sa, b)
                #define Gsize   sizeof(struct s1)
                struct s1 *try_with_value(int fieldnum, long long value)
                {
                    static struct s1 s;
                    memset(&s, 0, sizeof(s));
                    switch (fieldnum) { %s }
                    return &s;
                }
            """ % (source, ' '.join(setters)))
        if sys.platform == 'win32':
            expected_ofs_y = lib.Gofs_y
            expected_align = lib.Galign
            expected_size  = lib.Gsize
        else:
            assert (lib.Gofs_y, lib.Galign, lib.Gsize) == (
                expected_ofs_y, expected_align, expected_size)
        # the real test follows
        assert ffi.offsetof("struct s1", "y") == expected_ofs_y
        assert ffi.alignof("struct s1") == expected_align
        assert ffi.sizeof("struct s1") == expected_size
        # compare the actual storage of the two
        for name, cfield in ctype.fields:
            if cfield.bitsize < 0 or not name:
                continue
            if int(ffi.cast(cfield.type, -1)) == -1:   # signed
                min_value = -(1 << (cfield.bitsize-1))
                max_value = (1 << (cfield.bitsize-1)) - 1
            else:
                min_value = 0
                max_value = (1 << cfield.bitsize) - 1
            for t in [1, 2, 4, 8, 16, 128, 2813, 89728, 981729,
                     -1,-2,-4,-8,-16,-128,-2813,-89728,-981729]:
                if min_value <= t <= max_value:
>                   self._fieldcheck(ffi, lib, fnames, name, t)

testing/test_ffi_backend.py:98: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x11863558>
ffi = <cffi.api.FFI object at 0x11f5cff0>
lib = <cffi.vengine_cpy.FFILibrary object at 0x11910dd0>, fnames = ['z']
name = 'z', value = -1

    def _fieldcheck(self, ffi, lib, fnames, name, value):
        s = ffi.new("struct s1 *")
        setattr(s, name, value)
        assert getattr(s, name) == value
        raw1 = ffi.buffer(s)[:]
        t = lib.try_with_value(fnames.index(name), value)
        raw2 = ffi.buffer(t, len(raw1))[:]
>       assert raw1 == raw2
E       assert '\x00\x00\x01\x00' == '\x00\x80\x00\x00'
E         - 
E         + 

testing/test_ffi_backend.py:107: AssertionError
_______________________ TestBitfield.test_bitfield_zero ________________________

self = <testing.test_ffi_backend.TestBitfield instance at 0x1185a3a0>

    @pytest.mark.skipif("platform.machine().startswith('arm')")
    def test_bitfield_zero(self):
        L = FFI().alignof("long long")
        self.check("char y; int :0;", 0, 1, 4)
        self.check("char x; int :0; char y;", 4, 1, 5)
        self.check("char x; int :0; int :0; char y;", 4, 1, 5)
        self.check("char x; long long :0; char y;", L, 1, L + 1)
        self.check("short x, y; int :0; int :0;", 2, 2, 4)
>       self.check("char x; int :0; short b:1; char y;", 5, 2, 6)

testing/test_ffi_backend.py:159: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x1185a3a0>
source = 'char x; int :0; short b:1; char y;', expected_ofs_y = 5
expected_align = 2, expected_size = 6

    def check(self, source, expected_ofs_y, expected_align, expected_size):
        # NOTE: 'expected_*' is the numbers expected from GCC.
        # The numbers expected from MSVC are not explicitly written
        # in this file, and will just be taken from the compiler.
        ffi = FFI()
        ffi.cdef("struct s1 { %s };" % source)
        ctype = ffi.typeof("struct s1")
        # verify the information with gcc
        ffi1 = FFI()
        ffi1.cdef("""
                static const int Gofs_y, Galign, Gsize;
                struct s1 *try_with_value(int fieldnum, long long value);
            """)
        fnames = [name for name, cfield in ctype.fields
                       if name and cfield.bitsize > 0]
        setters = ['case %d: s.%s = value; break;' % iname
                   for iname in enumerate(fnames)]
        lib = ffi1.verify("""
                struct s1 { %s };
                struct sa { char a; struct s1 b; };
                #define Gofs_y  offsetof(struct s1, y)
                #define Galign  offsetof(struct sa, b)
                #define Gsize   sizeof(struct s1)
                struct s1 *try_with_value(int fieldnum, long long value)
                {
                    static struct s1 s;
                    memset(&s, 0, sizeof(s));
                    switch (fieldnum) { %s }
                    return &s;
                }
            """ % (source, ' '.join(setters)))
        if sys.platform == 'win32':
            expected_ofs_y = lib.Gofs_y
            expected_align = lib.Galign
            expected_size  = lib.Gsize
        else:
            assert (lib.Gofs_y, lib.Galign, lib.Gsize) == (
                expected_ofs_y, expected_align, expected_size)
        # the real test follows
        assert ffi.offsetof("struct s1", "y") == expected_ofs_y
        assert ffi.alignof("struct s1") == expected_align
        assert ffi.sizeof("struct s1") == expected_size
        # compare the actual storage of the two
        for name, cfield in ctype.fields:
            if cfield.bitsize < 0 or not name:
                continue
            if int(ffi.cast(cfield.type, -1)) == -1:   # signed
                min_value = -(1 << (cfield.bitsize-1))
                max_value = (1 << (cfield.bitsize-1)) - 1
            else:
                min_value = 0
                max_value = (1 << cfield.bitsize) - 1
            for t in [1, 2, 4, 8, 16, 128, 2813, 89728, 981729,
                     -1,-2,-4,-8,-16,-128,-2813,-89728,-981729]:
                if min_value <= t <= max_value:
>                   self._fieldcheck(ffi, lib, fnames, name, t)

testing/test_ffi_backend.py:98: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <testing.test_ffi_backend.TestBitfield instance at 0x1185a3a0>
ffi = <cffi.api.FFI object at 0x1190db70>
lib = <cffi.vengine_cpy.FFILibrary object at 0x1190deb0>, fnames = ['b']
name = 'b', value = -1

    def _fieldcheck(self, ffi, lib, fnames, name, value):
        s = ffi.new("struct s1 *")
        setattr(s, name, value)
        assert getattr(s, name) == value
        raw1 = ffi.buffer(s)[:]
        t = lib.try_with_value(fnames.index(name), value)
        raw2 = ffi.buffer(t, len(raw1))[:]
>       assert raw1 == raw2
E       assert '\x00\x00\x00\x00\x00\x01' == '\x00\x00\x00\x00\x80\x00'
E         - 
E         ?      -
E         + 
E         ?     +

testing/test_ffi_backend.py:107: AssertionError
============== 4 failed, 970 passed, 53 skipped in 236.49 seconds ==============

Comments (2)

  1. Log in to comment