Diff: bug fix in simplify.m

Andrew Bromage bromage at cs.mu.oz.au
Mon Jul 28 14:00:46 AEST 1997


G'day.

Simon, could you please review this change?  Thanks.

Cheers,
Andrew Bromage


Estimated hours taken: 1

Fix to a bug where the compiler was spitting out incorrect warnings
about infinite recursion when the recursive call was inside a lambda.

compiler/simplify.m:
	Fix detailed above.

tests/warnings/Mmake:
tests/warnings/inf_recursion_lambda.exp:
tests/warnings/inf_recursion_lambda.m:
	Test case.



Index: compiler/simplify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/simplify.m,v
retrieving revision 1.42
diff -u -r1.42 simplify.m
--- simplify.m	1997/07/27 15:01:36	1.42
+++ simplify.m	1997/07/28 03:23:55
@@ -65,7 +65,7 @@
 :- import_module hlds_module, hlds_goal, hlds_data, (inst), inst_match.
 :- import_module globals, options, passes_aux, prog_data, mode_util, type_util.
 :- import_module code_util, quantification, modes.
-:- import_module bool, list, set, map, require, std_util, term, varset.
+:- import_module bool, list, set, map, require, std_util, term, varset, int.
 
 %-----------------------------------------------------------------------------%
 
@@ -462,6 +462,12 @@
 		IsBuiltin \= inline_builtin,
 
 		%
+		% Don't warn if we're inside a lambda goal, because the
+		% recursive call may not be executed.
+		%
+		\+ simplify_info_inside_lambda(Info1),
+
+		%
 		% Are the input arguments the same (or equivalent)?
 		%
 		simplify_info_get_module_info(Info1, ModuleInfo1),
@@ -503,25 +509,27 @@
 		RT0 = lambda_goal(PredOrFunc, Vars, Modes, LambdaDeclaredDet,
 			LambdaGoal0)
 	->
-		simplify_info_get_common_info(Info0, Common0),
-		simplify_info_get_module_info(Info0, ModuleInfo),
-		simplify_info_get_instmap(Info0, InstMap0),
+		simplify_info_enter_lambda(Info0, Info1),
+		simplify_info_get_common_info(Info1, Common1),
+		simplify_info_get_module_info(Info1, ModuleInfo),
+		simplify_info_get_instmap(Info1, InstMap1),
 		instmap__pre_lambda_update(ModuleInfo, Vars, Modes,
-			InstMap0, InstMap1),
-		simplify_info_set_instmap(Info0, InstMap1, Info1),
+			InstMap1, InstMap2),
+		simplify_info_set_instmap(Info1, InstMap2, Info2),
 
 		% Don't attempt to pass structs into lambda_goals,
 		% since that could change the curried non-locals of the 
 		% lambda_goal, and that would be difficult to fix up.
-		common_info_init(Common1),
-		simplify_info_set_common_info(Info1, Common1, Info2),
+		common_info_init(Common2),
+		simplify_info_set_common_info(Info2, Common2, Info3),
 
 		% Don't attempt to pass structs out of lambda_goals.
-		simplify__goal(LambdaGoal0, LambdaGoal, Info2, Info3),
-		simplify_info_set_common_info(Info3, Common0, Info4),
-		simplify_info_set_instmap(Info4, InstMap0, Info),
+		simplify__goal(LambdaGoal0, LambdaGoal, Info3, Info4),
+		simplify_info_set_common_info(Info4, Common1, Info5),
+		simplify_info_set_instmap(Info5, InstMap1, Info6),
 		RT = lambda_goal(PredOrFunc, Vars, Modes, LambdaDeclaredDet,
 			LambdaGoal),
+		simplify_info_leave_lambda(Info6, Info),
 		Goal = unify(LT0, RT, M, U0, C),
 		GoalInfo = GoalInfo0
 	;
@@ -1265,9 +1273,11 @@
 			bool,		% Does the goal need requantification.
 			bool,		% Does mode analysis need rerunning
 					% rather than recompute_instmap_delta.
-			maybe(branch_info)	% Final instmaps at the end
+			maybe(branch_info),	% Final instmaps at the end
 					% of each branch of the last 
 					% branching goal
+			int		% Count of the number of lambdas
+					% which enclose the current goal.
 		).
 
 	% info used to merge adjacent switches and prepare for rerunning
@@ -1283,7 +1293,7 @@
 	common_info_init(CommonInfo),
 	set__init(Msgs),
 	Info = simplify_info(DetInfo, Msgs, Simplify, CommonInfo,
-			InstMap, VarSet, VarTypes, no, no, no). 
+			InstMap, VarSet, VarTypes, no, no, no, 0). 
 
 	% exported for common.m
 :- interface.
@@ -1307,19 +1317,20 @@
 
 :- implementation.
 
