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