public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: c++/6831: Wrong base class alignment (nvalign vs. align)
@ 2002-07-03 13:04 nathan
  0 siblings, 0 replies; 4+ messages in thread
From: nathan @ 2002-07-03 13:04 UTC (permalink / raw)
  To: Grigory_Zagorodnev, gcc-bugs, gcc-prs, nathan, nobody

Synopsis: Wrong base class alignment (nvalign vs. align)

Responsible-Changed-From-To: unassigned->nathan
Responsible-Changed-By: nathan
Responsible-Changed-When: Wed Jul  3 13:04:14 2002
Responsible-Changed-Why:
    investigating

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6831


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: c++/6831: Wrong base class alignment (nvalign vs. align)
@ 2002-07-05  5:17 nathan
  0 siblings, 0 replies; 4+ messages in thread
From: nathan @ 2002-07-05  5:17 UTC (permalink / raw)
  To: Grigory_Zagorodnev, gcc-bugs, gcc-prs, nathan

Synopsis: Wrong base class alignment (nvalign vs. align)

State-Changed-From-To: open->closed
State-Changed-By: nathan
State-Changed-When: Fri Jul  5 05:17:50 2002
State-Changed-Why:
    not reproducable. see attached email. Also, generated code
    looks good, being
            addl r14 = 8, r0
    i.e. offset is 8

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6831


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: c++/6831: Wrong base class alignment (nvalign vs. align)
@ 2002-07-05  5:16 Nathan Sidwell
  0 siblings, 0 replies; 4+ messages in thread
From: Nathan Sidwell @ 2002-07-05  5:16 UTC (permalink / raw)
  To: nathan; +Cc: gcc-prs

The following reply was made to PR c++/6831; it has been noted by GNATS.

From: Nathan Sidwell <nathan@codesourcery.com>
To: Grigory_Zagorodnev@vniief.ims.intel.com, gcc-gnats@gcc.gnu.org,
   gcc-prs@gcc.gnu.org, nathan@gcc.gnu.org, gcc-bugs@gcc.gnu.org
Cc:  
Subject: Re: c++/6831: Wrong base class alignment (nvalign vs. align)
Date: Fri, 05 Jul 2002 13:08:23 +0100

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6831
 I do not get the different layout that you describe. I do get a different
 layout to the one you think you should get. The layout I get
 accords to the ABI. Here is the -fdump-class-hierarchy output for E. I have
 marked the important offsets.
 
 this is with a cross compiler configured as --target=ia64-intel-unix
 Class E
    size=48 align=16
 E (0x40090a40) 0 <- offsetof (E)
     vptridx=0 vptr=((&E::_ZTV1E) + 32)
   B (0x40090a80) 0 nearly-empty <- offset of (B)
       primary-for E (0x40090a40)
       subvttidx=8
     A (0x40090ac0) 24 virtual canonical <- offset of A
         vbaseoffset=-24
   D (0x40090b00) 8 <- offset of D
       subvttidx=16 vptridx=24 vptr=((&E::_ZTV1E) + 56)
     C (0x40090b40) 32 virtual canonical <- offset of C
         vbaseoffset=-32
 
 Note D has a dsize of 12, and 4 bytes of tail padding. Because D is a
 non-pod, we can overlay that tail padding with another object. Here
 is the layout we should and do get for ia64
 
 off size name
 0   8 	 E::B::vptr
 8   8    E::D::vptr
 16  4    E::D::d
 20  4    E::e overlayed ontop of D's tail padding
 24  4    E::A
 28  4    alignment padding
 32  16   E::C
 48
 
 nathan
 
 -- 
 Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
          'But that's a lie.' - 'Yes it is. What's your point?'
 nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org


^ permalink raw reply	[flat|nested] 4+ messages in thread

* c++/6831: Wrong base class alignment (nvalign vs. align)
@ 2002-05-27  4:26 Grigory_Zagorodnev
  0 siblings, 0 replies; 4+ messages in thread
From: Grigory_Zagorodnev @ 2002-05-27  4:26 UTC (permalink / raw)
  To: gcc-gnats


>Number:         6831
>Category:       c++
>Synopsis:       Wrong base class alignment (nvalign vs. align)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon May 27 03:36:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Grigory Zagorodnev
>Release:        3.1
>Organization:
>Environment:
host: ia64-unknown-linux
build: ia64-unknown-linux
target: ia64-unknown-linux
configured with: ./configure
>Description:
G++3 gives wrong layout of class E object in the testcase below.

1. The testcase
---------------
struct A {
    int a;
};

struct B : public virtual A {};

struct C {
  long double c;
};

struct D : public virtual C {
    int d;
};

struct E : public B, public D {
    int e;
};


2. The issue
------------
Expected layout of class E on ia64 is the following:
    Offset Size	Contents
    [0000] 8	B's virtual table pointer (B is the primary base for E)
    [0008] 8	D's virtual table pointer
    [0010] 4	D::d
    [0014] 4	Padding to round up D size to multiple of pointer align (8)
    [0018] 4	E::e
    [001c] 4	A::a
    [0020] 16	C::c

But G++3 compiler gives another object layout for E:
    Offset Size	Contents
    [0000] 8	B's virtual table pointer (B is the primary base for E)
    [0008] 8	Padding 
    [0010] 8	D's virtual table pointer
    [0018] 4	D::d
    [001c] 4	E::e
    [0020] 4	A::a
    [0024] 12	Padding
    [0030] 16	C::c

The layout is different and is wrong.

3. Details and analisis
-----------------------
We see difference in three points here, all related to padding bytes added.

I. No padding after D::d
Class D is laying out using common rules. It means that D should be finalized either - rounded up to a non-zero multiple of align(D). g++3 does not perform this step for base classes. 


II. Extra padding after A::a
There is nothing wrong - C::c should be 16-byte aligned.
Difference is just a side-effect of inconsistency listed above.

III. Padding after B's virtual table pointer
This is the major inconsistency. Let's see...

The C++ ABI says [Chapter 2: Data Layout/2.4 Non-POD Class Types/II. Allocation of Members Other Than Virtual Bases]:
"if D is not an empty base class (including all data members), start at offset dsize(C), incremented if necessary for alignment to nvalign(type(D)) for base 
classes or to align(type(D)) for data members. "

In our case, nvalign(D) == 8, align(D) == 16. 
So, it looks like g++3 did increment address to keep 16-bytes alignment of class D. But this is valid for data members only and not for base classes. Such behaviour is wrong. Since D is the base class, it should be aligned to nvalign (D)==8 bytes within class E and there should not be any padding.

In other words, g++3 erroneously uses align(D) instead of nvalign(D).
>How-To-Repeat:
It's not so easy to dump object as showed above. So we are using run-time test which checks offset of class D within the object E. It used to be sizeof(void *), i.e. D is comming right after class B, when B contains only the virtual table pointer.

1. Build attached fail.cpp test using simple command line
     g++ fail.cpp
2. Run it
     ./a.out
3. Look for 'passed' word in the output

Actual Results:  
failed
D's offset is 16
expected 8

Expected Results:  passed
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="fail.cpp"
Content-Disposition: inline; filename="fail.cpp"

#include <stdio.h>

struct A {
    int a;
};

struct B : public virtual A {};

struct C {
  long double c;
};

struct D : public virtual C {
    int d;
};

struct E : public B, public D {
    int e;
};

E e;

/* Expected layout of class E on ia64 is the following:
    Offset Size	Contents
    [0000] 8	B's virtual table pointer (B is the primary base for E)
    [0008] 8	D's virtual table pointer
    [0010] 4	D::d
    [0014] 4	Padding to round up D size to multiple of pointer align (8)
    [0018] 4	E::e
    [001c] 4	A::a
    [0020] 16	C::c
*/

int main ()
{
    // Offset of base class D is expected to be sizeof(void *)
    size_t d_offset = ((char*) (D*) (&e)) - (char*) &e;
    if( d_offset != sizeof(void *) ){
	puts("failed");
	printf("D's offset is %d\nexpected %d\n", d_offset, sizeof(void *));
    } else
	puts("passed");
}


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-07-05 12:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-03 13:04 c++/6831: Wrong base class alignment (nvalign vs. align) nathan
  -- strict thread matches above, loose matches on Subject: below --
2002-07-05  5:17 nathan
2002-07-05  5:16 Nathan Sidwell
2002-05-27  4:26 Grigory_Zagorodnev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).