From e72132c8ae54c543a0ede95fe486d6f4cbf33bfc Mon Sep 17 00:00:00 2001 From: Greg King Date: Sun, 24 May 2015 08:32:15 -0400 Subject: [PATCH] Made cc65 properly test variadic-function pointer assignments. Improved some error messages. --- src/cc65/declare.c | 11 ++++------- src/cc65/typecmp.c | 18 +++++++++--------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 4fab3ea0a..060a6756d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -335,26 +335,23 @@ static void FixQualifiers (Type* DataType) T = DataType; while (T->C != T_END) { if (IsTypePtr (T)) { - /* Calling convention qualifier on the pointer? */ if (IsQualCConv (T)) { /* Pull the convention off of the pointer */ Q = T[0].C & T_QUAL_CCONV; T[0].C &= ~T_QUAL_CCONV; + /* Pointer to a function which doesn't have an explicit convention? */ if (IsTypeFunc (T + 1)) { if (IsQualCConv (T + 1)) { - if (T[1].C == Q) { - /* TODO: The end of Declarator() catches this error. - ** Try to make it let the error be caught here, instead. - */ + if ((T[1].C & T_QUAL_CCONV) == Q) { Warning ("Pointer duplicates function's calling convention"); } else { - Error ("Mismatch between pointer's and function's calling conventions"); + Error ("Function's and pointer's calling conventions are different"); } } else { if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) { - Error ("Variadic-function pointers cannot be `__fastcall__'"); + Error ("Variadic-function pointers cannot be __fastcall__"); } else { /* Move the qualifier from the pointer to the function. */ T[1].C |= Q; diff --git a/src/cc65/typecmp.c b/src/cc65/typecmp.c index b01cd3f51..8025f4efe 100644 --- a/src/cc65/typecmp.c +++ b/src/cc65/typecmp.c @@ -249,7 +249,7 @@ 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 still are compatible. On the second level, - ** that is a (maybe minor) error. We create a special return code + ** 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. @@ -272,22 +272,22 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result) SetResult (Result, TC_STRICT_COMPATIBLE); } + if (LeftType != T_TYPE_FUNC) { + 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; + if (LeftQual == T_QUAL_NONE) { + LeftQual = (AutoCDecl || IsVariadicFunc (lhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL; } RightQual &= T_QUAL_CCONV; - if (RightQual == 0) { - RightQual = AutoCDecl ? T_QUAL_CDECL : T_QUAL_FASTCALL; + if (RightQual == T_QUAL_NONE) { + RightQual = (AutoCDecl || IsVariadicFunc (rhs)) ? 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; } -- 2.39.5