[m-rev.] for review: fix bug #257

Julien Fischer jfischer at opturion.com
Mon May 20 17:44:43 AEST 2013


For review by anyone.

Branches: master, 13.05

-------------------

Fix bug #257.

Emit a warning if the variable that is the subject of a require_complete_switch
scope does not occur in the sub-goal.

compiler/det_report.m:
 	As above.

tests/valid/Mmakefile:
tests/valid/bug257b.{m,exp}:
tests/warnings/Mmakefile:
tests/warnings/bug257.{m,exp}:
 	Test cases for the above.

Julien.

diff --git a/compiler/det_report.m b/compiler/det_report.m
index 8a5653f..2fd4455 100644
--- a/compiler/det_report.m
+++ b/compiler/det_report.m
@@ -1140,7 +1140,32 @@ reqscope_check_scope(Reason, SubGoal, ScopeGoalInfo, InstMap0, !DetInfo) :-
                  det_info_add_error_spec(SwitchSpec, !DetInfo)
              )
          ;
-            true
+            % Emit a warning if the variable in the head of a
+            % require_complete_switch scope does not occur somewhere in the
+            % body.  Note that since the goal inside the scope does not need to
+            % be a switch, the variable will not necessarily appear in the
+            % non-locals set.  We only emit the  warning when the variable does
+            % not occur at all.
+            % 
+            goal_vars(SubGoal, SubGoalVars),
+            ( if set_of_var.member(SubGoalVars, RequiredVar) then
+                true
+            else
+                det_get_proc_info(!.DetInfo, ProcInfo),
+                proc_info_get_varset(ProcInfo, VarSet),
+                VarStr = mercury_var_to_string(VarSet, no, RequiredVar),
+                MissingRequiredPieces = [
+                    words("Warning: variable "), quote(VarStr),
+                    words("in require_complete_switch scope does"),
+                    words("does not occur in the goal.")
+                ],
+                Context = goal_info_get_context(ScopeGoalInfo),
+                MissingRequiredMsg = simple_msg(Context,
+                    [always(MissingRequiredPieces)]),
+                MissingRequiredSpec = error_spec(severity_warning,
+                    phase_detism_check, [MissingRequiredMsg]),
+                det_info_add_error_spec(MissingRequiredSpec, !DetInfo)
+            )
          )
      ;
          Reason = loop_control(_, _, _),
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index f87c397..62f01f1 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -75,6 +75,7 @@ OTHER_PROGS= \
  	bug159 \
  	bug180 \
  	bug190 \
+	bug257b \
  	builtin_false \
  	call_failure \
  	common_struct_bug \
diff --git a/tests/valid/bug257b.m b/tests/valid/bug257b.m
new file mode 100644
index 0000000..e3dbbca
--- /dev/null
+++ b/tests/valid/bug257b.m
@@ -0,0 +1,23 @@
+% Don't emit an erroneous warning about the variable that is the subject
+% of a require_complete_switch scope not occurring in the sub-goal if
+% the sub-goal in question is not a switch and the varialbe in question
+% does not occur in the non-local set of the sub-goal.
+% (See also tests/warning/bug257b.m.)
+
+:- module bug257b.
+:- interface.
+
+:- import_module io.
+
+:- type xyz ---> x ; y ; z.
+ 
+:- pred oops(xyz::in, int::out, io::di, io::uo) is det.
+ 
+:- implementation.
+
+ oops(_G, N, !IO) :-
+   require_complete_switch [Gee] (
+	Gee = 123,
+	io.write(Gee, !IO),
+	N = 3
+   ).
diff --git a/tests/warnings/Mmakefile b/tests/warnings/Mmakefile
index c712e31..0225d6f 100644
--- a/tests/warnings/Mmakefile
+++ b/tests/warnings/Mmakefile
@@ -14,6 +14,7 @@ COMPILE_PROGS=	\

  ERRORCHECK_PROGS= \
  	ambiguous_overloading \
+	bug257 \
  	det_infer_warning \
  	double_underscore \
  	duplicate_call \
diff --git a/tests/warnings/bug257.exp b/tests/warnings/bug257.exp
new file mode 100644
index 0000000..270c61d
--- /dev/null
+++ b/tests/warnings/bug257.exp
@@ -0,0 +1,2 @@
+bug257.m:015: Warning: variable `Gee' in require_complete_switch scope does
+bug257.m:015:   does not occur in the goal.
diff --git a/tests/warnings/bug257.m b/tests/warnings/bug257.m
new file mode 100644
index 0000000..6f83290
--- /dev/null
+++ b/tests/warnings/bug257.m
@@ -0,0 +1,22 @@
+% Regression test for bug #257: the compiler was not issuing a warning about
+% the fact that the variable Gee which was the subject of a
+% require_complete_switch did not occur in the scoped goal.
+
+:- module bug257.
+:- interface.
+
+:- type xyz ---> x ; y ; z.
+ 
+:- pred oops(xyz::in, int::out) is semidet.
+ 
+:- implementation.
+ 
+    oops(G, N) :-
+        require_complete_switch [Gee]
+        (
+            G = x, 
+            N = 1
+        ;
+            G = y, 
+            fail
+        ).



More information about the reviews mailing list