From 7ed0eb22285570adce8192f6e63cd6f271d52739 Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 10 Oct 2003 19:33:22 +0000 Subject: [PATCH] Fixed a bug git-svn-id: svn://svn.cc65.org/cc65/trunk@2511 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/typeconv.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cc65/typeconv.c b/src/cc65/typeconv.c index 612aa0213..5af7e513c 100644 --- a/src/cc65/typeconv.c +++ b/src/cc65/typeconv.c @@ -144,7 +144,16 @@ static int DoConversion (ExprDesc* Expr, int k, type* NewType) /* If the new type is signed, sign extend the value */ if (!IsSignUnsigned (NewType)) { if (Expr->ConstVal & (0x01UL << (NewBits-1))) { - Expr->ConstVal |= ((~0L) << NewBits); + /* Beware: NewBits may be 32, in which case a shift + * creates undefined behaviour if a long does also + * have 32 bits. So apply a somewhat complex special + * handling. + */ + unsigned long SignBits = ~0UL; + SignBits <<= (NewBits / 2); + NewBits -= (NewBits / 2); + SignBits <<= NewBits; + Expr->ConstVal |= SignBits; } } }