From d5b3ff4bca8659ec11877fdbb5ee3522ca62b785 Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 26 Jul 2003 07:31:15 +0000 Subject: [PATCH] Fixed a bug git-svn-id: svn://svn.cc65.org/cc65/trunk@2234 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeseg.h | 18 +++++++++++++++--- src/cc65/expr.c | 6 +++--- src/cc65/swstmt.c | 32 +++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h index aa923e3de..4a96bb57d 100644 --- a/src/cc65/codeseg.h +++ b/src/cc65/codeseg.h @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2001-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2001-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -189,6 +189,18 @@ int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count); * possible span instead. */ +#if defined(HAVE_INLINE) +INLINE int CS_HavePendingLabel (const CodeSeg* S) +/* Return true if there are open labels that will get attached to the next + * instruction that is added. + */ +{ + return (CollCount (&S->Labels) > 0); +} +#else +# define CS_HavePendingLabel(S) (CollCount (&(S)->Labels) > 0) +#endif + CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name); /* Add a code label for the next instruction to follow */ diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 92d6013d8..b10c568b4 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -224,15 +224,15 @@ unsigned assignadjust (type* lhst, ExprDesc* rhs) if (IsClassPtr (rhst)) { /* Pointer -> int conversion */ Warning ("Converting pointer to integer without a cast"); - } else if (!IsClassInt (rhst)) { - Error ("Incompatible types"); - } else { + } else if (IsClassInt (rhst)) { /* Convert the rhs to the type of the lhs. */ unsigned flags = TypeOf (rhst); if (rhs->Flags == E_MCONST) { flags |= CF_CONST; } return g_typecast (TypeOf (lhst), flags); + } else { + Error ("Incompatible types"); } } else if (IsClassPtr (lhst)) { if (IsClassPtr (rhst)) { diff --git a/src/cc65/swstmt.c b/src/cc65/swstmt.c index c7446c020..7a6b716c2 100644 --- a/src/cc65/swstmt.c +++ b/src/cc65/swstmt.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2002 Ullrich von Bassewitz */ +/* (C) 1998-2003 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@cc65.org */ @@ -73,6 +73,7 @@ void SwitchStatement (void) unsigned ExitLabel; /* Exit label */ unsigned CaseLabel; /* Label for case */ unsigned DefaultLabel; /* Label for the default branch */ + unsigned SwitchCodeLabel; /* Label for the switch code */ long Val; /* Case label value */ int HaveBreak = 0; /* True if the last statement had a break */ @@ -85,12 +86,26 @@ void SwitchStatement (void) intexpr (&SwitchExpr); ConsumeRParen (); + /* Add a jump to the switch code. This jump is usually unnecessary, + * because the switch code will moved up just behind the switch + * expression. However, in rare cases, there's a label at the end of + * the switch expression. This label will not get moved, so the code + * jumps around the switch code, and after moving the switch code, + * things look really weird. If we add a jump here, we will never have + * a label attached to the current code position, and the jump itself + * will get removed by the optimizer if it is unnecessary. + */ + SwitchCodeLabel = GetLocalLabel (); + g_jump (SwitchCodeLabel); + + /* Remember the current code position. We will move the switch code + * to this position later. + */ + CaseCodeStart = GetCodePos(); + /* Opening curly brace */ ConsumeLCurly (); - /* Remember the current code position */ - CaseCodeStart = GetCodePos(); - /* Get the unqualified type of the switch expression */ SwitchExprType = UnqualifiedType (SwitchExpr.Type[0]); @@ -124,7 +139,7 @@ void SwitchStatement (void) /* Read the selector expression */ ConstExpr (&CaseExpr); if (!IsClassInt (CaseExpr.Type)) { - Error ("Switch quantity not an integer"); + Error ("Switch quantity not an integer"); } /* Check the range of the expression */ @@ -167,7 +182,7 @@ void SwitchStatement (void) } /* Insert the case selector into the selector table */ - CaseLabel = InsertCaseValue (Nodes, Val, Depth); + CaseLabel = InsertCaseValue (Nodes, Val, Depth); /* Define this label */ g_defcodelabel (CaseLabel); @@ -211,7 +226,7 @@ void SwitchStatement (void) Warning ("No case labels"); } else { - + CodeMark SwitchCodeStart; /* If the last statement did not have a break, we may have an open @@ -228,6 +243,9 @@ void SwitchStatement (void) /* Remember the current position */ SwitchCodeStart = GetCodePos(); + /* Output the switch code label */ + g_defcodelabel (SwitchCodeLabel); + /* Generate code */ g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth); -- 2.39.5