1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-30 08:57:49 +00:00

Made cc65 properly test variadic-function pointer assignments.

Improved some error messages.
This commit is contained in:
Greg King 2015-05-24 08:32:15 -04:00
parent 0bb3bafb3e
commit e72132c8ae
2 changed files with 13 additions and 16 deletions

View File

@ -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;

View File

@ -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;
}