From 67594cca70e21cf29caf16b1cda065d2b5858814 Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 3 Mar 2022 16:14:26 +0800 Subject: [PATCH] Testcases for long bit-fields. --- test/val/{enum-bitfield.c => bitfield-enum.c} | 162 ++++++++- test/val/bitfield-packing-char.c | 278 ++++++++++++++++ test/val/bitfield-packing-long.c | 315 ++++++++++++++++++ test/val/{bitfield.c => bitfield-packing.c} | 18 +- test/val/bitfield-plain.c | 180 ++++++++++ test/val/bitfield-signed.c | 180 ++++++++++ test/val/plain-int-bitfield.c | 63 ---- 7 files changed, 1123 insertions(+), 73 deletions(-) rename test/val/{enum-bitfield.c => bitfield-enum.c} (61%) create mode 100644 test/val/bitfield-packing-char.c create mode 100644 test/val/bitfield-packing-long.c rename test/val/{bitfield.c => bitfield-packing.c} (93%) create mode 100644 test/val/bitfield-plain.c create mode 100644 test/val/bitfield-signed.c delete mode 100644 test/val/plain-int-bitfield.c diff --git a/test/val/enum-bitfield.c b/test/val/bitfield-enum.c similarity index 61% rename from test/val/enum-bitfield.c rename to test/val/bitfield-enum.c index 5669978c9..ce74b062e 100644 --- a/test/val/enum-bitfield.c +++ b/test/val/bitfield-enum.c @@ -1,5 +1,5 @@ /* - Copyright 2020 The cc65 Authors + Copyright 2020-2022 The cc65 Authors This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -247,7 +247,7 @@ static void test_enum_bitfield_char(void) failures++; } if (e8scbf.y != 5) { - printf ("Got e8scbf.y = %d, expected 10.\n", e8scbf.y); + printf ("Got e8scbf.y = %d, expected 5.\n", e8scbf.y); failures++; } if (e8scbf.z != 100) { @@ -273,12 +273,170 @@ static void test_enum_bitfield_char(void) } } +/* Enum with underlying type unsigned long. */ +enum e20ul { + E20UL_10 = 10, + E20UL_1000 = 1000, + E20UL_1000000000 = 1000000000L, +}; + +static struct enum_bitfield_ulong { + enum e20ul x : 4; + enum e20ul y : 16; + enum e20ul z : CHAR_BIT * sizeof (enum e20ul); +} e20ulbf = {E20UL_10, E20UL_1000, E20UL_1000000000}; + +static void test_enum_bitfield_ulong(void) +{ + if (sizeof (struct enum_bitfield_ulong) != 7) { + printf ("Got sizeof(struct enum_bitfield_ulong) = %zu, expected 7.\n", + sizeof(struct enum_bitfield_ulong)); + failures++; + } + + if (e20ulbf.x != 10) { + printf ("Got e20ulbf.x = %u, expected 10.\n", e20ulbf.x); + failures++; + } + if (e20ulbf.y != 1000) { + printf ("Got e20ulbf.y = %u, expected 1000.\n", e20ulbf.y); + failures++; + } + if (e20ulbf.z != 1000000000L) { + printf ("Got e20ulbf.z = %ul, expected 1000000000.\n", e20ulbf.z); + failures++; + } + + e20ulbf.x = 8; + e20ulbf.y = -1; /* Will store 65535. */ + e20ulbf.z = 1048575L; + + if (e20ulbf.x != 8) { + printf ("Got e20ulbf.x = %ld, expected 8.\n", (long)e20ulbf.x); + failures++; + } + + /* Check signedness, should be signed. */ + { + if (e20ulbf.x - 9 >= 0) { + printf ("Got non-negative e20ulbf.x - 9 = %lu, expected negative.\n", (unsigned long)(e20ulbf.x - 9)); + failures++; + } + } + + if (e20ulbf.y != 65535L) { + printf ("Got e20ulbf.y = %ld, expected 65535.\n", (long)e20ulbf.y); + failures++; + } + + /* Check signedness, should be signed. */ + { + if (e20ulbf.y - 65536L >= 0) { + printf ("Got non-negative e20ulbf.y - 65536L = %lu, expected negative.\n", (unsigned long)(e20ulbf.y - 65536L)); + failures++; + } + } + + if (e20ulbf.z != 1048575L) { + printf ("Got e20ulbf.z = %lu, expected 1048575.\n", (unsigned long)e20ulbf.z); + failures++; + } + + /* Check signedness, should be unsigned. */ + { + if (e20ulbf.z - 1048576L < 0) { + printf ("Got negative e20ulbf.z - 1048576 = %ld, expected positive.\n", (long)(e20ulbf.z - 1048576L)); + failures++; + } + } +} + +/* Enum with underlying type signed long. */ +enum e20sl { + E20SL_M1 = -1, + E20SL_1000 = 1000, + E20SL_1000000000 = 1000000000L, +}; + +static struct enum_bitfield_long { + enum e20sl x : 2; + enum e20sl y : 16; + enum e20sl z : CHAR_BIT * sizeof (enum e20sl); +} e20slbf = {E20SL_M1, E20SL_1000, E20SL_1000000000}; + +static void test_enum_bitfield_long(void) +{ + if (sizeof (struct enum_bitfield_long) != 7) { + printf ("Got sizeof(struct enum_bitfield_long) = %zu, expected 8.\n", + sizeof(struct enum_bitfield_long)); + failures++; + } + + if (e20slbf.x != -1) { + printf ("Got e20slbf.x = %ld, expected -1.\n", (long)e20slbf.x); + failures++; + } + if (e20slbf.y != 1000) { + printf ("Got e20slbf.y = %ld, expected 1000.\n", (long)e20slbf.y); + failures++; + } + if (e20slbf.z != 1000000000L) { + printf ("Got e20slbf.z = %ld, expected 1000000000.\n", (long)e20slbf.z); + failures++; + } + + e20slbf.x = 1; + e20slbf.y = 257; + e20slbf.z = 1048575L; + + if (e20slbf.x != 1) { + printf ("Got e20slbf.x = %d, expected 1.\n", e20slbf.x); + failures++; + } + + /* Check signedness, should be signed. */ + { + if (e20slbf.x - 2 >= 0) { + printf ("Got non-negative e20slbf.x - 2 = %lu, expected negative.\n", (unsigned long)(e20slbf.x - 2)); + failures++; + } + } + + if (e20slbf.y != 257) { + printf ("Got e20slbf.y = %ld, expected 257.\n", (long)e20slbf.y); + failures++; + } + + /* Check signedness, should be signed. */ + { + if (e20slbf.y - 258 >= 0) { + printf ("Got non-negative e20slbf.y - 258 = %lu, expected negative.\n", (unsigned long)(e20slbf.y - 258)); + failures++; + } + } + + if (e20slbf.z != 1048575L) { + printf ("Got e20slbf.z = %ld, expected 1048575.\n", (long)e20slbf.z); + failures++; + } + + /* Check signedness, should be signed. */ + { + if (e20slbf.z - 1048576L >= 0) { + printf ("Got non-negative e20slbf.z - 1048576L = %ld, expected negative.\n", (long)(e20slbf.z - 1048576L)); + failures++; + } + } +} + int main(void) { test_enum_bitfield_uint(); test_enum_bitfield_int(); test_enum_bitfield_uchar(); test_enum_bitfield_char(); + test_enum_bitfield_ulong(); + test_enum_bitfield_long(); printf("failures: %u\n", failures); return failures; } diff --git a/test/val/bitfield-packing-char.c b/test/val/bitfield-packing-char.c new file mode 100644 index 000000000..18621e0eb --- /dev/null +++ b/test/val/bitfield-packing-char.c @@ -0,0 +1,278 @@ +/* + Copyright 2020-2022 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Tests of char bit-field packing and typedef works with them; see issues below + - packing issue: https://github.com/cc65/cc65/issues/1054 + - typedef issue: https://github.com/cc65/cc65/pull/1662 + - char bit-field support: https://github.com/cc65/cc65/issues/1047 +*/ + +#include + +static unsigned char failures = 0; + +typedef unsigned char field_type; + +static struct four_bits { + field_type x : 4; +} fb = {1}; + +static void test_four_bits(void) +{ + if (sizeof(struct four_bits) != 1) { + printf("Got sizeof(struct four_bits) = %zu, expected 1.\n", + sizeof(struct four_bits)); + failures++; + } + + if (fb.x != 1) { + printf("Got fb.x = %u, expected 1.\n", fb.x); + failures++; + } + + fb.x = 3; + + if (fb.x != 3) { + printf("Got fb.x = %u, expected 3.\n", fb.x); + failures++; + } +} + +/* + Logic is somewhat diferent for bit-fields that end a struct vs + having additional fields. +*/ + +static struct four_bits_with_char { + field_type x : 4; + field_type y; +} fbi = {1, 2}; + +static void test_four_bits_with_char(void) +{ + /* The first 4-bit bit-field just takes one byte, so the size is 2. */ + if (sizeof(struct four_bits_with_char) != 2) { + printf("Got sizeof(struct four_bits_with_char) = %zu, expected 2.\n", + sizeof(struct four_bits_with_char)); + failures++; + } + + if (fbi.x != 1) { + printf("Got fbi.x = %u, expected 1.\n", fbi.x); + failures++; + } + + if (fbi.y != 2) { + printf("Got fbi.y = %u, expected 2.\n", fbi.y); + failures++; + } + + fbi.x = 3; + fbi.y = 17; + + if (fbi.x != 3) { + printf("Got fbi.x = %u, expected 3.\n", fbi.x); + failures++; + } + + if (fbi.y != 17) { + printf("Got fbi.y = %u, expected 17.\n", fbi.y); + failures++; + } +} + +static struct overlap { + field_type x : 6; + field_type y : 6; +} o = {11, 22}; + +/* Tests that bit-fields can share allocation units. */ +static void test_overlap(void) +{ + if (sizeof(struct overlap) != 2) { + printf("Got sizeof(struct overlap) = %zu, expected 2.\n", + sizeof(struct overlap)); + failures++; + } + + if (o.x != 11) { + printf("Got o.x = %u, expected 11.\n", o.x); + failures++; + } + + if (o.y != 22) { + printf("Got o.y = %u, expected 22.\n", o.y); + failures++; + } + + o.x = 33; + o.y = 44; + + if (o.x != 33) { + printf("Got o.x = %u, expected 33.\n", o.x); + failures++; + } + + if (o.y != 44) { + printf("Got o.y = %u, expected 44.\n", o.y); + failures++; + } +} + +static struct overlap_with_char { + field_type x : 6; + field_type y : 6; + field_type z; +} oi = {11, 22, 33}; + +static void test_overlap_with_char(void) +{ + /* First two fields in 2 bytes, then another 1 byte. */ + if (sizeof(struct overlap_with_char) != 3) { + printf("Got sizeof(struct overlap_with_char) = %zu, expected 3.\n", + sizeof(struct overlap_with_char)); + failures++; + } + + if (oi.x != 11) { + printf("Got oi.x = %u, expected 11.\n", oi.x); + failures++; + } + + if (oi.y != 22) { + printf("Got oi.y = %u, expected 22.\n", oi.y); + failures++; + } + + if (oi.z != 33) { + printf("Got oi.z = %u, expected 33.\n", oi.z); + failures++; + } + + oi.x = 44; + oi.y = 55; + oi.z = 66; + + if (oi.x != 44) { + printf("Got oi.x = %u, expected 44.\n", oi.x); + failures++; + } + + if (oi.y != 55) { + printf("Got oi.y = %u, expected 55.\n", oi.y); + failures++; + } + + if (oi.z != 66) { + printf("Got oi.z = %u, expected 66.\n", oi.z); + failures++; + } +} + +static struct full_width { + field_type x : 8; + field_type y : 8; +} fw = {255, 17}; + +static void test_full_width(void) +{ + if (sizeof(struct full_width) != 2) { + printf("Got sizeof(struct full_width) = %zu, expected 2.\n", + sizeof(struct full_width)); + failures++; + } + + if (fw.x != 255) { + printf("Got fw.x = %u, expected 255.\n", fw.x); + failures++; + } + + if (fw.y != 17) { + printf("Got fw.y = %u, expected 17.\n", fw.y); + failures++; + } + + fw.x = 42; + fw.y = 255; + + if (fw.x != 42) { + printf("Got fw.x = %u, expected 42.\n", fw.x); + failures++; + } + + if (fw.y != 255) { + printf("Got fw.y = %u, expected 255.\n", fw.y); + failures++; + } +} + +static struct aligned_end { + field_type : 2; + field_type x : 6; + /* y crosses a byte boundary, but fits in a byte when shifted. */ + field_type : 6; + field_type y : 7; +} ae = {63, 17}; + +static void test_aligned_end(void) +{ + if (sizeof(struct aligned_end) != 3) { + printf("Got sizeof(struct aligned_end) = %zu, expected 3.\n", + sizeof(struct aligned_end)); + failures++; + } + + if (ae.x != 63) { + printf("Got ae.x = %u, expected 63.\n", ae.x); + failures++; + } + + if (ae.y != 17) { + printf("Got ae.y = %u, expected 17.\n", ae.y); + failures++; + } + + ae.x = 42; + ae.y = 127; + + if (ae.x != 42) { + printf("Got ae.x = %u, expected 42.\n", ae.x); + failures++; + } + + if (ae.y != 127) { + printf("Got ae.y = %u, expected 127.\n", ae.y); + failures++; + } + +} + +int main(void) +{ + test_four_bits(); + test_four_bits_with_char(); + test_overlap(); + test_overlap_with_char(); + test_full_width(); + test_aligned_end(); + printf("failures: %u\n", failures); + return failures; +} diff --git a/test/val/bitfield-packing-long.c b/test/val/bitfield-packing-long.c new file mode 100644 index 000000000..fcc8eb7fe --- /dev/null +++ b/test/val/bitfield-packing-long.c @@ -0,0 +1,315 @@ +/* + Copyright 2020-2022 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Tests of long bit-field packing and typedef works with them; see issues below + - packing: https://github.com/cc65/cc65/issues/1054 + - typedef: https://github.com/cc65/cc65/pull/1662 + - long bit-field support: https://github.com/cc65/cc65/issues/1131 +*/ + +#include + +static unsigned char failures = 0; + +typedef unsigned long field_type; + +static struct four_bits { + field_type x : 4; +} fb = {1}; + +static void test_four_bits(void) +{ + if (sizeof(struct four_bits) != 1) { + printf("Got sizeof(struct four_bits) = %zu, expected 1.\n", + sizeof(struct four_bits)); + failures++; + } + + if (fb.x != 1) { + printf("Got fb.x = %u, expected 1.\n", fb.x); + failures++; + } + + fb.x = 3; + + if (fb.x != 3) { + printf("Got fb.x = %u, expected 3.\n", fb.x); + failures++; + } +} + +/* + Logic is somewhat diferent for bit-fields that end a struct vs + having additional fields. +*/ + +static struct four_bits_with_long { + field_type x : 4; + field_type y; +} fbi = {1, 2}; + +static void test_four_bits_with_long(void) +{ + /* The first 4-bit bit-field just takes one byte, so the size is 5. */ + if (sizeof(struct four_bits_with_long) != 5) { + printf("Got sizeof(struct four_bits_with_long) = %zu, expected 5.\n", + sizeof(struct four_bits_with_long)); + failures++; + } + + if (fbi.x != 1) { + printf("Got fbi.x = %u, expected 1.\n", fbi.x); + failures++; + } + + if (fbi.y != 2) { + printf("Got fbi.y = %lu, expected 2.\n", fbi.y); + failures++; + } + + fbi.x = 3; + fbi.y = 65537; + + if (fbi.x != 3) { + printf("Got fbi.x = %u, expected 3.\n", fbi.x); + failures++; + } + + if (fbi.y != 65537) { + printf("Got fbi.y = %lu, expected 65537.\n", fbi.y); + failures++; + } +} + +static struct overlap { + field_type x : 10; + field_type y : 10; +} o = {11, 22}; + +/* Tests that bit-fields can share allocation units. */ +static void test_overlap(void) +{ + if (sizeof(struct overlap) != 3) { + printf("Got sizeof(struct overlap) = %zu, expected 3.\n", + sizeof(struct overlap)); + failures++; + } + + if (o.x != 11) { + printf("Got o.x = %u, expected 11.\n", o.x); + failures++; + } + + if (o.y != 22) { + printf("Got o.y = %u, expected 22.\n", o.y); + failures++; + } + + o.x = 33; + o.y = 44; + + if (o.x != 33) { + printf("Got o.x = %u, expected 33.\n", o.x); + failures++; + } + + if (o.y != 44) { + printf("Got o.y = %u, expected 44.\n", o.y); + failures++; + } +} + +static struct overlap_with_long { + field_type x : 10; + field_type y : 10; + field_type z; +} oi = {111, 222, 333}; + +static void test_overlap_with_long(void) +{ + /* First two fields in 3 bytes, then another 4 bytes. */ + if (sizeof(struct overlap_with_long) != 7) { + printf("Got sizeof(struct overlap_with_long) = %zu, expected 7.\n", + sizeof(struct overlap_with_long)); + failures++; + } + + if (oi.x != 111) { + printf("Got oi.x = %u, expected 111.\n", oi.x); + failures++; + } + + if (oi.y != 222) { + printf("Got oi.y = %u, expected 222.\n", oi.y); + failures++; + } + + if (oi.z != 333) { + printf("Got oi.z = %u, expected 333.\n", oi.z); + failures++; + } + + oi.x = 444; + oi.y = 555; + oi.z = 4294967295; + + if (oi.x != 444) { + printf("Got oi.x = %u, expected 444.\n", oi.x); + failures++; + } + + if (oi.y != 555) { + printf("Got oi.y = %u, expected 555.\n", oi.y); + failures++; + } + + if (oi.z != 4294967295) { + printf("Got oi.z = %lu, expected 4294967295.\n", oi.z); + failures++; + } +} + +static struct full_width { + field_type x : 8; + field_type y : 16; + field_type z : 32; +} fw = {255, 17, 1}; + +static void test_full_width(void) +{ + if (sizeof(struct full_width) != 7) { + printf("Got sizeof(struct full_width) = %zu, expected 7.\n", + sizeof(struct full_width)); + failures++; + } + + if (fw.x != 255) { + printf("Got fw.x = %u, expected 255.\n", fw.x); + failures++; + } + + if (fw.y != 17) { + printf("Got fw.y = %u, expected 17.\n", fw.y); + failures++; + } + + if (fw.z != 1) { + printf("Got fw.z = %lu, expected 1.\n", fw.z); + failures++; + } + + fw.x = 42; + fw.y = 1023; + fw.z = 65537; + + if (fw.x != 42) { + printf("Got fw.x = %u, expected 42.\n", fw.x); + failures++; + } + + if (fw.y != 1023) { + printf("Got fw.y = %u, expected 1023.\n", fw.y); + failures++; + } + + if (fw.z != 65537) { + printf("Got fw.z = %lu, expected 65537.\n", fw.z); + failures++; + } +} + +static struct aligned_end { + field_type : 2; + field_type x : 6; + field_type : 3; + field_type y : 13; + field_type : 14; + field_type z : 18; + /* w crosses a byte boundary, but fits in a byte when shifted. */ + field_type : 6; + field_type w : 7; +} ae = {63, 17, 1, 100}; + +static void test_aligned_end(void) +{ + if (sizeof(struct aligned_end) != 9) { + printf("Got sizeof(struct aligned_end) = %zu, expected 9.\n", + sizeof(struct aligned_end)); + failures++; + } + + if (ae.x != 63) { + printf("Got ae.x = %u, expected 63.\n", ae.x); + failures++; + } + + if (ae.y != 17) { + printf("Got ae.y = %u, expected 17.\n", ae.y); + failures++; + } + + if (ae.z != 1) { + printf("Got ae.z = %lu, expected 1.\n", ae.z); + failures++; + } + + if (ae.w != 100) { + printf("Got ae.w = %u, expected 100.\n", ae.w); + failures++; + } + + ae.x = 42; + ae.y = 1023; + ae.z = 262143; + ae.w = 66; + + if (ae.x != 42) { + printf("Got ae.x = %u, expected 42.\n", ae.x); + failures++; + } + + if (ae.y != 1023) { + printf("Got ae.y = %u, expected 1023.\n", ae.y); + failures++; + } + + if (ae.z != 262143) { + printf("Got ae.z = %lu, expected 262143.\n", ae.z); + failures++; + } + + if (ae.w != 66) { + printf("Got ae.w = %u, expected 66.\n", ae.w); + failures++; + } +} + +int main(void) +{ + test_four_bits(); + test_four_bits_with_long(); + test_overlap(); + test_overlap_with_long(); + test_full_width(); + test_aligned_end(); + printf("failures: %u\n", failures); + return failures; +} diff --git a/test/val/bitfield.c b/test/val/bitfield-packing.c similarity index 93% rename from test/val/bitfield.c rename to test/val/bitfield-packing.c index 1de19777a..5786d6906 100644 --- a/test/val/bitfield.c +++ b/test/val/bitfield-packing.c @@ -1,5 +1,5 @@ /* - Copyright 2020 The cc65 Authors + Copyright 2020-2022 The cc65 Authors This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,9 @@ */ /* - Tests of bit-field packing; see https://github.com/cc65/cc65/issues/1054 + Tests of int bit-field packing and typedef works with them; see issues below + - packing issue: https://github.com/cc65/cc65/issues/1054 + - typedef issue: https://github.com/cc65/cc65/pull/1662 */ #include @@ -83,15 +85,15 @@ static void test_four_bits_with_int(void) } fbi.x = 3; - fbi.y = 17; + fbi.y = 257; if (fbi.x != 3) { printf("Got fbi.x = %u, expected 3.\n", fbi.x); failures++; } - if (fbi.y != 17) { - printf("Got fbi.y = %u, expected 17.\n", fbi.y); + if (fbi.y != 257) { + printf("Got fbi.y = %u, expected 257.\n", fbi.y); failures++; } } @@ -166,7 +168,7 @@ static void test_overlap_with_int(void) oi.x = 444; oi.y = 555; - oi.z = 666; + oi.z = 65535; if (oi.x != 444) { printf("Got oi.x = %u, expected 444.\n", oi.x); @@ -178,8 +180,8 @@ static void test_overlap_with_int(void) failures++; } - if (oi.z != 666) { - printf("Got oi.z = %u, expected 666.\n", oi.z); + if (oi.z != 65535) { + printf("Got oi.z = %u, expected 65535.\n", oi.z); failures++; } } diff --git a/test/val/bitfield-plain.c b/test/val/bitfield-plain.c new file mode 100644 index 000000000..735f3dc87 --- /dev/null +++ b/test/val/bitfield-plain.c @@ -0,0 +1,180 @@ +/* + Copyright 2020-2022 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Tests that plain bit-fields are unsigned; see issues below + - unsigned integer types by default: https://github.com/cc65/cc65/issues/1095 + - char bit-field support: https://github.com/cc65/cc65/issues/1047 + - long bit-field support: https://github.com/cc65/cc65/issues/1131 +*/ + +#include + +static unsigned char failures = 0; + +static struct plain_ints { + int x : 4; + int y : 10; +} pi = {15, 700}; + +static void test_plain_int_bitfields (void) +{ + if (pi.x != 15) { + printf ("Got pi.x = %ld, expected 15.\n", (long)pi.x); + failures++; + } + if (pi.y != 700) { + printf ("Got pi.y = %ld, expected 700.\n", (long)pi.y); + failures++; + } + + pi.x = 3; + pi.y = 1023; + + if (pi.x != 3) { + printf ("Got pi.x = %ld, expected 3.\n", (long)pi.x); + failures++; + } + if (pi.y != 1023) { + printf ("Got pi.y = %ld, expected 1023.\n", (long)pi.y); + failures++; + } +} + +static struct plain_shorts { + short x : 4; + short y : 10; +} ps = {15, 700}; + +static void test_plain_short_bitfields (void) +{ + if (ps.x != 15) { + printf ("Got ps.x = %ld, expected 15.\n", (long)ps.x); + failures++; + } + if (ps.y != 700) { + printf ("Got ps.y = %ld, expected 700.\n", (long)ps.y); + failures++; + } + + ps.x = 3; + ps.y = 1023; + + if (ps.x != 3) { + printf ("Got ps.x = %ld, expected 3.\n", (long)ps.x); + failures++; + } + if (ps.y != 1023) { + printf ("Got ps.y = %ld, expected 1023.\n", (long)ps.y); + failures++; + } +} + +static struct plain_chars { + char x : 4; +} pc = {15}; + +static void test_plain_char_bitfields (void) +{ + if (pc.x != 15) { + printf ("Got pc.x = %ld, expected 15.\n", (long)pc.x); + failures++; + } + + pc.x = 3; + + if (pc.x != 3) { + printf ("Got pc.x = %ld, expected 3.\n", (long)pc.x); + failures++; + } +} + +static struct plain_longs { + long x : 4; + long y : 10; + long z : 18; +} pl = {15, 700, 200000}; + +static void test_plain_long_bitfields (void) +{ + if (pl.x != 15) { + if (pl.x < 0) { + printf ("Got pl.x = %ld, expected 15.\n", (long)pl.x); + } else { + printf ("Got pl.x = %lu, expected 15.\n", (unsigned long)pl.x); + } + failures++; + } + if (pl.y != 700) { + if (pl.y < 0) { + printf ("Got pl.y = %ld, expected 700.\n", (long)pl.y); + } else { + printf ("Got pl.y = %lu, expected 700.\n", (unsigned long)pl.y); + } + failures++; + } + if (pl.z != 200000) { + if (pl.z < 0) { + printf ("Got pl.z = %ld, expected 200000.\n", (long)pl.z); + } else { + printf ("Got pl.z = %lu, expected 200000.\n", (unsigned long)pl.z); + } + failures++; + } + + pl.x = 3; + pl.y = 1023; + pl.z = 262143; + + if (pl.x != 3) { + if (pl.x < 0) { + printf ("Got pl.x = %ld, expected 3.\n", (long)pl.x); + } else { + printf ("Got pl.x = %lu, expected 3.\n", (unsigned long)pl.x); + } + failures++; + } + if (pl.y != 1023) { + if (pl.y < 0) { + printf ("Got pl.y = %ld, expected 1023.\n", (long)pl.y); + } else { + printf ("Got pl.y = %lu, expected 1023.\n", (unsigned long)pl.y); + } + failures++; + } + if (pl.z != 262143) { + if (pl.z < 0) { + printf ("Got pl.z = %ld, expected 262143.\n", (long)pl.z); + } else { + printf ("Got pl.z = %lu, expected 262143.\n", (unsigned long)pl.z); + } + failures++; + } +} + +int main (void) +{ + test_plain_int_bitfields (); + test_plain_short_bitfields (); + test_plain_char_bitfields (); + test_plain_long_bitfields (); + printf ("failures: %u\n", failures); + return failures; +} diff --git a/test/val/bitfield-signed.c b/test/val/bitfield-signed.c new file mode 100644 index 000000000..68f36f92a --- /dev/null +++ b/test/val/bitfield-signed.c @@ -0,0 +1,180 @@ +/* + Copyright 2020-2022 The cc65 Authors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be signedly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* + Tests that signed bit-fields are indeed signed; see issues below + - unsigned integer types by default: https://github.com/cc65/cc65/issues/1095 + - char bit-field support: https://github.com/cc65/cc65/issues/1047 + - long bit-field support: https://github.com/cc65/cc65/issues/1131 +*/ + +#include + +static unsigned char failures = 0; + +static struct signed_ints { + signed int x : 4; + signed int y : 10; +} pi = {-8, -500}; + +static void test_signed_int_bitfields (void) +{ + if (pi.x != -8) { + printf ("Got pi.x = %ld, expected -8.\n", (long)pi.x); + failures++; + } + if (pi.y != -500) { + printf ("Got pi.y = %ld, expected -500.\n", (long)pi.y); + failures++; + } + + pi.x = -3; + pi.y = -512; + + if (pi.x != -3) { + printf ("Got pi.x = %ld, expected -3.\n", (long)pi.x); + failures++; + } + if (pi.y != -512) { + printf ("Got pi.y = %ld, expected -512.\n", (long)pi.y); + failures++; + } +} + +static struct signed_shorts { + signed short x : 4; + signed short y : 10; +} ps = {-8, -500}; + +static void test_signed_short_bitfields (void) +{ + if (ps.x != -8) { + printf ("Got ps.x = %ld, expected -8.\n", (long)ps.x); + failures++; + } + if (ps.y != -500) { + printf ("Got ps.y = %ld, expected -500.\n", (long)ps.y); + failures++; + } + + ps.x = -3; + ps.y = -512; + + if (ps.x != -3) { + printf ("Got ps.x = %ld, expected -3.\n", (long)ps.x); + failures++; + } + if (ps.y != -512) { + printf ("Got ps.y = %ld, expected -512.\n", (long)ps.y); + failures++; + } +} + +static struct signed_chars { + signed char x : 4; +} pc = {-8}; + +static void test_signed_char_bitfields (void) +{ + if (pc.x != -8) { + printf ("Got pc.x = %ld, expected -8.\n", (long)pc.x); + failures++; + } + + pc.x = -3; + + if (pc.x != -3) { + printf ("Got pc.x = %ld, expected -3.\n", (long)pc.x); + failures++; + } +} + +static struct signed_longs { + signed long x : 4; + signed long y : 10; + signed long z : 18; +} pl = {-8, -500, -70000}; + +static void test_signed_long_bitfields (void) +{ + if (pl.x != -8) { + if (pl.x < 0) { + printf ("Got pl.x = %ld, expected -8.\n", (long)pl.x); + } else { + printf ("Got pl.x = %lu, expected -8.\n", (unsigned long)pl.x); + } + failures++; + } + if (pl.y != -500) { + if (pl.y < 0) { + printf ("Got pl.y = %ld, expected -500.\n", (long)pl.y); + } else { + printf ("Got pl.y = %lu, expected -500.\n", (unsigned long)pl.y); + } + failures++; + } + if (pl.z != -70000) { + if (pl.z < 0) { + printf ("Got pl.z = %ld, expected -70000.\n", (long)pl.z); + } else { + printf ("Got pl.z = %lu, expected -70000.\n", (unsigned long)pl.z); + } + failures++; + } + + pl.x = -3; + pl.y = -512; + pl.z = -131072; + + if (pl.x != -3) { + if (pl.x < 0) { + printf ("Got pl.x = %ld, expected -3.\n", (long)pl.x); + } else { + printf ("Got pl.x = %lu, expected -3.\n", (unsigned long)pl.x); + } + failures++; + } + if (pl.y != -512) { + if (pl.y < 0) { + printf ("Got pl.y = %ld, expected -512.\n", (long)pl.y); + } else { + printf ("Got pl.y = %lu, expected -512.\n", (unsigned long)pl.y); + } + failures++; + } + if (pl.z != -131072) { + if (pl.z < 0) { + printf ("Got pl.z = %ld, expected -131072.\n", (long)pl.z); + } else { + printf ("Got pl.z = %lu, expected -131072.\n", (unsigned long)pl.z); + } + failures++; + } +} + +int main (void) +{ + test_signed_int_bitfields (); + test_signed_short_bitfields (); + test_signed_char_bitfields (); + test_signed_long_bitfields (); + printf ("failures: %u\n", failures); + return failures; +} diff --git a/test/val/plain-int-bitfield.c b/test/val/plain-int-bitfield.c deleted file mode 100644 index 4d158eca9..000000000 --- a/test/val/plain-int-bitfield.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright 2020 The cc65 Authors - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - Tests that plain int bit-fields are unsigned. -*/ - -#include - -static unsigned char failures = 0; - -static struct plain_ints { - int x : 4; - int y : 10; -} pi = {15, 700}; - -static void test_plain_int_bitfields (void) -{ - if (pi.x != 15) { - printf ("Got pi.x = %u, expected 15.\n", pi.x); - failures++; - } - if (pi.y != 700) { - printf ("Got pi.y = %u, expected 700.\n", pi.y); - failures++; - } - - pi.x = 3; - pi.y = 1023; - - if (pi.x != 3) { - printf ("Got pi.x = %u, expected 3.\n", pi.x); - failures++; - } - if (pi.y != 1023) { - printf ("Got pi.y = %u, expected 1023.\n", pi.y); - failures++; - } -} - -int main (void) -{ - test_plain_int_bitfields (); - printf ("failures: %u\n", failures); - return failures; -}