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]

C++ PATCH to build_base_path for 4460


When constructing a virtual base, we know that it is at a fixed offset.
Unfortunately, we forgot that for the cleanup that gets run if the derived
constructor throws; we tried to look in the vtable for the offset, but the
vtable pointer was no longer pointing to a useful vtable.  This patch fixes
build_base_path so that all references to a virtual base from an in-charge
constructor or destructor will use the fixed offset.

Tested i686-pc-linux-gnu, applied to trunk and 3.1 branch.
Test in g++.eh/ctor2.C.

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.

*** class.c.~1~	Sun Mar 17 16:17:43 2002
--- class.c	Sun Mar 17 23:45:59 2002
*************** build_base_path (code, expr, binfo, nonn
*** 290,301 ****
      }
  
    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))
      expr = save_expr (expr);
!     
    if (!want_pointer)
      expr = build_unary_op (ADDR_EXPR, expr, 0);
    else if (!nonnull)
--- 290,298 ----
      }
  
    fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
!   if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
      expr = save_expr (expr);
! 
    if (!want_pointer)
      expr = build_unary_op (ADDR_EXPR, expr, 0);
    else if (!nonnull)
*************** build_base_path (code, expr, binfo, nonn
*** 303,309 ****
    
    offset = BINFO_OFFSET (binfo);
    
!   if (v_binfo && !fixed_type_p)
      {
        /* Going via virtual base V_BINFO.  We need the static offset
           from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
--- 300,306 ----
    
    offset = BINFO_OFFSET (binfo);
    
!   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
*************** build_base_path (code, expr, binfo, nonn
*** 324,330 ****
  			   size_diffop (offset, BINFO_OFFSET (v_binfo)));
  
        if (!integer_zerop (offset))
! 	offset = build (code, ptrdiff_type_node, v_offset, offset);
        else
  	offset = v_offset;
      }
--- 321,337 ----
  			   size_diffop (offset, BINFO_OFFSET (v_binfo)));
  
        if (!integer_zerop (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;
      }

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