Fixed warnings on const comparison.

Warnings on expressions with no effects.
Fixed const ternary.
Fixed ternary with struct/union types as the true/false-branch expressions.
This commit is contained in:
acqn
2020-08-20 07:52:06 +08:00
parent b15ab348ba
commit 3ea3887c77
17 changed files with 399 additions and 132 deletions

View File

@@ -132,6 +132,8 @@ static void ParseByteArg (StrBuf* T, unsigned Arg)
ExprDesc Expr; ExprDesc Expr;
char Buf [16]; char Buf [16];
ED_Init (&Expr);
/* We expect an argument separated by a comma */ /* We expect an argument separated by a comma */
ConsumeComma (); ConsumeComma ();
@@ -166,6 +168,8 @@ static void ParseWordArg (StrBuf* T, unsigned Arg)
ExprDesc Expr; ExprDesc Expr;
char Buf [16]; char Buf [16];
ED_Init (&Expr);
/* We expect an argument separated by a comma */ /* We expect an argument separated by a comma */
ConsumeComma (); ConsumeComma ();
@@ -200,6 +204,8 @@ static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused)))
ExprDesc Expr; ExprDesc Expr;
char Buf [16]; char Buf [16];
ED_Init (&Expr);
/* We expect an argument separated by a comma */ /* We expect an argument separated by a comma */
ConsumeComma (); ConsumeComma ();
@@ -309,6 +315,8 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused)))
ExprDesc Expr; ExprDesc Expr;
char Buf [64]; char Buf [64];
ED_Init (&Expr);
/* We expect an argument separated by a comma */ /* We expect an argument separated by a comma */
ConsumeComma (); ConsumeComma ();

View File

