[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [tlaplus] Re: PlusCal: implicit label Error (PlusCal translator bug?)
Bump. Reattaching the minimal test-case.
On 02.12.2015 15:45, Jaak Ristioja wrote:
> On 01.12.2015 18:28, Leslie Lamport wrote:
>> A goto to the "Error" label is supposed to be executed when execution
>> reaches the end of a procedure without finding a return statement. I
>> suspect that in this case, the return is returning to someplace that
>> drops it off the end of a calling procedure. I can't tell exactly
>> what's happening without seeing a complete example. If you have an
>> example in which such a goto is being executed when it shouldn't be,
>> please send it to me. (But please try to pare it down to the smallest
>> example you can find.)
>
> I've attached a minimum testcase to this email. It seems that a
> workaround is to write
>
> if (cond) {
> call g();
> };
> return;
>
> instead of simply:
>
> if (cond)
> call g();
> return;
Any update on this?
>> The translator does not produce an error because it doesn't know
>> whether that goto "Error" can actually be executed. Determining
>> whether a particular statement in a program will be executed is an
>> unsolvable problem, and we had more important things to do than add
>> heuristics to the translator for attempting to solve this problem.
>
> I agree, but I don't currently see why anybody would want to or should
> be allowed to write PlusCal procedures which fall off the end. Can you
> present an use-case for this? Wouldn't it just be better for the PlusCal
> procedure to always return implicitly when it reaches the end of the
> procedure block?
I've been thinking about this for a few days and have come up with no
good use case. Anybody?
Best regards,
Jaak
-------------------------------- MODULE bug --------------------------------
EXTENDS Sequences
(* --algorithm bug {
procedure g() { return; }
procedure f() {
if (FALSE)
call g();
return;
}
{ call f(); } \* Single process
} *)
\* BEGIN TRANSLATION
VARIABLES pc, stack
vars == << pc, stack >>
Init == /\ stack = << >>
/\ pc = "Lbl_3"
Lbl_1 == /\ pc = "Lbl_1"
/\ pc' = Head(stack).pc
/\ stack' = Tail(stack)
g == Lbl_1
Lbl_2 == /\ pc = "Lbl_2"
/\ IF FALSE
THEN /\ stack' = << [ procedure |-> "g",
pc |-> Head(stack).pc ] >>
\o Tail(stack)
/\ pc' = "Lbl_1"
ELSE /\ pc' = "Error"
/\ stack' = stack
f == Lbl_2
Lbl_3 == /\ pc = "Lbl_3"
/\ stack' = << [ procedure |-> "f",
pc |-> "Done" ] >>
\o stack
/\ pc' = "Lbl_2"
Next == g \/ f \/ Lbl_3
\/ (* Disjunct to prevent deadlock on termination *)
(pc = "Done" /\ UNCHANGED vars)
Spec == Init /\ [][Next]_vars
Termination == <>(pc = "Done")
\* END TRANSLATION
=============================================================================