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