Message ID | 20201226175129.9621-7-luc.vanoostenryck@gmail.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | support __packed struct | expand |
On 26/12/2020 17:51, Luc Van Oostenryck wrote: > Currently, packed bitfields are not handled correctly. > > Add some testcases for them. > > Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> > --- > validation/packed-bitfield0.c | 67 +++++++++++++++++++++++++++++++++++ > validation/packed-bitfield1.c | 28 +++++++++++++++ > validation/packed-bitfield2.c | 16 +++++++++ > validation/packed-bitfield3.c | 29 +++++++++++++++ > validation/packed-bitfield4.c | 19 ++++++++++ > validation/packed-bitfield5.c | 21 +++++++++++ > 6 files changed, 180 insertions(+) > create mode 100644 validation/packed-bitfield0.c > create mode 100644 validation/packed-bitfield1.c > create mode 100644 validation/packed-bitfield2.c > create mode 100644 validation/packed-bitfield3.c > create mode 100644 validation/packed-bitfield4.c > create mode 100644 validation/packed-bitfield5.c > > diff --git a/validation/packed-bitfield0.c b/validation/packed-bitfield0.c > new file mode 100644 > index 000000000000..907500dedbf0 > --- /dev/null > +++ b/validation/packed-bitfield0.c > @@ -0,0 +1,67 @@ > +#define alignof(X) __alignof__(X) > +#define __packed __attribute__((packed)) > + > +struct sa { > + int a:7; > + int c:10; > + int b:2; > +} __packed; > +_Static_assert(alignof(struct sa) == 1, "alignof(struct sa)"); > +_Static_assert( sizeof(struct sa) == 3, "sizeof(struct sa)"); > + > +struct __packed sb { > + int a:7; > + int c:10; > + int b:2; > +}; > +_Static_assert(alignof(struct sb) == 1, "alignof(struct sb)"); > +_Static_assert( sizeof(struct sb) == 3, "sizeof(struct sb)"); Why 'struct sb'? It is not used in the rest of the test (and is identical to 'struct sa'). > + > + > +static int get_size(void) > +{ > + return sizeof(struct sa); > +} > + > +static void chk_align(struct sa sa, struct sa *p) > +{ > + _Static_assert(alignof(sa) == 1, "alignof(sa)"); > + _Static_assert(alignof(*p) == 1, "alignof(*p)"); > +} > + > +static int fp0(struct sa *sa) > +{ > + return sa->c; > +} > + > +static int fpx(struct sa *sa, int idx) > +{ > + return sa[idx].c; > +} > + > +static int fglobal(void) > +{ > + extern struct sa g; > + return g.c; > +} > + > +static struct sa l; > +static int flocal(void) > +{ > + return l.c; > +} > + > + > +int main(void) > +{ > + extern void fun(struct sa *); > + struct sa sa = { 0 }; > + > + fun(&sa); > + return 0; > +} > + > +/* > + * check-name: packed-bitfield0 > + * check-known-to-fail > + */ > diff --git a/validation/packed-bitfield1.c b/validation/packed-bitfield1.c > new file mode 100644 > index 000000000000..208a3dc5127c > --- /dev/null > +++ b/validation/packed-bitfield1.c > @@ -0,0 +1,28 @@ > +#define __packed __attribute__((packed)) > + > +struct s { > + unsigned int f0:1; > + unsigned int f1:1; > + unsigned int pad:6; > +} __packed; > +_Static_assert(sizeof(struct s) == 1, "sizeof(struct s)"); > + > +extern struct s g; > + > +static int foo(struct s *ptr) > +{ > + int f = 0; > + > + f += g.f0; > + f += g.f1; > + > + f += ptr->f0; > + f += ptr->f1; > + > + return f; > +} > + > +/* > + * check-name: packed-bitfield1 > + * check-known-to-fail > + */ > diff --git a/validation/packed-bitfield2.c b/validation/packed-bitfield2.c > new file mode 100644 > index 000000000000..4587ebec5c90 > --- /dev/null > +++ b/validation/packed-bitfield2.c > @@ -0,0 +1,16 @@ > +struct bf2 { > + unsigned p1:2; > + unsigned i1:32; > + unsigned p2:2; > + unsigned s9:9; > + unsigned s9:9; > + unsigned s9:9; > + unsigned b1:1; > +} __attribute__((packed)); > + > +_Static_assert(sizeof(struct bf2) == 8); > + > +/* > + * check-name: packed-bitfield2 > + * check-known-to-fail > + */ > diff --git a/validation/packed-bitfield3.c b/validation/packed-bitfield3.c > new file mode 100644 > index 000000000000..6acff875299f > --- /dev/null > +++ b/validation/packed-bitfield3.c > @@ -0,0 +1,29 @@ > +#define __packed __attribute__((packed)) > + > +typedef unsigned char u8; > +typedef __UINT16_TYPE__ u16; > +typedef __UINT32_TYPE__ u32; > +typedef __UINT64_TYPE__ u64; > + > +struct b { > + u32 a:1; > + u32 b:2; > + u32 c:4; > + u32 d:8; > + u32 e:16; > +} __packed; > +_Static_assert(__alignof(struct b) == 1); > +_Static_assert( sizeof(struct b) == sizeof(u32)); Again '== sizeof(u32)' does not seem useful. (what is it trying to say?) > + > +struct c { > + u8 a; > + u8 b; > + u64 c:48; > +} __packed; > +_Static_assert(__alignof(struct c) == 1); > +_Static_assert( sizeof(struct c) == sizeof(u64)); ditto. ATB, Ramsay Jones > + > +/* > + * check-name: packed-bitfield3 > + * check-known-to-fail > + */ > diff --git a/validation/packed-bitfield4.c b/validation/packed-bitfield4.c > new file mode 100644 > index 000000000000..0342b2414b6e > --- /dev/null > +++ b/validation/packed-bitfield4.c > @@ -0,0 +1,19 @@ > +#define __packed __attribute__((packed)) > + > +typedef __UINT32_TYPE__ u32; > + > +struct s { > + u32 f:24; > +} __packed; > +_Static_assert(sizeof(struct s) == 3); > + > +static int ld(struct s *s) > +{ > + return s->f; > +} > + > +/* > + * check-name: packed-bitfield4 > + * check-description: Is check_access() OK with short packed bitfields? > + * check-known-to-fail > + */ > diff --git a/validation/packed-bitfield5.c b/validation/packed-bitfield5.c > new file mode 100644 > index 000000000000..8f44d4c2c277 > --- /dev/null > +++ b/validation/packed-bitfield5.c > @@ -0,0 +1,21 @@ > +#define __packed __attribute__((packed)) > + > +typedef __UINT32_TYPE__ u32; > + > +struct s { > + u32 a:5; > + u32 f:30; > + u32 z:5; > +} __packed; > +_Static_assert(sizeof(struct s) == 5); > + > +static int ld(struct s *s) > +{ > + return s->f; > +} > + > +/* > + * check-name: packed-bitfield5 > + * check-description: is check_access() OK with 'overlapping' packed bitfields? > + * check-known-to-fail > + */ >
On Mon, Dec 28, 2020 at 04:28:24PM +0000, Ramsay Jones wrote: > > > On 26/12/2020 17:51, Luc Van Oostenryck wrote: > > Currently, packed bitfields are not handled correctly. > > > > Add some testcases for them. > > > > Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> > > --- > > validation/packed-bitfield0.c | 67 +++++++++++++++++++++++++++++++++++ > > validation/packed-bitfield1.c | 28 +++++++++++++++ > > validation/packed-bitfield2.c | 16 +++++++++ > > validation/packed-bitfield3.c | 29 +++++++++++++++ > > validation/packed-bitfield4.c | 19 ++++++++++ > > validation/packed-bitfield5.c | 21 +++++++++++ > > 6 files changed, 180 insertions(+) > > create mode 100644 validation/packed-bitfield0.c > > create mode 100644 validation/packed-bitfield1.c > > create mode 100644 validation/packed-bitfield2.c > > create mode 100644 validation/packed-bitfield3.c > > create mode 100644 validation/packed-bitfield4.c > > create mode 100644 validation/packed-bitfield5.c > > > > diff --git a/validation/packed-bitfield0.c b/validation/packed-bitfield0.c > > new file mode 100644 > > index 000000000000..907500dedbf0 > > --- /dev/null > > +++ b/validation/packed-bitfield0.c > > @@ -0,0 +1,67 @@ > > +#define alignof(X) __alignof__(X) > > +#define __packed __attribute__((packed)) > > + > > +struct sa { > > + int a:7; > > + int c:10; > > + int b:2; > > +} __packed; > > +_Static_assert(alignof(struct sa) == 1, "alignof(struct sa)"); > > +_Static_assert( sizeof(struct sa) == 3, "sizeof(struct sa)"); > > + > > +struct __packed sb { > > + int a:7; > > + int c:10; > > + int b:2; > > +}; > > +_Static_assert(alignof(struct sb) == 1, "alignof(struct sb)"); > > +_Static_assert( sizeof(struct sb) == 3, "sizeof(struct sb)"); > > Why 'struct sb'? It is not used in the rest of the test (and is > identical to 'struct sa'). Good question :) I've probably reused some previous file as a kind of template. > > diff --git a/validation/packed-bitfield3.c b/validation/packed-bitfield3.c > > new file mode 100644 > > index 000000000000..6acff875299f > > --- /dev/null > > +++ b/validation/packed-bitfield3.c > > @@ -0,0 +1,29 @@ > > +#define __packed __attribute__((packed)) > > + > > +typedef unsigned char u8; > > +typedef __UINT16_TYPE__ u16; > > +typedef __UINT32_TYPE__ u32; > > +typedef __UINT64_TYPE__ u64; > > + > > +struct b { > > + u32 a:1; > > + u32 b:2; > > + u32 c:4; > > + u32 d:8; > > + u32 e:16; > > +} __packed; > > +_Static_assert(__alignof(struct b) == 1); > > +_Static_assert( sizeof(struct b) == sizeof(u32)); > > Again '== sizeof(u32)' does not seem useful. (what is it > trying to say?) > > > + > > +struct c { > > + u8 a; > > + u8 b; > > + u64 c:48; > > +} __packed; > > +_Static_assert(__alignof(struct c) == 1); > > +_Static_assert( sizeof(struct c) == sizeof(u64)); > > ditto. Yes, I agree. -- Luc
diff --git a/validation/packed-bitfield0.c b/validation/packed-bitfield0.c new file mode 100644 index 000000000000..907500dedbf0 --- /dev/null +++ b/validation/packed-bitfield0.c @@ -0,0 +1,67 @@ +#define alignof(X) __alignof__(X) +#define __packed __attribute__((packed)) + +struct sa { + int a:7; + int c:10; + int b:2; +} __packed; +_Static_assert(alignof(struct sa) == 1, "alignof(struct sa)"); +_Static_assert( sizeof(struct sa) == 3, "sizeof(struct sa)"); + +struct __packed sb { + int a:7; + int c:10; + int b:2; +}; +_Static_assert(alignof(struct sb) == 1, "alignof(struct sb)"); +_Static_assert( sizeof(struct sb) == 3, "sizeof(struct sb)"); + + +static int get_size(void) +{ + return sizeof(struct sa); +} + +static void chk_align(struct sa sa, struct sa *p) +{ + _Static_assert(alignof(sa) == 1, "alignof(sa)"); + _Static_assert(alignof(*p) == 1, "alignof(*p)"); +} + +static int fp0(struct sa *sa) +{ + return sa->c; +} + +static int fpx(struct sa *sa, int idx) +{ + return sa[idx].c; +} + +static int fglobal(void) +{ + extern struct sa g; + return g.c; +} + +static struct sa l; +static int flocal(void) +{ + return l.c; +} + + +int main(void) +{ + extern void fun(struct sa *); + struct sa sa = { 0 }; + + fun(&sa); + return 0; +} + +/* + * check-name: packed-bitfield0 + * check-known-to-fail + */ diff --git a/validation/packed-bitfield1.c b/validation/packed-bitfield1.c new file mode 100644 index 000000000000..208a3dc5127c --- /dev/null +++ b/validation/packed-bitfield1.c @@ -0,0 +1,28 @@ +#define __packed __attribute__((packed)) + +struct s { + unsigned int f0:1; + unsigned int f1:1; + unsigned int pad:6; +} __packed; +_Static_assert(sizeof(struct s) == 1, "sizeof(struct s)"); + +extern struct s g; + +static int foo(struct s *ptr) +{ + int f = 0; + + f += g.f0; + f += g.f1; + + f += ptr->f0; + f += ptr->f1; + + return f; +} + +/* + * check-name: packed-bitfield1 + * check-known-to-fail + */ diff --git a/validation/packed-bitfield2.c b/validation/packed-bitfield2.c new file mode 100644 index 000000000000..4587ebec5c90 --- /dev/null +++ b/validation/packed-bitfield2.c @@ -0,0 +1,16 @@ +struct bf2 { + unsigned p1:2; + unsigned i1:32; + unsigned p2:2; + unsigned s9:9; + unsigned s9:9; + unsigned s9:9; + unsigned b1:1; +} __attribute__((packed)); + +_Static_assert(sizeof(struct bf2) == 8); + +/* + * check-name: packed-bitfield2 + * check-known-to-fail + */ diff --git a/validation/packed-bitfield3.c b/validation/packed-bitfield3.c new file mode 100644 index 000000000000..6acff875299f --- /dev/null +++ b/validation/packed-bitfield3.c @@ -0,0 +1,29 @@ +#define __packed __attribute__((packed)) + +typedef unsigned char u8; +typedef __UINT16_TYPE__ u16; +typedef __UINT32_TYPE__ u32; +typedef __UINT64_TYPE__ u64; + +struct b { + u32 a:1; + u32 b:2; + u32 c:4; + u32 d:8; + u32 e:16; +} __packed; +_Static_assert(__alignof(struct b) == 1); +_Static_assert( sizeof(struct b) == sizeof(u32)); + +struct c { + u8 a; + u8 b; + u64 c:48; +} __packed; +_Static_assert(__alignof(struct c) == 1); +_Static_assert( sizeof(struct c) == sizeof(u64)); + +/* + * check-name: packed-bitfield3 + * check-known-to-fail + */ diff --git a/validation/packed-bitfield4.c b/validation/packed-bitfield4.c new file mode 100644 index 000000000000..0342b2414b6e --- /dev/null +++ b/validation/packed-bitfield4.c @@ -0,0 +1,19 @@ +#define __packed __attribute__((packed)) + +typedef __UINT32_TYPE__ u32; + +struct s { + u32 f:24; +} __packed; +_Static_assert(sizeof(struct s) == 3); + +static int ld(struct s *s) +{ + return s->f; +} + +/* + * check-name: packed-bitfield4 + * check-description: Is check_access() OK with short packed bitfields? + * check-known-to-fail + */ diff --git a/validation/packed-bitfield5.c b/validation/packed-bitfield5.c new file mode 100644 index 000000000000..8f44d4c2c277 --- /dev/null +++ b/validation/packed-bitfield5.c @@ -0,0 +1,21 @@ +#define __packed __attribute__((packed)) + +typedef __UINT32_TYPE__ u32; + +struct s { + u32 a:5; + u32 f:30; + u32 z:5; +} __packed; +_Static_assert(sizeof(struct s) == 5); + +static int ld(struct s *s) +{ + return s->f; +} + +/* + * check-name: packed-bitfield5 + * check-description: is check_access() OK with 'overlapping' packed bitfields? + * check-known-to-fail + */
Currently, packed bitfields are not handled correctly. Add some testcases for them. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- validation/packed-bitfield0.c | 67 +++++++++++++++++++++++++++++++++++ validation/packed-bitfield1.c | 28 +++++++++++++++ validation/packed-bitfield2.c | 16 +++++++++ validation/packed-bitfield3.c | 29 +++++++++++++++ validation/packed-bitfield4.c | 19 ++++++++++ validation/packed-bitfield5.c | 21 +++++++++++ 6 files changed, 180 insertions(+) create mode 100644 validation/packed-bitfield0.c create mode 100644 validation/packed-bitfield1.c create mode 100644 validation/packed-bitfield2.c create mode 100644 validation/packed-bitfield3.c create mode 100644 validation/packed-bitfield4.c create mode 100644 validation/packed-bitfield5.c