mirror of
https://github.com/cc65/cc65.git
synced 2024-12-30 20:29:25 +00:00
Made cc65 catch an assignment of a function pointer to a pointer with a different calling convention.
This commit is contained in:
parent
b24c87e61f
commit
0bb3bafb3e
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* (C) 1998-2015, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
@ -37,6 +37,7 @@
|
||||
|
||||
/* cc65 */
|
||||
#include "funcdesc.h"
|
||||
#include "global.h"
|
||||
#include "symtab.h"
|
||||
#include "typecmp.h"
|
||||
|
||||
@ -247,21 +248,21 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
||||
}
|
||||
if (LeftQual != RightQual) {
|
||||
/* On the first indirection level, different qualifiers mean
|
||||
** that the types are still compatible. On the second level,
|
||||
** this is a (maybe minor) error, so we create a special
|
||||
** return code, since a qualifier is dropped from a pointer.
|
||||
** Starting from the next level, the types are incompatible
|
||||
** if the qualifiers differ.
|
||||
** that the types still are compatible. On the second level,
|
||||
** that is a (maybe minor) error. We create a special return code
|
||||
** if a qualifier is dropped from a pointer. But, different calling
|
||||
** conventions are incompatible. Starting from the next level,
|
||||
** the types are incompatible if the qualifiers differ.
|
||||
*/
|
||||
/* (Debugging statement) */
|
||||
/* printf ("Ind = %d %06X != %06X\n", Indirections, LeftQual, RightQual); */
|
||||
switch (Indirections) {
|
||||
|
||||
case 0:
|
||||
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* A non const value on the right is compatible to a
|
||||
/* A non-const value on the right is compatible to a
|
||||
** const one to the left, same for volatile.
|
||||
*/
|
||||
if ((LeftQual & T_QUAL_CONST) < (RightQual & T_QUAL_CONST) ||
|
||||
@ -270,7 +271,27 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
||||
} else {
|
||||
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||
}
|
||||
break;
|
||||
|
||||
/* If a calling convention wasn't set explicitly,
|
||||
** then assume the default one.
|
||||
*/
|
||||
LeftQual &= T_QUAL_CCONV;
|
||||
if (LeftQual == 0) {
|
||||
LeftQual = AutoCDecl ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
||||
}
|
||||
RightQual &= T_QUAL_CCONV;
|
||||
if (RightQual == 0) {
|
||||
RightQual = AutoCDecl ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
||||
}
|
||||
|
||||
/* (If the objects actually aren't pointers to functions,
|
||||
** then this test will pass anyway; and, more appropriate
|
||||
** tests will be performed.)
|
||||
*/
|
||||
if (LeftQual == RightQual) {
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
|
||||
default:
|
||||
SetResult (Result, TC_INCOMPATIBLE);
|
||||
@ -280,7 +301,6 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
||||
|
||||
/* Check for special type elements */
|
||||
switch (LeftType) {
|
||||
|
||||
case T_TYPE_PTR:
|
||||
++Indirections;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user