[m-dev.] diff: report errors for missing type decls in interface
Fergus Henderson
fjh at cs.mu.OZ.AU
Sat Sep 16 10:45:16 AEDT 2000
Estimated hours taken: 2.5
Fix a bug where the compiler was not reporting errors for some invalid code.
compiler/make_hlds.m:
Fix a bug: in the code for handling predicates which have
mode declarations (or clauses, etc.) but no pred/func
declaration, if --infer-types is enabled, make sure that
we still report errors for exported predicates and for
type class methods. This required passing down a bool
`IsTypeClassMethod' argument in a number of places.
tests/invalid/Mmakefile:
tests/invalid/typeclass_mode.m:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/imported_mode.m:
tests/invalid/imported_mode.err_exp:
tests/invalid/exported_mode.m:
tests/invalid/exported_mode.err_exp:
Add some regression tests.
For the imported_mode/exported_mode test case, the previous
compiler generated code that dumped core at runtime.
For the typeclass_mode test case, the previous
compiler reported a misleading error message.
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.340
diff -u -d -r1.340 make_hlds.m
--- compiler/make_hlds.m 2000/08/09 07:47:00 1.340
+++ compiler/make_hlds.m 2000/09/15 23:31:38
@@ -209,15 +209,19 @@
add_item_decl_pass_1(pred_mode(VarSet, PredName, Modes, MaybeDet, Cond),
Context, Status, Module0, Status, Module) -->
{ Status = item_status(ImportStatus, _) },
+ { IsClassMethod = no },
module_add_mode(Module0, VarSet, PredName, Modes, MaybeDet, Cond,
- ImportStatus, Context, predicate, _, Module).
+ ImportStatus, Context, predicate, IsClassMethod,
+ _, Module).
add_item_decl_pass_1(func_mode(VarSet, FuncName, Modes, RetMode, MaybeDet,
Cond), Context, Status, Module0, Status, Module) -->
{ list__append(Modes, [RetMode], Modes1) },
{ Status = item_status(ImportStatus, _) },
+ { IsClassMethod = no },
module_add_mode(Module0, VarSet, FuncName, Modes1,
- MaybeDet, Cond, ImportStatus, Context, function, _, Module).
+ MaybeDet, Cond, ImportStatus, Context, function, IsClassMethod,
+ _, Module).
add_item_decl_pass_1(pragma(_), _, Status, Module, Status, Module) --> [].
@@ -2159,8 +2163,14 @@
MaybeDet = no
}
->
+ { check_marker(Markers, class_method) ->
+ IsClassMethod = yes
+ ;
+ IsClassMethod = no
+ },
module_add_mode(Module1, InstVarSet, PredName, Modes, MaybeDet,
- Cond, Status, Context, predicate, PredProcId, Module),
+ Cond, Status, Context, predicate, IsClassMethod,
+ PredProcId, Module),
{ MaybePredProcId = yes(PredProcId) }
;
{ Module = Module1 },
@@ -2215,9 +2225,14 @@
{ MaybeRetMode = yes(RetMode) }
->
{ list__append(Modes, [RetMode], Modes1) },
+ { check_marker(Markers, class_method) ->
+ IsClassMethod = yes
+ ;
+ IsClassMethod = no
+ },
module_add_mode(Module1, InstVarSet, FuncName, Modes1,
MaybeDet, Cond, Status, Context, function,
- PredProcId, Module),
+ IsClassMethod, PredProcId, Module),
{ MaybePredProcId = yes(PredProcId) }
;
{ Module = Module1 },
@@ -2365,8 +2380,9 @@
{ Method = pred_mode(VarSet, PredName, Modes, MaybeDet,
Cond, Context) },
{ Status = item_status(ImportStatus, _) },
+ { IsClassMethod = yes },
module_add_mode(Module0, VarSet, PredName, Modes, MaybeDet,
- Cond, ImportStatus, Context, predicate,
+ Cond, ImportStatus, Context, predicate, IsClassMethod,
PredIdProcId, Module),
{ MaybePredIdProcId = yes(PredIdProcId) }
;
@@ -2374,8 +2390,9 @@
Cond, Context) },
{ list__append(Modes, [RetMode], Modes1) },
{ Status = item_status(ImportStatus, _) },
- module_add_mode(Module0, VarSet, FuncName, Modes1,
- MaybeDet, Cond, ImportStatus, Context, function,
+ { IsClassMethod = yes },
+ module_add_mode(Module0, VarSet, FuncName, Modes1, MaybeDet,
+ Cond, ImportStatus, Context, function, IsClassMethod,
PredIdProcId, Module),
{ MaybePredIdProcId = yes(PredIdProcId) }
).
@@ -3029,16 +3046,17 @@
:- pred module_add_mode(module_info, inst_varset, sym_name, list(mode),
maybe(determinism), condition, import_status, prog_context,
- pred_or_func, pair(pred_id, proc_id), module_info,
+ pred_or_func, bool, pair(pred_id, proc_id), module_info,
io__state, io__state).
-:- mode module_add_mode(in, in, in, in, in, in, in, in, in, out, out,
+:- mode module_add_mode(in, in, in, in, in, in, in, in, in, in, out, out,
di, uo) is det.
% We should store the mode varset and the mode condition
% in the hlds - at the moment we just ignore those two arguments.
module_add_mode(ModuleInfo0, _VarSet, PredName, Modes, MaybeDet, _Cond,
- Status, MContext, PredOrFunc, PredProcId, ModuleInfo) -->
+ Status, MContext, PredOrFunc, IsClassMethod, PredProcId,
+ ModuleInfo) -->
% Lookup the pred or func declaration in the predicate table.
% If it's not there (or if it is ambiguous), optionally print a
@@ -3059,8 +3077,9 @@
{ PredId = PredId0 }
;
preds_add_implicit_report_error(ModuleName,
- PredOrFunc, PredName, Arity, Status, MContext,
- "mode declaration", PredId, ModuleInfo0, ModuleInfo1)
+ PredOrFunc, PredName, Arity, Status, IsClassMethod,
+ MContext, "mode declaration", PredId,
+ ModuleInfo0, ModuleInfo1)
),
% Lookup the pred_info for this predicate
@@ -3121,16 +3140,16 @@
% type inference.
:- pred preds_add_implicit_report_error(module_name, pred_or_func, sym_name,
- arity, import_status, prog_context, string,
+ arity, import_status, bool, prog_context, string,
pred_id, module_info, module_info, io__state, io__state).
-:- mode preds_add_implicit_report_error(in, in, in, in, in, in, in,
+:- mode preds_add_implicit_report_error(in, in, in, in, in, in, in, in,
out, in, out, di, uo) is det.
preds_add_implicit_report_error(ModuleName, PredOrFunc, PredName, Arity,
- Status, Context, Description, PredId,
+ Status, IsClassMethod, Context, Description, PredId,
ModuleInfo0, ModuleInfo) -->
- maybe_undefined_pred_error(PredName, Arity, PredOrFunc,
- Context, Description),
+ maybe_undefined_pred_error(PredName, Arity, PredOrFunc, Status,
+ IsClassMethod, Context, Description),
( { PredOrFunc = function } ->
{ adjust_func_arity(function, FuncArity, Arity) },
@@ -3325,8 +3344,9 @@
{ IsAssertion = no },
preds_add_implicit_report_error(ModuleName,
- PredOrFunc, PredName, Arity, Status, Context,
- "clause", PredId, ModuleInfo0, ModuleInfo1)
+ PredOrFunc, PredName, Arity, Status, no,
+ Context, "clause", PredId,
+ ModuleInfo0, ModuleInfo1)
)
),
% Lookup the pred_info for this pred,
@@ -3538,7 +3558,7 @@
{ ModuleInfo1 = ModuleInfo0 }
;
preds_add_implicit_report_error(ModuleName,
- PredOrFunc, PredName, Arity, Status, Context,
+ PredOrFunc, PredName, Arity, Status, no, Context,
"`:- pragma import' declaration",
PredId, ModuleInfo0, ModuleInfo1)
),
@@ -3849,7 +3869,7 @@
{ ModuleInfo1 = ModuleInfo0 }
;
preds_add_implicit_report_error(ModuleName,
- PredOrFunc, PredName, Arity, Status, Context,
+ PredOrFunc, PredName, Arity, Status, no, Context,
"`:- pragma c_code' declaration",
PredId, ModuleInfo0, ModuleInfo1)
),
@@ -3970,8 +3990,9 @@
[s(EvalMethodS)], Message1) },
preds_add_implicit_report_error(ModuleName,
- PredOrFunc, PredName, Arity, Status, Context,
- Message1, PredId, ModuleInfo0, ModuleInfo1),
+ PredOrFunc, PredName, Arity, Status, no,
+ Context, Message1, PredId,
+ ModuleInfo0, ModuleInfo1),
{ PredIds = [PredId] }
)
;
@@ -3987,8 +4008,9 @@
[s(EvalMethodS)], Message1) },
preds_add_implicit_report_error(ModuleName,
- predicate, PredName, Arity, Status, Context,
- Message1, PredId, ModuleInfo0, ModuleInfo1),
+ predicate, PredName, Arity, Status, no,
+ Context, Message1, PredId,
+ ModuleInfo0, ModuleInfo1),
{ PredIds = [PredId] }
)
),
@@ -7298,17 +7320,28 @@
prog_out__write_sym_name_and_arity(Name/Arity),
io__write_string("' specifies non-existent mode.\n").
-:- pred maybe_undefined_pred_error(sym_name, int, pred_or_func, prog_context,
- string, io__state, io__state).
-:- mode maybe_undefined_pred_error(in, in, in, in, in, di, uo) is det.
+:- pred maybe_undefined_pred_error(sym_name, int, pred_or_func, import_status,
+ bool, prog_context, string, io__state, io__state).
+:- mode maybe_undefined_pred_error(in, in, in, in, in, in, in, di, uo) is det.
% This is not considered an unconditional error anymore:
-% if there is no :- pred declaration, we just infer one,
-% unless the `--no-infer-types' option was specified.
+% if there is no `:- pred' or `:- func' declaration,
+% and the declaration is local, and not a type class method,
+% and the `--infer-types' option was specified,
+% then we just add an implicit declaration for that predicate or
+% function, marking it as one whose type will be inferred.
-maybe_undefined_pred_error(Name, Arity, PredOrFunc, Context, Description) -->
+maybe_undefined_pred_error(Name, Arity, PredOrFunc, Status, IsClassMethod,
+ Context, Description) -->
+ { status_defined_in_this_module(Status, DefinedInThisModule) },
+ { status_is_exported(Status, IsExported) },
globals__io_lookup_bool_option(infer_types, InferTypes),
- ( { InferTypes = yes } ->
+ (
+ { DefinedInThisModule = yes },
+ { IsExported = no },
+ { IsClassMethod = no },
+ { InferTypes = yes }
+ ->
[]
;
io__set_exit_status(1),
Index: tests/invalid/exported_mode.err_exp
===================================================================
RCS file: exported_mode.err_exp
diff -N exported_mode.err_exp
--- /dev/null Thu Mar 30 14:06:13 2000
+++ exported_mode.err_exp Sat Sep 16 10:37:41 2000
@@ -0,0 +1,4 @@
+exported_mode.m:004: Error: mode declaration for predicate `exported_mode:p/2'
+exported_mode.m:004: without preceding `pred' declaration.
+exported_mode.m:004: Inferred :- pred p(T1, string).
+For more information, try recompiling with `-E'.
Index: tests/invalid/exported_mode.m
===================================================================
RCS file: exported_mode.m
diff -N exported_mode.m
--- /dev/null Thu Mar 30 14:06:13 2000
+++ exported_mode.m Sat Sep 16 00:23:02 2000
@@ -0,0 +1,8 @@
+:- module exported_mode.
+:- interface.
+
+:- mode p(in, in) is semidet.
+
+:- implementation.
+
+p(_, "foo").
Index: tests/invalid/imported_mode.err_exp
===================================================================
RCS file: imported_mode.err_exp
diff -N imported_mode.err_exp
--- /dev/null Thu Mar 30 14:06:13 2000
+++ imported_mode.err_exp Sat Sep 16 10:37:02 2000
@@ -0,0 +1,4 @@
+exported_mode.int:003: Error: mode declaration for predicate `exported_mode:p/2'
+exported_mode.int:003: without preceding `pred' declaration.
+exported_mode.int:003: Inferred :- pred p(T1, T2).
+For more information, try recompiling with `-E'.
Index: tests/invalid/imported_mode.m
===================================================================
RCS file: imported_mode.m
diff -N imported_mode.m
--- /dev/null Thu Mar 30 14:06:13 2000
+++ imported_mode.m Sat Sep 16 00:23:22 2000
@@ -0,0 +1,11 @@
+:- module imported_mode.
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module exported_mode.
+
+main --> ( { p(41, 42) } -> print("yes"), nl ; print("no"), nl ).
+
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.67
diff -u -d -r1.67 Mmakefile
--- tests/invalid/Mmakefile 2000/09/15 11:25:01 1.67
+++ tests/invalid/Mmakefile 2000/09/15 23:28:50
@@ -30,11 +30,13 @@
errors2.m \
external.m \
ext_type_bug.m \
+ exported_mode.m \
func_errors.m \
funcs_as_preds.m \
ho_type_mode_bug.m \
ho_unique_error.m \
impure_method_impl.m \
+ imported_mode.m \
inline_conflict.m \
invalid_main.m \
inst_list_dup.m \
@@ -71,6 +73,7 @@
type_loop.m \
type_mismatch.m \
type_vars.m \
+ typeclass_mode.m \
typeclass_test_1.m \
typeclass_test_2.m \
typeclass_test_3.m \
@@ -112,6 +115,9 @@
MCFLAGS-no_exports = --halt-at-warn
MCFLAGS-sub_c = --verbose-error-messages
MCFLAGS-record_syntax_errors = --verbose-error-messages
+MCFLAGS-imported_mode = --infer-all
+MCFLAGS-exported_mode = --infer-all
+MCFLAGS-typeclass_mode = --infer-all
# The bug is caught when generating dependencies, so it is
# easiest just to do that step.
@@ -142,10 +148,14 @@
# We only need to make the dependencies for test cases consisting of
# multiple modules; currently the following are the only such cases.
-depend: aditi_errors.depend aditi_state_errors.depend \
- aditi_update_errors.depend aditi_update_mode_errors.depend \
- test_nested.depend partial_implied_mode.depend \
- undef_mod_qual.depend
+depend: aditi_errors.depend \
+ aditi_state_errors.depend \
+ aditi_update_errors.depend \
+ aditi_update_mode_errors.depend \
+ imported_mode.depend \
+ partial_implied_mode.depend \
+ test_nested.depend \
+ undef_mod_qual.depend
clean_local:
rm -f *.err *.err_res
Index: tests/invalid/typeclass_mode.err_exp
===================================================================
RCS file: typeclass_mode.err_exp
diff -N typeclass_mode.err_exp
--- /dev/null Thu Mar 30 14:06:13 2000
+++ typeclass_mode.err_exp Sat Sep 16 10:38:02 2000
@@ -0,0 +1,4 @@
+typeclass_mode.m:005: Error: mode declaration for predicate `typeclass_mode:p/1'
+typeclass_mode.m:005: without preceding `pred' declaration.
+typeclass_mode.m:005: Error: no clauses for predicate `typeclass_mode:p/1'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/typeclass_mode.m
===================================================================
RCS file: typeclass_mode.m
diff -N typeclass_mode.m
--- /dev/null Thu Mar 30 14:06:13 2000
+++ typeclass_mode.m Sat Sep 16 10:17:43 2000
@@ -0,0 +1,7 @@
+:- module typeclass_mode.
+:- interface.
+
+:- typeclass c(T) where [
+ mode p(in) is det
+].
+
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list