Files
mercury/tests/hard_coded/reuse_array.m
Zoltan Somogyi 33eb3028f5 Clean up the tests in half the test directories.
tests/accumulator/*.m:
tests/analysis_*/*.m:
tests/benchmarks*/*.m:
tests/debugger*/*.{m,exp,inp}:
tests/declarative_debugger*/*.{m,exp,inp}:
tests/dppd*/*.m:
tests/exceptions*/*.m:
tests/general*/*.m:
tests/grade_subdirs*/*.m:
tests/hard_coded*/*.m:
    Make these tests use four-space indentation, and ensure that
    each module is imported on its own line. (I intend to use the latter
    to figure out which subdirectories' tests can be executed in parallel.)

    These changes usually move code to different lines. For the debugger tests,
    specify the new line numbers in .inp files and expect them in .exp files.
2015-02-14 20:14:03 +11:00

88 lines
2.4 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
% Test structure sharing annotations on array operations.
%---------------------------------------------------------------------------%
:- module reuse_array.
:- interface.
:- import_module io.
:- impure pred main(io::di, io::uo) is cc_multi.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module array.
:- import_module list.
:- type struct
---> struct(int, f :: int).
%---------------------------------------------------------------------------%
main(!IO) :-
Struct1 = struct(1, dummy),
impure addr(Struct1, Addr1),
array.init(5, Struct1, Array0),
% Structure reuse requires a deconstruction which it can consider the death
% of a structure, so we oblige.
unused(Struct1 ^ f),
Struct2 = struct(2, dummy),
impure addr(Struct2, Addr2),
unused(Struct2 ^ f),
% Struct1 should NOT be reused here, as it shares with Array0.
% Struct2 can and should be reused instead.
Struct3 = struct(3, dummy),
impure addr(Struct3, Addr3),
array.unsafe_set(3, Struct3, Array0, Array),
unused(Struct3 ^ f),
% Struct3 should NOT be reused for Struct4, as it is shared with Array.
Struct4 = struct(4, dummy),
impure addr(Struct4, Addr4),
array.to_list(Array, List),
io.write(List, !IO),
io.nl(!IO),
list.sort_and_remove_dups([Addr1, Addr2, Addr3, Addr4], Addrs),
list.length(Addrs, NumAddrs),
(
NumAddrs = 4
->
io.write_string("4 distinct addresses - no reuse detected\n", !IO)
;
NumAddrs = 3,
Addr2 = Addr3
->
io.write_string("3 distinct addresses - reuse detected\n", !IO)
;
io.write_string("unexpected addresses: ", !IO),
io.write(Addrs, !IO),
io.nl(!IO)
).
:- impure pred addr(T::ui, int::uo) is cc_multi.
:- pragma foreign_proc("C",
addr(T::ui, Ptr::uo),
[will_not_call_mercury, thread_safe, no_sharing],
"
Ptr = (MR_Integer) T;
").
% This is used to force structures to be constructed dynamically.
:- func dummy = (int::uo).
:- pragma no_inline(dummy/0).
dummy = 999.
:- pred unused(int::unused) is det.
unused(_).