mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-24 13:53:54 +00:00
Estimated hours taken: 2 Branches: main Predicates generated by the untupling transformation were being given the same forms of names, no matter if the original procedure being transformed was a predicate or a function. If a module had a predicate and a function with the same name and arity, and tracing was enabled, and a low enough optimisation level was being used, this would result in an exception being thrown. A similar nameclash happened when two procedures of the same name but different arities were expanded into procedures of the same arity. compiler/untupling.m: Give generated procedures different names depending on whether the proc being transformed was a predicate or function. Keep more goal context information when transforming procedures; the line number becomes part of the generated procedure's name. Use a counter for generating procedure names to catch the pathological case where the name, pred-or-func, arity and line numbers of two generated procs are all the same. compiler/loop_inv.m: Give generated procedures different names depending on whether the proc being transformed was a predicate or function. tests/valid/Mercury.options: tests/valid/Mmakefile: tests/valid/untuple_bug.m: Add a test case.
52 lines
1.5 KiB
Mathematica
52 lines
1.5 KiB
Mathematica
% Predicates generated by the untupling transformation were being given the
|
|
% same forms of names, no matter if the original procedure being transformed
|
|
% was a predicate or a function. If a module had a predicate and a function
|
|
% with the same name and arity, and tracing was enabled, and a low enough
|
|
% optimisation level was being used, this would result in an exception being
|
|
% thrown.
|
|
%
|
|
% mmc -C -O0 --untuple --trace deep --trace-optimized untuple_bug.m
|
|
%
|
|
% Uncaught Mercury exception:
|
|
% Software Error: map__det_insert: key already present
|
|
% Key Type: ll_backend.llds.label
|
|
% Key Value: internal(2, proc(unqualified("untuple_bug"), predicate,
|
|
% unqualified("untuple_bug"), "untupling_0__pred__f__0__1", 1, 0))
|
|
% Value Type: ll_backend.llds.data_addr
|
|
%
|
|
% A similar nameclash happened when two procedures of the same name but
|
|
% different arities were expanded into procedures of the same arity.
|
|
%
|
|
|
|
:- module untuple_bug.
|
|
|
|
:- interface.
|
|
|
|
:- type t ---> t(int).
|
|
:- type tt ---> tt(int, int).
|
|
|
|
% A function and predicate of the same name and arity.
|
|
|
|
:- func f = t.
|
|
:- pred f(t::out) is det.
|
|
|
|
% Two predicates that expand into the same name and arity.
|
|
|
|
:- pred g(t::in, t::in) is semidet.
|
|
:- pred g(tt::in) is semidet.
|
|
|
|
:- pred h(t::in, t::in) is semidet.
|
|
:- pred h(tt::in) is semidet.
|
|
|
|
:- implementation.
|
|
|
|
f = t(0).
|
|
f(t(0)).
|
|
|
|
g(t(T), t(T)).
|
|
g(tt(T, T)).
|
|
|
|
% These are on the same line to make sure that a counter is being used
|
|
% properly when generating names.
|
|
h(t(T), t(T)). h(tt(T, T)).
|