diff --git a/src/cc65/assignment.c b/src/cc65/assignment.c index 1ada3af0b..09a10a642 100644 --- a/src/cc65/assignment.c +++ b/src/cc65/assignment.c @@ -136,10 +136,11 @@ static int CopyStruct (ExprDesc* LExpr, ExprDesc* RExpr) void Assignment (ExprDesc* Expr) /* Parse an assignment */ { - ExprDesc Expr2; Type* ltype = Expr->Type; + ExprDesc Expr2; ED_Init (&Expr2); + Expr2.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* We must have an lvalue for an assignment */ if (ED_IsRVal (Expr)) { diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 4071728ac..b91fab8a8 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -332,7 +332,7 @@ static void WarnConstCompareResult (const ExprDesc* Expr) -static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) +static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall, ExprDesc* ED) /* Parse a function parameter list, and pass the arguments to the called ** function. Depending on several criteria, this may be done by just pushing ** into each parameter separately, or creating the parameter frame once, and @@ -391,9 +391,10 @@ static unsigned FunctionParamList (FuncDesc* Func, int IsFastcall) /* Parse the actual argument list */ while (CurTok.Tok != TOK_RPAREN) { - unsigned Flags; + unsigned Flags; /* Code generator flags, not expression flags */ ExprDesc Expr; ED_Init (&Expr); + Expr.Flags |= ED->Flags & E_MASK_KEEP_SUBEXPR; /* Count arguments */ ++PushedCount; @@ -609,7 +610,7 @@ static void FunctionCall (ExprDesc* Expr) } /* Parse the parameter list */ - ParamSize = FunctionParamList (Func, IsFastcall); + ParamSize = FunctionParamList (Func, IsFastcall, Expr); /* We need the closing paren here */ ConsumeRParen (); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 8335177bb..74579212e 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -141,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, Type* Type) +static void ParseArg (ArgDesc* Arg, Type* Type, ExprDesc* Expr) /* Parse one argument but do not push it onto the stack. Make all fields in ** Arg valid. */ @@ -154,6 +154,7 @@ static void ParseArg (ArgDesc* Arg, Type* Type) /* Init expression */ ED_Init (&Arg->Expr); + Arg->Expr.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* Read the expression we're going to pass to the function */ MarkedExprWithCheck (hie1, &Arg->Expr); @@ -221,14 +222,14 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Offs; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); ConsumeComma (); /* Argument #2 */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); g_push (Arg2.Flags, Arg2.Expr.IVal); GetCodePos (&Arg2.End); ParamSize += SizeOf (Arg2Type); @@ -239,7 +240,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** also ignored for the calculation of the parameter size, since it is ** not passed via the stack. */ - ParseArg (&Arg3, Arg3Type); + ParseArg (&Arg3, Arg3Type, Expr); if (Arg3.Flags & CF_CONST) { LoadExpr (CF_NONE, &Arg3.Expr); } @@ -562,7 +563,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) unsigned Label; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); @@ -571,7 +572,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Argument #2. This argument is special in that we will call another ** function if it is a constant zero. */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); if ((Arg2.Flags & CF_CONST) != 0 && Arg2.Expr.IVal == 0) { /* Don't call memset, call bzero instead */ MemSet = 0; @@ -588,7 +589,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** also ignored for the calculation of the parameter size, since it is ** not passed via the stack. */ - ParseArg (&Arg3, Arg3Type); + ParseArg (&Arg3, Arg3Type, Expr); if (Arg3.Flags & CF_CONST) { LoadExpr (CF_NONE, &Arg3.Expr); } @@ -790,13 +791,13 @@ static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Arg2Type[1].C = T_CHAR | T_QUAL_CONST; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); ParamSize += SizeOf (Arg1Type); ConsumeComma (); /* Argument #2. */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); /* Since strcmp is a fastcall function, we must load the ** arg into the primary if it is not already there. This parameter is @@ -990,7 +991,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) Arg2Type[1].C = T_CHAR | T_QUAL_CONST; /* Argument #1 */ - ParseArg (&Arg1, Arg1Type); + ParseArg (&Arg1, Arg1Type, Expr); g_push (Arg1.Flags, Arg1.Expr.IVal); GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); @@ -1001,7 +1002,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) ** also ignored for the calculation of the parameter size, since it is ** not passed via the stack. */ - ParseArg (&Arg2, Arg2Type); + ParseArg (&Arg2, Arg2Type, Expr); if (Arg2.Flags & CF_CONST) { LoadExpr (CF_NONE, &Arg2.Expr); } @@ -1184,6 +1185,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) unsigned L; ED_Init (&Arg); + Arg.Flags |= Expr->Flags & E_MASK_KEEP_SUBEXPR; /* Setup the argument type string */ ArgType[1].C = T_CHAR | T_QUAL_CONST;