/* bug-3003.c The wrong location is used for a local variable; observable effects vary by backend. For stm8, this results in overwriting other local variables. For z80, it results in use of location below the stack. */ #include #include #include #pragma disable_warning 88 void g(void) { } static volatile uint8_t* f(const uint8_t id) { volatile uint8_t* result = 0; // Bug: For stm8, this variable is accessed at stack at sp+255, overwriting part of buffer. switch (id) { case 0: result = (volatile uint8_t *)0x5000; break; case 1: result = (volatile uint8_t *)0x5005; break; case 2: result = (volatile uint8_t *)0x500a; break; } g(); // This call overwrites result by the return address for z80. return result; } #if defined (__SDCC_pdk14) || defined (__SDCC_pdk15) || defined (__SDCC_mcs51) || defined (__SDCC_STACK_AUTO) // Lack of memory #define BUFFERSIZE 20 #else #define BUFFERSIZE 300 #endif void testBug(void) { unsigned char buffer[BUFFERSIZE]; // Bug: Overwritten in f() on stm8. memset(buffer, 0xa5, BUFFERSIZE); ASSERT(f(0) == (volatile uint8_t *)0x5000); ASSERT(f(1) == (volatile uint8_t *)0x5005); ASSERT(f(2) == (volatile uint8_t *)0x500a); for(size_t i = 0; i < BUFFERSIZE; i++) ASSERT (buffer[i] == 0xa5); }