From e20bda21b3425310edc24ae8fc7815d3fd1e3db2 Mon Sep 17 00:00:00 2001 From: cuz Date: Tue, 19 Aug 2003 20:31:10 +0000 Subject: [PATCH] Fixed type conversion problems git-svn-id: svn://svn.cc65.org/cc65/trunk@2371 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/expr.c | 122 ++++++++++++++++++++++++-------------------- src/cc65/typeconv.c | 4 +- 2 files changed, 68 insertions(+), 58 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 702f89c12..bf9ccb5b0 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -426,29 +426,35 @@ void exprhs (unsigned flags, int k, ExprDesc* lval) flags |= CF_TEST; lval->Test &= ~E_FORCETEST; } - if (f & E_MGLOBAL) { /* ref to globalvar */ - /* Generate code */ + if (f & E_MGLOBAL) { + /* Reference to a global variable */ flags |= GlobalModeFlags (f); g_getstatic (flags, lval->Name, lval->ConstVal); } else if (f & E_MLOCAL) { - /* ref to localvar */ + /* Reference to a local variable */ g_getlocal (flags, lval->ConstVal); } else if (f & E_MCONST) { - /* ref to absolute address */ + /* Reference to an absolute address */ g_getstatic (flags | CF_ABSOLUTE, lval->ConstVal, 0); } else if (f == E_MEOFFS) { + /* Reference to address in primary with offset in lval */ g_getind (flags, lval->ConstVal); } else if (f != E_MREG) { + /* Reference with address in primary */ g_getind (flags, 0); } - } else if (f == E_MEOFFS) { - /* reference not storable */ - flags |= TypeOf (lval->Type); - g_inc (flags | CF_CONST, lval->ConstVal); - } else if ((f & E_MEXPR) == 0) { - /* Constant of some sort, load it into the primary */ - LoadConstant (flags, lval); + } else { + /* An rvalue */ + if (f == E_MEOFFS) { + /* reference not storable */ + flags |= TypeOf (lval->Type); + g_inc (flags | CF_CONST, lval->ConstVal); + } else if ((f & E_MEXPR) == 0) { + /* Constant of some sort, load it into the primary */ + LoadConstant (flags, lval); + } } + /* Are we testing this value? */ if (lval->Test & E_FORCETEST) { /* Yes, force a test */ @@ -592,7 +598,7 @@ static unsigned FunctionParamList (FuncDesc* Func) /* We have the space already allocated, store in the frame. * Because of invalid type conversions (that have produced an * error before), we can end up here with a non aligned stack - * frame. Since no output will be generated anyway, handle + * frame. Since no output will be generated anyway, handle * these cases gracefully instead of doing a CHECK. */ if (FrameSize >= ArgSize) { @@ -2579,33 +2585,32 @@ static int hieOr (ExprDesc *lval) static int hieQuest (ExprDesc *lval) /* Parse "lvalue ? exp : exp" */ { - int k; + int k1, k2, k3; int labf; int labt; - ExprDesc lval2; /* Expression 2 */ - ExprDesc lval3; /* Expression 3 */ - type* type2; /* Type of expression 2 */ - type* type3; /* Type of expression 3 */ - type* rtype; /* Type of result */ + ExprDesc lval2; /* Expression 2 */ + ExprDesc lval3; /* Expression 3 */ + type* rtype; /* Type of result */ - k = Preprocessing? hieOrPP (lval) : hieOr (lval); + k1 = Preprocessing? hieOrPP (lval) : hieOr (lval); if (CurTok.Tok == TOK_QUEST) { NextToken (); if ((lval->Test & E_CC) == 0) { /* Condition codes not set, force a test */ lval->Test |= E_FORCETEST; } - exprhs (CF_NONE, k, lval); + exprhs (CF_NONE, k1, lval); labf = GetLocalLabel (); g_falsejump (CF_NONE, labf); /* Parse second expression */ - k = expr (hie1, &lval2); - type2 = lval2.Type; + k2 = expr (hie1, &lval2); if (!IsTypeVoid (lval2.Type)) { /* Load it into the primary */ - exprhs (CF_NONE, k, &lval2); + exprhs (CF_NONE, k2, &lval2); + lval2.Flags = E_MEXPR; + k2 = 0; } labt = GetLocalLabel (); ConsumeColon (); @@ -2613,11 +2618,12 @@ static int hieQuest (ExprDesc *lval) /* Parse the third expression */ g_defcodelabel (labf); - k = expr (hie1, &lval3); - type3 = lval3.Type; + k3 = expr (hie1, &lval3); if (!IsTypeVoid (lval3.Type)) { /* Load it into the primary */ - exprhs (CF_NONE, k, &lval3); + exprhs (CF_NONE, k3, &lval3); + lval3.Flags = E_MEXPR; + k3 = 0; } /* Check if any conversions are needed, if so, do them. @@ -2633,62 +2639,62 @@ static int hieQuest (ExprDesc *lval) * type void. * - all other cases are flagged by an error. */ - if (IsClassInt (type2) && IsClassInt (type3)) { + if (IsClassInt (lval2.Type) && IsClassInt (lval3.Type)) { /* Get common type */ - rtype = promoteint (type2, type3); + rtype = promoteint (lval2.Type, lval3.Type); /* Convert the third expression to this type if needed */ - g_typecast (TypeOf (rtype), TypeOf (type3)); + TypeConversion (&lval3, k3, rtype); /* Setup a new label so that the expr3 code will jump around * the type cast code for expr2. */ labf = GetLocalLabel (); /* Get new label */ - g_jump (labf); /* Jump around code */ + g_jump (labf); /* Jump around code */ /* The jump for expr2 goes here */ g_defcodelabel (labt); /* Create the typecast code for expr2 */ - g_typecast (TypeOf (rtype), TypeOf (type2)); + TypeConversion (&lval2, k2, rtype); /* Jump here around the typecase code. */ g_defcodelabel (labf); - labt = 0; /* Mark other label as invalid */ + labt = 0; /* Mark other label as invalid */ - } else if (IsClassPtr (type2) && IsClassPtr (type3)) { + } else if (IsClassPtr (lval2.Type) && IsClassPtr (lval3.Type)) { /* Must point to same type */ - if (TypeCmp (Indirect (type2), Indirect (type3)) < TC_EQUAL) { - Error ("Incompatible pointer types"); + if (TypeCmp (Indirect (lval2.Type), Indirect (lval3.Type)) < TC_EQUAL) { + Error ("Incompatible pointer types"); } /* Result has the common type */ rtype = lval2.Type; - } else if (IsClassPtr (type2) && IsNullPtr (&lval3)) { + } else if (IsClassPtr (lval2.Type) && IsNullPtr (&lval3)) { /* Result type is pointer, no cast needed */ rtype = lval2.Type; - } else if (IsNullPtr (&lval2) && IsClassPtr (type3)) { + } else if (IsNullPtr (&lval2) && IsClassPtr (lval3.Type)) { /* Result type is pointer, no cast needed */ rtype = lval3.Type; - } else if (IsTypeVoid (type2) && IsTypeVoid (type3)) { + } else if (IsTypeVoid (lval2.Type) && IsTypeVoid (lval3.Type)) { /* Result type is void */ rtype = lval3.Type; - } else { - Error ("Incompatible types"); - rtype = lval2.Type; /* Doesn't matter here */ - } + } else { + Error ("Incompatible types"); + rtype = lval2.Type; /* Doesn't matter here */ + } - /* If we don't have the label defined until now, do it */ - if (labt) { - g_defcodelabel (labt); - } + /* If we don't have the label defined until now, do it */ + if (labt) { + g_defcodelabel (labt); + } - /* Setup the target expression */ + /* Setup the target expression */ lval->Flags = E_MEXPR; - lval->Type = rtype; - k = 0; + lval->Type = rtype; + k1 = 0; } - return k; + return k1; } @@ -2780,7 +2786,7 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *lval, int k) ExprDesc lval2; unsigned lflags; unsigned rflags; - int MustScale; + int MustScale; /* We must have an lvalue */ @@ -2809,16 +2815,20 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *lval, int k) rflags = 0; /* Evaluate the rhs */ - if (evalexpr (CF_NONE, hie1, &lval2) == 0) { + k = hie1 (&lval2); + if (k == 0 && lval2.Flags == E_MCONST) { /* The resulting value is a constant. */ if (MustScale) { /* lhs is a pointer, scale rhs */ lval2.ConstVal *= CheckedSizeOf (lval->Type+1); } rflags |= CF_CONST; - lflags |= CF_CONST; + lflags |= CF_CONST; } else { - /* rhs is not constant and already in the primary register */ + /* Not constant, load into the primary */ + exprhs (CF_NONE, k, &lval2); + lval2.Flags = E_MEXPR; + k = 0; if (MustScale) { /* lhs is a pointer, scale rhs */ g_scale (TypeOf (lval2.Type), CheckedSizeOf (lval->Type+1)); @@ -2829,8 +2839,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *lval, int k) lflags |= TypeOf (lval->Type) | CF_FORCECHAR; rflags |= TypeOf (lval2.Type); - /* Cast the rhs to the type of the lhs */ - g_typecast (lflags, rflags); + /* Convert the type of the lhs to that of the rhs */ + TypeConversion (&lval2, k, lval->Type); /* Output apropriate code */ if (lval->Flags & E_MGLOBAL) { diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 35662ec88..916afbfd6 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -112,7 +112,7 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType) exprhs (CF_NONE, k, Expr); /* Emit typecast code */ - g_typecast (TypeOf (OldType), TypeOf (NewType)); + g_typecast (TypeOf (NewType), TypeOf (OldType)); /* Value is now in primary */ Expr->Flags = E_MEXPR; @@ -161,7 +161,7 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType) exprhs (CF_NONE, k, Expr); /* Emit typecast code. */ - g_typecast (TypeOf (OldType), TypeOf (NewType) | CF_FORCECHAR); + g_typecast (TypeOf (NewType) | CF_FORCECHAR, TypeOf (OldType)); /* Value is now in primary */ Expr->Flags = E_MEXPR;