re PR c++/4460 (g++ 3.0.1 seg faults instead of throwing in a complicated inheritance hierarchy)

PR c++/4460
        * class.c (build_base_path): Virtual base layout is fixed in
        in-charge [cd]tors.

From-SVN: r50931
This commit is contained in:
Jason Merrill 2002-03-17 19:00:14 -05:00 committed by Jason Merrill
parent 94ea34195b
commit f2606a975a
3 changed files with 63 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2002-03-17 Jason Merrill <jason@redhat.com>
PR c++/4460
* class.c (build_base_path): Virtual base layout is fixed in
in-charge [cd]tors.
2002-03-17 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_PARSE_FILE): Redefine.

View File

@ -290,10 +290,7 @@ build_base_path (code, expr, binfo, nonnull)
}
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
if (fixed_type_p < 0)
/* Virtual base layout is not fixed, even in ctors and dtors. */
fixed_type_p = 0;
if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
expr = save_expr (expr);
if (!want_pointer)
@ -303,7 +300,7 @@ build_base_path (code, expr, binfo, nonnull)
offset = BINFO_OFFSET (binfo);
if (v_binfo && !fixed_type_p)
if (v_binfo && fixed_type_p <= 0)
{
/* Going via virtual base V_BINFO. We need the static offset
from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
@ -324,7 +321,17 @@ build_base_path (code, expr, binfo, nonnull)
size_diffop (offset, BINFO_OFFSET (v_binfo)));
if (!integer_zerop (offset))
offset = build (code, ptrdiff_type_node, v_offset, offset);
v_offset = build (code, ptrdiff_type_node, v_offset, offset);
if (fixed_type_p < 0)
/* Negative fixed_type_p means this is a constructor or destructor;
virtual base layout is fixed in in-charge [cd]tors, but not in
base [cd]tors. */
offset = build (COND_EXPR, ptrdiff_type_node,
build (EQ_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node),
v_offset,
BINFO_OFFSET (binfo));
else
offset = v_offset;
}

View File

@ -0,0 +1,42 @@
// PR c++/4460
// Test that the cleanup for fully-constructed subobjects when a
// constructor throws gets the right address for a virtual base.
// { dg-do run }
int r;
void *p;
struct VBase
{
virtual void f () {}
VBase() { p = this; }
~VBase() { if (p != this) r = 1; }
};
struct StreamBase
{
virtual ~StreamBase() {}
};
struct Stream : public virtual VBase, public StreamBase
{
Stream() {}
virtual ~Stream() {}
};
struct DerivedStream : public Stream
{
DerivedStream() { throw 1; }
};
int main() {
try
{
DerivedStream str;
}
catch (...) { }
return r;
}