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:
parent
1ea503a036
commit
0a9c7484ad
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user