/* */
/* */
/* */
-/* (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 */
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 */
/*****************************************************************************/
-/* Subroutines working with struct Function */
+/* Subroutines working with struct Function */
/*****************************************************************************/
F->RetLab = GetLocalLabel ();
F->TopLevelSP = 0;
F->RegOffs = RegisterSpace;
+ F->HasRetStmt = 0;
/* Return the new structure */
return 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 */
{
void NewFunc (SymEntry* Func)
/* Parse argument declarations and function body. */
{
- int HadReturn;
SymEntry* Param;
/* Get the function descriptor from the function entry */
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 */
/* */
/* */
/* */
-/* (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 */
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 */
/* */
/* */
/* */
-/* (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 */
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));
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));