Compiler: Fix return omission with else-after-return.
Imported from SM: https://bugs.alliedmods.net/show_bug.cgi?id=4852.
This commit is contained in:
parent
9b5c6bfff0
commit
95f3b0d354
|
@ -370,6 +370,7 @@ typedef struct s_stringpair {
|
||||||
#define tLABEL 331
|
#define tLABEL 331
|
||||||
#define tSTRING 332
|
#define tSTRING 332
|
||||||
#define tEXPR 333 /* for assigment to "lastst" only */
|
#define tEXPR 333 /* for assigment to "lastst" only */
|
||||||
|
#define tEMPTYBLOCK 334 /* empty blocks for AM bug 4825 */
|
||||||
|
|
||||||
/* (reversed) evaluation of staging buffer */
|
/* (reversed) evaluation of staging buffer */
|
||||||
#define sSTARTREORDER 0x01
|
#define sSTARTREORDER 0x01
|
||||||
|
|
|
@ -113,7 +113,7 @@ static int doexpr(int comma,int chkeffect,int allowarray,int mark_endexpr,
|
||||||
static void doassert(void);
|
static void doassert(void);
|
||||||
static void doexit(void);
|
static void doexit(void);
|
||||||
static void test(int label,int parens,int invert);
|
static void test(int label,int parens,int invert);
|
||||||
static void doif(void);
|
static int doif(void);
|
||||||
static void dowhile(void);
|
static void dowhile(void);
|
||||||
static void dodo(void);
|
static void dodo(void);
|
||||||
static void dofor(void);
|
static void dofor(void);
|
||||||
|
@ -4572,16 +4572,19 @@ static void statement(int *lastindent,int allow_decl)
|
||||||
break;
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
tok=fline;
|
tok=fline;
|
||||||
if (!matchtoken('}')) /* {} is the empty statement */
|
if (!matchtoken('}')) { /* {} is the empty statement */
|
||||||
compound(tok==fline);
|
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;
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
error(36); /* empty statement */
|
error(36); /* empty statement */
|
||||||
break;
|
break;
|
||||||
case tIF:
|
case tIF:
|
||||||
doif();
|
lastst=doif();
|
||||||
lastst=tIF;
|
|
||||||
break;
|
break;
|
||||||
case tWHILE:
|
case tWHILE:
|
||||||
dowhile();
|
dowhile();
|
||||||
|
@ -4851,10 +4854,11 @@ static void test(int label,int parens,int invert)
|
||||||
} /* if */
|
} /* if */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doif(void)
|
static int doif(void)
|
||||||
{
|
{
|
||||||
int flab1,flab2;
|
int flab1,flab2;
|
||||||
int ifindent;
|
int ifindent;
|
||||||
|
int lastst_true;
|
||||||
|
|
||||||
ifindent=stmtindent; /* save the indent of the "if" instruction */
|
ifindent=stmtindent; /* save the indent of the "if" instruction */
|
||||||
flab1=getlabel(); /* get label number for false branch */
|
flab1=getlabel(); /* get label number for false branch */
|
||||||
|
@ -4863,6 +4867,7 @@ static void doif(void)
|
||||||
if (matchtoken(tELSE)==0){ /* if...else ? */
|
if (matchtoken(tELSE)==0){ /* if...else ? */
|
||||||
setlabel(flab1); /* no, simple if..., print false label */
|
setlabel(flab1); /* no, simple if..., print false label */
|
||||||
} else {
|
} else {
|
||||||
|
lastst_true=lastst;
|
||||||
/* to avoid the "dangling else" error, we want a warning if the "else"
|
/* to avoid the "dangling else" error, we want a warning if the "else"
|
||||||
* has a lower indent than the matching "if" */
|
* has a lower indent than the matching "if" */
|
||||||
if (stmtindent<ifindent && sc_tabsize>0)
|
if (stmtindent<ifindent && sc_tabsize>0)
|
||||||
|
@ -4873,7 +4878,14 @@ static void doif(void)
|
||||||
setlabel(flab1); /* print false label */
|
setlabel(flab1); /* print false label */
|
||||||
statement(NULL,FALSE); /* do "else" clause */
|
statement(NULL,FALSE); /* do "else" clause */
|
||||||
setlabel(flab2); /* print true label */
|
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 */
|
} /* endif */
|
||||||
|
return tIF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dowhile(void)
|
static void dowhile(void)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user