Merge pull request #2499 from kugelfuhr/kugelfuhr/disable-recursive-calls-to-main
Disallow recursive calls to main() in cc65 mode
This commit is contained in:
@@ -507,13 +507,13 @@ void g_enter (unsigned flags, unsigned argsize)
|
||||
|
||||
|
||||
|
||||
void g_leave (int IsMainFunc)
|
||||
void g_leave (int DoCleanup)
|
||||
/* Function epilogue */
|
||||
{
|
||||
/* In the main function nothing has to be dropped because the program
|
||||
** is terminated anyway.
|
||||
/* In the main function in cc65 mode nothing has to be dropped because
|
||||
** the program is terminated anyway.
|
||||
*/
|
||||
if (!IsMainFunc) {
|
||||
if (DoCleanup) {
|
||||
/* How many bytes of locals do we have to drop? */
|
||||
unsigned ToDrop = (unsigned) -StackPtr;
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ void g_scale (unsigned flags, long val);
|
||||
void g_enter (unsigned flags, unsigned argsize);
|
||||
/* Function prologue */
|
||||
|
||||
void g_leave (int IsMainFunc);
|
||||
void g_leave (int DoCleanup);
|
||||
/* Function epilogue */
|
||||
|
||||
|
||||
|
||||
@@ -1219,9 +1219,6 @@ static void Primary (ExprDesc* E)
|
||||
/* Is the symbol known? */
|
||||
if (Sym) {
|
||||
|
||||
/* We found the symbol - skip the name token */
|
||||
NextToken ();
|
||||
|
||||
/* Check for illegal symbol types */
|
||||
CHECK ((Sym->Flags & SC_TYPEMASK) != SC_LABEL);
|
||||
if ((Sym->Flags & SC_TYPEMASK) == SC_TYPEDEF) {
|
||||
@@ -1230,9 +1227,14 @@ static void Primary (ExprDesc* E)
|
||||
/* Assume an int type to make E valid */
|
||||
E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
|
||||
E->Type = type_int;
|
||||
/* Skip the erroneous token */
|
||||
NextToken ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Skip the name token */
|
||||
NextToken ();
|
||||
|
||||
/* Mark the symbol as referenced */
|
||||
Sym->Flags |= SC_REF;
|
||||
|
||||
@@ -1286,7 +1288,23 @@ static void Primary (ExprDesc* E)
|
||||
** rvalue, too, because we cannot store anything in a function.
|
||||
** So fix the flags depending on the type.
|
||||
*/
|
||||
if (IsTypeArray (E->Type) || IsTypeFunc (E->Type)) {
|
||||
if (IsTypeArray (E->Type)) {
|
||||
ED_AddrExpr (E);
|
||||
} else if (IsTypeFunc (E->Type)) {
|
||||
/* In cc65 mode we cannot call or take the address of
|
||||
** main().
|
||||
*/
|
||||
if (IS_Get (&Standard) == STD_CC65 &&
|
||||
strcmp (Sym->Name, "main") == 0) {
|
||||
/* Adjust the error message depending on a call or an
|
||||
** address operation.
|
||||
*/
|
||||
if (CurTok.Tok == TOK_LPAREN) {
|
||||
Error ("'main' must not be called recursively");
|
||||
} else {
|
||||
Error ("The address of 'main' cannot be taken");
|
||||
}
|
||||
}
|
||||
ED_AddrExpr (E);
|
||||
}
|
||||
|
||||
|
||||
@@ -646,13 +646,17 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
|
||||
/* Output the function exit code label */
|
||||
g_defcodelabel (F_GetRetLab (CurrentFunc));
|
||||
|
||||
/* Restore the register variables (not necessary for main function) */
|
||||
if (!F_IsMainFunc (CurrentFunc)) {
|
||||
/* Restore the register variables (not necessary for the main function in
|
||||
** cc65 mode)
|
||||
*/
|
||||
int CleanupOnExit = (IS_Get (&Standard) != STD_CC65) ||
|
||||
!F_IsMainFunc (CurrentFunc);
|
||||
if (CleanupOnExit) {
|
||||
F_RestoreRegVars (CurrentFunc);
|
||||
}
|
||||
|
||||
/* Generate the exit code */
|
||||
g_leave (F_IsMainFunc (CurrentFunc));
|
||||
g_leave (CleanupOnExit);
|
||||
|
||||
/* Emit references to imports/exports */
|
||||
EmitExternals ();
|
||||
|
||||
@@ -111,6 +111,13 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg)
|
||||
/* Get the size of the variable */
|
||||
unsigned Size = SizeOf (Decl->Type);
|
||||
|
||||
/* Check if this is the main function and we are in cc65 mode. If so, we
|
||||
** won't save the old contents of the register variables since in cc65
|
||||
** mode main() may not be called recursively.
|
||||
*/
|
||||
int SaveRegVars = (IS_Get (&Standard) != STD_CC65) ||
|
||||
!F_IsMainFunc (CurrentFunc);
|
||||
|
||||
/* Check for an optional initialization */
|
||||
if (CurTok.Tok == TOK_ASSIGN) {
|
||||
|
||||
@@ -126,13 +133,13 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg)
|
||||
/* Save the current contents of the register variable on stack. This is
|
||||
** not necessary for the main function.
|
||||
*/
|
||||
if (!F_IsMainFunc (CurrentFunc)) {
|
||||
if (SaveRegVars) {
|
||||
g_save_regvars (Reg, Size);
|
||||
}
|
||||
|
||||
/* Add the symbol to the symbol table. We do that now, because for
|
||||
** register variables the current stack pointer is implicitly used
|
||||
** as location for the save area (unused in case of main()).
|
||||
** as location for the save area (maybe unused in case of main()).
|
||||
*/
|
||||
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg);
|
||||
|
||||
@@ -187,14 +194,14 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg)
|
||||
/* Save the current contents of the register variable on stack. This is
|
||||
** not necessary for the main function.
|
||||
*/
|
||||
if (!F_IsMainFunc (CurrentFunc)) {
|
||||
if (SaveRegVars) {
|
||||
F_AllocLocalSpace (CurrentFunc);
|
||||
g_save_regvars (Reg, Size);
|
||||
}
|
||||
|
||||
/* Add the symbol to the symbol table. We do that now, because for
|
||||
** register variables the current stack pointer is implicitly used
|
||||
** as location for the save area (unused in case of main()).
|
||||
** as location for the save area (maybe unused in case of main()).
|
||||
*/
|
||||
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user