diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index e8d581f54..3bc7d47cb 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -59,8 +59,8 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Emit code to convert the given expression to a new type. */ { Type* OldType; - unsigned OldSize; - unsigned NewSize; + unsigned OldBits; + unsigned NewBits; /* Remember the old type */ @@ -83,8 +83,12 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) /* Get the sizes of the types. Since we've excluded void types, checking ** for known sizes makes sense here. */ - OldSize = CheckedSizeOf (OldType); - NewSize = CheckedSizeOf (NewType); + if (ED_IsBitField (Expr)) { + OldBits = Expr->BitWidth; + } else { + OldBits = CheckedSizeOf (OldType) * CHAR_BITS; + } + NewBits = CheckedSizeOf (NewType) * CHAR_BITS; /* lvalue? */ if (ED_IsLVal (Expr)) { @@ -97,7 +101,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** If both sizes are equal, do also leave the value alone. ** If the new size is larger, we must convert the value. */ - if (NewSize > OldSize) { + if (NewBits > OldBits) { /* Load the value into the primary */ LoadExpr (CF_NONE, Expr); @@ -114,10 +118,6 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** to handle sign extension correctly. */ - /* Get the current and new size of the value */ - unsigned OldBits = OldSize * 8; - unsigned NewBits = NewSize * 8; - /* Check if the new datatype will have a smaller range. If it ** has a larger range, things are OK, since the value is ** internally already represented by a long. @@ -151,7 +151,7 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ** not equal, add conversion code. Be sure to convert chars ** correctly. */ - if (OldSize != NewSize) { + if (OldBits != NewBits) { /* Load the value into the primary */ LoadExpr (CF_NONE, Expr); @@ -167,6 +167,11 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType) ExitPoint: /* The expression has always the new type */ ReplaceType (Expr, NewType); + + /* Bit-fields are converted to integers */ + if (ED_IsBitField (Expr)) { + ED_DisBitField (Expr); + } }