LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 11893 - When noexcept is violated clang should call __cxa_begin_catch(unwind_arg) prior to calling std::terminate
Summary: When noexcept is violated clang should call __cxa_begin_catch(unwind_arg) pri...
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: C++11 (show other bugs)
Version: trunk
Hardware: PC All
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-30 20:00 PST by Howard Hinnant
Modified: 2013-06-20 20:53 PDT (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Howard Hinnant 2012-01-30 20:00:11 PST
This test:

#include <iostream>
#include <stdexcept>
#include <exception>
#include <cstdlib>

void handler1()
{
    std::cout << "handler 1\n";
    std::abort();
}

void handler2()
{
    std::cout << "handler 2\n";
    std::abort();
}

struct A
{
    ~A() {std::set_terminate(handler2);}
};

void f2()
{
    std::set_terminate(handler1);
    throw std::runtime_error("throw in f2");
}

void f1() noexcept
{
    A a;
    f2();
}

int main()
{
    f1();
}

Should output:

handler 1

When run against the trunk libc++abi.   Note that the trunk libc++abi won't run with the trunk libc++, but this will change soon (within a few days).

When the noexcept is violated, clang currently outputs a call to std::terminate().  Just prior to that call clang needs to call __cxa_begin_catch(unwind_arg) to make this work.

Reference [except.handle]/p7:

Also, an implicit handler is considered active when std::terminate() or std::unexpected() is entered due to a throw.

With the Itanium ABI, the way you make a handler active is by calling __cxa_begin_catch(unwind_arg).
Comment 1 Howard Hinnant 2012-01-31 11:09:01 PST
I'm just now noticing that we have the same issue when ever clang calls terminate for *any* reason during stack unwinding.  I.e. if a cleanup section throws when it shouldn't, and clang calls terminate, call __cxa_begin_catch first!
Comment 2 John McCall 2012-09-24 19:54:07 PDT
I see what you're saying, but for what it's worth, I think every existing compiler does this.  You might just want to make std::terminate more robust.
Comment 3 Howard Hinnant 2012-09-24 20:01:04 PDT
How?
Comment 4 John McCall 2012-09-24 20:59:15 PDT
Do you not already track the exception curently being thrown?  I suppose you don't.
Comment 5 John McCall 2013-06-20 20:53:59 PDT
Fixed in r174939, r174940, and r184475.