[m-rev.] diff: Make most_specific_rval handle mkword_hole.
Peter Wang
novalazy at gmail.com
Wed May 22 14:57:41 AEST 2013
dupelim.most_specific_rval did not handle the `mkword_hole' option that
was added to the `rval' type.
compiler/dupelim.m:
Fix the bug.
tests/valid/Mmakefile:
tests/valid/dupelim_mkword_hole.m:
Add test case.
diff --git a/compiler/dupelim.m b/compiler/dupelim.m
index 3afe74a..4794831 100644
--- a/compiler/dupelim.m
+++ b/compiler/dupelim.m
@@ -975,6 +975,7 @@ most_specific_lval(LvalA, LvalB, Lval) :-
:- pred most_specific_rval(rval::in, rval::in, rval::out) is semidet.
most_specific_rval(RvalA, RvalB, Rval) :-
+ require_complete_switch [RvalA]
(
RvalA = lval(LvalA),
RvalB = lval(LvalB),
@@ -985,6 +986,7 @@ most_specific_rval(RvalA, RvalB, Rval) :-
unexpected($module, $pred, "var")
;
( RvalA = mkword(_, _)
+ ; RvalA = mkword_hole(_)
; RvalA = const(_)
; RvalA = mem_addr(_)
),
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index 62f01f1..afddc8f 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -95,6 +95,7 @@ OTHER_PROGS= \
det_string_switch \
det_switch \
double_vn \
+ dupelim_mkword_hole \
easy_nondet_test \
easy_nondet_test_2 \
empty_bound_inst_list \
diff --git a/tests/valid/dupelim_mkword_hole.m b/tests/valid/dupelim_mkword_hole.m
new file mode 100644
index 0000000..8543a62
--- /dev/null
+++ b/tests/valid/dupelim_mkword_hole.m
@@ -0,0 +1,99 @@
+% dupelim.m did not handle mkword_hole case leading to:
+%
+% predicate `ll_backend.dupelim.process_elim_labels'/11:
+% Unexpected: blocks with same standard form don't antiunify
+
+:- module dupelim_mkword_hole.
+:- interface.
+
+:- import_module bool.
+:- import_module io.
+
+:- type foo
+ ---> foo.
+
+:- type value
+ ---> object(object).
+
+:- type object
+ ---> some [T] object(T).
+
+:- pred p1(foo::in, object::in, value::in, bool::out, io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+:- import_module require.
+
+:- type thing
+ ---> f1
+ ; f2
+ ; f3
+ ; f4
+ ; f5
+ ; f6
+ ; f7
+ ; f8(int, int)
+ ; f9(int, int, int)
+ ; struct(struct). % direct arg functor
+
+:- type struct
+ ---> struct(string, int).
+
+%-----------------------------------------------------------------------------%
+
+p1(Foo, X, object(Y), Res, !IO) :-
+ ( get_thing(X, struct(_)) ->
+ p2(Foo, X, Y, Res, !IO)
+ ;
+ unexpected($module, $pred)
+ ).
+
+:- pred p2(foo::in, object::in, object::in, bool::out, io::di, io::uo) is det.
+
+p2(Foo, X, Y, Res, !IO) :-
+ ( get_thing(X, struct(_)) ->
+ p3(Foo, X, Z),
+ ( Z = [] ->
+ Res = no
+ ; get_thing(Y, struct(_)) ->
+ Res = yes
+ ;
+ Res = no
+ )
+ ; get_thing(X, struct(_)) ->
+ ( get_thing(Y, struct(_)) ->
+ Res = yes
+ ;
+ Res = no
+ )
+ ;
+ Res = no
+ ).
+
+:- pred p3(foo::in, object::in, list(int)::out) is det.
+
+p3(Foo, X, Z) :-
+ p4(Foo, X, Y),
+ (
+ Y = [],
+ Z = []
+ ;
+ Y = [_ | _],
+ Z = [1]
+ ).
+
+:- pragma no_inline(p4/3).
+:- pred p4(foo, object, list(int)).
+:- mode p4(in, in, out) is det.
+
+p4(_, _, []).
+
+:- pred get_thing(object, T).
+:- mode get_thing(in, out) is semidet.
+
+get_thing(object(T0), T) :-
+ dynamic_cast(T0, T).
More information about the reviews
mailing list