Made cc65 properly test variadic-function pointer assignments.
Improved some error messages.
This commit is contained in:
@@ -335,26 +335,23 @@ static void FixQualifiers (Type* DataType)
|
|||||||
T = DataType;
|
T = DataType;
|
||||||
while (T->C != T_END) {
|
while (T->C != T_END) {
|
||||||
if (IsTypePtr (T)) {
|
if (IsTypePtr (T)) {
|
||||||
|
|
||||||
/* Calling convention qualifier on the pointer? */
|
/* Calling convention qualifier on the pointer? */
|
||||||
if (IsQualCConv (T)) {
|
if (IsQualCConv (T)) {
|
||||||
/* Pull the convention off of the pointer */
|
/* Pull the convention off of the pointer */
|
||||||
Q = T[0].C & T_QUAL_CCONV;
|
Q = T[0].C & T_QUAL_CCONV;
|
||||||
T[0].C &= ~T_QUAL_CCONV;
|
T[0].C &= ~T_QUAL_CCONV;
|
||||||
|
|
||||||
/* Pointer to a function which doesn't have an explicit convention? */
|
/* Pointer to a function which doesn't have an explicit convention? */
|
||||||
if (IsTypeFunc (T + 1)) {
|
if (IsTypeFunc (T + 1)) {
|
||||||
if (IsQualCConv (T + 1)) {
|
if (IsQualCConv (T + 1)) {
|
||||||
if (T[1].C == Q) {
|
if ((T[1].C & T_QUAL_CCONV) == Q) {
|
||||||
/* TODO: The end of Declarator() catches this error.
|
|
||||||
** Try to make it let the error be caught here, instead.
|
|
||||||
*/
|
|
||||||
Warning ("Pointer duplicates function's calling convention");
|
Warning ("Pointer duplicates function's calling convention");
|
||||||
} else {
|
} else {
|
||||||
Error ("Mismatch between pointer's and function's calling conventions");
|
Error ("Function's and pointer's calling conventions are different");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) {
|
if (Q == T_QUAL_FASTCALL && IsVariadicFunc (T + 1)) {
|
||||||
Error ("Variadic-function pointers cannot be `__fastcall__'");
|
Error ("Variadic-function pointers cannot be __fastcall__");
|
||||||
} else {
|
} else {
|
||||||
/* Move the qualifier from the pointer to the function. */
|
/* Move the qualifier from the pointer to the function. */
|
||||||
T[1].C |= Q;
|
T[1].C |= Q;
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
|
|||||||
if (LeftQual != RightQual) {
|
if (LeftQual != RightQual) {
|
||||||
/* On the first indirection level, different qualifiers mean
|
/* On the first indirection level, different qualifiers mean
|
||||||
** that the types still are compatible. On the second level,
|
** 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
|
** if a qualifier is dropped from a pointer. But, different calling
|
||||||
** conventions are incompatible. Starting from the next level,
|
** conventions are incompatible. Starting from the next level,
|
||||||
** the types are incompatible if the qualifiers differ.
|
** 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);
|
SetResult (Result, TC_STRICT_COMPATIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LeftType != T_TYPE_FUNC) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* If a calling convention wasn't set explicitly,
|
/* If a calling convention wasn't set explicitly,
|
||||||
** then assume the default one.
|
** then assume the default one.
|
||||||
*/
|
*/
|
||||||
LeftQual &= T_QUAL_CCONV;
|
LeftQual &= T_QUAL_CCONV;
|
||||||
if (LeftQual == 0) {
|
if (LeftQual == T_QUAL_NONE) {
|
||||||
LeftQual = AutoCDecl ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
LeftQual = (AutoCDecl || IsVariadicFunc (lhs)) ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
||||||
}
|
}
|
||||||
RightQual &= T_QUAL_CCONV;
|
RightQual &= T_QUAL_CCONV;
|
||||||
if (RightQual == 0) {
|
if (RightQual == T_QUAL_NONE) {
|
||||||
RightQual = AutoCDecl ? T_QUAL_CDECL : T_QUAL_FASTCALL;
|
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) {
|
if (LeftQual == RightQual) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user