1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-24 11:31:31 +00:00

Improved checks on function return types.

This commit is contained in:
acqn 2023-09-13 22:26:41 +08:00
parent f381d23001
commit 8e62cbf092
2 changed files with 16 additions and 25 deletions

View File

@ -466,11 +466,15 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* Check return type */ /* Check return type */
ReturnType = F_GetReturnType (CurrentFunc); ReturnType = F_GetReturnType (CurrentFunc);
if (IsIncompleteESUType (ReturnType)) {
/* There are already diagnostics on returning arrays or functions */
if (!IsTypeArray (ReturnType) && !IsTypeFunc (ReturnType)) { if (!IsTypeArray (ReturnType) && !IsTypeFunc (ReturnType)) {
/* There are already diagnostics on returning arrays or functions */
if (IsIncompleteESUType (ReturnType)) {
Error ("Function has incomplete return type '%s'", Error ("Function has incomplete return type '%s'",
GetFullTypeName (ReturnType)); GetFullTypeName (ReturnType));
} else if (IsPassByRefType (ReturnType)) {
/* Handle struct/union specially */
Error ("Function return type '%s' of size %u is unsupported",
GetFullTypeName (ReturnType), SizeOf (ReturnType));
} }
} }

View File

@ -311,7 +311,6 @@ static void ReturnStatement (void)
/* Handle the 'return' statement */ /* Handle the 'return' statement */
{ {
ExprDesc Expr; ExprDesc Expr;
const Type* ReturnType;
ED_Init (&Expr); ED_Init (&Expr);
NextToken (); NextToken ();
@ -327,32 +326,20 @@ static void ReturnStatement (void)
if (F_HasVoidReturn (CurrentFunc)) { if (F_HasVoidReturn (CurrentFunc)) {
Error ("Returning a value in function with return type 'void'"); Error ("Returning a value in function with return type 'void'");
} else { } else {
/* Check the return type first */ /* Check the return type first */
ReturnType = F_GetReturnType (CurrentFunc); const Type* ReturnType = F_GetReturnType (CurrentFunc);
if (IsIncompleteESUType (ReturnType)) {
/* Avoid excess errors */
if (ErrorCount == 0) {
Error ("Returning a value in function with incomplete return type");
}
} else {
/* Convert the return value to the type of the function result */ /* Convert the return value to the type of the function result */
TypeConversion (&Expr, ReturnType); TypeConversion (&Expr, ReturnType);
/* Load the value into the primary */ /* Load the value into the primary */
if (IsClassStruct (Expr.Type)) { if (IsClassStruct (Expr.Type)) {
/* Handle struct/union specially */ /* Handle struct/union specially */
ReturnType = GetStructReplacementType (Expr.Type); LoadExpr (CG_TypeOf (GetStructReplacementType (ReturnType)), &Expr);
if (ReturnType == Expr.Type) {
Error ("Returning '%s' of this size by value is not supported", GetFullTypeName (Expr.Type));
}
LoadExpr (CG_TypeOf (ReturnType), &Expr);
} else { } else {
/* Load the value into the primary */ /* Load the value into the primary */
LoadExpr (CF_NONE, &Expr); LoadExpr (CF_NONE, &Expr);
} }
}
/* Append deferred inc/dec at sequence point */ /* Append deferred inc/dec at sequence point */
DoDeferred (SQP_KEEP_EAX, &Expr); DoDeferred (SQP_KEEP_EAX, &Expr);