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:
parent
4eb31d4f7e
commit
1bddbeb409
3 changed files with 88 additions and 14 deletions
|
@ -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.
|
||||
|
|
49
gcc/except.c
49
gcc/except.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
46
gcc/testsuite/g++.dg/eh/cleanup2.C
Normal file
46
gcc/testsuite/g++.dg/eh/cleanup2.C
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue