1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 23:29:39 +00:00

Fixed constant expression checks with no-code requirement.

Used return-by-value initialization for ExprDesc.
This commit is contained in:
acqn 2020-08-20 07:52:11 +08:00
parent 1abb9da2b2
commit 725511131a
8 changed files with 73 additions and 98 deletions

View File

@ -129,16 +129,13 @@ static SymEntry* AsmGetSym (unsigned Arg, unsigned Type)
static void ParseByteArg (StrBuf* T, unsigned Arg)
/* Parse the %b format specifier */
{
ExprDesc Expr;
char Buf [16];
ED_Init (&Expr);
/* We expect an argument separated by a comma */
ConsumeComma ();
/* Evaluate the expression */
ConstAbsIntExpr (hie1, &Expr);
ExprDesc Expr = StaticConstAbsIntExpr (hie1);
/* Check the range but allow negative values if the type is signed */
if (IsSignUnsigned (Expr.Type)) {
@ -165,16 +162,13 @@ static void ParseByteArg (StrBuf* T, unsigned Arg)
static void ParseWordArg (StrBuf* T, unsigned Arg)
/* Parse the %w format specifier */
{
ExprDesc Expr;
char Buf [16];
ED_Init (&Expr);
/* We expect an argument separated by a comma */
ConsumeComma ();
/* Evaluate the expression */
ConstAbsIntExpr (hie1, &Expr);
ExprDesc Expr = StaticConstAbsIntExpr (hie1);
/* Check the range but allow negative values if the type is signed */
if (IsSignUnsigned (Expr.Type)) {
@ -201,16 +195,13 @@ static void ParseWordArg (StrBuf* T, unsigned Arg)
static void ParseLongArg (StrBuf* T, unsigned Arg attribute ((unused)))
/* Parse the %l format specifier */
{
ExprDesc Expr;
char Buf [16];
ED_Init (&Expr);
/* We expect an argument separated by a comma */
ConsumeComma ();
/* Evaluate the expression */
ConstAbsIntExpr (hie1, &Expr);
ExprDesc Expr = StaticConstAbsIntExpr (hie1);
/* Convert into a hex number */
xsprintf (Buf, sizeof (Buf), "$%08lX", Expr.IVal & 0xFFFFFFFF);
@ -315,8 +306,6 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused)))
ExprDesc Expr;
char Buf [64];
ED_Init (&Expr);
/* We expect an argument separated by a comma */
ConsumeComma ();
@ -336,7 +325,7 @@ static void ParseStrArg (StrBuf* T, unsigned Arg attribute ((unused)))
break;
default:
ConstAbsIntExpr (hie1, &Expr);
Expr = StaticConstAbsIntExpr (hie1);
xsprintf (Buf, sizeof (Buf), "%ld", Expr.IVal);
SB_AppendStr (T, Buf);
break;

View File

@ -590,10 +590,8 @@ static SymEntry* ParseEnumDecl (const char* Name)
/* Check for an assigned value */
if (CurTok.Tok == TOK_ASSIGN) {
ExprDesc Expr;
ED_Init (&Expr);
NextToken ();
ConstAbsIntExpr (hie1, &Expr);
ExprDesc Expr = StaticConstAbsIntExpr (hie1);
EnumVal = Expr.IVal;
MemberType = Expr.Type;
IsSigned = IsSignSigned (MemberType);
@ -720,9 +718,6 @@ static int ParseFieldWidth (Declaration* Decl)
** otherwise the width of the field.
*/
{
ExprDesc Expr;
ED_Init (&Expr);
if (CurTok.Tok != TOK_COLON) {
/* No bit-field declaration */
return -1;
@ -746,7 +741,7 @@ static int ParseFieldWidth (Declaration* Decl)
/* Read the width */
NextToken ();
ConstAbsIntExpr (hie1, &Expr);
ExprDesc Expr = StaticConstAbsIntExpr (hie1);
if (Expr.IVal < 0) {
Error ("Negative width in bit-field");
@ -1819,9 +1814,7 @@ static void Declarator (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
/* Read the size if it is given */
if (CurTok.Tok != TOK_RBRACK) {
ExprDesc Expr;
ED_Init (&Expr);
ConstAbsIntExpr (hie1, &Expr);
ExprDesc Expr = StaticConstAbsIntExpr (hie1);
if (Expr.IVal <= 0) {
if (D->Ident[0] != '\0') {
Error ("Size of array '%s' is invalid", D->Ident);
@ -2158,7 +2151,7 @@ static void OutputBitFieldData (StructInitData* SI)
static void ParseScalarInitInternal (Type* T, ExprDesc* ED)
static ExprDesc ParseScalarInitInternal (Type* T)
/* Parse initializaton for scalar data types. This function will not output the
** data but return it in ED.
*/
@ -2174,11 +2167,13 @@ static void ParseScalarInitInternal (Type* T, ExprDesc* ED)
}
/* Get the expression and convert it to the target type */
ConstExpr (hie1, ED);
TypeConversion (ED, T);
ExprDesc ED = StaticConstExpr (hie1);
TypeConversion (&ED, T);
/* Close eventually opening braces */
ClosingCurlyBraces (BraceCount);
return ED;
}
@ -2186,11 +2181,8 @@ static void ParseScalarInitInternal (Type* T, ExprDesc* ED)
static unsigned ParseScalarInit (Type* T)
/* Parse initializaton for scalar data types. Return the number of data bytes. */
{
ExprDesc ED;
ED_Init (&ED);
/* Parse initialization */
ParseScalarInitInternal (T, &ED);
ExprDesc ED = ParseScalarInitInternal (T);
/* Output the data */
DefineData (&ED);
@ -2208,10 +2200,7 @@ static unsigned ParsePointerInit (Type* T)
unsigned BraceCount = OpeningCurlyBraces (0);
/* Expression */
ExprDesc ED;
ED_Init (&ED);
ConstExpr (hie1, &ED);
ExprDesc ED = StaticConstExpr (hie1);
TypeConversion (&ED, T);
/* Output the data */
@ -2438,7 +2427,7 @@ static unsigned ParseStructInit (Type* T, int* Braces, int AllowFlexibleMembers)
SI.Offs * CHAR_BITS + SI.ValBits);
/* Read the data, check for a constant integer, do a range check */
ParseScalarInitInternal (Entry->Type, &ED);
ED = ParseScalarInitInternal (Entry->Type);
if (!ED_IsConstAbsInt (&ED)) {
Error ("Constant initializer expected");
ED_MakeConstAbsInt (&ED, 1);
@ -2556,10 +2545,7 @@ static unsigned ParseVoidInit (Type* T)
/* Allow an arbitrary list of values */
Size = 0;
do {
ExprDesc Expr;
ED_Init (&Expr);
ConstExpr (hie1, &Expr);
ExprDesc Expr = StaticConstExpr (hie1);
switch (GetUnderlyingTypeCode (&Expr.Type[0])) {
case T_SCHAR:

View File

@ -3147,17 +3147,14 @@ static void hieAndPP (ExprDesc* Expr)
** called recursively from the preprocessor.
*/
{
ConstAbsIntExpr (hie2, Expr);
*Expr = StaticConstAbsIntExpr (hie2);
while (CurTok.Tok == TOK_BOOL_AND) {
ExprDesc Expr2;
ED_Init (&Expr2);
/* Skip the && */
NextToken ();
/* Get rhs */
ConstAbsIntExpr (hie2, &Expr2);
ExprDesc Expr2 = StaticConstAbsIntExpr (hie2);
/* Combine the two */
Expr->IVal = (Expr->IVal && Expr2.IVal);
@ -3171,17 +3168,14 @@ static void hieOrPP (ExprDesc *Expr)
** called recursively from the preprocessor.
*/
{
ConstAbsIntExpr (hieAndPP, Expr);
*Expr = StaticConstAbsIntExpr (hieAndPP);
while (CurTok.Tok == TOK_BOOL_OR) {
ExprDesc Expr2;
ED_Init (&Expr2);
/* Skip the && */
NextToken ();
/* Get rhs */
ConstAbsIntExpr (hieAndPP, &Expr2);
ExprDesc Expr2 = StaticConstAbsIntExpr (hieAndPP);
/* Combine the two */
Expr->IVal = (Expr->IVal || Expr2.IVal);
@ -3900,24 +3894,6 @@ void Expression0 (ExprDesc* Expr)
void ConstExpr (void (*Func) (ExprDesc*), ExprDesc* Expr)
/* Will evaluate an expression via the given function. If the result is not
** a constant of some sort, a diagnostic will be printed, and the value is
** replaced by a constant one to make sure there are no internal errors that
** result from this input error.
*/
{
Expr->Flags |= E_EVAL_CONST;
ExprWithCheck (Func, Expr);
if (!ED_IsConst (Expr)) {
Error ("Constant expression expected");
/* To avoid any compiler errors, make the expression a valid const */
ED_MakeConstAbsInt (Expr, 1);
}
}
void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr)
/* Will evaluate an expression via the given function. If the result is not
** something that may be evaluated in a boolean context, a diagnostic will be
@ -3927,26 +3903,56 @@ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr)
{
ExprWithCheck (Func, Expr);
if (!ED_IsBool (Expr)) {
Error ("Boolean expression expected");
Error ("Scalar expression expected");
/* To avoid any compiler errors, make the expression a valid int */
ED_MakeConstAbsInt (Expr, 1);
ED_MakeConstBool (Expr, 1);
}
}
void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr)
/* Will evaluate an expression via the given function. If the result is not
** a constant numeric integer value, a diagnostic will be printed, and the
ExprDesc StaticConstExpr (void (*Func) (ExprDesc*))
/* Will evaluate an expression via the given function. If the result is not a
** static constant expression, a diagnostic will be printed, and the value is
** replaced by a constant one to make sure there are no internal errors that
** result from this input error.
*/
{
ExprDesc Expr;
ED_Init (&Expr);
Expr.Flags |= E_EVAL_C_CONST;
MarkedExprWithCheck (Func, &Expr);
if (!ED_IsConst (&Expr) || !ED_CodeRangeIsEmpty (&Expr)) {
Error ("Constant expression expected");
/* To avoid any compiler errors, make the expression a valid const */
ED_MakeConstAbsInt (&Expr, 1);
}
/* Return by value */
return Expr;
}
ExprDesc StaticConstAbsIntExpr (void (*Func) (ExprDesc*))
/* Will evaluate an expression via the given function. If the result is not a
** static constant numeric integer value, a diagnostic will be printed, and the
** value is replaced by a constant one to make sure there are no internal
** errors that result from this input error.
*/
{
Expr->Flags |= E_EVAL_CONST;
ExprWithCheck (Func, Expr);
if (!ED_IsConstAbsInt (Expr)) {
ExprDesc Expr;
ED_Init (&Expr);
Expr.Flags |= E_EVAL_C_CONST;
MarkedExprWithCheck (Func, &Expr);
if (!ED_IsConstAbsInt (&Expr) || !ED_CodeRangeIsEmpty (&Expr)) {
Error ("Constant integer expression expected");
/* To avoid any compiler errors, make the expression a valid const */
ED_MakeConstAbsInt (Expr, 1);
ED_MakeConstAbsInt (&Expr, 1);
}
/* Return by value */
return Expr;
}

View File

@ -54,13 +54,6 @@ int evalexpr (unsigned flags, void (*Func) (ExprDesc*), ExprDesc* Expr);
void Expression0 (ExprDesc* Expr);
/* Evaluate an expression via hie0 and put the result into the primary register */
void ConstExpr (void (*Func) (ExprDesc*), ExprDesc* Expr);
/* Will evaluate an expression via the given function. If the result is not
** a constant of some sort, a diagnostic will be printed, and the value is
** replaced by a constant one to make sure there are no internal errors that
** result from this input error.
*/
void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr);
/* Will evaluate an expression via the given function. If the result is not
** something that may be evaluated in a boolean context, a diagnostic will be
@ -68,9 +61,16 @@ void BoolExpr (void (*Func) (ExprDesc*), ExprDesc* Expr);
** are no internal errors that result from this input error.
*/
void ConstAbsIntExpr (void (*Func) (ExprDesc*), ExprDesc* Expr);
/* Will evaluate an expression via the given function. If the result is not
** a constant numeric integer value, a diagnostic will be printed, and the
ExprDesc StaticConstExpr (void (*Func) (ExprDesc*));
/* Get an expression evaluated via the given function. If the result is not a
** static constant expression, a diagnostic will be printed, and the value is
** replaced by a constant one to make sure there are no internal errors that
** result from this input error.
*/
ExprDesc StaticConstAbsIntExpr (void (*Func) (ExprDesc*));
/* Get an expression evaluate via the given function. If the result is not a
** static constant numeric integer value, a diagnostic will be printed, and the
** value is replaced by a constant one to make sure there are no internal
** errors that result from this input error.
*/

View File

@ -1042,9 +1042,6 @@ static void DoError (void)
static int DoIf (int Skip)
/* Process #if directive */
{
ExprDesc Expr;
ED_Init (&Expr);
/* We're about to abuse the compiler expression parser to evaluate the
** #if expression. Save the current tokens to come back here later.
** NOTE: Yes, this is a hack, but it saves a complete separate expression
@ -1079,7 +1076,7 @@ static int DoIf (int Skip)
NextToken ();
/* Call the expression parser */
ConstExpr (hie1, &Expr);
ExprDesc Expr = StaticConstExpr (hie1);
/* End preprocessing mode */
Preprocessing = 0;

View File

@ -44,7 +44,7 @@
/* Set when the preprocessor calls ConstExpr() recursively */
/* Set when the preprocessor calls StaticConstExpr() recursively */
extern unsigned char Preprocessing;

View File

@ -55,8 +55,6 @@ void ParseStaticAssert ()
ExprDesc Expr;
int failed;
ED_Init (&Expr);
/* Skip the _Static_assert token itself */
CHECK (CurTok.Tok == TOK_STATIC_ASSERT);
NextToken ();
@ -67,7 +65,7 @@ void ParseStaticAssert ()
}
/* Parse assertion condition */
ConstAbsIntExpr (hie1, &Expr);
Expr = StaticConstAbsIntExpr (hie1);
failed = !Expr.IVal;
/* If there is a comma, we also have an error message. The message is optional because we

View File

@ -216,8 +216,7 @@ void CaseLabel (void)
NextToken ();
/* Read the selector expression */
ED_Init (&CaseExpr);
ConstAbsIntExpr (hie1, &CaseExpr);
CaseExpr = StaticConstAbsIntExpr (hie1);
Val = CaseExpr.IVal;
/* Now check if we're inside a switch statement */