diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /support/regression/tests/bug1908493.c | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'support/regression/tests/bug1908493.c')
| -rw-r--r-- | support/regression/tests/bug1908493.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/support/regression/tests/bug1908493.c b/support/regression/tests/bug1908493.c new file mode 100644 index 0000000..f61fb65 --- /dev/null +++ b/support/regression/tests/bug1908493.c @@ -0,0 +1,139 @@ +/* Bug 1908493 + * Bug test contains code fragments from qpnano framework, + * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved. + * and released under the GPL + * See www.quantum-leaps.com/downloads/index.htm#QPN + */ + +#include <testfwk.h> + +#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) + +#define Q_REENTRANT __reentrant +#define Q_ASSERT +#define Q_SIG(me_) (((QFsm *)(me_))->evt.sig) +#define int8_t char +#define QEP_MAX_NEST_DEPTH 5 + +#define QEP_EMPTY_SIG 0 + +enum QReservedSignals { + Q_ENTRY_SIG = 1, /**< signal for coding entry actions */ + Q_EXIT_SIG, /**< signal for coding exit actions */ + Q_INIT_SIG, /**< signal for coding nested initial transitions */ + Q_TIMEOUT_SIG, /**< signal used by time events */ + Q_USER_SIG /**< first signal that can be used in user applications */ +}; + +typedef int8_t QSignal; +typedef struct QEventTag { + QSignal sig; +} QEvent; + +struct QFsmTag; +struct QHsmTag; + +typedef void (*QState) (struct QFsmTag *me); +typedef QState (*QHsmState) (struct QHsmTag *me); + +typedef QState QSTATE; + +typedef struct QFsmTag { + QState state; + QEvent evt; +} QFsm; + +typedef struct QHsmTag { + QHsmState state; + QEvent evt; +} QHsm; + +typedef struct QHsmDerivedTag { + QHsm super; + char value; +} QHsmDerived; + +QHsmDerived AO_derived; + +QSTATE +state_1 (QHsmDerived *me) Q_REENTRANT +{ + if (Q_SIG (me) == Q_INIT_SIG) + me->value = 3; + + return (QSTATE)0; +} + +QSTATE +state_2 (QHsmDerived *me) Q_REENTRANT +{ + if (Q_SIG (me) == Q_USER_SIG) + return (QSTATE)state_1; + + return (QSTATE)0; +} + +void +QHsm_dispatch (QHsm *me) Q_REENTRANT +{ + QHsmState path[QEP_MAX_NEST_DEPTH]; + QHsmState s; + QHsmState t = me->state; + + path[1] = t; /* save the current state in case a transition is taken */ + + do /* process the event hierarchically... */ + { + s = t; + + /******************************************************************** + * + * The call which fails when s is copied from the stack frame + * + ********************************************************************/ + t = (QHsmState)((*s) (me)); /* invoke state handler s */ + + } + while (t != (QHsmState)0); + + if (me->evt.sig == (QSignal)0) /* transition taken? */ + { + QHsmState src = s; /* the source of the transition */ + int8_t ip = (int8_t)(-1); /* transition entry path index */ + + path[0] = me->state; /* save the new state */ + me->state = path[1]; /* restore the current state */ + + /* exit current state to the transition source src... */ + for (s = path[1]; s != src; ) + { + Q_SIG (me) = (QSignal)Q_EXIT_SIG; + t = (QHsmState)(*s) (me); /* find superstate of s */ + if (t != (QHsmState)0) /* exit action unhandled */ + { + s = t; /* t points to superstate */ + } + else /* exit action handled */ + { + Q_SIG (me) = (QSignal)QEP_EMPTY_SIG; + s = (QHsmState)(*s) (me); /* find superstate of s */ + } + } + + t = path[0]; /* target of the transition */ + } +} +#endif + +void +testBug (void) +{ +#if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) + AO_derived.super.state = (QHsmState)state_2; + AO_derived.super.evt.sig = 2; + + QHsm_dispatch ((QHsm *)&AO_derived); + + ASSERT (1); /*if we don't get here the regression test will timeout */ +#endif +} |
