mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 00:29:31 +00:00
RHS primary integer promotion must happen after loading the primary, not before. See: #2060
This commit is contained in:
parent
805e98a7aa
commit
1c26b1cf1b
@ -3090,9 +3090,10 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
||||
Expr->Type = Expr2.Type;
|
||||
} else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||
/* Integer addition */
|
||||
flags = typeadjust (Expr, &Expr2, 0);
|
||||
/* Load rhs into the primary */
|
||||
LoadExpr (CF_NONE, &Expr2);
|
||||
/* Adjust rhs primary if needed */
|
||||
flags = typeadjust (Expr, &Expr2, 0);
|
||||
} else {
|
||||
/* OOPS */
|
||||
AddDone = -1;
|
||||
|
56
test/val/bug2060.c
Normal file
56
test/val/bug2060.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* Test of bug: https://github.com/cc65/cc65/issues/2060 */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define W 320
|
||||
|
||||
unsigned long test1(unsigned char* p, unsigned long n)
|
||||
{
|
||||
(void)p;
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned long test0(unsigned char* p, int x, int y, unsigned char b)
|
||||
{
|
||||
(void)b;
|
||||
return test1(p, (long)y * W + x);
|
||||
}
|
||||
|
||||
#define TEST(ta,tb) \
|
||||
expect = (long)tb * W + ta; \
|
||||
result = test0(p,ta,tb,0x56); \
|
||||
printf("%4d * %3d + %4d = %08lx",tb,W,ta,result); \
|
||||
if (expect != result) { printf(" expected: %08lx\n",expect); ++fail; } \
|
||||
else printf("\n");
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned char* p = (unsigned char*)0x1234;
|
||||
unsigned long expect, result;
|
||||
int fail = 0;
|
||||
|
||||
TEST(1,3);
|
||||
TEST(50,60);
|
||||
TEST(99,88);
|
||||
TEST(128,102);
|
||||
TEST(129,102);
|
||||
TEST(320,102);
|
||||
/* Bug 2060 indicated failure when y > 102.
|
||||
Because: (y * 320) > 32767
|
||||
The promotion of x from int to long had an incorrect high word,
|
||||
because it was done before loading x into AX, rather than after.
|
||||
*/
|
||||
TEST(0,103);
|
||||
TEST(150,170);
|
||||
TEST(300,180);
|
||||
/* x < 0 also fails because its high word sign extend is incorrect. */
|
||||
TEST(-100,50);
|
||||
TEST(-49,99);
|
||||
TEST(-300,-180);
|
||||
/* This passed despite the bug, because y * 320 coincidentally had the
|
||||
same high word.
|
||||
*/
|
||||
TEST(-1,-1);
|
||||
|
||||
return fail;
|
||||
}
|
Loading…
Reference in New Issue
Block a user