diff --git a/doc/cc65.sgml b/doc/cc65.sgml index 1476b40a3..683249bda 100644 --- a/doc/cc65.sgml +++ b/doc/cc65.sgml @@ -741,7 +741,7 @@ Here is a description of all the command line options: Warn about no return statement in function returning non-void. - Warn when passing structs by value. (Disabled by default.) + Warn when passing structs by value. Warn about #pragmas that aren't recognized by cc65. @@ -806,8 +806,9 @@ and the one defined by the ISO standard: The datatypes "float" and "double" are not available.

- C Functions may pass and return structs (or unions) by value, but only - of 1, 2 or 4 byte sizes. + C Functions may not return structs (or unions), and structs may not + be passed as parameters by value. However, struct assignment *is* + possible.

Most of the C library is available with only the fastcall calling convention (). It means diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index caa41a7a4..6907ee099 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -803,6 +803,7 @@ const Type* GetStructReplacementType (const Type* SType) switch (SizeOf (SType)) { case 1: NewType = type_uchar; break; case 2: NewType = type_uint; break; + case 3: /* FALLTHROUGH */ case 4: NewType = type_ulong; break; default: NewType = SType; break; } diff --git a/test/val/struct-by-value.c b/test/val/struct-by-value.c deleted file mode 100644 index 0e846c117..000000000 --- a/test/val/struct-by-value.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Test of passing and returning structs by value. - Structs of 1, 2 and 4 bytes are supported. - Note that structs of 3 bytes are disabled, see: - https://github.com/cc65/cc65/issues/2022 -*/ - -int fail = 0; - -struct s1 { char a; }; -struct s2 { char a, b; }; -struct s3 { char a, b, c; }; -struct s4 { char a, b, c, d; }; - -const struct s1 c1 = { 1 }; -const struct s2 c2 = { 2, 3 }; -const struct s3 c3 = { 4, 5, 6 }; -const struct s4 c4 = { 7, 8, 9, 10 }; - -struct s1 return1() { return c1; } -struct s2 return2() { return c2; } -/*struct s3 return3() { return c3; }*/ -struct s4 return4() { return c4; } - -int compare1(struct s1 a, struct s1 b) -{ - if (a.a != b.a) return 1; - return 0; -} - -int compare2(struct s2 a, struct s2 b) -{ - if (a.a != b.a) return 1; - if (a.b != b.b) return 1; - return 0; -} - -/*int compare3(struct s3 a, struct s3 b) -{ - if (a.a != b.a) return 1; - if (a.b != b.b) return 1; - if (a.c != b.c) return 1; - return 0; -}*/ - -int compare4(struct s4 a, struct s4 b) -{ - if (a.a != b.a) return 1; - if (a.b != b.b) return 1; - if (a.c != b.c) return 1; - if (a.d != b.d) return 1; - return 0; -} - -int pass1(struct s1 p1) -{ - struct s1 a1; - a1 = p1; - if (a1.a != c1.a) return 1; - return 0; -} - -int pass2(struct s2 p2) -{ - struct s2 a2; - a2 = p2; - if (a2.a != c2.a) return 1; - if (a2.b != c2.b) return 1; - return 0; -} - -/*int pass3(struct s3 p3) -{ - struct s3 a3; - a3 = p3; - if (a3.a != c3.a) return 1; - if (a3.b != c3.b) return 1; - if (a3.c != c3.c) return 1; - return 0; -}*/ - -int pass4(struct s4 p4) -{ - struct s4 a4; - a4 = p4; - if (a4.a != c4.a) return 1; - if (a4.b != c4.b) return 1; - if (a4.c != c4.c) return 1; - if (a4.d != c4.d) return 1; - return 0; -} - -void reset(char* gg) -{ - char i; - for (i=0;i<5;++i) gg[i] = 128+i; -} - -int test(char* gg, char start) -{ - char i; - for (i=start;i<5;++i) - if (gg[i] != 128+i) return 1; - return 0; -} - -int main() -{ - /* Used to check #2022 bug condition of extra bytes being overwritten. */ - union - { - char gg[5]; - struct s1 g1; - struct s2 g2; - struct s3 g3; - struct s4 g4; - } guard; - - reset(guard.gg); - guard.g1 = return1(); - fail += compare1(guard.g1,c1); - fail += test(guard.gg,1); - - reset(guard.gg); - guard.g2 = return2(); - fail += compare2(guard.g2,c2); - fail += test(guard.gg,2); - - /*reset(guard.gg); - guard.g3 = return3(); - fail += compare3(guard.g3,c3); - fail += test(guard.gg,3);*/ - - reset(guard.gg); - guard.g4 = return4(); - fail += compare4(guard.g4,c4); - fail += test(guard.gg,4); - - fail += pass1(c1); - fail += pass2(c2); - /*fail += pass3(c3);*/ - fail += pass4(c4); - - return fail; -}