From 95f3b0d3540daab63ab9062cef14689e8cf96448 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Wed, 13 Aug 2014 18:43:32 +0200 Subject: [PATCH] Compiler: Fix return omission with else-after-return. Imported from SM: https://bugs.alliedmods.net/show_bug.cgi?id=4852. --- compiler/libpc300/sc.h | 1 + compiler/libpc300/sc1.c | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/compiler/libpc300/sc.h b/compiler/libpc300/sc.h index 012bcc6c..a0341786 100755 --- a/compiler/libpc300/sc.h +++ b/compiler/libpc300/sc.h @@ -370,6 +370,7 @@ typedef struct s_stringpair { #define tLABEL 331 #define tSTRING 332 #define tEXPR 333 /* for assigment to "lastst" only */ +#define tEMPTYBLOCK 334 /* empty blocks for AM bug 4825 */ /* (reversed) evaluation of staging buffer */ #define sSTARTREORDER 0x01 diff --git a/compiler/libpc300/sc1.c b/compiler/libpc300/sc1.c index 1cdcf643..28428190 100755 --- a/compiler/libpc300/sc1.c +++ b/compiler/libpc300/sc1.c @@ -113,7 +113,7 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr, static void doassert(void); static void doexit(void); static void test(int label,int parens,int invert); -static void doif(void); +static int doif(void); static void dowhile(void); static void dodo(void); static void dofor(void); @@ -4572,16 +4572,19 @@ static void statement(int *lastindent,int allow_decl) break; case '{': tok=fline; - if (!matchtoken('}')) /* {} is the empty statement */ + if (!matchtoken('}')) { /* {} is the empty statement */ compound(tok==fline); - /* lastst (for "last statement") does not change */ + } else { + lastst = tEMPTYBLOCK; + } + /* lastst (for "last statement") does not change + you're not my father, don't tell me what to do */ break; case ';': error(36); /* empty statement */ break; case tIF: - doif(); - lastst=tIF; + lastst=doif(); break; case tWHILE: dowhile(); @@ -4851,10 +4854,11 @@ static void test(int label,int parens,int invert) } /* if */ } -static void doif(void) +static int doif(void) { int flab1,flab2; int ifindent; + int lastst_true; ifindent=stmtindent; /* save the indent of the "if" instruction */ flab1=getlabel(); /* get label number for false branch */ @@ -4863,6 +4867,7 @@ static void doif(void) if (matchtoken(tELSE)==0){ /* if...else ? */ setlabel(flab1); /* no, simple if..., print false label */ } else { + lastst_true=lastst; /* to avoid the "dangling else" error, we want a warning if the "else" * has a lower indent than the matching "if" */ if (stmtindent0) @@ -4873,7 +4878,14 @@ static void doif(void) setlabel(flab1); /* print false label */ statement(NULL,FALSE); /* do "else" clause */ setlabel(flab2); /* print true label */ + /* if both the "true" branch and the "false" branch ended with the same + * kind of statement, set the last statement id to that kind, rather than + * to the generic tIF; this allows for better "unreachable code" checking + */ + if (lastst == lastst_true) + return lastst; } /* endif */ + return tIF; } static void dowhile(void)