1 /* bug-2822.c 2 Overwritten register in call to __z88dk_fastcall function pointer in struct. 3 */ 4 5 #include <testfwk.h> 6 7 #include <stdint.h> 8 9 #if !defined(__SDCC_z80) && !defined(__SDCC_z180) && !defined(__SDCC_r2k) && !defined(__SDCC_r3ka) && !defined(__SDCC_tlcs90) 10 #define __z88dk_fastcall 11 #endif 12 13 #ifndef __SDCC_pdk14 // Lack of memory 14 struct wibble 15 { 16 int (*wobble)(uint8_t *x) __z88dk_fastcall __reentrant; 17 } w; 18 19 struct wibble *wubble = &w; 20 uint8_t xp[4]; 21 foo(uint8_t minor)22void foo(uint8_t minor) 23 { 24 uint8_t x; 25 uint8_t err; 26 uint8_t *bar = xp + minor; 27 28 for(x = 0; x < 4; x++) { 29 err = wubble->wobble(bar); 30 if (err) 31 wubble->wobble(bar); 32 } 33 } 34 35 uint8_t called; 36 f(uint8_t * x)37int f(uint8_t *x) __z88dk_fastcall __reentrant 38 { 39 ASSERT(*x == 0x5a); 40 called++; 41 return(1); 42 } 43 44 struct wibble2 45 { 46 int (*wobble2)(uint32_t) __z88dk_fastcall __reentrant; 47 } w2; 48 49 struct wibble2 *wubble2 = &w2; 50 uint32_t xp2[4]; 51 foo2(uint8_t minor)52void foo2(uint8_t minor) 53 { 54 uint8_t x; 55 uint8_t err; 56 uint32_t *bar = xp2 + minor; 57 58 for(x = 0; x < 4; x++) { 59 err = wubble2->wobble2(*bar); 60 if (err) 61 wubble2->wobble2(*bar); 62 } 63 } 64 65 uint8_t called2; 66 f2(uint32_t x)67int f2(uint32_t x) __z88dk_fastcall __reentrant 68 { 69 ASSERT(x == 0x1155aa88); 70 called2++; 71 return(1); 72 } 73 #endif 74 testBug(void)75void testBug(void) 76 { 77 #ifndef __SDCC_pdk14 // Lack of memory 78 wubble->wobble = &f; 79 xp[1] = 0x5a; 80 foo(1); 81 ASSERT(called == 8); 82 83 wubble2->wobble2 = &f2; 84 xp2[1] = 0x1155aa88; 85 foo2(1); 86 ASSERT(called2 == 8); 87 #endif 88 } 89 90