public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: Grigory_Zagorodnev@vniief.ims.intel.com To: gcc-gnats@gcc.gnu.org Subject: c++/6831: Wrong base class alignment (nvalign vs. align) Date: Mon, 27 May 2002 04:26:00 -0000 [thread overview] Message-ID: <20020527103352.29003.qmail@sources.redhat.com> (raw) >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"); }
next reply other threads:[~2002-05-27 10:36 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2002-05-27 4:26 Grigory_Zagorodnev [this message] 2002-07-03 13:04 nathan 2002-07-05 5:16 Nathan Sidwell 2002-07-05 5:17 nathan
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20020527103352.29003.qmail@sources.redhat.com \ --to=grigory_zagorodnev@vniief.ims.intel.com \ --cc=gcc-gnats@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).