Files
mercury/tests/hard_coded/conditional_trace_scope.m
Zoltan Somogyi 1b65853d2d Fix a bug that caused the compiler to mishandle code like this:
Estimated hours taken: 4
Branches: main

Fix a bug that caused the compiler to mishandle code like this:

	test(X, Y) :-
	    ( X < 10 ->
		X = Y
	    ;
		trace [compiletime(flag("flag_is_not_set"))] (
		    error("error_is_not_thrown")
		),
		Y = X + 1
	    ).

The problem was that the compiler deleted everything after the call to error
as unreachable code, even though the trace scope may not be enabled, and if
it isn't, then the code after it WILL be reached.

compiler/det_analysis.m:
	Fix the bug.

compiler/modecheck_goal.m:
compiler/modes.m:
compiler/unique_modes.m:
	Do not allow goals in trace scopes to bind variables in unique_modes.m.
	We already disallow this during ordinary mode checking; do likewise
	during unique mode checking.

	When --debug-modes enables progress messages from the modechecker,
	make the messages for scopes more specific, to help track down
	problems like this.

	Make the debug progress messages also indicate procedure boundaries
	and entries into and exits from more kinds of goals, again to help
	to track down problems like this.

	Put some argument lists in a more logical order.

tests/hard_coded/conditional_trace_scope.{m,exp}:
	A regression test case for the bug.

tests/hard_coded/Mmakefile:
	Enable the new test case.
2011-08-17 03:28:17 +00:00

39 lines
860 B
Mathematica

% vim: ts=4 sw=4 et ft=mercury
%
% The test predicate of this test case contains a conditionally enabled
% trace goal that throws an exception. Both the main and the unique mode
% checkers normally discard any goals after any erroneous goals, but if
% the erroneous goal is in a trace scope that may be deleted, they should
% not do so.
:- module conditional_trace_scope.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module int.
:- import_module list.
:- import_module require.
:- import_module string.
main(!IO) :-
test(42, Y),
io.format("X = %d\n", [i(Y)], !IO).
:- pred test(int::in, int::out) is det.
test(X, Y) :-
( X < 10 ->
X = Y
;
trace [compiletime(flag("flag_is_not_set"))] (
error("error_is_not_thrown")
),
Y = X + 1
).