mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 09:23:44 +00:00
compiler/simplify_goal_conj.m:
Add conditionally-enabled code that can help debug problems with the code
that merges two successive switches on the same variable.
When doing such merges, do not insist on every cons_id that as an arm
in the second switch also having an arm in the first switch.
Document how situations can come about in which such insistence
would be wrong.
This fixes Mantis bug #570. The rest of the diff to the compiler directory
build the debugging infrastructure that lead to tracking down the bug.
compiler/simplify_info.m:
Include the progress stream in the simplify_info, for use by debugging code
such as what this diff adds to simplify_goal_conj.m.
Fix documentation rot.
compiler/simplify_proc.m:
Give the progress stream to simplify_info.m.
Make the argument order of some predicates match our guidelines.
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/pd_util.m:
compiler/size_prof.m:
compiler/stack_opt.m:
compiler/structure_sharing.analysis.m:
Conform to the changes above.
compiler/pd_debug.m:
Put the parts of some debugging code into meaningful groups.
tests/hard_coded/bug570.{m,exp}:
tests/hard_coded/bug570_can_fail.{m,exp}:
Two variants of the Mantis bug's test case. Both are needed for the
explanation in simplify_goal_conj.m.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
Enable the new test cases.
99 lines
2.6 KiB
Mathematica
99 lines
2.6 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% A version of the bug570 test case that shows why the bug cannot occur
|
|
% directly in user-written code. (The explanation for this is available
|
|
% in a comment mentioning this file in compiler/simplify_goal_conj.m.)
|
|
%
|
|
|
|
:- module bug570_can_fail.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module bool.
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
:- type header
|
|
---> header(field_name, header_value).
|
|
|
|
:- type field_name
|
|
---> field_name(string).
|
|
|
|
:- type header_value
|
|
---> header_value(string).
|
|
|
|
:- type message_id
|
|
---> message_id(string).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
main(!IO) :-
|
|
Value = header_value("value"),
|
|
test(prepare_send, Value, !IO),
|
|
io.nl(!IO),
|
|
test(prepare_edit, Value, !IO),
|
|
io.nl(!IO),
|
|
test(prepare_postpone, Value, !IO).
|
|
|
|
:- pred test(prepare_temp::in, header_value::in, io::di, io::uo) is det.
|
|
|
|
test(Prepare, Value, !IO) :-
|
|
io.format("Prepare: %s\n", [s(string.string(Prepare))], !IO),
|
|
( if make_headers(Prepare, Value, Headers) then
|
|
list.foldl(io.print_line, Headers, !IO)
|
|
else
|
|
io.write_string("no headers\n", !IO)
|
|
).
|
|
|
|
:- type prepare_temp
|
|
---> prepare_send
|
|
; prepare_edit
|
|
; prepare_postpone.
|
|
|
|
:- pred make_headers(prepare_temp::in, header_value::in, list(header)::out)
|
|
is semidet.
|
|
|
|
make_headers(Prepare, Value, Headers) :-
|
|
some [!Acc] (
|
|
!:Acc = [],
|
|
(
|
|
Prepare = prepare_send,
|
|
cons(header(field_name("Message-ID"), Value), !Acc)
|
|
;
|
|
Prepare = prepare_postpone
|
|
),
|
|
(
|
|
Prepare = prepare_send,
|
|
SkipEmpty = yes
|
|
;
|
|
( Prepare = prepare_postpone
|
|
; Prepare = prepare_edit % This gets a warning, which is OK.
|
|
),
|
|
SkipEmpty = no
|
|
),
|
|
maybe_cons(SkipEmpty, !Acc),
|
|
Headers = !.Acc
|
|
).
|
|
|
|
:- pred maybe_cons(bool::in, list(header)::in, list(header)::out)
|
|
is det.
|
|
|
|
maybe_cons(SkipEmpty, !Acc) :-
|
|
(
|
|
SkipEmpty = no,
|
|
!:Acc = [header(field_name("skip_empty"), header_value("no")) | !.Acc]
|
|
;
|
|
SkipEmpty = yes,
|
|
!:Acc = [header(field_name("skip_empty"), header_value("yes")) | !.Acc]
|
|
).
|