for review: fix warnings without context
Simon Taylor
stayl at cs.mu.OZ.AU
Wed Jun 10 16:26:11 AEST 1998
Hi,
Fergus, could you please review this.
Simon.
Estimated hours taken: 2
Fix a bug reported by Philip Dart where "this disjunct cannot succeed"
warnings for predicates using sub-typing in modes were being output
without a context.
compiler/hlds_goal.m
Add versions of true_goal and fail_goal which take
a context for the goal.
compiler/simplify.m
Pass a valid context to true_goal and fail_goal.
Only report --warn-simple-code messages which occur for
all modes of a predicate - this avoids spurious
"this disjunct cannot succeed" warnings for sub-typing.
compiler/passes_aux.m
Add a task type update_pred_error for use by simplify.m.
tests/warning/simple_code.m
Add a testcase.
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/hlds_goal.m,v
retrieving revision 1.53
diff -u -t -u -r1.53 hlds_goal.m
--- hlds_goal.m 1998/06/09 02:12:52 1.53
+++ hlds_goal.m 1998/06/10 01:03:29
@@ -693,10 +693,16 @@
:- pred true_goal(hlds_goal).
:- mode true_goal(out) is det.
+:- pred true_goal(term__context, hlds_goal).
+:- mode true_goal(in, out) is det.
+
% Return the HLDS equivalent of `fail'.
:- pred fail_goal(hlds_goal).
:- mode fail_goal(out) is det.
+:- pred fail_goal(term__context, hlds_goal).
+:- mode fail_goal(in, out) is det.
+
% Return the union of all the nonlocals of a list of goals.
:- pred goal_list_nonlocals(list(hlds_goal), set(var)).
:- mode goal_list_nonlocals(in, out) is det.
@@ -980,12 +986,20 @@
instmap_delta_init_reachable(InstMapDelta),
goal_info_set_instmap_delta(GoalInfo1, InstMapDelta, GoalInfo).
+true_goal(Context, Goal - GoalInfo) :-
+ true_goal(Goal - GoalInfo0),
+ goal_info_set_context(GoalInfo0, Context, GoalInfo).
+
fail_goal(disj([], SM) - GoalInfo) :-
map__init(SM),
goal_info_init(GoalInfo0),
goal_info_set_determinism(GoalInfo0, failure, GoalInfo1),
instmap_delta_init_unreachable(InstMapDelta),
goal_info_set_instmap_delta(GoalInfo1, InstMapDelta, GoalInfo).
+
+fail_goal(Context, Goal - GoalInfo) :-
+ fail_goal(Goal - GoalInfo0),
+ goal_info_set_context(GoalInfo0, Context, GoalInfo).
%-----------------------------------------------------------------------------%
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/mercury_compile.m,v
retrieving revision 1.98
diff -u -t -u -r1.98 mercury_compile.m
--- mercury_compile.m 1998/06/09 02:13:36 1.98
+++ mercury_compile.m 1998/06/10 01:47:27
@@ -1088,7 +1088,7 @@
),
{ simplify__find_simplifications(no, Globals, Simplifications) },
simplify__proc([do_once | Simplifications], PredId, ProcId,
- ModuleInfo1, ModuleInfo2, ProcInfo1, ProcInfo2, _, _),
+ ModuleInfo1, ModuleInfo2, ProcInfo1, ProcInfo2),
{ globals__lookup_bool_option(Globals, optimize_saved_vars,
SavedVars) },
( { SavedVars = yes } ->
@@ -1334,7 +1334,7 @@
{ Simplifications = Simplifications0 }
),
process_all_nonimported_procs(
- update_proc_error(simplify__proc(Simplifications)),
+ update_pred_error(simplify__pred(Simplifications)),
HLDS0, HLDS),
maybe_write_string(Verbose, "% done.\n"),
maybe_report_stats(Stats).
Index: compiler/passes_aux.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/passes_aux.m,v
retrieving revision 1.26
diff -u -t -u -r1.26 passes_aux.m
--- passes_aux.m 1998/06/08 08:25:12 1.26
+++ passes_aux.m 1998/06/10 01:30:30
@@ -29,6 +29,7 @@
pred_id, proc_id, module_info, module_info,
proc_info, proc_info, int, int,
io__state, io__state))
+ ; update_pred_error(pred_error_task)
; update_module(pred(
proc_info, proc_info,
module_info, module_info))
@@ -45,6 +46,11 @@
univ)
.
+
+:- type pred_error_task ==
+ pred(pred_id, module_info, module_info, pred_info, pred_info,
+ int, int, io__state, io__state).
+
/****************
Note that update_module_cookie causes some difficulties.
@@ -79,6 +85,8 @@
; update_proc_io(pred(in, in, in, in, out, di, uo) is det)
; update_proc_error(pred(in, in, in, out, in, out,
out, out, di, uo) is det)
+ ; update_pred_error(pred(in, in, out, in, out,
+ out, out, di, uo) is det)
; update_module(pred(in, out, in, out) is det)
; update_module_io(pred(in, in, in, out,
in, out, di, uo) is det)
@@ -86,6 +94,9 @@
in, out) is det, ground)
)).
+:- inst pred_error_task =
+ (pred(in, in, out, in, out, out, out, di, uo) is det).
+
:- mode task :: task -> task.
:- pred process_all_nonimported_procs(task, module_info, module_info,
@@ -135,14 +146,39 @@
process_all_nonimported_procs(Task, ModuleInfo0, ModuleInfo) -->
{ module_info_predids(ModuleInfo0, PredIds) },
- process_nonimported_procs_in_preds(PredIds, Task, _,
- ModuleInfo0, ModuleInfo).
+ ( { Task = update_pred_error(Pred) } ->
+ list__foldl2(process_nonimported_pred(Pred), PredIds,
+ ModuleInfo0, ModuleInfo)
+ ;
+ process_nonimported_procs_in_preds(PredIds, Task, _,
+ ModuleInfo0, ModuleInfo)
+ ).
process_all_nonimported_procs(Task0, Task, ModuleInfo0, ModuleInfo) -->
{ module_info_predids(ModuleInfo0, PredIds) },
process_nonimported_procs_in_preds(PredIds, Task0, Task,
ModuleInfo0, ModuleInfo).
+:- pred process_nonimported_pred(pred_error_task, pred_id,
+ module_info, module_info, io__state, io__state).
+:- mode process_nonimported_pred(in(pred_error_task), in,
+ in, out, di, uo) is det.
+
+process_nonimported_pred(Task, PredId, ModuleInfo0, ModuleInfo,
+ IO0, IO) :-
+ module_info_pred_info(ModuleInfo0, PredId, PredInfo0),
+ ( pred_info_is_imported(PredInfo0) ->
+ ModuleInfo = ModuleInfo0,
+ IO = IO0
+ ;
+ call(Task, PredId, ModuleInfo0, ModuleInfo1,
+ PredInfo0, PredInfo, WarnCnt, ErrCnt, IO0, IO1),
+ module_info_set_pred_info(ModuleInfo1,
+ PredId, PredInfo, ModuleInfo2),
+ passes_aux__handle_errors(WarnCnt, ErrCnt,
+ ModuleInfo2, ModuleInfo, IO1, IO)
+ ).
+
:- pred process_nonimported_procs_in_preds(list(pred_id), task, task,
module_info, module_info, io__state, io__state).
:- mode process_nonimported_procs_in_preds(in, task, out(task), in, out,
@@ -207,23 +243,12 @@
Task0 = update_proc_error(Closure),
call(Closure, PredId, ProcId, ModuleInfo0, ModuleInfo1,
Proc0, Proc, WarnCnt, ErrCnt, State0, State1),
- globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn,
- State1, State2),
Task1 = Task0,
- (
- (
- ErrCnt > 0
- ;
- WarnCnt > 0,
- HaltAtWarn = yes
- )
- ->
- io__set_exit_status(1, State2, State9),
- module_info_incr_errors(ModuleInfo1, ModuleInfo8)
- ;
- ModuleInfo8 = ModuleInfo1,
- State9 = State2
- )
+ passes_aux__handle_errors(WarnCnt, ErrCnt,
+ ModuleInfo1, ModuleInfo8, State1, State9)
+ ;
+ Task0 = update_pred_error(_),
+ error("passes_aux:process_non_imported_procs")
;
Task0 = update_module_cookie(Closure, Cookie0),
call(Closure, PredId, ProcId, Proc0, Proc,
@@ -282,6 +307,29 @@
io__write_string(ErrorMessage),
io__write_string("\n"),
io__set_exit_status(1).
+
+:- pred passes_aux__handle_errors(int, int, module_info, module_info,
+ io__state, io__state).
+:- mode passes_aux__handle_errors(in, in, in, out, di, uo) is det.
+
+passes_aux__handle_errors(WarnCnt, ErrCnt, ModuleInfo1, ModuleInfo8,
+ State1, State9) :-
+ globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn,
+ State1, State2),
+ (
+ (
+ ErrCnt > 0
+ ;
+ WarnCnt > 0,
+ HaltAtWarn = yes
+ )
+ ->
+ io__set_exit_status(1, State2, State9),
+ module_info_incr_errors(ModuleInfo1, ModuleInfo8)
+ ;
+ ModuleInfo8 = ModuleInfo1,
+ State9 = State2
+ ).
invoke_system_command(Command, Succeeded) -->
globals__io_lookup_bool_option(verbose, Verbose),
Index: compiler/simplify.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/simplify.m,v
retrieving revision 1.60
diff -u -t -u -r1.60 simplify.m
--- simplify.m 1998/06/09 02:14:41 1.60
+++ simplify.m 1998/06/10 01:46:40
@@ -32,10 +32,13 @@
:- import_module common, instmap, globals.
:- import_module io, bool, list, map, term, varset.
+:- pred simplify__pred(list(simplification), pred_id, module_info, module_info,
+ pred_info, pred_info, int, int, io__state, io__state).
+:- mode simplify__pred(in, in, in, out, in, out, out, out, di, uo) is det.
+
:- pred simplify__proc(list(simplification), pred_id, proc_id,
- module_info, module_info, proc_info, proc_info,
- int, int, io__state, io__state).
-:- mode simplify__proc(in, in, in, in, out, in, out, out, out, di, uo) is det.
+ module_info, module_info, proc_info, proc_info, io__state, io__state).
+:- mode simplify__proc(in, in, in, in, out, in, out, di, uo) is det.
:- pred simplify__process_goal(hlds_goal, hlds_goal,
simplify_info, simplify_info).
@@ -74,32 +77,74 @@
%-----------------------------------------------------------------------------%
-simplify__proc(Simplifications, PredId, ProcId, ModuleInfo0, ModuleInfo,
- Proc0, Proc, WarnCnt, ErrCnt) -->
+simplify__pred(Simplifications0, PredId, ModuleInfo0, ModuleInfo,
+ PredInfo0, PredInfo, WarnCnt, ErrCnt) -->
write_pred_progress_message("% Simplifying ", PredId, ModuleInfo0),
- simplify__proc_2(Simplifications, PredId, ProcId, ModuleInfo0,
- ModuleInfo, Proc0, Proc, WarnCnt, ErrCnt).
-
-:- pred simplify__proc_2(list(simplification), pred_id, proc_id, module_info,
- module_info, proc_info, proc_info, int, int,
- io__state, io__state).
-:- mode simplify__proc_2(in, in, in, in, out, in, out,
- out, out, di, uo) is det.
-
-simplify__proc_2(Simplifications0, PredId, ProcId, ModuleInfo0, ModuleInfo,
- ProcInfo0, ProcInfo, WarnCnt, ErrCnt, State0, State) :-
- (
+ { pred_info_non_imported_procids(PredInfo0, ProcIds) },
+ { MaybeMsgs0 = no },
+ {
% Don't warn for compiler-generated procedures.
list__member(warn_simple_code, Simplifications0),
- module_info_pred_info(ModuleInfo0, PredId, PredInfo),
- code_util__compiler_generated(PredInfo)
+ module_info_pred_info(ModuleInfo0, PredId, PredInfo0),
+ code_util__compiler_generated(PredInfo0)
->
list__delete_all(Simplifications0, warn_simple_code,
Simplifications)
;
Simplifications = Simplifications0
- ),
- globals__io_get_globals(Globals, State0, State1),
+ },
+ simplify__procs(Simplifications, PredId, ProcIds, ModuleInfo0,
+ ModuleInfo, PredInfo0, PredInfo, MaybeMsgs0, MaybeMsgs),
+ ( { MaybeMsgs = yes(Msgs0) } ->
+ { set__to_sorted_list(Msgs0, Msgs) },
+ det_report_msgs(Msgs, ModuleInfo, WarnCnt, ErrCnt)
+ ;
+ { WarnCnt = 0 },
+ { ErrCnt = 0 }
+ ).
+
+:- pred simplify__procs(list(simplification), pred_id, list(proc_id),
+ module_info, module_info, pred_info, pred_info,
+ maybe(set(det_msg)), maybe(set(det_msg)),
+ io__state, io__state).
+:- mode simplify__procs(in, in, in, in, out, in, out,
+ in, out, di, uo) is det.
+
+simplify__procs(_, _, [], ModuleInfo, ModuleInfo, PredInfo, PredInfo,
+ Msgs, Msgs) --> [].
+simplify__procs(Simplifications, PredId, [ProcId | ProcIds], ModuleInfo0,
+ ModuleInfo, PredInfo0, PredInfo, MaybeMsgs0, MaybeMsgs) -->
+ { pred_info_procedures(PredInfo0, Procs0) },
+ { map__lookup(Procs0, ProcId, Proc0) },
+ simplify__proc_2(Simplifications, PredId, ProcId, ModuleInfo0,
+ ModuleInfo1, Proc0, Proc, Msgs1),
+ { map__det_update(Procs0, ProcId, Proc, Procs) },
+ { pred_info_set_procedures(PredInfo0, Procs, PredInfo1) },
+ { MaybeMsgs0 = yes(Msgs0) ->
+ set__intersect(Msgs0, Msgs1, Msgs),
+ MaybeMsgs1 = yes(Msgs)
+ ;
+ MaybeMsgs1 = yes(Msgs1)
+ },
+ simplify__procs(Simplifications, PredId, ProcIds, ModuleInfo1,
+ ModuleInfo, PredInfo1, PredInfo, MaybeMsgs1, MaybeMsgs).
+
+simplify__proc(Simplifications, PredId, ProcId, ModuleInfo0, ModuleInfo,
+ Proc0, Proc) -->
+ write_pred_progress_message("% Simplifying ", PredId, ModuleInfo0),
+ simplify__proc_2(Simplifications, PredId, ProcId, ModuleInfo0,
+ ModuleInfo, Proc0, Proc, _).
+
+:- pred simplify__proc_2(list(simplification), pred_id, proc_id, module_info,
+ module_info, proc_info, proc_info, set(det_msg),
+ io__state, io__state).
+:- mode simplify__proc_2(in, in, in, in, out, in, out,
+ out, di, uo) is det.
+
+simplify__proc_2(Simplifications, PredId, ProcId, ModuleInfo0, ModuleInfo,
+ ProcInfo0, ProcInfo, Msgs, State0, State) :-
+
+ globals__io_get_globals(Globals, State0, State),
det_info_init(ModuleInfo0, PredId, ProcId, Globals, DetInfo0),
proc_info_get_initial_instmap(ProcInfo0, ModuleInfo0, InstMap0),
proc_info_varset(ProcInfo0, VarSet0),
@@ -111,10 +156,8 @@
simplify__process_goal(Goal0, Goal, Info0, Info),
simplify_info_get_module_info(Info, ModuleInfo),
- simplify_info_get_msgs(Info, Msgs0),
- set__to_sorted_list(Msgs0, Msgs),
- det_report_msgs(Msgs, ModuleInfo, WarnCnt,
- ErrCnt, State1, State),
+ simplify_info_get_msgs(Info, Msgs),
+
simplify_info_get_varset(Info, VarSet),
simplify_info_get_var_types(Info, VarTypes),
proc_info_set_varset(ProcInfo0, VarSet, ProcInfo1),
@@ -243,7 +286,8 @@
->
pd_cost__goal(Goal0, CostDelta),
simplify_info_incr_cost_delta(Info0, CostDelta, Info1),
- fail_goal(Goal1)
+ goal_info_get_context(GoalInfo0, Context),
+ fail_goal(Context, Goal1)
;
%
% if --no-fully-strict,
@@ -270,7 +314,8 @@
->
pd_cost__goal(Goal0, CostDelta),
simplify_info_incr_cost_delta(Info0, CostDelta, Info1),
- true_goal(Goal1)
+ goal_info_get_context(GoalInfo0, Context),
+ true_goal(Context, Goal1)
;
Goal1 = Goal0,
Info1 = Info0
@@ -421,7 +466,8 @@
% An empty switch always fails.
pd_cost__eliminate_switch(CostDelta),
simplify_info_incr_cost_delta(Info1, CostDelta, Info),
- fail_goal(Goal - GoalInfo)
+ goal_info_get_context(GoalInfo0, Context),
+ fail_goal(Context, Goal - GoalInfo)
; Cases = [case(ConsId, SingleGoal)] ->
% a singleton switch is equivalent to the goal itself with
% a possibly can_fail unification with the functor on the front.
@@ -640,7 +686,8 @@
RT0 = var(LT0)
->
- true_goal(Goal - GoalInfo),
+ goal_info_get_context(GoalInfo0, Context),
+ true_goal(Context, Goal - GoalInfo),
Info = Info0
;
RT0 = lambda_goal(PredOrFunc, NonLocals, Vars,
@@ -967,7 +1014,9 @@
% specification, mode analysis does not use inferred
% determinism information when deciding what can
% never succeed.
- fail_goal(Fail),
+ Goal0 = _ - GoalInfo0,
+ goal_info_get_context(GoalInfo0, Context),
+ fail_goal(Context, Fail),
simplify__conjoin_goal_and_rev_goal_list(Fail,
RevGoals1, RevGoals)
),
Index: tests/warnings/simple_code.exp
===================================================================
RCS file: /home/staff/zs/imp/tests/warnings/simple_code.exp,v
retrieving revision 1.1
diff -u -t -u -r1.1 simple_code.exp
--- simple_code.exp 1997/04/28 00:05:25 1.1
+++ simple_code.exp 1998/06/10 05:09:13
@@ -7,3 +7,4 @@
simple_code.m:030: Warning: the condition of this if-then-else cannot succeed.
simple_code.m:033: Warning: the negated goal cannot succeed.
simple_code.m:039: Warning: call to obsolete predicate `simple_code:obsolete/0'.
+simple_code.m:064: Warning: this disjunct will never have any solutions.
Index: tests/warnings/simple_code.m
===================================================================
RCS file: /home/staff/zs/imp/tests/warnings/simple_code.m,v
retrieving revision 1.2
diff -u -t -u -r1.2 simple_code.m
--- simple_code.m 1997/05/21 02:16:52 1.2
+++ simple_code.m 1998/06/10 05:09:05
@@ -55,3 +55,21 @@
:- pragma obsolete(obsolete/0).
obsolete.
+
+% This should give a warning about the second disjunct never succeeding.
+:- pred r(int, int).
+:- mode r(in(bound(1)), out(bound(42))) is det.
+
+r(1, 42).
+r(2, 21).
+
+% This should not give a warning, because the second disjunct can
+% succeed in the first mode.
+:- pred q(int, int).
+:- mode q(in, out) is semidet.
+:- mode q(in(bound(1)), out(bound(42))) is det.
+
+q(1, 42).
+q(2, 21).
+
+
More information about the developers
mailing list