From: uz Date: Mon, 31 Aug 2009 13:18:49 +0000 (+0000) Subject: Add a warning if a function returning something does not contain a return X-Git-Tag: V2.13.0rc1~161 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;ds=sidebyside;h=0a9c7484ad7299f2189e42f6e300f6cd3ab4c334;p=cc65 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 --- diff --git a/src/cc65/function.c b/src/cc65/function.c index b8f1cb753..7e2e9145f 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -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 */ diff --git a/src/cc65/function.h b/src/cc65/function.h index d56d30757..d827cba6a 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -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 */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index ef150fad5..b9b258aa0 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -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));