g++: exceptions thrown from asm declarations
Stephan Bergmann
stephan.bergmann@sun.com
Wed Sep 22 14:50:00 GMT 2004
Hi all.
I have the following problematic code (used within OpenOffice.org's UNO
component model to synthesize calls to C++ class member functions):
void dummy(); // can throw anything
namespace {
static void inner(bool b) {
if (b) dummy(); // never called
asm(/* make a call to a function that may throw */);
}
}
void outer(bool b) { // always called as outer(false)
try {
inner(b);
} catch (...) {
// handle...
}
}
With g++ 3.3, this works fine: outer does not inline the call to inner,
and since inner might call dummy (which could throw exceptions), an
error-handling range is spanned around the call to inner within outer.
The call to dummy in inner (which actually is never taken at runtime) is
a hack to ensure that the compiler assumes that inner may throw
exceptions, as the compiler obviously assumes that asm declarations do
not throw exceptions (an assumption that is violated in this case).
With g++ 3.4, this no longer works: inner is static and only called
from outer, so it is inlined there. There is still an error-handling
range spanned around the call to dummy, but no longer around the asm
declaration. If, at runtime, an exception is thrown from the asm
declaration, it is thus not caught by the catch handler.
In the current case, the solution is easy: If I remove the static from
inner, g++ 3.4 obviously no longer considers it for inlining (this could
be considered an error: functions within unnamed namespaces should be
treated the same as static functions here). However, that still has two
drawbacks:
- If a future g++ version is smart enough to inline both static
functions and functions within unnamed namespaces, the problem reappears
(and has to be worked around with more drastic measures, like moving
inner to a different translation unit).
- The call to dummy is a hack, and it would be nice to get rid of it.
The real solution would be to somehow specify that (the call instruction
within) the asm declaration can throw exceptions. Is that possible in
g++? I did not find anything about that in the manual.
-Stephan
More information about the Gcc
mailing list