G++ ABI mismatches

Richard Henderson rth at redhat.com
Mon Aug 25 22:19:07 UTC 2003


On Mon, Aug 25, 2003 at 08:47:51AM +0100, Nathan Sidwell wrote:
> >... I also noticed that G++ is building __cxa_begin_catch with type
> >void*(*)(void*), instead of void(*)(void*) as it is defined in section
> >2.5.3 of the ABI spec.
> >
> >Which one is wrong?
>
> gcc's implementation is incorrect. its return value is never used

This is false.

The return value is the adjusted pointer to the exception object.
Consider the following test case, which shows that pointer adjustment
must happen on a per-handler basis.

	extern "C" void abort();

	struct A { int x; };
	struct B { int y; };
	struct C { int z; };
	struct D : public A, B, C { };

	static D *d;
	static int match;

	static void do_throw()
	{
	  match = 0;
	  d = new D;
	  throw d;
	}

	static void testA()
	{
	  try {
	    do_throw();
	  } catch (A *a) {
	    match |= (d == a) << 0;
	    throw;
	  }
	}

	static void testB()
	{
	  try {
	    testA();
	  } catch (B *b) {
	    match |= (d == b) << 1;
	    throw;
	  }
	}

	static void testC()
	{
	  try {
	    testB();
	  } catch (C *c) {
	    match |= (d == c) << 2;
	  }
	}

	int main()
	{
	  testC();
	  if (match != 7)
	    abort ();
	}

> and its implementation has the following
>       // ??? No sensible value to return; we don't know what the
>       // object is, much less where it is in relation to the header.
>       return 0;
> for one of its returns :)

Note that this is for the case of non-C++ types being caught.  This
case can only appear in a catch(...) clause, at which point the 
return value indeed is not used.



r~



More information about the cxx-abi-dev mailing list