This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR vs TRY_CATCH_EXPR
- To: gcc2 at cygnus dot com, egcs at cygnus dot com
- Subject: CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR vs TRY_CATCH_EXPR
- From: Per Bothner <bothner at cygnus dot com>
- Date: Fri, 18 Dec 1998 10:52:09 -0800
I am working on a try-finally type construct. Specifically,
I am trying to implement the Java synchronized statement.
This has the form:
synchronized (OBJ) { BODY }
It is equivalent to:
tmp = OBJ;
_Jv_MonitorEnter(tmp);
try {
BODY
} finally {
_Jv_MonitorExit(tmp);
}
which is equivalent to the C++:
tmp = OBJ;
_Jv_MonitorEnter(tmp);
try {
BODY
_Jv_MonitorExit(tmp);
} catch (...) {
_Jv_MonitorExit(tmp);
throw;
}
So I'm trying to express this using existing gcc tree node types,
and having no luck. The complications are that the finalization
expression (this this case _Jv_MonitorExit(tmp)) need to be done
after any of:
(a) BODY completes normally.
(b) there is a return, break, or continue that exits BODY.
(c) there is an unhandled exception thrown by BODY.
The tree code CLEANUP_POINT_EXPR+WITH_CLEANUP_EXPR and/or TRY_CATCH_EXPR
look like they should do the right thing, but they don't seem to.
The first question is what are these forms *supposed* to do?
(1) Is a cleanup specified with CLEANUP_POINT_EXPR supposed to be
executed if an unhandled exception is thrown? I would assume so,
but the comments in tree.def don't specifically say, and the code
(in egcs) doesn't seem to handle it. However, this could easily
be bit-rot left over from re-writing the exception handling code,
since as far as I know CLEANUP_POINT_EXPR+WITH_CLEANUP_EXPR don't
seem to be used by any egcs front-end. I suspect they are only
used by Ada, which is not integrated into egcs.
(2) Is a cleanup specified with CLEANUP_POINT_EXPR supposed
to be executed if there is a jump (or return) out of the BODY?
This I'm more confident about that the answer is "yes".
(3) If an exception is thrown by the first operand of TRY_CATCH_EXPR,
is it re-thrown after the second operand is executed? I assume
so, and it seems to be the case.
(4) If there is a jump out of the first operand of TRY_CATCH_EXPR,
is the second operand evaluated? I assume not.
My guess is that what I should be using is:
build1 (CLEANUP_POINT_EXPR, void_type_node,
build (WITH_CLEANUP_EXPR, void_type_node,
BODY, NULL_TREE,
build (CALL_EXPR, ... "_Jv_MonitorExit" ..., tmp)));
However, the implementation of CLEANUP_POINT_EXPR+WITH_CLEANUP_EXPR
is broken and needs to be fixed for the new correct exception handling.
But before I bug the exception handling people, I'd like to verify
that my understanding is correct.
--Per Bothner
Cygnus Solutions bothner@cygnus.com http://www.cygnus.com/~bothner