1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 07:29:33 +00:00

Merge pull request #1899 from acqn/TypeCmpFix

[cc65] Fixed compatibility checks on "pointer to pointer" vs "pointer to array" etc.
This commit is contained in:
Bob Andrews 2022-11-18 19:04:35 +01:00 committed by GitHub
commit 93b015660d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 301 additions and 12 deletions

View File

@ -266,18 +266,6 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
LeftType = (GetUnderlyingTypeCode (lhs) & T_MASK_TYPE);
RightType = (GetUnderlyingTypeCode (rhs) & T_MASK_TYPE);
/* If one side is a pointer and the other side is an array, both are
** compatible.
*/
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
RightType = T_TYPE_PTR;
SetResult (Result, TC_PTR_DECAY);
}
if (LeftType == T_TYPE_ARRAY && RightType == T_TYPE_PTR) {
LeftType = T_TYPE_PTR;
SetResult (Result, TC_STRICT_COMPATIBLE);
}
/* Bit-fields are considered compatible if they have the same
** signedness, bit-offset and bit-width.
*/
@ -287,12 +275,27 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
lhs->A.B.Offs != rhs->A.B.Offs ||
lhs->A.B.Width != rhs->A.B.Width) {
SetResult (Result, TC_INCOMPATIBLE);
return;
}
if (LeftType != RightType) {
SetResult (Result, TC_STRICT_COMPATIBLE);
}
}
/* If one side is a pointer and the other side is an array, both are
** compatible.
*/
if (Result->Indirections == 0) {
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
RightType = T_TYPE_PTR;
SetResult (Result, TC_PTR_DECAY);
}
if (LeftType == T_TYPE_ARRAY && RightType == T_TYPE_PTR) {
LeftType = T_TYPE_PTR;
SetResult (Result, TC_STRICT_COMPATIBLE);
}
}
/* If the underlying types are not identical, the types are incompatible */
if (LeftType != RightType) {
SetResult (Result, TC_INCOMPATIBLE);

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_1_A
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_1_B
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_2_A
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_2_B
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_4_A
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_4_B
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_5_A
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_1_SUB_5_B
#include "bug1895-common.h"

196
test/err/bug1895-common.h Normal file
View File

@ -0,0 +1,196 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types
Test of incompatible pointer/array types in assignment ans conditional
expressions, as well as function prototypes.
In each source file, define a single macro and include this file to perform
a coresponding test individually.
https://github.com/cc65/cc65/issues/1895
*/
/* Test 1 suite */
#ifdef DO_TEST_1_SUB_1_A
#define TEST_1_SUB_1_A CMP_TYPES_1
#else
#define TEST_1_SUB_1_A BLANK
#endif
#ifdef DO_TEST_1_SUB_1_B
#define TEST_1_SUB_1_B CMP_TYPES_1
#else
#define TEST_1_SUB_1_B BLANK
#endif
#ifdef DO_TEST_1_SUB_2_A
#define TEST_1_SUB_2_A CMP_TYPES_1
#else
#define TEST_1_SUB_2_A BLANK
#endif
#ifdef DO_TEST_1_SUB_2_B
#define TEST_1_SUB_2_B CMP_TYPES_1
#else
#define TEST_1_SUB_2_B BLANK
#endif
#ifdef DO_TEST_1_SUB_4_A
#define TEST_1_SUB_4_A CMP_TYPES_1
#else
#define TEST_1_SUB_4_A BLANK
#endif
#ifdef DO_TEST_1_SUB_4_B
#define TEST_1_SUB_4_B CMP_TYPES_1
#else
#define TEST_1_SUB_4_B BLANK
#endif
#ifdef DO_TEST_1_SUB_5_A
#define TEST_1_SUB_5_A CMP_TYPES_1
#else
#define TEST_1_SUB_5_A BLANK
#endif
#ifdef DO_TEST_1_SUB_5_B
#define TEST_1_SUB_5_B CMP_TYPES_1
#else
#define TEST_1_SUB_5_B BLANK
#endif
/* Test 2 suite */
#ifdef DO_TEST_2_SUB_1
#define TEST_2_SUB_1 CMP_TYPES_2
#else
#define TEST_2_SUB_1 BLANK
#endif
#ifdef DO_TEST_2_SUB_2
#define TEST_2_SUB_2 CMP_TYPES_2
#else
#define TEST_2_SUB_2 BLANK
#endif
#ifdef DO_TEST_2_SUB_3
#define TEST_2_SUB_3 CMP_TYPES_2
#else
#define TEST_2_SUB_3 BLANK
#endif
#ifdef DO_TEST_2_SUB_4
#define TEST_2_SUB_4 CMP_TYPES_2
#else
#define TEST_2_SUB_4 BLANK
#endif
#ifdef DO_TEST_2_SUB_5
#define TEST_2_SUB_5 CMP_TYPES_2
#else
#define TEST_2_SUB_5 BLANK
#endif
/* Test 3 suite */
#ifdef DO_TEST_3_SUB_1
#define TEST_3_SUB_1 CMP_TYPES_3
#else
#define TEST_3_SUB_1 BLANK
#endif
#ifdef DO_TEST_3_SUB_2
#define TEST_3_SUB_2 CMP_TYPES_3
#else
#define TEST_3_SUB_2 BLANK
#endif
#ifdef DO_TEST_3_SUB_3
#define TEST_3_SUB_3 CMP_TYPES_3
#else
#define TEST_3_SUB_3 BLANK
#endif
#ifdef DO_TEST_3_SUB_4
#define TEST_3_SUB_4 CMP_TYPES_3
#else
#define TEST_3_SUB_4 BLANK
#endif
#ifdef DO_TEST_3_SUB_5
#define TEST_3_SUB_5 CMP_TYPES_3
#else
#define TEST_3_SUB_5 BLANK
#endif
/* Implementation */
#define CONCAT(a, b) CONCAT_impl_(a, b)
#define CONCAT_impl_(a, b) a##b
#define BLANK(...)
#define DECL_FUNCS(A, B)\
void CONCAT(foo_,__LINE__)(A); void CONCAT(foo_,__LINE__)(B);
/* Test with assignment */
#define CMP_TYPES_1(A, B)\
do {\
A p; B q;\
_Pragma("warn(error, on)")\
p = q;\
_Pragma("warn(error, off)")\
} while (0)
/* Test with conditional expression */
#define CMP_TYPES_2(A, B)\
do {\
A p; B q;\
_Pragma("warn(error, on)")\
v = v ? p : q;\
_Pragma("warn(error, off)")\
} while (0)
/* Test with function prototype */
#define CMP_TYPES_3(A, B)\
do {\
DECL_FUNCS(A,B);\
} while (0)
static void *v;
typedef int (*p1)[3]; /* pointer to array */
typedef int **q1; /* pointer to pointer */
typedef int (**p2)[3]; /* pointer to pointer to array */
typedef int ***q2; /* pointer to pointer to pointer */
typedef int p3[1][3]; /* array of array */
typedef int *q3[1]; /* array of pointer */
typedef int const **p4; /* pointer to pointer to const */
typedef int **q4; /* pointer to pointer to non-const */
typedef int (*p5)(int (*)(p3)); /* pointer to function taking pointer to function taking pointer to array */
typedef int (*q5)(int (*)(q3)); /* pointer to function taking pointer to function taking pointer to pointer */
int main(void)
{
/* Warnings */
TEST_1_SUB_1_A(p1, q1);
TEST_1_SUB_1_B(q1, p1);
TEST_1_SUB_2_A(p2, q2);
TEST_1_SUB_2_B(q2, p2);
/* TEST_1_SUB_3_A(p3, q3); */
/* TEST_1_SUB_3_B(q3, p3); */
TEST_1_SUB_4_A(p4, q4);
TEST_1_SUB_4_B(q4, p4);
TEST_1_SUB_5_A(p5, q5);
TEST_1_SUB_5_B(q5, p5);
/* GCC and clang give warnings while cc65 gives errors */
TEST_2_SUB_1(p1, q1);
TEST_2_SUB_2(p2, q2);
TEST_2_SUB_3(p3, q3);
TEST_2_SUB_4(p4, q4);
TEST_2_SUB_5(p5, q5);
/* Errors */
TEST_3_SUB_1(p1, q1);
TEST_3_SUB_2(p2, q2);
TEST_3_SUB_3(p3, q3);
TEST_3_SUB_4(p4, q4);
TEST_3_SUB_5(p5, q5);
return 0;
}

5
test/err/bug1895-cond1.c Normal file
View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_2_SUB_1
#include "bug1895-common.h"

5
test/err/bug1895-cond2.c Normal file
View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_2_SUB_2
#include "bug1895-common.h"

5
test/err/bug1895-cond3.c Normal file
View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_2_SUB_3
#include "bug1895-common.h"

5
test/err/bug1895-cond4.c Normal file
View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_2_SUB_4
#include "bug1895-common.h"

5
test/err/bug1895-cond5.c Normal file
View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_2_SUB_5
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_3_SUB_1
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_3_SUB_2
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_3_SUB_3
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_3_SUB_4
#include "bug1895-common.h"

View File

@ -0,0 +1,5 @@
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
#define DO_TEST_3_SUB_5
#include "bug1895-common.h"