-simplify_info_get_det_info(simplify_info(Det, _,_,_,_,_,_,_,_,_), Det). 
-simplify_info_get_msgs(simplify_info(_, Msgs, _,_,_,_,_,_,_,_), Msgs).
-simplify_info_get_simplify(simplify_info(_,_,Simplify,_,_,_,_,_,_,_),
+simplify_info_get_det_info(simplify_info(Det, _,_,_,_,_,_,_,_,_,_), Det). 
+simplify_info_get_msgs(simplify_info(_, Msgs, _,_,_,_,_,_,_,_,_), Msgs).
+simplify_info_get_simplify(simplify_info(_,_,Simplify,_,_,_,_,_,_,_,_),
 	Simplify). 
-simplify_info_get_common_info(simplify_info(_,_,_,Common, _,_,_,_,_,_),
+simplify_info_get_common_info(simplify_info(_,_,_,Common, _,_,_,_,_,_,_),
 	Common).
-simplify_info_get_instmap(simplify_info(_,_,_,_, InstMap,_,_,_,_,_), InstMap). 
-simplify_info_get_varset(simplify_info(_,_,_,_,_, VarSet, _,_,_,_), VarSet). 
-simplify_info_get_var_types(simplify_info(_,_,_,_,_,_, VarTypes, _,_,_),
+simplify_info_get_instmap(simplify_info(_,_,_,_, InstMap,_,_,_,_,_,_),
+	InstMap).
+simplify_info_get_varset(simplify_info(_,_,_,_,_, VarSet, _,_,_,_,_), VarSet). 
+simplify_info_get_var_types(simplify_info(_,_,_,_,_,_, VarTypes, _,_,_,_),
 	VarTypes). 
-simplify_info_requantify(simplify_info(_,_,_,_,_,_,_, yes, _,_)).
-simplify_info_recompute_atomic(simplify_info(_,_,_,_,_,_,_,_, yes,_)).
-simplify_info_get_branch_info(simplify_info(_,_,_,_,_,_,_,_,_, BranchInfo),
+simplify_info_requantify(simplify_info(_,_,_,_,_,_,_, yes, _,_,_)).
+simplify_info_recompute_atomic(simplify_info(_,_,_,_,_,_,_,_, yes,_,_)).
+simplify_info_get_branch_info(simplify_info(_,_,_,_,_,_,_,_,_, BranchInfo, _),
 	BranchInfo).
 
 simplify_info_get_module_info(Info, ModuleInfo) :-
@@ -1354,34 +1365,41 @@
 		maybe(branch_info)::in, simplify_info::out) is det.
 :- pred simplify_info_add_msg(simplify_info::in, det_msg::in,
 		simplify_info::out) is det.
+:- pred simplify_info_enter_lambda(simplify_info::in, simplify_info::out)
+		is det.
+:- pred simplify_info_leave_lambda(simplify_info::in, simplify_info::out)
+		is det.
+:- pred simplify_info_inside_lambda(simplify_info::in) is semidet.
 
 :- pred simplify_info_set_module_info(simplify_info::in,
 		module_info::in, simplify_info::out) is det.
 
 :- implementation.
 
-simplify_info_set_det_info(simplify_info(_, B, C, D, E, F, G, H, I,J), Det,
-		simplify_info(Det, B, C, D, E, F, G, H, I,J)).
-simplify_info_set_msgs(simplify_info(A, _, C, D, E, F, G, H, I,J), Msgs,
-		simplify_info(A, Msgs, C, D, E, F, G, H, I, J)). 
-simplify_info_set_simplify(simplify_info(A, B, _, D, E, F, G, H, I,J), Simp,
-		simplify_info(A, B, Simp, D, E, F, G, H, I,J)).
-simplify_info_set_instmap(simplify_info(A, B, C, D, _, F, G, H, I, J), InstMap,
-		simplify_info(A, B, C, D, InstMap, F, G, H, I, J)). 
-simplify_info_set_common_info(simplify_info(A, B, C, _, E, F, G, H, I, J),
-		Common, simplify_info(A, B, C, Common, E, F, G, H, I, J)). 
-simplify_info_set_varset(simplify_info(A, B, C, D, E, _, G, H, I, J), VarSet,
-		simplify_info(A, B, C, D, E, VarSet, G, H, I, J)). 
-simplify_info_set_var_types(simplify_info(A, B, C, D, E, F, _, H, I, J),
-		VarTypes, simplify_info(A, B, C, D, E, F, VarTypes, H, I, J)). 
-simplify_info_set_requantify(simplify_info(A, B, C, D, E, F, G, _, I, J),
-		simplify_info(A, B, C, D, E, F, G, yes, I, J)). 
-simplify_info_set_recompute_atomic(simplify_info(A, B, C, D, E, F, G, H, _, J),
-		simplify_info(A, B, C, D, E, F, G, H, yes, J)). 
-simplify_info_reset_branch_info(simplify_info(A, B, C, D, E, F, G, H, I, Info),
-		simplify_info(A, B, C, D, E, F, G, H, I, no), Info). 
-simplify_info_set_branch_info(simplify_info(A, B, C, D, E, F, G, H, I, _),
-		Info, simplify_info(A, B, C, D, E, F, G, H, I, Info)). 
+simplify_info_set_det_info(simplify_info(_, B, C, D, E, F, G, H, I, J, K), Det,
+		simplify_info(Det, B, C, D, E, F, G, H, I, J, K)).
+simplify_info_set_msgs(simplify_info(A, _, C, D, E, F, G, H, I, J, K), Msgs,
+		simplify_info(A, Msgs, C, D, E, F, G, H, I, J, K)). 
+simplify_info_set_simplify(simplify_info(A, B, _, D, E, F, G, H, I, J, K), Simp,
+		simplify_info(A, B, Simp, D, E, F, G, H, I, J, K)).
+simplify_info_set_instmap(simplify_info(A, B, C, D, _, F, G, H, I, J, K),
+		InstMap, simplify_info(A, B, C, D, InstMap, F, G, H, I, J, K)). 
+simplify_info_set_common_info(simplify_info(A, B, C, _, E, F, G, H, I, J, K),
+		Common, simplify_info(A, B, C, Common, E, F, G, H, I, J, K)). 
+simplify_info_set_varset(simplify_info(A, B, C, D, E, _, G, H, I, J, K), VarSet,
+		simplify_info(A, B, C, D, E, VarSet, G, H, I, J, K)). 
+simplify_info_set_var_types(simplify_info(A, B, C, D, E, F, _, H, I, J, K),
+		VarTypes, simplify_info(A, B, C, D, E, F, VarTypes, H, I, J, K)). 
+simplify_info_set_requantify(simplify_info(A, B, C, D, E, F, G, _, I, J, K),
+		simplify_info(A, B, C, D, E, F, G, yes, I, J, K)). 
+simplify_info_set_recompute_atomic(
+		simplify_info(A, B, C, D, E, F, G, H, _, J, K),
+		simplify_info(A, B, C, D, E, F, G, H, yes, J, K)). 
+simplify_info_reset_branch_info(
+		simplify_info(A, B, C, D, E, F, G, H, I, Info, K),
+		simplify_info(A, B, C, D, E, F, G, H, I, no, K), Info). 
+simplify_info_set_branch_info(simplify_info(A, B, C, D, E, F, G, H, I, _, K),
+		Info, simplify_info(A, B, C, D, E, F, G, H, I, Info, K)). 
 
 simplify_info_add_msg(Info0, Msg, Info) :-
 	( simplify_do_warn(Info0) ->
@@ -1392,6 +1410,25 @@
 		Info = Info0
 	).
 
+simplify_info_enter_lambda(
+		simplify_info(A, B, C, D, E, F, G, H, I, J, LambdaCount0),
+		simplify_info(A, B, C, D, E, F, G, H, I, J, LambdaCount)) :-
+	LambdaCount is LambdaCount0 + 1.
+simplify_info_leave_lambda(
+		simplify_info(A, B, C, D, E, F, G, H, I, J, LambdaCount0),
+		simplify_info(A, B, C, D, E, F, G, H, I, J, LambdaCount)) :-
+	LambdaCount1 is LambdaCount0 - 1,
+	(
+		LambdaCount1 >= 0
+	->
+		LambdaCount = LambdaCount1
+	;
+		error("simplify_info_leave_lambda: Left too many lambdas")
+	).
+simplify_info_inside_lambda(
+		simplify_info(_,_,_,_,_,_,_,_,_,_,LambdaCount)) :-
+	LambdaCount > 0.
+
 simplify_info_set_module_info(Info0, ModuleInfo, Info) :-
 	simplify_info_get_det_info(Info0, DetInfo0),
 	det_info_set_module_info(DetInfo0, ModuleInfo, DetInfo),
@@ -1435,8 +1472,8 @@
 		simplify_info::out) is det.
 
 simplify_info_update_instmap(
-		simplify_info(A, B, C, D, InstMap0, F, G, H, I, J), Goal,
-		simplify_info(A, B, C, D, InstMap, F, G, H, I, J)) :-
+		simplify_info(A, B, C, D, InstMap0, F, G, H, I, J, K), Goal,
+		simplify_info(A, B, C, D, InstMap, F, G, H, I, J, K)) :-
 	update_instmap(Goal, InstMap0, InstMap).
 
 :- type before_after
Index: tests/warnings/Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/warnings/Mmake,v
retrieving revision 1.18
diff -u -r1.18 Mmake
--- Mmake	1997/04/28 00:05:23	1.18
+++ Mmake	1997/07/28 03:18:52
@@ -7,6 +7,7 @@
 PROGS=	\
 	double_underscore \
 	duplicate_call \
+	inf_recursion_lambda \
 	infinite_recursion \
 	missing_if \
 	pragma_source_file \

New File: tests/warnings/inf_recursion_lambda.exp
===================================================================

New File: tests/warnings/inf_recursion_lambda.m
===================================================================
% This test case should produce _no_ warnings.

:- module inf_recursion_lambda.
:- interface.

:- type closure ---> closure((func) = closure).
:- inst closure = bound(closure((func) = out(closure) is det)).

:- func return_me = (closure :: out(closure)) is det.

:- implementation.

return_me = closure((func) = return_me).





More information about the developers mailing list