[m-rev.] for review: Do not opt-export `try' goals.
Peter Wang
novalazy at gmail.com
Mon Sep 19 13:37:09 AEST 2016
This fixes a serious issue as `try' goals are not properly written to
.opt files, so when read back would not actually catch any exceptions.
Bug #420.
At the point where we are to create the .opt file, the pieces of a `try'
goal exist in a "pre-transformed" hlds_goal. Teasing apart the pieces to
resemble the original `try' goal would be non-trivial.
compiler/intermod.m:
Do not export any predicate or function with a clause containing a
`try' goal.
library/exception.m
Throw an exception if the dummy predicate
`magic_exception_result/1' is ever called.
tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/intermod_try_goal.exp:
tests/hard_coded/intermod_try_goal.m:
tests/hard_coded/intermod_try_goal2.m:
Add test case.
NEWS:
Announce change.
---
NEWS | 5 +++++
compiler/intermod.m | 8 ++++----
library/exception.m | 4 ++--
tests/hard_coded/Mercury.options | 2 ++
tests/hard_coded/Mmakefile | 1 +
tests/hard_coded/intermod_try_goal.exp | 2 ++
tests/hard_coded/intermod_try_goal.m | 29 +++++++++++++++++++++++++++++
tests/hard_coded/intermod_try_goal2.m | 30 ++++++++++++++++++++++++++++++
8 files changed, 75 insertions(+), 6 deletions(-)
create mode 100644 tests/hard_coded/intermod_try_goal.exp
create mode 100644 tests/hard_coded/intermod_try_goal.m
create mode 100644 tests/hard_coded/intermod_try_goal2.m
diff --git a/NEWS b/NEWS
index 10c4b89..ef18920 100644
--- a/NEWS
+++ b/NEWS
@@ -443,6 +443,11 @@ Changes to the Mercury compiler:
prevent the compiler adding any directories to the runtime search path
automatically.
+* We have disabled intermodule optimisation of any predicates or functions
+ using `try' goals. This fixes a serious issue as `try' goals are not
+ properly written to .opt files, so when read back would not actually
+ catch any exceptions.
+
Change to the Mercury debugger:
* Interactive queries are now supported on OS X.
diff --git a/compiler/intermod.m b/compiler/intermod.m
index 0ae6cae..f7bfe84 100644
--- a/compiler/intermod.m
+++ b/compiler/intermod.m
@@ -697,10 +697,10 @@ gather_entities_to_opt_export_in_goal_expr(GoalExpr0, GoalExpr,
ShortHand = atomic_goal(GoalType, Outer, Inner, MaybeOutputVars,
MainGoal, OrElseGoals, OrElseInners)
;
- ShortHand0 = try_goal(MaybeIO, ResultVar, SubGoal0),
- gather_entities_to_opt_export_in_goal(SubGoal0, SubGoal,
- DoWrite, !IntermodInfo),
- ShortHand = try_goal(MaybeIO, ResultVar, SubGoal)
+ ShortHand0 = try_goal(_MaybeIO, _ResultVar, _SubGoal0),
+ % hlds_out_goal.m does not write out `try' goals properly.
+ DoWrite = no,
+ ShortHand = ShortHand0
;
ShortHand0 = bi_implication(_, _),
% These should have been expanded out by now.
diff --git a/library/exception.m b/library/exception.m
index 2f133b9..ed99dda 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -616,8 +616,8 @@ unsafe_call_transaction_goal(Goal, STM0, {Result, STM}) :-
%---------------------------------------------------------------------------%
-magic_exception_result(succeeded({})).
-magic_exception_result(succeeded({})). % force cc_multi
+magic_exception_result(_) :-
+ throw("magic_exception_result called").
unreachable :-
throw("unreachable code reached").
diff --git a/tests/hard_coded/Mercury.options b/tests/hard_coded/Mercury.options
index d375801..da88e2a 100644
--- a/tests/hard_coded/Mercury.options
+++ b/tests/hard_coded/Mercury.options
@@ -45,6 +45,8 @@ MCFLAGS-intermod_poly_mode = --intermodule-optimization
MCFLAGS-intermod_poly_mode_2 = --intermodule-optimization
MCFLAGS-intermod_pragma_clause = --intermodule-optimization
MCFLAGS-intermod_pragma_clause_sub = --intermodule-optimization
+MCFLAGS-intermod_try_goal = --intermodule-optimization
+MCFLAGS-intermod_try_goal2 = --intermodule-optimization
MCFLAGS-intermod_type_qual = --intermodule-optimization
MCFLAGS-intermod_type_qual2 = --intermodule-optimization
MCFLAGS-intermod_multimode = --intermodule-optimization
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index d2dc634..2c2e75a 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -171,6 +171,7 @@ ORDINARY_PROGS = \
intermod_multimode_main \
intermod_poly_mode \
intermod_pragma_clause \
+ intermod_try_goal \
intermod_type_qual \
intermod_unused_args \
java_rtti_bug \
diff --git a/tests/hard_coded/intermod_try_goal.exp b/tests/hard_coded/intermod_try_goal.exp
new file mode 100644
index 0000000..b636aa5
--- /dev/null
+++ b/tests/hard_coded/intermod_try_goal.exp
@@ -0,0 +1,2 @@
+caught exception: "catch me"
+done.
diff --git a/tests/hard_coded/intermod_try_goal.m b/tests/hard_coded/intermod_try_goal.m
new file mode 100644
index 0000000..dd8db3e
--- /dev/null
+++ b/tests/hard_coded/intermod_try_goal.m
@@ -0,0 +1,29 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module intermod_try_goal.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+
+:- import_module exception.
+
+:- import_module intermod_try_goal2.
+
+main(!IO) :-
+ catcher(thrower, !IO),
+ io.write_string("done.\n", !IO).
+
+:- pred thrower(io::di, io::uo) is det.
+
+thrower(!IO) :-
+ ( if semidet_true then
+ throw("catch me")
+ else
+ true
+ ).
diff --git a/tests/hard_coded/intermod_try_goal2.m b/tests/hard_coded/intermod_try_goal2.m
new file mode 100644
index 0000000..88fea0d
--- /dev/null
+++ b/tests/hard_coded/intermod_try_goal2.m
@@ -0,0 +1,30 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+
+:- module intermod_try_goal2.
+:- interface.
+
+:- import_module io.
+
+:- pred catcher(pred(io, io), io, io).
+:- mode catcher(pred(di, uo) is det, di, uo) is cc_multi.
+
+:- implementation.
+
+:- import_module string.
+
+ % intermod.m must ignore this pragma until `try' goals can be written
+ % properly to .opt files.
+ %
+:- pragma inline(catcher/3).
+
+catcher(Pred, !IO) :-
+ ( try [io(!IO)]
+ Pred(!IO)
+ then
+ true
+ catch_any Excp ->
+ io.write_string("caught exception: " ++ string(Excp), !IO),
+ io.nl(!IO)
+ ).
--
2.9.0
More information about the reviews
mailing list