Files
mercury/tests/warnings/bug477.m
Zoltan Somogyi 30901debf3 Warn about infinite recursive calls inside try goals.
compiler/hlds_goal.m:
    Add a goal feature that is intended to mark lambda goals
    created to implement try goals.

compiler/try_expand.m:
    Add this feature to the lambda goals created to implement try goals.

compiler/simplify_info.m:
    Replace an old counter "number of lambdas we are inside" with a
    slightly different counter "number of non-try lambdas we are inside".
    Move the position of the counter in its structure to reveal
    all the places that must be updated to account for this.

compiler/simplify_goal_unify.m:
    Do NOT increment the changed counter while traversing lambda goals
    that are part of the implementation of try goals.

compiler/simplify_goal_call.m:
    We used to suppress the generation of warnings about infinite recursion
    if we were inside any lambdas. This is because if the code of e.g.
    "p(InArgs, OutArgsA)" constructs a higher order value that contains
    the apparently-infinitely-recursive call "p(InARgs, OutArgsB)",
    the code that calls the new closure may well be *outside* the call tree
    of predicate p, and would thus no longer be recursive.

    However, a closure constructed to implement a try goal *will* be called
    inside the predicate that constructs it. So we now suppress the warning
    only if the number of *non-try* lambdas we are inside is nonzero.
    This is the motive behind the change in semantics in simplify_info.

    This implements feature request Mantis #477.

compiler/simplify_proc.m:
compiler/saved_vars.m:
    Conform to the changes above.

tests/warnings/bug477.{m,exp}:
    A test case for the new functionality.

tests/warnings/Mmakefile:
    Enable the new test.
2019-04-20 12:00:40 +10:00

50 lines
1.2 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
%
% Test for infinite recursion through a try wrapper.
%
%---------------------------------------------------------------------------%
:- module bug477.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.
:- implementation.
:- import_module string.
:- type logger
---> logger.
:- type jscenario
---> jscenario.
:- type jsolution
---> jsolution.
main(!IO) :-
reconstruct_route(logger, jscenario, Solution),
io.print_line(Solution, !IO).
:- pred reconstruct_route(logger::in, jscenario::in, jsolution::out)
is cc_multi.
reconstruct_route(Log, JScenario, JSolution) :-
( try []
reconstruct_route(Log, JScenario, JSolution0)
then
JSolution = JSolution0
catch_any Excp ->
trace [io(!IO)] (
Msg = "Exception during route reconstruction: " ++ string(Excp),
error(Log, Msg, !IO)
),
JSolution = jsolution
).
:- pred error(logger::in, string::in, io::di, io::uo) is det.
error(_, _, !IO).