65816-llvm-mos/demos/cxxProbe.cpp
2026-05-30 19:40:29 -05:00

60 lines
1.5 KiB
C++

// cxxProbe.cpp - full C++ ABI validation incl. dtor invocation.
// $025000 = 0xC0DE Singleton ctor (1st inst())
// $025002 = 0x4242 heap value via new + member access
// $025004 = 1 Singleton ctor count after 3 inst()s (guard works)
// $025006 = 0x6707 global ctor (init_array)
// $025008 = 0x900D end of main
// $02500A = 0xDEAD Singleton DTOR ran (via __cxa_atexit walk)
// $02500C = 0xFEED Global DTOR ran (via __cxa_atexit walk)
extern "C" {
#include <stdint.h>
}
static int gSingletonCtorCalls = 0;
struct Singleton {
int n;
Singleton() : n(0xC0DE) {
gSingletonCtorCalls++;
*(volatile uint16_t *)0x025000UL = (uint16_t)n;
}
~Singleton() {
*(volatile uint16_t *)0x02500AUL = 0xDEAD;
}
};
static Singleton &inst() {
static Singleton s;
return s;
}
struct Heap {
int v;
Heap(int x) : v(x) {}
};
struct GlobalCtor {
GlobalCtor() {
*(volatile uint16_t *)0x025006UL = 0x6707;
}
~GlobalCtor() {
*(volatile uint16_t *)0x02500CUL = 0xFEED;
}
};
static GlobalCtor gGlobal;
static volatile Heap *gHeapEscape = nullptr;
int main(void) {
inst(); inst();
Singleton &s = inst();
(void)s;
Heap *h = new Heap(0x4242);
gHeapEscape = h;
*(volatile uint16_t *)0x025002UL = (uint16_t)gHeapEscape->v;
gHeapEscape = nullptr;
delete h;
*(volatile uint16_t *)0x025004UL = (uint16_t)gSingletonCtorCalls;
*(volatile uint16_t *)0x025008UL = 0x900D;
return 0;
}