This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfc] fix libstdc++/10606


Benjamin Kosnik wrote:
...
For the lazy among us, can you post the test code for constructing
that table please?

I don't have the original code anymore but the attached program should be close enough. I just quickly whipped it up so be kind to me if it's buggy :)


Also, this clarifies/simplifies uncaught_exception to something that means true when an exception object (not temporary object) is "in flight." I like that part.

Just so there's no misunderstanding: by the temporary object I meant the unnamed object constructed by the runtime library as a copy of the value of argument of the throw-expression. I.e., in this snippet:

    try {
        S s0, s1;
        throw 1 ? s0 : s1;   // invokes S(const S&) with s0 as argument
    }
    catch (...) {
        throw;   // rethrows s2
    }

s0 is the /thrown object/. The unnamed temporary object created
by the runtime by invoking the copy ctor for S is known as the
/exception object/ (let's call it s2). The issue proposes to
make it clear that uncaught_exception() returns *false* until
the completion of the evaluation of the expression 1 ? s0 : s1,
and *true* immediately after that, i.e., true in the copy ctor
invoked to copy s0 to s2. This copy is what I would call the
object "in flight" because that's what gets caught by handlers
that catch by reference and what gets rethrown from such handlers
by a throw expression with no operands.

Martin
#include <stdio.h>
#include <exception>

static int n;

struct B {

    int id;

    B (): id (n++) {
        printf ("%d: B::B() [%d]\n", std::uncaught_exception (), id);
    }

    B (const B&);

    ~B () {
        printf ("%d: ~B::~B() [%d]\n", std::uncaught_exception (), id);
    }
};


struct D: B
{
    D (): B () {
        printf ("%d: D::D() [%d]\n", std::uncaught_exception (), id);
    }

    D (const B &b): B (b) {
        printf ("%d: %D::%D(const %D& [%d]) [%d]\n",
                std::uncaught_exception (), b.id, id);
    }

    D (const D &d): B (d) {
        printf ("%d: %D::%D(const %D& [%d]) [%d]\n",
                std::uncaught_exception (), d.id, id);
    }

    ~D () {
        printf ("%d: ~D::~D() [%d]\n", std::uncaught_exception (), id);
    }
};


B::B (const B &b)
    : id (n++)
{
    printf ("%d: B::B(const B& [%d]) [%d]\n",
            std::uncaught_exception (), b.id, id);

    static int rethrow;

    if (!rethrow++) {
        printf ("   throw D\n");
        throw D (*this);
    }
}


int main ()
{
    try {
        try {
            B b;
            printf ("throw B\n");

            throw b;
        }
        catch (B b) {
            printf ("%d: caught B [%d], rethrowing\n",
                    std::uncaught_exception (), b.id);
            throw;
        }
    }
    catch (B b) {
        printf ("%d: caught B [%d]\n", std::uncaught_exception (), b.id);
    }
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]