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).