[C++ PATCH] fix 3145

Mark Mitchell mark@codesourcery.com
Tue Nov 13 15:03:00 GMT 2001



--On Tuesday, November 20, 2001 08:10:26 PM +0000 Nathan Sidwell 
<nathan@codesourcery.com> wrote:

> Hi,
> this fixes 3145, one of the KDE virtual base bugs.
>
> The core of the problem is how build_vbase_path and get_base_distance
> behave. build_vbase_path was doing much more work than is now necessary,
> so I replaced it with a new build_base_path function, which copes
> with any kind of base binfo.  Then get_base_distance was called
> via convert_pointer_to_real in various circumstances that lead it
> to apparently locate the wrong base binfo.  I replaced get_base_distance
> with a new function lookup_base, which has (IMO) a cleaner interface.
> Following things through led to the elimination of convert_pointer_to
> and convert_pointer_to_real.

This is very exciting.  Getting rid of get_base_distance and
build_vbase_path is definitely nice.

I think that this patch is too big for the 3.0 branch; once it's approved
we'll put it on the mainline.

I'm having a hard time reading the patch due to the documentation being
a little sparse.  I think this is definitely the right approach, so I'll
point out some places where I think more comments would help, and then
we'll iterate.

! /* Build an access from EXPR to or from a base BINFO. CODE is
!    PLUS_EXPR if we're going from derived to base BINFO and MINUS_EXPR
!    if we're going from base BINFO to most derived. For that latter
!    case we cannot cross virtual bases. NONNULL is true if we know that
!    EXPR is not null.  EXPR may have pointer or class type and a
!    correctly qualifed pointer or class type is returned. */

  tree
! build_base_path (code, expr, binfo, nonnull)

I'm not sure I quite understand the interface.  Maybe this is the
right comment, or at least something close:

  /* Convert EXPR (an expression whose type is `A' or `A*'
     for some class type `A') to the base subobject `B' given by
     BINFO.  The expression returned will be of type `B' or `B*', matching
     the form provided in EXPR.  If CODE is PLUS_EXPR, `A' is derived
     from `B'; if it is MINUS_EXPR `B' is derived from `A'.  (In the latter
     case, there must be no virtual bases along the path from `A' to
     `B'.)  NONNULL is true if EXPR is known to be non-NULL.  */

And shouldn't NONNULL have type `bool'?

We should probably assert that CODE is either MINUS_EXPR or PLUS_EXPR
up front.

!          Under the 3.0 ABI, that offset is an entry in T's vtable.  */

Remove the first clause; there is now only one ABI.

+   bk_inaccessible = -3,   /* the base is inaccessible */

Capitalize the comments, I think?


! 	  /* If EXPR is NULL, then we don't need to do any arithmetic
! 	     to convert it:
!
! 	       [conv.ptr]
!
! 	       The null pointer value is converted to the null pointer
! 	       value of the destination type.  */
! 	  && !integer_zerop (expr))

Where did this check go in the new code?  Or is it no longer necessary?

This may have been an optimization so that:

  (A*)(B*)0

did not result in any code.  Would you check to see if we still generate
no instructions for such code?

+ static base_kind
+ lookup_base_recursive (binfo, base, access, within_current_scope,

Needs a comment.  And maybe some bool parameters.  And, I think the
pseudo-convention is to name these helper functions _r rather than
_recursive.

Thanks,


--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com



More information about the Gcc-patches mailing list