[PATCH] Fix std::uncaught_exception() to return true during exception initialization

Howard Hinnant howard.hinnant at gmail.com
Wed Dec 11 15:41:51 PST 2013


On Dec 9, 2013, at 4:42 PM, Mark Seaborn <mseaborn at chromium.org> wrote:

> Hi howard.hinnant,
> 
> Fix std::uncaught_exception() to return true during exception initialization
> 
> std::uncaught_exception() should return true during the call to the
> copy constructor that "throw X" does to initialize the exception
> object after the expression X has been evaluated (or during the call
> to the normal constructor if the compiler has done copy elision).
> 
> Fix this by incrementing uncaughtExceptions earlier, in
> __cxa_allocate_exception() rather than in __cxa_throw().
> 
> This fixes PR18193.
> 
> 
> http://llvm-reviews.chandlerc.com/D2366
> 
> Files:
>  src/cxa_exception.cpp
> 
> Index: src/cxa_exception.cpp
> ===================================================================
> --- src/cxa_exception.cpp
> +++ src/cxa_exception.cpp
> @@ -160,6 +160,11 @@
>     if (NULL == exception_header)
>         std::terminate();
>     std::memset(exception_header, 0, actual_size);
> +    // Increment uncaughtExceptions now so that
> +    // std::uncaught_exception() returns true in the copy constructor
> +    // that "throw" calls to initialize the exception.  The increment
> +    // here is not atomic because the globals are thread-local.
> +    __cxa_get_globals()->uncaughtExceptions += 1;
>     return thrown_object_from_cxa_exception(exception_header);
> }
> 
> @@ -229,7 +234,6 @@
>     exception_header->exceptionDestructor = dest;
>     setExceptionClass(&exception_header->unwindHeader);
>     exception_header->referenceCount = 1;  // This is a newly allocated exception, no need for thread safety.
> -    globals->uncaughtExceptions += 1;   // Not atomically, since globals are thread-local
> 
>     exception_header->unwindHeader.exception_cleanup = exception_cleanup_func;
> #if __arm__
> <D2366.1.patch>

It appears to me that that CWG 475 (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#475) decided in  April 2006 the opposite direction of the fix made to gcc implemented a year earlier.

The current draft retains the wording from CWG 475 (15.5.3/p1):

> The function std::uncaught_exception() returns true *after* completing the initialization of the exception object...

(I added the emphasis)

The current output of your test on OS X:

std::uncaught_exception()=0

appears to me to be the standard conforming output.

Howard





More information about the cfe-commits mailing list