struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / support / regression / tests / bug-3606.c
blob480caa75d64a506e439ccdcc610851c4476c4b48
1 /* bug-3606.c
2 Codegen for sm83 could geneate code for a left shift of a 16-bit variable that would result in stack corruption.
3 */
5 #include <testfwk.h>
7 #include <stdint.h>
9 #define FALSE 0
10 #define TRUE 1
12 typedef enum {
13 DIR_UP = 0U,
14 DIR_DOWN = 24U,
15 DIR_LEFT = 36U,
16 DIR_RIGHT = 12U
17 } DIRECTION;
19 #define PLAYER_X_LEFT_BOUND_PX 8U
20 #define PLAYER_X_CENTER_BOUND_PX 88U
21 #define PLAYER_X_RIGHT_BOUND_PX 160U
22 #define PLAYER_Y_UP_BOUND_PX 16U
23 #define PLAYER_Y_CENTER_BOUND_PX 80U
24 #define PLAYER_Y_DOWN_BOUND_PX 152U
25 #define PLAYER_SPEED 21
26 #define LEFT_BOUND 48
27 #define RIGHT_BOUND 652
28 #define TOP_BOUND 48
29 #define BOTTOM_BOUND 652
31 typedef struct PlayerObject {
32 uint8_t spriteId;
33 uint8_t animFrame;
34 uint16_t xSpr;
35 uint16_t ySpr;
36 int16_t xMap;
37 int16_t yMap;
38 uint8_t xTile;
39 uint8_t yTile;
40 uint8_t topOffsetInPx;
41 uint8_t bottomOffsetInPx;
42 uint8_t leftOffsetInPx;
43 uint8_t rightOffsetInPx;
44 DIRECTION dir;
45 uint8_t moveSpeed;
46 int8_t xVel;
47 int8_t yVel;
48 uint8_t hpMax;
49 uint8_t hpCur;
50 } PlayerObject;
53 uint8_t i;
54 uint8_t j;
55 uint8_t k;
57 #if !defined(__SDCC_pdk13) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) && !defined(__SDCC_mcs51) // Lack of memory
58 static uint8_t playGrid[32U][32U]; // We need the array sizes of 32 to trigger the bug.
59 #endif
61 #define STARTPOS 0U
62 #define STARTCAM 0U
64 static uint8_t roomId;
65 static uint8_t gridW;
66 static uint8_t gridH;
67 static uint16_t camera_max_x = 10U * 16U;
68 static uint16_t camera_max_y = 9U * 16U;
69 static uint8_t walkableTileCount = 6U;
71 static uint16_t camera_x = STARTCAM, camera_y = STARTCAM, new_camera_x = STARTCAM, new_camera_y = STARTCAM;
72 static uint8_t map_pos_x = STARTPOS, map_pos_y = STARTPOS, new_map_pos_x = STARTPOS, new_map_pos_y = STARTPOS;
73 static uint8_t redraw;
75 PlayerObject player;
77 static void func_1(void);
78 static void func_2(void);
80 void
81 testBug (void)
83 player.ySpr = 16;
84 func_1();
87 static void func_1(void)
89 player.xVel = player.moveSpeed;
90 player.yVel = 0;
91 player.dir = DIR_RIGHT;
93 func_2();
96 static void func_2(void)
98 #if !defined(__SDCC_pdk13) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) && !defined(__SDCC_mcs51) // Lack of memory
99 int16_t x = player.xSpr + player.xVel;
100 int16_t y = player.ySpr + player.yVel;
102 uint8_t topOffset = 8;
103 uint8_t bottomOffset = 1;
104 uint8_t leftOffset = 4;
105 uint8_t rightOffset = 5;
107 // If you comment/uncomment one of these...
108 static uint8_t playerTopMetatileIndex;
109 playerTopMetatileIndex = (y) - 16U;
111 uint8_t playerBottomMetatileIndex = y;
112 uint8_t playerLeftMetatileIndex = x;
113 uint8_t playerRightMetatileIndex = x;
115 uint8_t collided = TRUE;
116 switch (player.dir)
118 case DIR_UP:
119 if ((playGrid[playerTopMetatileIndex][playerLeftMetatileIndex] < walkableTileCount)
120 && (playGrid[playerTopMetatileIndex][playerRightMetatileIndex] < walkableTileCount))
121 collided = FALSE;
122 break;
123 case DIR_DOWN:
124 if ((playGrid[playerBottomMetatileIndex][playerLeftMetatileIndex] < walkableTileCount)
125 && (playGrid[playerBottomMetatileIndex][playerRightMetatileIndex] < walkableTileCount))
126 collided = FALSE;
127 break;
128 case DIR_LEFT:
129 if ((playGrid[playerTopMetatileIndex][playerLeftMetatileIndex] < walkableTileCount)
130 && (playGrid[playerBottomMetatileIndex][playerLeftMetatileIndex] < walkableTileCount))
131 collided = FALSE;
132 break;
133 case DIR_RIGHT:
134 if ((playGrid[playerTopMetatileIndex][playerRightMetatileIndex] < walkableTileCount)
135 && (playGrid[playerBottomMetatileIndex][playerRightMetatileIndex] < walkableTileCount))
136 collided = FALSE;
137 break;
141 i = (x) - 8U;
142 j = (y) - 16U;
144 if (collided == FALSE)
146 player.xSpr = x;
147 player.ySpr = y;
149 else
151 switch (player.dir)
153 case DIR_UP: player.ySpr = (playerTopMetatileIndex); break;
154 case DIR_DOWN: player.ySpr = (playerBottomMetatileIndex); break;
155 case DIR_LEFT: player.xSpr = (playerLeftMetatileIndex + 1U); break;
156 case DIR_RIGHT: player.xSpr = (playerRightMetatileIndex); break;
157 default: break;
160 player.xVel = 0U;
161 player.yVel = 0U;
163 #endif