mirror of
https://github.com/cc65/cc65.git
synced 2025-02-22 12:29:12 +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:
commit
93b015660d
@ -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);
|
||||
|
5
test/err/bug1895-assign1a.c
Normal file
5
test/err/bug1895-assign1a.c
Normal 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"
|
5
test/err/bug1895-assign1b.c
Normal file
5
test/err/bug1895-assign1b.c
Normal 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"
|
5
test/err/bug1895-assign2a.c
Normal file
5
test/err/bug1895-assign2a.c
Normal 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"
|
5
test/err/bug1895-assign2b.c
Normal file
5
test/err/bug1895-assign2b.c
Normal 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"
|
5
test/err/bug1895-assign4a.c
Normal file
5
test/err/bug1895-assign4a.c
Normal 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"
|
5
test/err/bug1895-assign4b.c
Normal file
5
test/err/bug1895-assign4b.c
Normal 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"
|
5
test/err/bug1895-assign5a.c
Normal file
5
test/err/bug1895-assign5a.c
Normal 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"
|
5
test/err/bug1895-assign5b.c
Normal file
5
test/err/bug1895-assign5b.c
Normal 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
196
test/err/bug1895-common.h
Normal 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
5
test/err/bug1895-cond1.c
Normal 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
5
test/err/bug1895-cond2.c
Normal 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
5
test/err/bug1895-cond3.c
Normal 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
5
test/err/bug1895-cond4.c
Normal 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
5
test/err/bug1895-cond5.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_2_SUB_5
|
||||
|
||||
#include "bug1895-common.h"
|
5
test/err/bug1895-prototype1.c
Normal file
5
test/err/bug1895-prototype1.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_1
|
||||
|
||||
#include "bug1895-common.h"
|
5
test/err/bug1895-prototype2.c
Normal file
5
test/err/bug1895-prototype2.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_2
|
||||
|
||||
#include "bug1895-common.h"
|
5
test/err/bug1895-prototype3.c
Normal file
5
test/err/bug1895-prototype3.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_3
|
||||
|
||||
#include "bug1895-common.h"
|
5
test/err/bug1895-prototype4.c
Normal file
5
test/err/bug1895-prototype4.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_4
|
||||
|
||||
#include "bug1895-common.h"
|
5
test/err/bug1895-prototype5.c
Normal file
5
test/err/bug1895-prototype5.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Bug #1895 - missing diagnostics on incompatible pointer/array types */
|
||||
|
||||
#define DO_TEST_3_SUB_5
|
||||
|
||||
#include "bug1895-common.h"
|
Loading…
x
Reference in New Issue
Block a user