[m-rev.] diff: use det code to warn about e.g. unused variables

Zoltan Somogyi zs at csse.unimelb.edu.au
Fri Jun 6 17:50:35 AEST 2008


compiler/make_hlds_warn.m:
	Use direct, det code instead of nondet code and solutions.
	Sort variable names, and remove duplicates.

tests/invalid/errors2.err_exp:
	Expect sorted variable names in an error message.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/make_hlds_warn.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds_warn.m,v
retrieving revision 1.27
diff -u -b -r1.27 make_hlds_warn.m
--- compiler/make_hlds_warn.m	27 Feb 2008 07:23:08 -0000	1.27
+++ compiler/make_hlds_warn.m	4 Jun 2008 13:24:14 -0000
@@ -79,7 +79,6 @@
 :- import_module bool.
 :- import_module char.
 :- import_module set.
-:- import_module solutions.
 :- import_module string.
 :- import_module varset.
 
@@ -306,14 +305,13 @@
     % or "DCG_", and don't have the same name as any variable in QuantVars
     % (i.e. weren't explicitly quantified).
 
-    solutions.solutions(
-        generate_singleton_vars(GoalVars, NonLocals, QuantVars, VarSet),
-        SingletonVars),
+    list.filter(is_singleton_var(NonLocals, QuantVars, VarSet), GoalVars,
+        SingleVars),
 
     % If there were any such variables, issue a warning.
     (
         (
-            SingletonVars = []
+            SingleVars = []
         ;
             goal_info_has_feature(GoalInfo, feature_dont_warn_singleton)
         )
@@ -322,9 +320,11 @@
     ;
         SinglesPreamble = [words("In clause for"),
             simple_call(PredOrFuncCallId), suffix(":"), nl],
-        SingleVarsPiece =
-            quote(mercury_vars_to_string(VarSet, no, SingletonVars)),
-        ( SingletonVars = [_] ->
+        SingleVarStrs0 = list.map(mercury_var_to_string(VarSet, no),
+            SingleVars),
+        list.sort_and_remove_dups(SingleVarStrs0, SingleVarStrs),
+        SingleVarsPiece = quote(string.join_list(", ", SingleVarStrs)),
+        ( SingleVarStrs = [_] ->
             SinglesPieces = [words("warning: variable"), SingleVarsPiece,
                 words("occurs only once in this scope."), nl]
         ;
@@ -345,16 +345,18 @@
     % (i.e. are not singleton) and have a variable name that starts
     % with "_". If there were any such variables, issue a warning.
 
-    solutions.solutions(generate_multi_vars(GoalVars, NonLocals, VarSet),
-        MultiVars),
+    list.filter(is_multi_var(NonLocals, VarSet), GoalVars, MultiVars),
     (
         MultiVars = []
     ;
         MultiVars = [_ | _],
         MultiPreamble = [words("In clause for"),
             simple_call(PredOrFuncCallId), suffix(":"), nl],
-        MultiVarsPiece = quote(mercury_vars_to_string(VarSet, no, MultiVars)),
-        ( MultiVars = [_] ->
+        MultiVarStrs0 = list.map(mercury_var_to_string(VarSet, no),
+            MultiVars),
+        list.sort_and_remove_dups(MultiVarStrs0, MultiVarStrs),
+        MultiVarsPiece = quote(string.join_list(", ", MultiVarStrs)),
+        ( MultiVarStrs = [_] ->
             MultiPieces = [words("warning: variable"), MultiVarsPiece,
                 words("occurs more than once in this scope."), nl]
         ;
@@ -379,20 +381,16 @@
     (
         PragmaImpl = fc_impl_ordinary(C_Code, _),
         c_code_to_name_list(C_Code, C_CodeList),
-        Filter = (pred(Name::out) is nondet :-
-            list.member(yes(Name - _), Args),
-            \+ string.prefix(Name, "_"),
-            \+ list.member(Name, C_CodeList)
-        ),
-        solutions.solutions(Filter, UnmentionedVars),
+        list.filter_map(var_is_unmentioned(C_CodeList), Args, UnmentionedVars),
         (
             UnmentionedVars = []
         ;
             UnmentionedVars = [_ | _],
             Pieces1 = [words("In the"), words(LangStr), words("code for"),
-                simple_call(PredOrFuncCallId), suffix(":"), nl,
-                words(variable_warning_start(UnmentionedVars)),
-                words("not occur in the"), words(LangStr), words("code."), nl],
+                simple_call(PredOrFuncCallId), suffix(":"), nl] ++
+                variable_warning_start(UnmentionedVars) ++
+                [words("not occur in the"), words(LangStr), words("code."),
+                nl],
             Msg1 = simple_msg(Context,
                 [option_is_set(warn_singleton_vars, yes, [always(Pieces1)])]),
             Severity1 = severity_conditional(warn_singleton_vars, yes,
@@ -407,21 +405,16 @@
         c_code_to_name_list(FirstCode, FirstCodeList),
         c_code_to_name_list(LaterCode, LaterCodeList),
         c_code_to_name_list(SharedCode, SharedCodeList),
-        InputFilter = (pred(Name::out) is nondet :-
-            list.member(yes(Name - Mode), Args),
-            mode_is_input(ModuleInfo, Mode),
-            \+ string.prefix(Name, "_"),
-            \+ list.member(Name, FirstCodeList)
-        ),
-        solutions.solutions(InputFilter, UnmentionedInputVars),
+        list.filter_map(input_var_is_unmentioned(ModuleInfo, FirstCodeList),
+            Args, UnmentionedInputVars),
         (
             UnmentionedInputVars = []
         ;
             UnmentionedInputVars = [_ | _],
             Pieces2 = [words("In the"), words(LangStr), words("code for"),
-                simple_call(PredOrFuncCallId), suffix(":"), nl,
-                words(variable_warning_start(UnmentionedInputVars)),
-                words("not occur in the first"), words(LangStr),
+                simple_call(PredOrFuncCallId), suffix(":"), nl] ++
+                variable_warning_start(UnmentionedInputVars) ++
+                [words("not occur in the first"), words(LangStr),
                 words("code."), nl],
             Msg2 = simple_msg(Context,
                 [option_is_set(warn_singleton_vars, yes, [always(Pieces2)])]),
@@ -431,22 +424,16 @@
                 [Msg2]),
             !:Specs = [Spec2 | !.Specs]
         ),
-        FirstOutputFilter = (pred(Name::out) is nondet :-
-            list.member(yes(Name - Mode), Args),
-                mode_is_output(ModuleInfo, Mode),
-                \+ string.prefix(Name, "_"),
-                \+ list.member(Name, FirstCodeList),
-                \+ list.member(Name, SharedCodeList)
-        ),
-        solutions.solutions(FirstOutputFilter, UnmentionedFirstOutputVars),
+        list.filter_map(output_var_is_unmentioned(ModuleInfo,
+            FirstCodeList, SharedCodeList), Args, UnmentionedFirstOutputVars),
         (
             UnmentionedFirstOutputVars = []
         ;
             UnmentionedFirstOutputVars = [_ | _],
             Pieces3 = [words("In the"), words(LangStr), words("code for"),
-                simple_call(PredOrFuncCallId), suffix(":"), nl,
-                words(variable_warning_start(UnmentionedFirstOutputVars)),
-                words("not occur in the first"), words(LangStr),
+                simple_call(PredOrFuncCallId), suffix(":"), nl] ++
+                variable_warning_start(UnmentionedFirstOutputVars) ++
+                [words("not occur in the first"), words(LangStr),
                 words("code or the shared"), words(LangStr), words("code."),
                 nl],
             Msg3 = simple_msg(Context,
@@ -457,22 +444,18 @@
                 [Msg3]),
             !:Specs = [Spec3 | !.Specs]
         ),
-        LaterOutputFilter = (pred(Name::out) is nondet :-
-            list.member(yes(Name - Mode), Args),
-            mode_is_output(ModuleInfo, Mode),
-            \+ string.prefix(Name, "_"),
-            \+ list.member(Name, LaterCodeList),
-            \+ list.member(Name, SharedCodeList)
-        ),
-        solutions.solutions(LaterOutputFilter, UnmentionedLaterOutputVars),
+        list.filter_map(output_var_is_unmentioned(ModuleInfo,
+            LaterCodeList, SharedCodeList), Args, UnmentionedLaterOutputVars),
         (
             UnmentionedLaterOutputVars = []
         ;
             UnmentionedLaterOutputVars = [_ | _],
+            list.sort(UnmentionedLaterOutputVars,
+                SortedUnmentionedLaterOutputVars),
             Pieces4 = [words("In the"), words(LangStr), words("code for"),
-                simple_call(PredOrFuncCallId), suffix(":"), nl,
-                words(variable_warning_start(UnmentionedLaterOutputVars)),
-                words("not occur in the retry"), words(LangStr),
+                simple_call(PredOrFuncCallId), suffix(":"), nl] ++
+                variable_warning_start(SortedUnmentionedLaterOutputVars) ++
+                [words("not occur in the retry"), words(LangStr),
                 words("code or the shared"), words(LangStr), words("code."),
                 nl],
             Msg4 = simple_msg(Context,
@@ -487,14 +470,44 @@
         PragmaImpl = fc_impl_import(_, _, _, _)
     ).
 
-:- func variable_warning_start(list(string)) = string.
+:- pred var_is_unmentioned(list(string)::in, maybe(pair(string, mer_mode))::in,
+    string::out) is semidet.
+
+var_is_unmentioned(NameList1, MaybeArg, Name) :-
+    MaybeArg = yes(Name - _Mode),
+    \+ string.prefix(Name, "_"),
+    \+ list.member(Name, NameList1).
+
+:- pred input_var_is_unmentioned(module_info::in,
+    list(string)::in, maybe(pair(string, mer_mode))::in,
+    string::out) is semidet.
+
+input_var_is_unmentioned(ModuleInfo, NameList1, MaybeArg, Name) :-
+    MaybeArg = yes(Name - Mode),
+    mode_is_input(ModuleInfo, Mode),
+    \+ string.prefix(Name, "_"),
+    \+ list.member(Name, NameList1).
+
+:- pred output_var_is_unmentioned(module_info::in,
+    list(string)::in, list(string)::in, maybe(pair(string, mer_mode))::in,
+    string::out) is semidet.
+
+output_var_is_unmentioned(ModuleInfo, NameList1, NameList2, MaybeArg, Name) :-
+    MaybeArg = yes(Name - Mode),
+    mode_is_output(ModuleInfo, Mode),
+    \+ string.prefix(Name, "_"),
+    \+ list.member(Name, NameList1),
+    \+ list.member(Name, NameList2).
+
+:- func variable_warning_start(list(string)) = list(format_component).
 
-variable_warning_start(UnmentionedVars) = Str :-
+variable_warning_start(UnmentionedVars) = Pieces :-
     ( UnmentionedVars = [Var] ->
-        Str = "warning: variable `" ++ Var ++ "' does"
+        Pieces = [words("warning: variable"), quote(Var), words("does")]
     ;
-        Str = "warning: variables `" ++
-            string.join_list(", ", UnmentionedVars) ++ "' do"
+        Pieces = [words("warning: variables)"),
+            words(add_quotes(string.join_list(", ", UnmentionedVars))),
+            words("do")]
     ).
 
     % c_code_to_name_list(Code, List) is true iff List is a list of the
@@ -530,8 +543,8 @@
         get_first_c_name_in_word(CodeChars, NameCharList0, TheRest),
         NameCharList = [C | NameCharList0]
     ;
-            % strip off any characters in the C code which
-            % don't form part of an identifier.
+        % Strip off any characters in the C code which don't form part
+        % of an identifier.
         get_first_c_name(CodeChars, NameCharList, TheRest)
     ).
 
@@ -541,20 +554,19 @@
 get_first_c_name_in_word([], [], []).
 get_first_c_name_in_word([C | CodeChars], NameCharList, TheRest) :-
     ( char.is_alnum_or_underscore(C) ->
-            % There are more characters in the word
+        % There are more characters in the word.
         get_first_c_name_in_word(CodeChars, NameCharList0, TheRest),
         NameCharList = [C|NameCharList0]
     ;
-            % The word is finished
+        % The word is finished.
         NameCharList = [],
         TheRest = CodeChars
     ).
 
-:- pred generate_singleton_vars(list(prog_var)::in, set(prog_var)::in,
-    set(prog_var)::in, prog_varset::in, prog_var::out) is nondet.
+:- pred is_singleton_var(set(prog_var)::in,
+    set(prog_var)::in, prog_varset::in, prog_var::in) is semidet.
 
-generate_singleton_vars(GoalVars, NonLocals, QuantVars, VarSet, Var) :-
-    list.member(Var, GoalVars),
+is_singleton_var(NonLocals, QuantVars, VarSet, Var) :-
     \+ set.member(Var, NonLocals),
     varset.search_name(VarSet, Var, Name),
     \+ string.prefix(Name, "_"),
@@ -564,11 +576,10 @@
         varset.search_name(VarSet, QuantVar, Name)
     ).
 
-:- pred generate_multi_vars(list(prog_var)::in, set(prog_var)::in,
-    prog_varset::in, prog_var::out) is nondet.
+:- pred is_multi_var(set(prog_var)::in, prog_varset::in, prog_var::in)
+    is semidet.
 
-generate_multi_vars(GoalVars, NonLocals, VarSet, Var) :-
-    list.member(Var, GoalVars),
+is_multi_var(NonLocals, VarSet, Var) :-
     set.member(Var, NonLocals),
     varset.search_name(VarSet, Var, Name),
     string.prefix(Name, "_").
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
Index: tests/invalid/errors2.err_exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/invalid/errors2.err_exp,v
retrieving revision 1.19
diff -u -b -r1.19 errors2.err_exp
--- tests/invalid/errors2.err_exp	15 Feb 2007 00:41:57 -0000	1.19
+++ tests/invalid/errors2.err_exp	4 Jun 2008 15:40:03 -0000
@@ -16,7 +16,7 @@
 errors2.m:070: In clause for predicate `errors2.type_error_7'/0:
 errors2.m:070:   warning: variable `Y' occurs only once in this scope.
 errors2.m:071: In clause for predicate `errors2.type_error_7'/0:
-errors2.m:071:   warning: variables `Z, A, B' occur only once in this scope.
+errors2.m:071:   warning: variables `A, B, Z' occur only once in this scope.
 errors2.m:007: Error: no clauses for predicate `bind_type_param'/2.
 errors2.m:009: Inferred :- pred bind_type_param(int).
 errors2.m:023: Error: no clauses for predicate `produce_string'/1.
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list