@@ -139,6 +139,7 @@ void Assignment (ExprDesc* Expr)
ExprDesc Expr2; ExprDesc Expr2;
Type* ltype = Expr->Type; Type* ltype = Expr->Type;
ED_Init (&Expr2);
/* We must have an lvalue for an assignment */ /* We must have an lvalue for an assignment */
if (ED_IsRVal (Expr)) { if (ED_IsRVal (Expr)) {

View File

@@ -591,6 +591,7 @@ static SymEntry* ParseEnumDecl (const char* Name)
if (CurTok.Tok == TOK_ASSIGN) { if (CurTok.Tok == TOK_ASSIGN) {
ExprDesc Expr; ExprDesc Expr;
ED_Init (&Expr);
NextToken (); NextToken ();
ConstAbsIntExpr (hie1, &Expr); ConstAbsIntExpr (hie1, &Expr);
EnumVal = Expr.IVal; EnumVal = Expr.IVal;
@@ -720,6 +721,7 @@ static int ParseFieldWidth (Declaration* Decl)
*/ */
{ {
ExprDesc Expr; ExprDesc Expr;
ED_Init (&Expr);
if (CurTok.Tok != TOK_COLON) { if (CurTok.Tok != TOK_COLON) {
/* No bit-field declaration */ /* No bit-field declaration */
@@ -1818,6 +1820,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
/* Read the size if it is given */ /* Read the size if it is given */
if (CurTok.Tok != TOK_RBRACK) { if (CurTok.Tok != TOK_RBRACK) {
ExprDesc Expr; ExprDesc Expr;
ED_Init (&Expr);
ConstAbsIntExpr (hie1, &Expr); ConstAbsIntExpr (hie1, &Expr);
if (Expr.IVal <= 0) { if (Expr.IVal <= 0) {
if (D->Ident[0] != '\0') { if (D->Ident[0] != '\0') {
@@ -2184,6 +2187,7 @@ static unsigned ParseScalarInit (Type* T)
/* Parse initializaton for scalar data types. Return the number of data bytes. */ /* Parse initializaton for scalar data types. Return the number of data bytes. */
{ {
ExprDesc ED; ExprDesc ED;
ED_Init (&ED);
/* Parse initialization */ /* Parse initialization */
ParseScalarInitInternal (T, &ED); ParseScalarInitInternal (T, &ED);
@@ -2205,6 +2209,8 @@ static unsigned ParsePointerInit (Type* T)
/* Expression */ /* Expression */
ExprDesc ED; ExprDesc ED;
ED_Init (&ED);
ConstExpr (hie1, &ED); ConstExpr (hie1, &ED);
TypeConversion (&ED, T); TypeConversion (&ED, T);
@@ -2420,6 +2426,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers)
** handling. ** handling.
*/ */
ExprDesc ED; ExprDesc ED;
ED_Init (&ED);
unsigned Val; unsigned Val;
unsigned Shift; unsigned Shift;
@@ -2541,7 +2548,6 @@ static unsigned ParseVoidInit (Type* T)
** Return the number of bytes initialized. ** Return the number of bytes initialized.
*/ */
{ {
ExprDesc Expr;
unsigned Size; unsigned Size;
/* Opening brace */ /* Opening brace */
@@ -2550,6 +2556,9 @@ static unsigned ParseVoidInit (Type* T)
/* Allow an arbitrary list of values */ /* Allow an arbitrary list of values */
Size = 0; Size = 0;
do { do {
ExprDesc Expr;
ED_Init (&Expr);
ConstExpr (hie1, &Expr); ConstExpr (hie1, &Expr);
switch (GetUnderlyingTypeCode (&Expr.Type[0])) { switch (GetUnderlyingTypeCode (&Expr.Type[0])) {

View File

@@ -311,13 +311,15 @@ void PushAddr (const ExprDesc* Expr)
static void WarnConstCompareResult (void) static void WarnConstCompareResult (const ExprDesc* Expr)
/* If the result of a comparison is constant, this is suspicious when not in /* If the result of a comparison is constant, this is suspicious when not in
** preprocessor mode. ** preprocessor mode.
*/ */
{ {
if (!Preprocessing && IS_Get (&WarnConstComparison) != 0) { if (!Preprocessing &&
Warning ("Result of comparison is constant"); !ED_NeedsConst (Expr) &&
IS_Get (&WarnConstComparison) != 0) {
Warning ("Result of comparison is always %s", Expr->IVal != 0 ? "true" : "false");
} }
} }
@@ -387,6 +389,7 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall)
unsigned Flags; unsigned Flags;
ExprDesc Expr; ExprDesc Expr;
ED_Init (&Expr);
/* Count arguments */ /* Count arguments */
++PushedCount; ++PushedCount;
@@ -727,23 +730,20 @@ static void Primary (ExprDesc* E)
{ {
SymEntry* Sym; SymEntry* Sym;
/* Initialize fields in the expression stucture */
ED_Init (E);
/* Character and integer constants. */ /* Character and integer constants. */
if (CurTok.Tok == TOK_ICONST || CurTok.Tok == TOK_CCONST) { if (CurTok.Tok == TOK_ICONST || CurTok.Tok == TOK_CCONST) {
E->IVal = CurTok.IVal; E->IVal = CurTok.IVal;
E->Flags = E_LOC_NONE | E_RTYPE_RVAL; E->Flags |= E_LOC_NONE | E_RTYPE_RVAL;
E->Type = CurTok.Type; E->Type = CurTok.Type;
NextToken (); NextToken ();
return; return;
} }
/* Floating point constant */ /* Floating point constant */
if (CurTok.Tok == TOK_FCONST) { if (CurTok.Tok == TOK_FCONST) {
E->FVal = CurTok.FVal; E->FVal = CurTok.FVal;
E->Flags = E_LOC_NONE | E_RTYPE_RVAL; E->Flags |= E_LOC_NONE | E_RTYPE_RVAL;
E->Type = CurTok.Type; E->Type = CurTok.Type;
NextToken (); NextToken ();
return; return;
} }
@@ -777,6 +777,8 @@ static void Primary (ExprDesc* E)
return; return;
} }
unsigned Flags = E->Flags & E_MASK_KEEP_MAKE;
switch (CurTok.Tok) { switch (CurTok.Tok) {
case TOK_BOOL_AND: case TOK_BOOL_AND:
@@ -812,8 +814,8 @@ static void Primary (ExprDesc* E)
/* Cannot use type symbols */ /* Cannot use type symbols */
Error ("Variable identifier expected"); Error ("Variable identifier expected");
/* Assume an int type to make E valid */ /* Assume an int type to make E valid */
E->Flags = E_LOC_STACK | E_RTYPE_LVAL; E->Flags |= E_LOC_STACK | E_RTYPE_LVAL;
E->Type = type_int; E->Type = type_int;
return; return;
} }
@@ -924,7 +926,7 @@ static void Primary (ExprDesc* E)
case TOK_ASM: case TOK_ASM:
/* ASM statement */ /* ASM statement */
AsmStatement (); AsmStatement ();
E->Flags = E_RTYPE_RVAL; E->Flags = E_RTYPE_RVAL | E_EVAL_MAYBE_UNUSED;
E->Type = type_void; E->Type = type_void;
break; break;
@@ -985,6 +987,8 @@ static void Primary (ExprDesc* E)
ED_MakeConstAbsInt (E, 1); ED_MakeConstAbsInt (E, 1);
break; break;
} }
E->Flags |= Flags;
} }
@@ -1000,6 +1004,8 @@ static void ArrayRef (ExprDesc* Expr)
Type* ElementType; Type* ElementType;
Type* tptr1; Type* tptr1;
ED_Init (&Subscript);
Subscript.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* Skip the bracket */ /* Skip the bracket */
NextToken (); NextToken ();
@@ -2029,7 +2035,6 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
int* UsedGen) int* UsedGen)
/* Helper function */ /* Helper function */
{ {
ExprDesc Expr2;
CodeMark Mark1; CodeMark Mark1;
CodeMark Mark2; CodeMark Mark2;
const GenDesc* Gen; const GenDesc* Gen;
@@ -2044,6 +2049,10 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
*UsedGen = 0; *UsedGen = 0;
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) { while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
ExprDesc Expr2;
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* Tell the caller that we handled it's ops */ /* Tell the caller that we handled it's ops */
*UsedGen = 1; *UsedGen = 1;
@@ -2248,7 +2257,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
void (*hienext) (ExprDesc*)) void (*hienext) (ExprDesc*))
/* Helper function for the compare operators */ /* Helper function for the compare operators */
{ {
ExprDesc Expr2;
CodeMark Mark0; CodeMark Mark0;
CodeMark Mark1; CodeMark Mark1;
CodeMark Mark2; CodeMark Mark2;
@@ -2263,6 +2271,10 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) { while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
ExprDesc Expr2;
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* Remember the generator function */ /* Remember the generator function */
void (*GenFunc) (unsigned, unsigned long) = Gen->Func; void (*GenFunc) (unsigned, unsigned long) = Gen->Func;
@@ -2362,11 +2374,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
/* Check for const operands */ /* Check for const operands */
if (ED_IsConstAbs (Expr) && rconst) { if (ED_IsConstAbs (Expr) && rconst) {
/* If the result is constant, this is suspicious when not in
** preprocessor mode.
*/
WarnConstCompareResult ();
/* Both operands are constant, remove the generated code */ /* Both operands are constant, remove the generated code */
RemoveCode (&Mark1); RemoveCode (&Mark1);
@@ -2403,6 +2410,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
} }
} }
/* If the result is constant, this is suspicious when not in
** preprocessor mode.
*/
WarnConstCompareResult (Expr);
} else { } else {
/* Determine the signedness of the operands */ /* Determine the signedness of the operands */
@@ -2461,7 +2473,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_EQ: case TOK_EQ:
if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) { if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) {
ED_MakeConstAbsInt (Expr, 0); ED_MakeConstAbsInt (Expr, 0);
WarnConstCompareResult (); WarnConstCompareResult (Expr);
goto Done; goto Done;
} }
break; break;
@@ -2469,7 +2481,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_NE: case TOK_NE:
if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) { if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) {
ED_MakeConstAbsInt (Expr, 1); ED_MakeConstAbsInt (Expr, 1);
WarnConstCompareResult (); WarnConstCompareResult (Expr);
goto Done; goto Done;
} }
break; break;
@@ -2477,7 +2489,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_LT: case TOK_LT:
if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) { if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) {
ED_MakeConstAbsInt (Expr, Expr2.IVal > LeftMax); ED_MakeConstAbsInt (Expr, Expr2.IVal > LeftMax);
WarnConstCompareResult (); WarnConstCompareResult (Expr);
goto Done; goto Done;
} }
break; break;
@@ -2485,7 +2497,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_LE: case TOK_LE:
if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) { if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) {
ED_MakeConstAbsInt (Expr, Expr2.IVal >= LeftMax); ED_MakeConstAbsInt (Expr, Expr2.IVal >= LeftMax);
WarnConstCompareResult (); WarnConstCompareResult (Expr);
goto Done; goto Done;
} }
break; break;
@@ -2493,7 +2505,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_GE: case TOK_GE:
if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) { if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) {
ED_MakeConstAbsInt (Expr, Expr2.IVal <= LeftMin); ED_MakeConstAbsInt (Expr, Expr2.IVal <= LeftMin);
WarnConstCompareResult (); WarnConstCompareResult (Expr);
goto Done; goto Done;
} }
break; break;
@@ -2501,7 +2513,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
case TOK_GT: case TOK_GT:
if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) { if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) {
ED_MakeConstAbsInt (Expr, Expr2.IVal < LeftMin); ED_MakeConstAbsInt (Expr, Expr2.IVal < LeftMin);
WarnConstCompareResult (); WarnConstCompareResult (Expr);
goto Done; goto Done;
} }
break; break;
@@ -2635,6 +2647,9 @@ static void parseadd (ExprDesc* Expr)
Type* lhst; /* Type of left hand side */ Type* lhst; /* Type of left hand side */
Type* rhst; /* Type of right hand side */ Type* rhst; /* Type of right hand side */
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* Skip the PLUS token */ /* Skip the PLUS token */
NextToken (); NextToken ();
@@ -2869,6 +2884,8 @@ static void parsesub (ExprDesc* Expr)
CodeMark Mark2; /* Another position in the queue */ CodeMark Mark2; /* Another position in the queue */
int rscale; /* Scale factor for the result */ int rscale; /* Scale factor for the result */
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* lhs cannot be function or pointer to function */ /* lhs cannot be function or pointer to function */
if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) { if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) {
@@ -3130,11 +3147,12 @@ static void hieAndPP (ExprDesc* Expr)
** called recursively from the preprocessor. ** called recursively from the preprocessor.
*/ */
{ {
ExprDesc Expr2;
ConstAbsIntExpr (hie2, Expr); ConstAbsIntExpr (hie2, Expr);
while (CurTok.Tok == TOK_BOOL_AND) { while (CurTok.Tok == TOK_BOOL_AND) {
ExprDesc Expr2;
ED_Init (&Expr2);
/* Skip the && */ /* Skip the && */
NextToken (); NextToken ();
@@ -3153,11 +3171,12 @@ static void hieOrPP (ExprDesc *Expr)
** called recursively from the preprocessor. ** called recursively from the preprocessor.
*/ */
{ {
ExprDesc Expr2;
ConstAbsIntExpr (hieAndPP, Expr); ConstAbsIntExpr (hieAndPP, Expr);
while (CurTok.Tok == TOK_BOOL_OR) { while (CurTok.Tok == TOK_BOOL_OR) {
ExprDesc Expr2;
ED_Init (&Expr2);
/* Skip the && */ /* Skip the && */
NextToken (); NextToken ();
@@ -3175,8 +3194,6 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
/* Process "exp && exp" */ /* Process "exp && exp" */
{ {
int FalseLab; int FalseLab;
ExprDesc Expr2;
ExprWithCheck (hie2, Expr); ExprWithCheck (hie2, Expr);
if (CurTok.Tok == TOK_BOOL_AND) { if (CurTok.Tok == TOK_BOOL_AND) {
@@ -3186,10 +3203,8 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
/* Get a label that we will use for false expressions */ /* Get a label that we will use for false expressions */
FalseLab = GetLocalLabel (); FalseLab = GetLocalLabel ();
/* If the expr hasn't set condition codes, set the force-test flag */ /* Set the test flag */
if (!ED_IsTested (Expr)) { ED_RequireTest (Expr);
ED_MarkForTest (Expr);
}
/* Load the value */ /* Load the value */
LoadExpr (CF_FORCECHAR, Expr); LoadExpr (CF_FORCECHAR, Expr);
@@ -3200,14 +3215,15 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
/* Parse more boolean and's */ /* Parse more boolean and's */
while (CurTok.Tok == TOK_BOOL_AND) { while (CurTok.Tok == TOK_BOOL_AND) {
ExprDesc Expr2;
ED_Init (&Expr2);
/* Skip the && */ /* Skip the && */
NextToken (); NextToken ();
/* Get rhs */ /* Get rhs */
hie2 (&Expr2); hie2 (&Expr2);
if (!ED_IsTested (&Expr2)) { ED_RequireTest (&Expr2);
ED_MarkForTest (&Expr2);
}
LoadExpr (CF_FORCECHAR, &Expr2); LoadExpr (CF_FORCECHAR, &Expr2);
/* Do short circuit evaluation */ /* Do short circuit evaluation */
@@ -3233,7 +3249,6 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
static void hieOr (ExprDesc *Expr) static void hieOr (ExprDesc *Expr)
/* Process "exp || exp". */ /* Process "exp || exp". */
{ {
ExprDesc Expr2;
int BoolOp = 0; /* Did we have a boolean op? */ int BoolOp = 0; /* Did we have a boolean op? */
int AndOp; /* Did we have a && operation? */ int AndOp; /* Did we have a && operation? */
unsigned TrueLab; /* Jump to this label if true */ unsigned TrueLab; /* Jump to this label if true */
@@ -3248,10 +3263,8 @@ static void hieOr (ExprDesc *Expr)
/* Any boolean or's? */ /* Any boolean or's? */
if (CurTok.Tok == TOK_BOOL_OR) { if (CurTok.Tok == TOK_BOOL_OR) {
/* If the expr hasn't set condition codes, set the force-test flag */ /* Set the test flag */
if (!ED_IsTested (Expr)) { ED_RequireTest (Expr);
ED_MarkForTest (Expr);
}
/* Get first expr */ /* Get first expr */
LoadExpr (CF_FORCECHAR, Expr); LoadExpr (CF_FORCECHAR, Expr);
@@ -3269,15 +3282,16 @@ static void hieOr (ExprDesc *Expr)
/* while there's more expr */ /* while there's more expr */
while (CurTok.Tok == TOK_BOOL_OR) { while (CurTok.Tok == TOK_BOOL_OR) {
ExprDesc Expr2;
ED_Init (&Expr2);
/* skip the || */ /* skip the || */
NextToken (); NextToken ();
/* Get a subexpr */ /* Get a subexpr */
AndOp = 0; AndOp = 0;
hieAnd (&Expr2, TrueLab, &AndOp); hieAnd (&Expr2, TrueLab, &AndOp);
if (!ED_IsTested (&Expr2)) { ED_RequireTest (&Expr2);
ED_MarkForTest (&Expr2);
}
LoadExpr (CF_FORCECHAR, &Expr2); LoadExpr (CF_FORCECHAR, &Expr2);
/* If there is more to come, add shortcut boolean eval. */ /* If there is more to come, add shortcut boolean eval. */
@@ -3308,6 +3322,7 @@ static void hieQuest (ExprDesc* Expr)
{ {
int FalseLab; int FalseLab;
int TrueLab; int TrueLab;
CodeMark SkippedBranch;
CodeMark TrueCodeEnd; CodeMark TrueCodeEnd;
ExprDesc Expr2; /* Expression 2 */ ExprDesc Expr2; /* Expression 2 */
ExprDesc Expr3; /* Expression 3 */ ExprDesc Expr3; /* Expression 3 */
@@ -3315,6 +3330,10 @@ static void hieQuest (ExprDesc* Expr)
int Expr3IsNULL; /* Expression 3 is a NULL pointer */ int Expr3IsNULL; /* Expression 3 is a NULL pointer */
Type* ResultType; /* Type of result */ Type* ResultType; /* Type of result */
ED_Init (&Expr2);
Expr2.Flags = Expr->Flags & E_MASK_KEEP_RESULT;
ED_Init (&Expr3);
Expr3.Flags = Expr->Flags & E_MASK_KEEP_RESULT;
/* Call the lower level eval routine */ /* Call the lower level eval routine */
if (Preprocessing) { if (Preprocessing) {
@@ -3325,14 +3344,20 @@ static void hieQuest (ExprDesc* Expr)
/* Check if it's a ternary expression */ /* Check if it's a ternary expression */
if (CurTok.Tok == TOK_QUEST) { if (CurTok.Tok == TOK_QUEST) {
int ConstantCond = ED_IsConstAbsInt (Expr);
NextToken (); NextToken ();
if (!ED_IsTested (Expr)) {
if (!ConstantCond) {
/* Condition codes not set, request a test */ /* Condition codes not set, request a test */
ED_MarkForTest (Expr); ED_RequireTest (Expr);
LoadExpr (CF_NONE, Expr);
FalseLab = GetLocalLabel ();
g_falsejump (CF_NONE, FalseLab);
} else if (Expr->IVal == 0) {
/* Remember the current code position */
GetCodePos (&SkippedBranch);
} }
LoadExpr (CF_NONE, Expr);
FalseLab = GetLocalLabel ();
g_falsejump (CF_NONE, FalseLab);
/* Parse second expression. Remember for later if it is a NULL pointer /* Parse second expression. Remember for later if it is a NULL pointer
** expression, then load it into the primary. ** expression, then load it into the primary.
@@ -3340,22 +3365,37 @@ static void hieQuest (ExprDesc* Expr)
ExprWithCheck (hie1, &Expr2); ExprWithCheck (hie1, &Expr2);
Expr2IsNULL = ED_IsNullPtr (&Expr2); Expr2IsNULL = ED_IsNullPtr (&Expr2);
if (!IsTypeVoid (Expr2.Type)) { if (!IsTypeVoid (Expr2.Type)) {
/* Load it into the primary */ if (!ConstantCond || !ED_IsConst (&Expr2)) {
LoadExpr (CF_NONE, &Expr2); /* Load it into the primary */
ED_FinalizeRValLoad (&Expr2); LoadExpr (CF_NONE, &Expr2);
ED_FinalizeRValLoad (&Expr2);
}
Expr2.Type = PtrConversion (Expr2.Type); Expr2.Type = PtrConversion (Expr2.Type);
} }
/* Remember the current code position */ if (!ConstantCond) {
GetCodePos (&TrueCodeEnd); /* Remember the current code position */
GetCodePos (&TrueCodeEnd);
/* Jump around the evaluation of the third expression */ /* Jump around the evaluation of the third expression */
TrueLab = GetLocalLabel (); TrueLab = GetLocalLabel ();
ConsumeColon ();
g_jump (TrueLab);
/* Jump here if the first expression was false */ ConsumeColon ();
g_defcodelabel (FalseLab);
g_jump (TrueLab);
/* Jump here if the first expression was false */
g_defcodelabel (FalseLab);
} else {
if (Expr->IVal == 0) {
/* Remove the load code of Expr2 */
RemoveCode (&SkippedBranch);
} else {
/* Remember the current code position */
GetCodePos (&SkippedBranch);
}
ConsumeColon();
}
/* Parse third expression. Remember for later if it is a NULL pointer /* Parse third expression. Remember for later if it is a NULL pointer
** expression, then load it into the primary. ** expression, then load it into the primary.
@@ -3363,12 +3403,19 @@ static void hieQuest (ExprDesc* Expr)
ExprWithCheck (hie1, &Expr3); ExprWithCheck (hie1, &Expr3);
Expr3IsNULL = ED_IsNullPtr (&Expr3); Expr3IsNULL = ED_IsNullPtr (&Expr3);
if (!IsTypeVoid (Expr3.Type)) { if (!IsTypeVoid (Expr3.Type)) {
/* Load it into the primary */ if (!ConstantCond || !ED_IsConst (&Expr3)) {
LoadExpr (CF_NONE, &Expr3); /* Load it into the primary */
ED_FinalizeRValLoad (&Expr3); LoadExpr (CF_NONE, &Expr3);
ED_FinalizeRValLoad (&Expr3);
}
Expr3.Type = PtrConversion (Expr3.Type); Expr3.Type = PtrConversion (Expr3.Type);
} }
if (ConstantCond && Expr->IVal != 0) {
/* Remove the load code of Expr3 */
RemoveCode (&SkippedBranch);
}
/* Check if any conversions are needed, if so, do them. /* Check if any conversions are needed, if so, do them.
** Conversion rules for ?: expression are: ** Conversion rules for ?: expression are:
** - if both expressions are int expressions, default promotion ** - if both expressions are int expressions, default promotion
@@ -3401,9 +3448,11 @@ static void hieQuest (ExprDesc* Expr)
TypeConversion (&Expr2, ResultType); TypeConversion (&Expr2, ResultType);
GetCodePos (&CvtCodeEnd); GetCodePos (&CvtCodeEnd);
/* If we had conversion code, move it to the right place */ if (!ConstantCond) {
if (!CodeRangeIsEmpty (&CvtCodeStart, &CvtCodeEnd)) { /* If we had conversion code, move it to the right place */
MoveCode (&CvtCodeStart, &CvtCodeEnd, &TrueCodeEnd); if (!CodeRangeIsEmpty (&CvtCodeStart, &CvtCodeEnd)) {
MoveCode (&CvtCodeStart, &CvtCodeEnd, &TrueCodeEnd);
}
} }
} else if (IsClassPtr (Expr2.Type) && IsClassPtr (Expr3.Type)) { } else if (IsClassPtr (Expr2.Type) && IsClassPtr (Expr3.Type)) {
@@ -3423,16 +3472,30 @@ static void hieQuest (ExprDesc* Expr)
/* Result type is void */ /* Result type is void */
ResultType = Expr3.Type; ResultType = Expr3.Type;
} else { } else {
TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1, if (IsClassStruct (Expr2.Type) && IsClassStruct (Expr3.Type) &&
"Incompatible types in ternary '%s' with '%s'"); TypeCmp (Expr2.Type, Expr3.Type) == TC_IDENTICAL) {
ResultType = Expr2.Type; /* Doesn't matter here */ /* Result type is struct/union */
ResultType = Expr2.Type;
} else {
TypeCompatibilityDiagnostic (Expr2.Type, Expr3.Type, 1,
"Incompatible types in ternary '%s' with '%s'");
ResultType = Expr2.Type; /* Doesn't matter here */
}
} }
/* Define the final label */ if (!ConstantCond) {
g_defcodelabel (TrueLab); /* Define the final label */
g_defcodelabel (TrueLab);
ED_FinalizeRValLoad (Expr);
} else {
if (Expr->IVal != 0) {
*Expr = Expr2;
} else {
*Expr = Expr3;
}
}
/* Setup the target expression */ /* Setup the target expression */
ED_FinalizeRValLoad (Expr);
Expr->Type = ResultType; Expr->Type = ResultType;
} }
} }
@@ -3442,7 +3505,6 @@ static void hieQuest (ExprDesc* Expr)
static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op) static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op)
/* Process "op=" operators. */ /* Process "op=" operators. */
{ {
ExprDesc Expr2;
unsigned flags; unsigned flags;
CodeMark Mark; CodeMark Mark;
int MustScale; int MustScale;
@@ -3483,6 +3545,10 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op)
GetCodePos (&Mark); GetCodePos (&Mark);
g_push (flags, 0); g_push (flags, 0);
ExprDesc Expr2;
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* Evaluate the rhs */ /* Evaluate the rhs */
MarkedExprWithCheck (hie1, &Expr2); MarkedExprWithCheck (hie1, &Expr2);
@@ -3563,6 +3629,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op)
unsigned rflags; unsigned rflags;
int MustScale; int MustScale;
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* We're currently only able to handle some addressing modes */ /* We're currently only able to handle some addressing modes */
if (ED_GetLoc (Expr) == E_LOC_EXPR || ED_GetLoc (Expr) == E_LOC_PRIMARY) { if (ED_GetLoc (Expr) == E_LOC_EXPR || ED_GetLoc (Expr) == E_LOC_PRIMARY) {
@@ -3756,8 +3824,33 @@ void hie1 (ExprDesc* Expr)
void hie0 (ExprDesc *Expr) void hie0 (ExprDesc *Expr)
/* Parse comma operator. */ /* Parse comma operator. */
{ {
unsigned Flags = Expr->Flags & E_MASK_KEEP_MAKE;
unsigned PrevErrorCount = ErrorCount;
CodeMark Start, End;
/* Remember the current code position */
GetCodePos (&Start);
hie1 (Expr); hie1 (Expr);
while (CurTok.Tok == TOK_COMMA) { while (CurTok.Tok == TOK_COMMA) {
/* If the expression didn't generate code or isn't cast to type void,
** emit a warning.
*/
GetCodePos (&End);
if (!ED_MayHaveNoEffect (Expr) &&
CodeRangeIsEmpty (&Start, &End) &&
IS_Get (&WarnNoEffect) &&
PrevErrorCount == ErrorCount) {
Warning ("Expression result unused");
}
PrevErrorCount = ErrorCount;
/* Remember the current code position */
GetCodePos (&Start);
/* Reset the expression */
ED_Init (Expr);
Expr->Flags = Flags;
NextToken (); NextToken ();
hie1 (Expr); hie1 (Expr);
} }
@@ -3791,8 +3884,18 @@ int evalexpr (unsigned Flags, void (*Func) (ExprDesc*), ExprDesc* Expr)
void Expression0 (ExprDesc* Expr) void Expression0 (ExprDesc* Expr)
/* Evaluate an expression via hie0 and put the result into the primary register */ /* Evaluate an expression via hie0 and put the result into the primary register */
{ {
unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT;
/* Only check further after the expression is evaluated */
ExprWithCheck (hie0, Expr); ExprWithCheck (hie0, Expr);
LoadExpr (CF_NONE, Expr);
if ((Expr->Flags & Flags & E_MASK_EVAL) != (Flags & E_MASK_EVAL)) {
Internal ("Expression flags tampered: %08X", Flags);
}
if (ED_YetToLoad (Expr)) {
LoadExpr (CF_NONE, Expr);
}
} }
@@ -3804,6 +3907,7 @@ void ConstExpr (void (*Func) (ExprDesc*), ExprDesc* Expr)
** result from this input error. ** result from this input error.
*/ */
{ {
Expr->Flags |= E_EVAL_CONST;
ExprWithCheck (Func, Expr); ExprWithCheck (Func, Expr);
if (!ED_IsConst (Expr)) { if (!ED_IsConst (Expr)) {
Error ("Constant expression expected"); Error ("Constant expression expected");
@@ -3838,6 +3942,7 @@ void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr)
** errors that result from this input error. ** errors that result from this input error.
*/ */
{ {
Expr->Flags |= E_EVAL_CONST;
ExprWithCheck (Func, Expr); ExprWithCheck (Func, Expr);
if (!ED_IsConstAbsInt (Expr)) { if (!ED_IsConstAbsInt (Expr)) {
Error ("Constant integer expression expected"); Error ("Constant integer expression expected");

View File

@@ -58,7 +58,7 @@ ExprDesc* ED_Init (ExprDesc* Expr)
{ {
Expr->Sym = 0; Expr->Sym = 0;
Expr->Type = 0; Expr->Type = 0;
Expr->Flags = 0; Expr->Flags = E_NEED_EAX;
Expr->Name = 0; Expr->Name = 0;
Expr->IVal = 0; Expr->IVal = 0;
Expr->FVal = FP_D_Make (0.0); Expr->FVal = FP_D_Make (0.0);
@@ -113,6 +113,24 @@ int ED_IsIndExpr (const ExprDesc* Expr)
int ED_YetToLoad (const ExprDesc* Expr)
/* Check if the expression needs to be loaded somehow. */
{
return ED_NeedsPrimary (Expr) ||
ED_YetToTest (Expr) ||
(ED_IsLVal (Expr) && IsQualVolatile (Expr->Type));
}
void ED_MarkForUneval (ExprDesc* Expr)
/* Mark the expression as not to be evaluated */
{
Expr->Flags = (Expr->Flags & ~E_MASK_EVAL) | E_EVAL_UNEVAL;
}
void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End) void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End)
/* Set the code range for this expression */ /* Set the code range for this expression */
{ {
@@ -206,7 +224,7 @@ ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type)
{ {
Expr->Sym = 0; Expr->Sym = 0;
Expr->Type = Type; Expr->Type = Type;
Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE);
Expr->Name = 0; Expr->Name = 0;
Expr->IVal = Value; Expr->IVal = Value;
Expr->FVal = FP_D_Make (0.0); Expr->FVal = FP_D_Make (0.0);
@@ -220,7 +238,7 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value)
{ {
Expr->Sym = 0; Expr->Sym = 0;
Expr->Type = type_int; Expr->Type = type_int;
Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS); Expr->Flags = E_LOC_NONE | E_RTYPE_RVAL | (Expr->Flags & E_MASK_KEEP_MAKE);
Expr->Name = 0; Expr->Name = 0;
Expr->IVal = Value; Expr->IVal = Value;
Expr->FVal = FP_D_Make (0.0); Expr->FVal = FP_D_Make (0.0);
@@ -412,7 +430,8 @@ int ED_IsBool (const ExprDesc* Expr)
/* Either ints, floats, or pointers can be used in a boolean context */ /* Either ints, floats, or pointers can be used in a boolean context */
return IsClassInt (Expr->Type) || return IsClassInt (Expr->Type) ||
IsClassFloat (Expr->Type) || IsClassFloat (Expr->Type) ||
IsClassPtr (Expr->Type); IsClassPtr (Expr->Type) ||
IsClassFunc (Expr->Type);
} }

View File

@@ -94,7 +94,7 @@ enum {
** E_LOC_<else> -- dereference -> E_LOC_EXPR (pointed-to-value, must load) ** E_LOC_<else> -- dereference -> E_LOC_EXPR (pointed-to-value, must load)
** + E_ADDRESS_OF -- dereference -> (lvalue reference) ** + E_ADDRESS_OF -- dereference -> (lvalue reference)
*/ */
E_MASK_LOC = 0x00FF, E_MASK_LOC = 0x01FF,
E_LOC_NONE = 0x0000, /* Pure rvalue with no storage */ E_LOC_NONE = 0x0000, /* Pure rvalue with no storage */
E_LOC_ABS = 0x0001, /* Absolute numeric addressed variable */ E_LOC_ABS = 0x0001, /* Absolute numeric addressed variable */
E_LOC_GLOBAL = 0x0002, /* Global variable */ E_LOC_GLOBAL = 0x0002, /* Global variable */
@@ -104,29 +104,58 @@ enum {
E_LOC_PRIMARY = 0x0020, /* Temporary in primary register */ E_LOC_PRIMARY = 0x0020, /* Temporary in primary register */
E_LOC_EXPR = 0x0040, /* A location that the primary register points to */ E_LOC_EXPR = 0x0040, /* A location that the primary register points to */
E_LOC_LITERAL = 0x0080, /* Literal in the literal pool */ E_LOC_LITERAL = 0x0080, /* Literal in the literal pool */
E_LOC_CODE = 0x0100, /* C code label location (&&Label) */
/* Constant location of some sort (only if rval) */ /* Immutable location addresses (immutable bases and offsets) */
E_LOC_CONST = E_LOC_NONE | E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC | E_LOC_CONST = E_LOC_NONE | E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC |
E_LOC_REGISTER | E_LOC_LITERAL, E_LOC_REGISTER | E_LOC_LITERAL | E_LOC_CODE,
/* Not-so-immutable location addresses (stack offsets can change) */
E_LOC_QUASICONST = E_LOC_CONST | E_LOC_STACK,
/* Expression type modifiers */
E_BITFIELD = 0x0200, /* Expression is a bit-field */
E_ADDRESS_OF = 0x0400, /* Expression is the address of the lvalue */
/* lvalue/rvalue in C language's sense */ /* lvalue/rvalue in C language's sense */
E_MASK_RTYPE = 0x0100, E_MASK_RTYPE = 0x0800,
E_RTYPE_RVAL = 0x0000, E_RTYPE_RVAL = 0x0000,
E_RTYPE_LVAL = 0x0100, E_RTYPE_LVAL = 0x0800,
/* Bit-field? */ /* Expression status */
E_BITFIELD = 0x0200, E_LOADED = 0x1000, /* Expression is loaded in primary */
E_CC_SET = 0x2000, /* Condition codes are set */
E_HAVE_MARKS = 0x4000, /* Code marks are valid */
/* Test */ /* Optimization hints */
E_NEED_TEST = 0x0400, /* Expression needs a test to set cc */ E_MASK_NEED = 0x030000,
E_CC_SET = 0x0800, /* Condition codes are set */ E_NEED_EAX = 0x000000, /* Expression needs to be loaded in Primary */
E_NEED_NONE = 0x010000, /* Expression value is unused */
E_NEED_TEST = 0x020000, /* Expression needs a test to set cc */
E_HAVE_MARKS = 0x1000, /* Code marks are valid */ /* Expression evaluation requirements.
** Usage: (Flags & E_EVAL_<Flag>) == E_EVAL_<Flag>
*/
E_MASK_EVAL = 0xFC0000,
E_EVAL_NONE = 0x000000, /* No requirements */
E_EVAL_CONST = 0x040000, /* Result must be immutable */
E_EVAL_COMPILE_TIME = 0x0C0000, /* Result must be known at compile time */
E_EVAL_PURE = 0x100000, /* Evaluation must have no side effects */
E_EVAL_STATIC = 0x340000, /* Evaluation must generate no code */
E_EVAL_MAYBE_UNUSED = 0x400000, /* Result may be unused */
E_EVAL_UNEVAL = 0xC00000, /* Expression is unevaluated */
E_LOADED = 0x4000, /* Expression is loaded in primary */ /* Expression must be static and have result known at compile time */
E_EVAL_C_CONST = E_EVAL_COMPILE_TIME | E_EVAL_STATIC,
E_ADDRESS_OF = 0x8000, /* Expression is the address of the lvalue */ /* Flags to keep in subexpressions */
E_MASK_KEEP_SUBEXPR = E_MASK_EVAL,
/* Flags to keep in ternary subexpressions */
E_MASK_KEEP_RESULT = E_MASK_NEED | E_MASK_EVAL,
/* Flags to keep when using the ED_Make functions */
E_MASK_KEEP_MAKE = E_HAVE_MARKS | E_MASK_KEEP_RESULT,
}; };
/* Forward */ /* Forward */
@@ -292,13 +321,33 @@ void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth);
/* Make this expression a bit field expression */ /* Make this expression a bit field expression */
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE void ED_MarkForTest (ExprDesc* Expr) INLINE void ED_RequireTest (ExprDesc* Expr)
/* Mark the expression for a test. */ /* Mark the expression for a test. */
{ {
Expr->Flags |= E_NEED_TEST; Expr->Flags |= E_NEED_TEST;
} }
#else #else
# define ED_MarkForTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0) # define ED_RequireTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_GetNeeds (const ExprDesc* Expr)
/* Get flags about what the expression needs. */
{
return (Expr->Flags & E_MASK_NEED);
}
#else
# define ED_GetNeeds(Expr) ((Expr)->Flags & E_MASK_NEED)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_NeedsPrimary (const ExprDesc* Expr)
/* Check if the expression needs to be in Primary. */
{
return (Expr->Flags & E_MASK_NEED) == E_NEED_EAX;
}
#else
# define ED_NeedsPrimary(Expr) (((Expr)->Flags & E_MASK_NEED) == E_NEED_EAX)
#endif #endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
@@ -311,15 +360,25 @@ INLINE int ED_NeedsTest (const ExprDesc* Expr)
# define ED_NeedsTest(Expr) (((Expr)->Flags & E_NEED_TEST) != 0) # define ED_NeedsTest(Expr) (((Expr)->Flags & E_NEED_TEST) != 0)
#endif #endif
#if defined(HAVE_INLINE)
INLINE int ED_YetToTest (const ExprDesc* Expr)
/* Check if the expression needs to be tested but not yet. */
{
return ((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST;
}
#else
# define ED_YetToTest(Expr) (((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST)
#endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE void ED_TestDone (ExprDesc* Expr) INLINE void ED_TestDone (ExprDesc* Expr)
/* Mark the expression as tested and condition codes set. */ /* Mark the expression as tested and condition codes set. */
{ {
Expr->Flags = (Expr->Flags & ~E_NEED_TEST) | E_CC_SET; Expr->Flags |= E_CC_SET;
} }
#else #else
# define ED_TestDone(Expr) \ # define ED_TestDone(Expr) \
do { (Expr)->Flags = ((Expr)->Flags & ~E_NEED_TEST) | E_CC_SET; } while (0) do { (Expr)->Flags |= E_CC_SET; } while (0)
#endif #endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
@@ -354,6 +413,42 @@ INLINE int ED_IsLoaded (const ExprDesc* Expr)
# define ED_IsLoaded(Expr) (((Expr)->Flags & E_LOADED) != 0) # define ED_IsLoaded(Expr) (((Expr)->Flags & E_LOADED) != 0)
#endif #endif
int ED_YetToLoad (const ExprDesc* Expr);
/* Check if the expression is yet to be loaded somehow. */
#if defined(HAVE_INLINE)
INLINE int ED_NeedsConst (const ExprDesc* Expr)
/* Check if the expression need be immutable */
{
return (Expr->Flags & E_EVAL_CONST) == E_EVAL_CONST;
}
#else
# define ED_NeedsConst(Expr) (((Expr)->Flags & E_EVAL_CONST) == E_EVAL_CONST)
#endif
void ED_MarkForUneval (ExprDesc* Expr);
/* Mark the expression as not to be evaluated */
#if defined(HAVE_INLINE)
INLINE int ED_MayBeUneval (const ExprDesc* Expr)
/* Check if the expression may be uevaluated */
{
return (Expr->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL;
}
#else
# define ED_MayBeUneval(Expr) (((Expr)->Flags & E_EVAL_UNEVAL) == E_EVAL_UNEVAL)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_MayHaveNoEffect (const ExprDesc* Expr)
/* Check if the expression may be present without effects */
{
return (Expr->Flags & E_EVAL_MAYBE_UNUSED) == E_EVAL_MAYBE_UNUSED;
}
#else
# define ED_MayHaveNoEffect(Expr) (((Expr)->Flags & E_EVAL_MAYBE_UNUSED) == E_EVAL_MAYBE_UNUSED)
#endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr) INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */ /* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
@@ -522,7 +617,7 @@ int ED_IsNullPtr (const ExprDesc* Expr);
int ED_IsBool (const ExprDesc* Expr); int ED_IsBool (const ExprDesc* Expr);
/* Return true of the expression can be treated as a boolean, that is, it can /* Return true of the expression can be treated as a boolean, that is, it can
** be an operand to a compare operation. ** be an operand to a compare operation with 0/NULL.
*/ */
void PrintExprDesc (FILE* F, ExprDesc* Expr); void PrintExprDesc (FILE* F, ExprDesc* Expr);

View File

@@ -80,6 +80,8 @@ void GotoStatement (void)
CodeEntry *E; CodeEntry *E;
unsigned char val; unsigned char val;
ED_Init (&desc);
NextToken (); NextToken ();
/* arr[foo], we only support simple foo for now */ /* arr[foo], we only support simple foo for now */

View File

@@ -145,7 +145,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
Flags |= TypeOf (Expr->Type); Flags |= TypeOf (Expr->Type);
} }
if (ED_NeedsTest (Expr)) { if (ED_YetToTest (Expr)) {
/* If we're only testing, we do not need to promote char to int. /* If we're only testing, we do not need to promote char to int.
** CF_FORCECHAR does nothing if the type is not CF_CHAR. ** CF_FORCECHAR does nothing if the type is not CF_CHAR.
*/ */
@@ -234,7 +234,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
*/ */
CHECK (Expr->BitOffs < CHAR_BITS); CHECK (Expr->BitOffs < CHAR_BITS);
if (ED_NeedsTest (Expr)) { if (ED_YetToTest (Expr)) {
g_testbitfield (Flags, Expr->BitOffs, Expr->BitWidth); g_testbitfield (Flags, Expr->BitOffs, Expr->BitWidth);
} else { } else {
g_extractbitfield (Flags, BitFieldFullWidthFlags, IsSignSigned (Expr->Type), g_extractbitfield (Flags, BitFieldFullWidthFlags, IsSignSigned (Expr->Type),
@@ -252,7 +252,7 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
LoadAddress (Flags, Expr); LoadAddress (Flags, Expr);
/* Are we testing this value? */ /* Are we testing this value? */
if (ED_NeedsTest (Expr)) { if (ED_YetToTest (Expr)) {
/* Yes, force a test */ /* Yes, force a test */
g_test (Flags); g_test (Flags);
ED_TestDone (Expr); ED_TestDone (Expr);

View File

@@ -122,8 +122,6 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg)
/* Check for an optional initialization */ /* Check for an optional initialization */
if (CurTok.Tok == TOK_ASSIGN) { if (CurTok.Tok == TOK_ASSIGN) {
ExprDesc Expr;
/* Skip the '=' */ /* Skip the '=' */
NextToken (); NextToken ();
@@ -152,6 +150,9 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg)
} else { } else {
ExprDesc Expr;
ED_Init (&Expr);
/* Parse the expression */ /* Parse the expression */
hie1 (&Expr); hie1 (&Expr);
@@ -203,8 +204,6 @@ static void ParseAutoDecl (Declaration* Decl)
/* Check for an optional initialization */ /* Check for an optional initialization */
if (CurTok.Tok == TOK_ASSIGN) { if (CurTok.Tok == TOK_ASSIGN) {
ExprDesc Expr;
/* Skip the '=' */ /* Skip the '=' */
NextToken (); NextToken ();
@@ -242,6 +241,9 @@ static void ParseAutoDecl (Declaration* Decl)
} else { } else {
ExprDesc Expr;
ED_Init (&Expr);
/* Allocate previously reserved local space */ /* Allocate previously reserved local space */
F_AllocLocalSpace (CurrentFunc); F_AllocLocalSpace (CurrentFunc);
@@ -303,8 +305,6 @@ static void ParseAutoDecl (Declaration* Decl)
/* Allow assignments */ /* Allow assignments */
if (CurTok.Tok == TOK_ASSIGN) { if (CurTok.Tok == TOK_ASSIGN) {
ExprDesc Expr;
/* Skip the '=' */ /* Skip the '=' */
NextToken (); NextToken ();
@@ -328,6 +328,9 @@ static void ParseAutoDecl (Declaration* Decl)
} else { } else {
ExprDesc Expr;
ED_Init (&Expr);
/* Allocate space for the variable */ /* Allocate space for the variable */
AllocStorage (DataLabel, g_usebss, Size); AllocStorage (DataLabel, g_usebss, Size);

View File

@@ -1043,6 +1043,7 @@ static int DoIf (int Skip)
/* Process #if directive */ /* Process #if directive */
{ {
ExprDesc Expr; ExprDesc Expr;
ED_Init (&Expr);
/* We're about to abuse the compiler expression parser to evaluate the /* We're about to abuse the compiler expression parser to evaluate the
** #if expression. Save the current tokens to come back here later. ** #if expression. Save the current tokens to come back here later.

View File

@@ -61,7 +61,6 @@
void ShiftExpr (struct ExprDesc* Expr) void ShiftExpr (struct ExprDesc* Expr)
/* Parse the << and >> operators. */ /* Parse the << and >> operators. */
{ {
ExprDesc Expr2;
CodeMark Mark1; CodeMark Mark1;
CodeMark Mark2; CodeMark Mark2;
token_t Tok; /* The operator token */ token_t Tok; /* The operator token */
@@ -78,6 +77,10 @@ void ShiftExpr (struct ExprDesc* Expr)
while (CurTok.Tok == TOK_SHL || CurTok.Tok == TOK_SHR) { while (CurTok.Tok == TOK_SHL || CurTok.Tok == TOK_SHR) {
ExprDesc Expr2;
ED_Init (&Expr2);
Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR;
/* All operators that call this function expect an int on the lhs */ /* All operators that call this function expect an int on the lhs */
if (!IsClassInt (Expr->Type)) { if (!IsClassInt (Expr->Type)) {
Error ("Integer expression expected"); Error ("Integer expression expected");

View File

@@ -55,6 +55,8 @@ void ParseStaticAssert ()
ExprDesc Expr; ExprDesc Expr;
int failed; int failed;
ED_Init (&Expr);
/* Skip the _Static_assert token itself */ /* Skip the _Static_assert token itself */
CHECK (CurTok.Tok == TOK_STATIC_ASSERT); CHECK (CurTok.Tok == TOK_STATIC_ASSERT);
NextToken (); NextToken ();

View File

@@ -152,6 +152,9 @@ static void ParseArg (ArgDesc* Arg, Type* Type)
/* Remember the required argument type */ /* Remember the required argument type */
Arg->ArgType = Type; Arg->ArgType = Type;
/* Init expression */
ED_Init (&Arg->Expr);
/* Read the expression we're going to pass to the function */ /* Read the expression we're going to pass to the function */
MarkedExprWithCheck (hie1, &Arg->Expr); MarkedExprWithCheck (hie1, &Arg->Expr);
@@ -1180,6 +1183,8 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
long ECount; long ECount;
unsigned L; unsigned L;
ED_Init (&Arg);
/* Setup the argument type string */ /* Setup the argument type string */
ArgType[1].C = T_CHAR | T_QUAL_CONST; ArgType[1].C = T_CHAR | T_QUAL_CONST;

View File

@@ -312,6 +312,7 @@ static void ReturnStatement (void)
ExprDesc Expr; ExprDesc Expr;
const Type* ReturnType; const Type* ReturnType;
ED_Init (&Expr);
NextToken (); NextToken ();
if (CurTok.Tok != TOK_SEMI) { if (CurTok.Tok != TOK_SEMI) {
@@ -424,8 +425,6 @@ static void ContinueStatement (void)
static void ForStatement (void) static void ForStatement (void)
/* Handle a 'for' statement */ /* Handle a 'for' statement */
{ {
ExprDesc lval1;
ExprDesc lval3;
int HaveIncExpr; int HaveIncExpr;
CodeMark IncExprStart; CodeMark IncExprStart;
CodeMark IncExprEnd; CodeMark IncExprEnd;
@@ -450,6 +449,10 @@ static void ForStatement (void)
/* Parse the initializer expression */ /* Parse the initializer expression */
if (CurTok.Tok != TOK_SEMI) { if (CurTok.Tok != TOK_SEMI) {
/* The value of the expression is unused */
ExprDesc lval1;
ED_Init (&lval1);
lval1.Flags = E_NEED_NONE;
Expression0 (&lval1); Expression0 (&lval1);
} }
ConsumeSemi (); ConsumeSemi ();
@@ -475,6 +478,10 @@ static void ForStatement (void)
/* Parse the increment expression */ /* Parse the increment expression */
HaveIncExpr = (CurTok.Tok != TOK_RPAREN); HaveIncExpr = (CurTok.Tok != TOK_RPAREN);
if (HaveIncExpr) { if (HaveIncExpr) {
/* The value of the expression is unused */
ExprDesc lval3;
ED_Init (&lval3);
lval3.Flags = E_NEED_NONE;
Expression0 (&lval3); Expression0 (&lval3);
} }
@@ -580,8 +587,10 @@ int Statement (int* PendingToken)
{ {
ExprDesc Expr; ExprDesc Expr;
int GotBreak; int GotBreak;
unsigned PrevErrorCount;
CodeMark Start, End; CodeMark Start, End;
unsigned PrevErrorCount = ErrorCount;
ED_Init (&Expr);
/* Assume no pending token */ /* Assume no pending token */
if (PendingToken) { if (PendingToken) {
@@ -666,25 +675,24 @@ int Statement (int* PendingToken)
break; break;
default: default:
/* Remember the current code position */ /* Remember the current error count and code position */
PrevErrorCount = ErrorCount;
GetCodePos (&Start); GetCodePos (&Start);
/* Actual statement */ /* Actual statement */
ExprWithCheck (hie0, &Expr); Expr.Flags |= E_NEED_NONE;
/* Load the result only if it is an lvalue and the type is Expression0 (&Expr);
** marked as volatile. Otherwise the load is useless.
*/
if (ED_IsLVal (&Expr) && IsQualVolatile (Expr.Type)) {
LoadExpr (CF_NONE, &Expr);
}
/* If the statement didn't generate code, and is not of type /* If the statement didn't generate code, and is not of type
** void, emit a warning. ** void, emit a warning.
*/ */
GetCodePos (&End); GetCodePos (&End);
if (CodeRangeIsEmpty (&Start, &End) && if (!ED_YetToLoad (&Expr) &&
!IsTypeVoid (Expr.Type) && !ED_MayHaveNoEffect (&Expr) &&
CodeRangeIsEmpty (&Start, &End) &&
IS_Get (&WarnNoEffect) && IS_Get (&WarnNoEffect) &&
PrevErrorCount == ErrorCount) { PrevErrorCount == ErrorCount) {
Warning ("Statement has no effect"); Warning ("Expression result unused");
} }
CheckSemi (PendingToken); CheckSemi (PendingToken);
} }

View File

@@ -97,7 +97,6 @@ void SwitchStatement (void)
SwitchCtrl* OldSwitch; /* Pointer to old switch control data */ SwitchCtrl* OldSwitch; /* Pointer to old switch control data */
SwitchCtrl SwitchData; /* New switch data */ SwitchCtrl SwitchData; /* New switch data */
/* Eat the "switch" token */ /* Eat the "switch" token */
NextToken (); NextToken ();
@@ -105,6 +104,8 @@ void SwitchStatement (void)
** integer type. ** integer type.
*/ */
ConsumeLParen (); ConsumeLParen ();
ED_Init (&SwitchExpr);
Expression0 (&SwitchExpr); Expression0 (&SwitchExpr);
if (!IsClassInt (SwitchExpr.Type)) { if (!IsClassInt (SwitchExpr.Type)) {
Error ("Switch quantity is not an integer"); Error ("Switch quantity is not an integer");
@@ -211,11 +212,11 @@ void CaseLabel (void)
long Val; /* Case label value */ long Val; /* Case label value */
unsigned CodeLabel; /* Code label for this case */ unsigned CodeLabel; /* Code label for this case */
/* Skip the "case" token */ /* Skip the "case" token */
NextToken (); NextToken ();
/* Read the selector expression */ /* Read the selector expression */
ED_Init (&CaseExpr);
ConstAbsIntExpr (hie1, &CaseExpr); ConstAbsIntExpr (hie1, &CaseExpr);
Val = CaseExpr.IVal; Val = CaseExpr.IVal;

View File

@@ -58,6 +58,8 @@ unsigned Test (unsigned Label, int Invert)
ExprDesc Expr; ExprDesc Expr;
unsigned Result; unsigned Result;
ED_Init (&Expr);
/* Read a boolean expression */ /* Read a boolean expression */
BoolExpr (hie0, &Expr); BoolExpr (hie0, &Expr);
@@ -80,10 +82,8 @@ unsigned Test (unsigned Label, int Invert)
/* Result is unknown */ /* Result is unknown */
Result = TESTEXPR_UNKNOWN; Result = TESTEXPR_UNKNOWN;
/* If the expr hasn't set condition codes, set the force-test flag */ /* Set the test flag */
if (!ED_IsTested (&Expr)) { ED_RequireTest (&Expr);
ED_MarkForTest (&Expr);
}
/* Load the value into the primary register */ /* Load the value into the primary register */
LoadExpr (CF_FORCECHAR, &Expr); LoadExpr (CF_FORCECHAR, &Expr);

View File

@@ -371,6 +371,11 @@ void TypeCast (ExprDesc* Expr)
GetBasicTypeName (NewType)); GetBasicTypeName (NewType));
} }
/* If the new type is void, the cast expression can have no effects */
if (IsTypeVoid (NewType)) {
Expr->Flags |= E_EVAL_MAYBE_UNUSED;
}
/* The result is always an rvalue */ /* The result is always an rvalue */
ED_MarkExprAsRVal (Expr); ED_MarkExprAsRVal (Expr);
} }