mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-20 20:03:44 +00:00
compiler/foreign.m:
When returning the list of identifiers inside a foreign_proc's code,
ignore the contents of comments. This means that warnings about
variable names that occur in the foreign_proc's argument list
but do not occur in the foreign_proc's code cannot be shut up anymore
by mention the variable name in comments.
The "mostly" part is that typecheck.m still looks at the bodies
of foreign_procs without knowing about comments. Fixing that
will be part a future change.
NEWS.md:
Announce this breaking change.
compiler/fact_table_gen.m:
When we try to generate a foreign_proc's body for a fact table
but cannot do so due to the fact table file not being readable,
add a marker to the predicate that the fact table is for.
compiler/hlds_markers.m:
Update the documentation of the existing predicate marker
we use for this.
compiler/make_hlds_warn.m:
Do not warn about singleton variables in foreign_proc bodies
that are empty due to missing fact table files.
library/array.m:
library/io.file.m:
library/profiling_builtin.m:
library/stm_builtin.m:
library/table_builtin.m:
library/term_size_prof_builtin.m:
tests/invalid/erroneous_throw_promise.m:
tests/invalid/foreign_procs_exist_type.m:
tests/invalid/foreign_purity_mismatch.m:
tests/invalid/gh72_errors.m:
tests/invalid_purity/purity.m:
tests/valid/solv.m:
Shut up warnings about singletons in foreign_procs by adding a _ prefix
to the names of the relevant arguments, and delete the comments
that can no longer do that job.
tests/invalid/foreign_purity_mismatch.err_exp:
tests/invalid/gh72_errors.err_exp:
tests/invalid/gh72_errors.err_exp2:
tests/invalid/gh72_errors.err_exp3:
tests/invalid_purity/purity.err_exp:
Expect updated line numbers.
tests/warnings/warn_return.{m,err_exp}:
Extend this test case to test that
- we DO warn about return statements outside comments, but
- we DO NOT warn about return statements inside comments.
348 lines
8.7 KiB
Mathematica
348 lines
8.7 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% This test exercises the situations which compiler/direct_arg_in_out.m
|
|
% cannot handle, each of which should result in an error message.
|
|
%
|
|
% The .err_exp{,2,3} files are for targeting C, Java and C# respectively.
|
|
% Since the direct arg optimization does not apply when we generate code
|
|
% for Java and C#, .err_exp[23] don't contain the errors that .err_exp does.
|
|
% However, reporting no errors would mean that the test case failed (because
|
|
% it failed to detect the problem the test case is for), so we add another
|
|
% problem for these backend: duplicate foreign_procs.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module gh72_errors.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module string.
|
|
:- import_module solutions.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
main(!IO) :-
|
|
test_exports(!IO),
|
|
test_fprocs(!IO).
|
|
% test_modes(!IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred test_exports(io::di, io::uo) is det.
|
|
|
|
test_exports(!IO) :-
|
|
A = f1(_),
|
|
test_export_1(A, !IO),
|
|
|
|
B = f2(_),
|
|
C = f3(_),
|
|
test_export_2(42, B, C, !IO).
|
|
|
|
:- pred test_export_1(t, io, io).
|
|
:- mode test_export_1(t4 >> ground, di, uo) is det.
|
|
:- pragma foreign_export("C",
|
|
test_export_1(t4 >> ground, di, uo),
|
|
"exported_test_export_1").
|
|
:- pragma foreign_export("Java",
|
|
test_export_1(t4 >> ground, di, uo),
|
|
"exported_test_export_1").
|
|
:- pragma foreign_export("C#",
|
|
test_export_1(t4 >> ground, di, uo),
|
|
"exported_test_export_1").
|
|
|
|
test_export_1(A, !IO) :-
|
|
fill3("c", A),
|
|
fill2("b", A),
|
|
fill1("a", A),
|
|
io.write_string(dump_t(A), !IO).
|
|
|
|
:- pred test_export_2(int, t, t, io, io).
|
|
:- mode test_export_2(in, t4 >> ground, t4 >> ground, di, uo) is det.
|
|
:- pragma foreign_export("C",
|
|
test_export_2(in, t4 >> ground, t4 >> ground, di, uo),
|
|
"exported_test_export_2").
|
|
:- pragma foreign_export("Java",
|
|
test_export_2(in, t4 >> ground, t4 >> ground, di, uo),
|
|
"exported_test_export_2").
|
|
:- pragma foreign_export("C#",
|
|
test_export_2(in, t4 >> ground, t4 >> ground, di, uo),
|
|
"exported_test_export_2").
|
|
|
|
test_export_2(_N, A, B, !IO) :-
|
|
fill3("c", A),
|
|
fill2("b", A),
|
|
fill1("a", A),
|
|
io.write_string(dump_t(A), !IO),
|
|
fill3("c", B),
|
|
fill2("b", B),
|
|
fill1("a", B),
|
|
io.write_string(dump_t(B), !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred test_fprocs(io::di, io::uo) is det.
|
|
|
|
test_fprocs(!IO) :-
|
|
A = f1(_),
|
|
test_fproc_1(A, !IO),
|
|
|
|
B = f2(_),
|
|
C = f3(_),
|
|
test_fproc_2(42, B, C, !IO).
|
|
|
|
:- pred test_fproc_1(t, io, io).
|
|
:- mode test_fproc_1(t4 >> ground, di, uo) is det.
|
|
|
|
:- pragma foreign_proc("C",
|
|
test_fproc_1(_A::(t4 >> ground), IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
:- pragma foreign_proc("Java",
|
|
test_fproc_1(_A::(t4 >> ground), IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
test_fproc_1(_A::(t4 >> ground), IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
|
|
:- pred test_fproc_2(int, t, t, io, io).
|
|
:- mode test_fproc_2(in, t4 >> ground, t4 >> ground, di, uo) is det.
|
|
|
|
:- pragma foreign_proc("C",
|
|
test_fproc_2(_N::in, _A::(t4 >> ground), _B::(t4 >> ground),
|
|
IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
:- pragma foreign_proc("Java",
|
|
test_fproc_2(_N::in, _A::(t4 >> ground), _B::(t4 >> ground),
|
|
IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
test_fproc_2(_N::in, _A::(t4 >> ground), _B::(t4 >> ground),
|
|
IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
|
|
% These foreign_procs are the deliberate duplicates referred to at the top.
|
|
:- pragma foreign_proc("Java",
|
|
test_fproc_2(_N::in, _A::(t4 >> ground), _B::(t4 >> ground),
|
|
IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
test_fproc_2(_N::in, _A::(t4 >> ground), _B::(t4 >> ground),
|
|
IO0::di, IO::uo),
|
|
[promise_pure, may_call_mercury],
|
|
"
|
|
IO = IO0;
|
|
").
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
/*
|
|
These test predicates all cause mode errors before direct_arg_in_out.m
|
|
is every invoked, and I (zs) cannot think of any simple way to fix
|
|
the mode errors without screwing up the purpose of these tests.
|
|
Proposed fixes welcome.
|
|
|
|
:- pred test_modes(io::di, io::uo) is det.
|
|
|
|
test_modes(!IO) :-
|
|
A = f1(_),
|
|
test_modes_1(A, !IO),
|
|
|
|
B = f2(_),
|
|
C = f3(_),
|
|
test_modes_2(B, 42, C, !IO),
|
|
|
|
D = f1(_),
|
|
E = f2(_),
|
|
F = f3(_),
|
|
test_modes_3(D, 42, E, F, !IO),
|
|
|
|
G = f1(_),
|
|
H = f2(_),
|
|
I = f3(_),
|
|
J = f1(_),
|
|
test_modes_4(G, 42, H, I, J, !IO).
|
|
|
|
:- pred test_modes_1(t, io, io).
|
|
:- mode test_modes_1(((I =< ground) >> ground), di, uo) is det.
|
|
|
|
test_modes_1(A, !IO) :-
|
|
fill3("c", A),
|
|
fill2("b", A),
|
|
fill1("a", A),
|
|
io.write_string(dump_t(A), !IO).
|
|
|
|
:- pred test_modes_2(t, int, t, io, io).
|
|
:- mode test_modes_2((I =< ground) >> ground, in, (I =< ground) >> ground,
|
|
di, uo) is det.
|
|
|
|
test_modes_2(A, _N, B, !IO) :-
|
|
fill3("c", A),
|
|
fill2("b", A),
|
|
fill1("a", A),
|
|
io.write_string(dump_t(A), !IO),
|
|
fill3("c", B),
|
|
fill2("b", B),
|
|
fill1("a", B),
|
|
io.write_string(dump_t(B), !IO).
|
|
|
|
:- pred test_modes_3(t, int, t, t, io, io).
|
|
:- mode test_modes_3(((I =< ground) >> ground), in, (t234 >> ground),
|
|
((I =< ground) >> ground), di, uo) is det.
|
|
|
|
test_modes_3(A, _N, B, C, !IO) :-
|
|
fill3("c", A),
|
|
fill2("b", A),
|
|
fill1("a", A),
|
|
io.write_string(dump_t(A), !IO),
|
|
fill3("c", B),
|
|
fill2("b", B),
|
|
fill1("a", B),
|
|
io.write_string(dump_t(B), !IO),
|
|
fill3("c", C),
|
|
fill2("b", C),
|
|
fill1("a", C),
|
|
io.write_string(dump_t(C), !IO).
|
|
|
|
:- pred test_modes_4(t, int, t, t, t, io, io).
|
|
:- mode test_modes_4(((I =< ground) >> ground), in, (t234 >> ground),
|
|
((I =< ground) >> ground), (t234 >> ground), di, uo) is det.
|
|
|
|
test_modes_4(A, _N, B, C, D, !IO) :-
|
|
fill3("c", A),
|
|
fill2("b", A),
|
|
fill1("a", A),
|
|
io.write_string(dump_t(A), !IO),
|
|
fill3("c", B),
|
|
fill2("b", B),
|
|
fill1("a", B),
|
|
io.write_string(dump_t(B), !IO),
|
|
fill3("c", C),
|
|
fill2("b", C),
|
|
fill1("a", C),
|
|
io.write_string(dump_t(C), !IO),
|
|
fill3("c", D),
|
|
fill2("b", D),
|
|
fill1("a", D),
|
|
io.write_string(dump_t(D), !IO).
|
|
*/
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type t
|
|
---> f1(package)
|
|
; f2(package)
|
|
; f3(package)
|
|
; f4(package).
|
|
|
|
:- inst t4 for t/0
|
|
---> f1(free)
|
|
; f2(free)
|
|
; f3(free)
|
|
; f4(ground).
|
|
|
|
:- inst t34 for t/0
|
|
---> f1(free)
|
|
; f2(free)
|
|
; f3(ground)
|
|
; f4(ground).
|
|
|
|
:- inst t234 for t/0
|
|
---> f1(free)
|
|
; f2(ground)
|
|
; f3(ground)
|
|
; f4(ground).
|
|
|
|
:- type package
|
|
---> package(string, string).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- func dump_t(t) = string.
|
|
:- pragma no_inline(dump_t/1).
|
|
|
|
dump_t(f1(Package)) = "f1(" ++ dump_package(Package) ++ ")\n".
|
|
dump_t(f2(Package)) = "f2(" ++ dump_package(Package) ++ ")\n".
|
|
dump_t(f3(Package)) = "f3(" ++ dump_package(Package) ++ ")\n".
|
|
dump_t(f4(Package)) = "f4(" ++ dump_package(Package) ++ ")\n".
|
|
|
|
:- func dump_package(package) = string.
|
|
:- pragma no_inline(dump_t/1).
|
|
|
|
dump_package(package(A, B)) = "package(" ++ A ++ ", " ++ B ++ ")".
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred fill3(string, t).
|
|
:- mode fill3(in, t4 >> t34) is det.
|
|
:- pragma no_inline(fill3/2).
|
|
|
|
fill3(S, T0) :-
|
|
( T0 = f1(_)
|
|
; T0 = f2(_)
|
|
; T0 = f3(package("fill3", S))
|
|
; T0 = f4(_)
|
|
).
|
|
|
|
:- pred fill23(string, t).
|
|
:- mode fill23(in, t4 >> t234) is det.
|
|
:- pragma no_inline(fill3/2).
|
|
|
|
fill23(S, T0) :-
|
|
( T0 = f1(_)
|
|
; T0 = f2(package("fill2", S))
|
|
; T0 = f3(package("fill3", S))
|
|
; T0 = f4(_)
|
|
).
|
|
|
|
:- pred fill2(string, t).
|
|
:- mode fill2(in, t34 >> t234) is det.
|
|
:- pragma no_inline(fill2/2).
|
|
|
|
fill2(S, T0) :-
|
|
( T0 = f1(_)
|
|
; T0 = f2(package("fill2", S))
|
|
; T0 = f3(_)
|
|
; T0 = f4(_)
|
|
).
|
|
|
|
:- pred fill1(string, t).
|
|
:- mode fill1(in, t234 >> ground) is det.
|
|
:- pragma no_inline(fill1/2).
|
|
|
|
fill1(S, T0) :-
|
|
( T0 = f1(package("fill1", S))
|
|
; T0 = f2(_)
|
|
; T0 = f3(_)
|
|
; T0 = f4(_)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|