struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / support / regression / tests / bug-3567.c
blobfd07dc0cd3b645c9bdfcb47a16a89e9eacc4dc40
1 /* bug-3255.c
2 For z80, a read from a pointer overwrote register a that was in use for a local variable.
3 */
5 #include <testfwk.h>
7 // Based on code by "Under4Mhz" licensed under GPL 2.0 or later
8 #include <stdint.h>
10 #if !(defined(__SDCC_mcs51) && defined(__SDCC_MODEL_SMALL)) && !defined(__SDCC_pdk14) // Lack of memory
11 static volatile uint8_t VDPControlPort;
12 static volatile uint8_t VDPDataPortOut;
14 #define BYTE_HI(x) ((x)>>8)
15 #define VDU_ADDRESS_SET_MASK 0x4000
17 void vdu_stop() {}
19 #define vdu_next_set_fast(value) VDPDataPortOut = value
20 #define vdu_address_set_unsafe(address) { VDPControlPort=address; VDPControlPort=BYTE_HI((address) | VDU_ADDRESS_SET_MASK ); }
22 #define for8( var, size ) for ( unsigned char var = 0; var < size; var++ )
23 typedef uint8_t u8;
24 typedef uint16_t u16;
26 #define MAX_TILES 24
28 typedef struct {
30 u16 address;
31 u8 size;
32 u8 tile[2];
34 } GameTile;
36 typedef struct {
38 GameTile tiles[MAX_TILES];
39 u8 size;
41 } GameTileState;
43 GameTileState gameTiles = { .size = 2, .tiles = { { 1, 2, { 2, 3 } }, { 6, 2, { 7, 8 } } } };
45 int p(int i)
47 ASSERT (i == 2);
50 void GameTileCallback() {
52 vdu_stop();
54 GameTile *gameTile = gameTiles.tiles;
56 for8( id, gameTiles.size ) {
58 vdu_address_set_unsafe( gameTile->address );
60 u8 *ptr = gameTile->tile;
61 u8 size; size = gameTile->size;
62 do {
63 vdu_next_set_fast( *ptr++ ); // Pointer read here overwrote size, which was allocated to register a.
65 } while ( --size );
67 p (ptr - gameTile->tile);
69 gameTile++;
72 gameTiles.size = 0;
74 #endif
76 void
77 testBug(void) {
78 #if !(defined(__SDCC_mcs51) && defined(__SDCC_MODEL_SMALL)) && !defined(__SDCC_pdk14) // Lack of memory
79 GameTileCallback();
80 #endif