1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-12 17:30:50 +00:00

Add a warning if a function returning something does not contain a return

statement.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4095 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-08-31 13:18:49 +00:00
parent 1ea503a036
commit 0a9c7484ad
3 changed files with 45 additions and 29 deletions

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 2000-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -71,6 +71,7 @@ struct Function {
unsigned RetLab; /* Return code label */
int TopLevelSP; /* SP at function top level */
unsigned RegOffs; /* Register variable space offset */
int HasRetStmt; /* Function has a return statement */
};
/* Pointer to current function */
@ -79,7 +80,7 @@ Function* CurrentFunc = 0;
/*****************************************************************************/
/* Subroutines working with struct Function */
/* Subroutines working with struct Function */
/*****************************************************************************/
@ -98,6 +99,7 @@ static Function* NewFunction (struct SymEntry* Sym)
F->RetLab = GetLocalLabel ();
F->TopLevelSP = 0;
F->RegOffs = RegisterSpace;
F->HasRetStmt = 0;
/* Return the new structure */
return F;
@ -153,6 +155,14 @@ int F_HasVoidReturn (const Function* F)
void F_HasReturn (Function* F)
/* Mark the function as having a return statement */
{
F->HasRetStmt = 1;
}
int F_IsVariadic (const Function* F)
/* Return true if this is a variadic function */
{
@ -335,7 +345,6 @@ static void F_RestoreRegVars (Function* F)
void NewFunc (SymEntry* Func)
/* Parse argument declarations and function body. */
{
int HadReturn;
SymEntry* Param;
/* Get the function descriptor from the function entry */
@ -467,13 +476,15 @@ void NewFunc (SymEntry* Func)
CurrentFunc->TopLevelSP = StackPtr;
/* Now process statements in this block */
HadReturn = 0;
while (CurTok.Tok != TOK_RCURLY) {
if (CurTok.Tok != TOK_CEOF) {
HadReturn = Statement (0);
} else {
break;
}
while (CurTok.Tok != TOK_RCURLY && CurTok.Tok != TOK_CEOF) {
Statement (0);
}
/* If this is not a void function, output a warning if we didn't see a
* return statement.
*/
if (!F_HasVoidReturn (CurrentFunc) && !CurrentFunc->HasRetStmt) {
Warning ("Control reaches end of non-void function");
}
/* Output the function exit code label */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 1998-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -73,6 +73,9 @@ Type* F_GetReturnType (Function* F);
int F_HasVoidReturn (const Function* F);
/* Return true if the function does not have a return value */
void F_HasReturn (Function* F);
/* Mark the function as having a return statement */
int F_IsVariadic (const Function* F);
/* Return true if this is a variadic function */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 1998-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -292,17 +292,16 @@ static void ReturnStatement (void)
NextToken ();
if (CurTok.Tok != TOK_SEMI) {
/* Check if the function has a return value declared */
if (F_HasVoidReturn (CurrentFunc)) {
Error ("Returning a value in function with return type void");
}
/* Evaluate the return expression */
hie0 (&Expr);
/* Ignore the return expression if the function returns void */
if (!F_HasVoidReturn (CurrentFunc)) {
/* If we return something in a void function, print an error and
* ignore the value. Otherwise convert the value to the type of the
* return.
*/
if (F_HasVoidReturn (CurrentFunc)) {
Error ("Returning a value in function with return type void");
} else {
/* Convert the return value to the type of the function result */
TypeConversion (&Expr, F_GetReturnType (CurrentFunc));
@ -314,6 +313,9 @@ static void ReturnStatement (void)
Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc));
}
/* Mark the function as having a return statement */
F_HasReturn (CurrentFunc);
/* Cleanup the stack in case we're inside a block with locals */
g_space (StackPtr - F_GetTopLevelSP (CurrentFunc));