Fixed a bug
git-svn-id: svn://svn.cc65.org/cc65/trunk@2234 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -6,9 +6,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2001-2002 Ullrich von Bassewitz */
|
/* (C) 2001-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<EFBFBD>merstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@@ -189,6 +189,18 @@ int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count);
|
|||||||
* possible span instead.
|
* 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);
|
CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name);
|
||||||
/* Add a code label for the next instruction to follow */
|
/* Add a code label for the next instruction to follow */
|
||||||
|
|
||||||
|
|||||||
@@ -224,15 +224,15 @@ unsigned assignadjust (type* lhst, ExprDesc* rhs)
|
|||||||
if (IsClassPtr (rhst)) {
|
if (IsClassPtr (rhst)) {
|
||||||
/* Pointer -> int conversion */
|
/* Pointer -> int conversion */
|
||||||
Warning ("Converting pointer to integer without a cast");
|
Warning ("Converting pointer to integer without a cast");
|
||||||
} else if (!IsClassInt (rhst)) {
|
} else if (IsClassInt (rhst)) {
|
||||||
Error ("Incompatible types");
|
|
||||||
} else {
|
|
||||||
/* Convert the rhs to the type of the lhs. */
|
/* Convert the rhs to the type of the lhs. */
|
||||||
unsigned flags = TypeOf (rhst);
|
unsigned flags = TypeOf (rhst);
|
||||||
if (rhs->Flags == E_MCONST) {
|
if (rhs->Flags == E_MCONST) {
|
||||||
flags |= CF_CONST;
|
flags |= CF_CONST;
|
||||||
}
|
}
|
||||||
return g_typecast (TypeOf (lhst), flags);
|
return g_typecast (TypeOf (lhst), flags);
|
||||||
|
} else {
|
||||||
|
Error ("Incompatible types");
|
||||||
}
|
}
|
||||||
} else if (IsClassPtr (lhst)) {
|
} else if (IsClassPtr (lhst)) {
|
||||||
if (IsClassPtr (rhst)) {
|
if (IsClassPtr (rhst)) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2002 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -73,6 +73,7 @@ void SwitchStatement (void)
|
|||||||
unsigned ExitLabel; /* Exit label */
|
unsigned ExitLabel; /* Exit label */
|
||||||
unsigned CaseLabel; /* Label for case */
|
unsigned CaseLabel; /* Label for case */
|
||||||
unsigned DefaultLabel; /* Label for the default branch */
|
unsigned DefaultLabel; /* Label for the default branch */
|
||||||
|
unsigned SwitchCodeLabel; /* Label for the switch code */
|
||||||
long Val; /* Case label value */
|
long Val; /* Case label value */
|
||||||
int HaveBreak = 0; /* True if the last statement had a break */
|
int HaveBreak = 0; /* True if the last statement had a break */
|
||||||
|
|
||||||
@@ -85,12 +86,26 @@ void SwitchStatement (void)
|
|||||||
intexpr (&SwitchExpr);
|
intexpr (&SwitchExpr);
|
||||||
ConsumeRParen ();
|
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 */
|
/* Opening curly brace */
|
||||||
ConsumeLCurly ();
|
ConsumeLCurly ();
|
||||||
|
|
||||||
/* Remember the current code position */
|
|
||||||
CaseCodeStart = GetCodePos();
|
|
||||||
|
|
||||||
/* Get the unqualified type of the switch expression */
|
/* Get the unqualified type of the switch expression */
|
||||||
SwitchExprType = UnqualifiedType (SwitchExpr.Type[0]);
|
SwitchExprType = UnqualifiedType (SwitchExpr.Type[0]);
|
||||||
|
|
||||||
@@ -124,7 +139,7 @@ void SwitchStatement (void)
|
|||||||
/* Read the selector expression */
|
/* Read the selector expression */
|
||||||
ConstExpr (&CaseExpr);
|
ConstExpr (&CaseExpr);
|
||||||
if (!IsClassInt (CaseExpr.Type)) {
|
if (!IsClassInt (CaseExpr.Type)) {
|
||||||
Error ("Switch quantity not an integer");
|
Error ("Switch quantity not an integer");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the range of the expression */
|
/* Check the range of the expression */
|
||||||
@@ -167,7 +182,7 @@ void SwitchStatement (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the case selector into the selector table */
|
/* Insert the case selector into the selector table */
|
||||||
CaseLabel = InsertCaseValue (Nodes, Val, Depth);
|
CaseLabel = InsertCaseValue (Nodes, Val, Depth);
|
||||||
|
|
||||||
/* Define this label */
|
/* Define this label */
|
||||||
g_defcodelabel (CaseLabel);
|
g_defcodelabel (CaseLabel);
|
||||||
@@ -228,6 +243,9 @@ void SwitchStatement (void)
|
|||||||
/* Remember the current position */
|
/* Remember the current position */
|
||||||
SwitchCodeStart = GetCodePos();
|
SwitchCodeStart = GetCodePos();
|
||||||
|
|
||||||
|
/* Output the switch code label */
|
||||||
|
g_defcodelabel (SwitchCodeLabel);
|
||||||
|
|
||||||
/* Generate code */
|
/* Generate code */
|
||||||
g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth);
|
g_switch (Nodes, DefaultLabel? DefaultLabel : ExitLabel, Depth);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user