re PR c++/12491 (Destructor fails to compile when optimizations (inlining) are enabled)

PR c++/12491
        * except.c (struct eh_region): Add u.fixup.resolved.
        (resolve_one_fixup_region): Split out from ...
        (resolve_fixup_regions): ... here.
	* g++.dg/eh/cleanup2.C: New.

From-SVN: r75883
This commit is contained in:
Richard Henderson 2004-01-14 13:01:18 -08:00 committed by Richard Henderson
parent 4eb31d4f7e
commit 1bddbeb409
3 changed files with 88 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2004-01-14 Richard Henderson <rth@redhat.com>
PR c++/12491
* except.c (struct eh_region): Add u.fixup.resolved.
(resolve_one_fixup_region): Split out from ...
(resolve_fixup_regions): ... here.
2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
* config/mn10300/mn10300.h (STRUCT_VALUE): Change to 0.

View File

@ -189,6 +189,7 @@ struct eh_region GTY(())
struct eh_region_u_fixup {
tree cleanup_exp;
struct eh_region *real_region;
bool resolved;
} GTY ((tag ("ERT_FIXUP"))) fixup;
} GTY ((desc ("%0.type"))) u;
@ -889,30 +890,50 @@ collect_eh_region_array (void)
}
}
static void
resolve_one_fixup_region (struct eh_region *fixup)
{
struct eh_region *cleanup, *real;
int j, n;
n = cfun->eh->last_region_number;
cleanup = 0;
for (j = 1; j <= n; ++j)
{
cleanup = cfun->eh->region_array[j];
if (cleanup && cleanup->type == ERT_CLEANUP
&& cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
break;
}
if (j > n)
abort ();
real = cleanup->outer;
if (real && real->type == ERT_FIXUP)
{
if (!real->u.fixup.resolved)
resolve_one_fixup_region (real);
real = real->u.fixup.real_region;
}
fixup->u.fixup.real_region = real;
fixup->u.fixup.resolved = true;
}
static void
resolve_fixup_regions (void)
{
int i, j, n = cfun->eh->last_region_number;
int i, n = cfun->eh->last_region_number;
for (i = 1; i <= n; ++i)
{
struct eh_region *fixup = cfun->eh->region_array[i];
struct eh_region *cleanup = 0;
if (! fixup || fixup->type != ERT_FIXUP)
if (!fixup || fixup->type != ERT_FIXUP || fixup->u.fixup.resolved)
continue;
for (j = 1; j <= n; ++j)
{
cleanup = cfun->eh->region_array[j];
if (cleanup && cleanup->type == ERT_CLEANUP
&& cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
break;
}
if (j > n)
abort ();
fixup->u.fixup.real_region = cleanup->outer;
resolve_one_fixup_region (fixup);
}
}

View File

@ -0,0 +1,46 @@
// PR c++/12491
// { dg-do compile }
// { dg-options "-O2" }
// The return statements are necessary to trigger this bug.
class Object
{
public:
virtual ~Object (void) { return; }
};
class AutoPtr
{
public:
~AutoPtr (void) { delete m_rep; return; }
private:
const Object *m_rep;
};
class Handle
{
public:
~Handle (void) { return; }
private:
AutoPtr m_rep;
};
class HandleOf:public Handle
{
public:
~HandleOf (void) { return; }
};
class Error
{
public:
~Error (void);
private:
HandleOf m_hndl;
};
Error::~Error (void)
{
return;
}