The model sequencer contains a Bug which leads to the omission of exit sequences.
Model
Consider the following statechart:
We'd expect that e is always executed when any of the states are left.
It is contained in the exit sequence of main_region.StateA:
/* Exit action for state 'StateA'. */
static void exact_main_region_StateA(Default* handle)
{
/* Exit action for state 'StateA'. */
defaultIface_e(handle);
}
Expectation
We'd expect the operation e to be called - always - when the statechart is exited.
Generated code
However, this is not the case. This is the exit sequence of main_region:
/* Default exit sequence for region main region */
static void exseq_main_region(Default* handle)
{
/* Default exit sequence for region main region */
/* Handle exit of all possible states (of default.main_region) at position 0... */
switch(handle->stateConfVector[ 0 ])
{
case Default_main_region_StateA_inner1_StateA1 :
{
exseq_main_region_StateA_inner1_StateA1(handle);
break;
}
case Default_main_region_StateA_inner1_State2_inner2a_State1 :
{
exseq_main_region_StateA_inner1_State2_inner2a_State1(handle);
break;
}
default: break;
}
/* Handle exit of all possible states (of default.main_region) at position 1... */
switch(handle->stateConfVector[ 1 ])
{
case Default_main_region_StateA_inner1_State2_inner2b_State1 :
{
exseq_main_region_StateA_inner1_State2_inner2b_State1(handle);
break;
}
default: break;
}
/* Handle exit of all possible states (of default.main_region) at position 2... */
switch(handle->stateConfVector[ 2 ])
{
case Default_main_region_StateA_inner1_State2_inner3b_State1 :
{
exseq_main_region_StateA_inner1_State2_inner3b_State1(handle);
exact_main_region_StateA(handle);
break;
}
default: break;
}
}
The function exact_main_region_StateA is only called from switch(handle->stateConfVector[ 2 ]). This seems like a good idea to avoid calling the exit sequence multiple times from each parallel state within, but: the whole state must not be active, because the execution can stop in Default_main_region_StateA_inner1_StateA1, and this leads to the exit sequence not being executed at all.
Possible reason
The reason is most likely this part of the new SequenceBuilder in the method defineExitSwitch:
So the exit sequence is only generated when the sum of size and offset of both statevectors are the same.
println added for debugging purposes, producing the following output with the given statechart:
One can see that the only match where default.main_region.StateA is part is the last one - exactly the place where the exit sequence ends up in the code.
The model sequencer contains a Bug which leads to the omission of exit sequences.
Model
Consider the following statechart: We'd expect that
e
is always executed when any of the states are left.It is contained in the exit sequence of
main_region.StateA
:Expectation
We'd expect the operation
e
to be called - always - when the statechart is exited.Generated code
However, this is not the case. This is the exit sequence of
main_region
:The function
exact_main_region_StateA
is only called fromswitch(handle->stateConfVector[ 2 ])
. This seems like a good idea to avoid calling the exit sequence multiple times from each parallel state within, but: the whole state must not be active, because the execution can stop inDefault_main_region_StateA_inner1_StateA1
, and this leads to the exit sequence not being executed at all.Possible reason
The reason is most likely this part of the new
SequenceBuilder
in the methoddefineExitSwitch
:So the exit sequence is only generated when the sum of
size
andoffset
of both statevectors are the same.println
added for debugging purposes, producing the following output with the given statechart:One can see that the only match where
default.main_region.StateA
is part is the last one - exactly the place where the exit sequence ends up in the code.