[Bug c++/37762] Member variable of empty base optimized (EBO) class appears on wrong offset

2008-10-07 Thread david dot rosenborg at pantor dot com


--- Comment #1 from david dot rosenborg at pantor dot com  2008-10-07 08:42 
---
Created an attachment (id=16474)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=16474&action=view)
Preprocessed program


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37762



[Bug c++/37762] Member variable of empty base optimized (EBO) class appears on wrong offset

2008-10-07 Thread david dot rosenborg at pantor dot com


--- Comment #3 from david dot rosenborg at pantor dot com  2008-10-07 09:31 
---
Ah, no, I wasn't aware of that document. I just thought that gcc was treating
the Good and Bad cases inconsitently.

Now, in layman's terms, is the reason for the padding that no two distinct
instances of Empty may share the same address? If that is the case, it would
explain the padding and this is not a bug.

Sorry, should have investigated more before hitting the commit button.

/David


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37762



[Bug c++/37762] New: Member variable of empty base optimized (EBO) class appears on wrong offset

2008-10-07 Thread david dot rosenborg at pantor dot com
A member variable of a class that utilizes EBO and has a type that also
utilizes EBO appears to be laid out at the wrong offset.

In the example below, the only difference between the classes Good and Bad is
that the member of Bad inherits from a class with no members. The sizeof
printouts show that EBO is in play, but the Bad class gets an extra four byte
padding before the member. There's no reason Bad should be any larger than
Good.

Kind Regards
/David

#include 

struct Empty { };

struct Member { int extent; };
struct MemberWithEBO : public Empty { int extent; };

struct Good : public Empty { Member m; }; // OK
struct Bad : public Empty { MemberWithEBO m; }; // Broken, see below

#define PRINT(x) printf ("%-25s %d\n", # x ":", (x))

template  long int offsetOf (T C::*m)
{
   C proto;
   return (long int)(void*)&(proto.*m) - (long int)(void *)&proto;
}

int
main (int argc, char ** argv)
{
   PRINT (sizeof (Member));
   PRINT (sizeof (Good));
   PRINT (offsetOf (&Good::m));

   PRINT (sizeof (MemberWithEBO));
   PRINT (sizeof (Bad));
   PRINT (offsetOf (&Bad::m));
}

// Printout:
//
// sizeof (Member):  4
// sizeof (Good):4
// offsetOf (&Good::m):  0
// sizeof (MemberWithEBO):   4
// sizeof (Bad): 8  <-- Should be 4
// offsetOf (&Bad::m):   4  <-- Should be 0




> g++ -v -save-temps ebo_bug.cc

Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --prefix=/usr/local/gcc431
--with-pkgversion=gcc431 --enable-languages=c,c++
Thread model: posix
gcc version 4.3.1 (gcc431) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
 /usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/cc1plus -E -quiet
-v -D_GNU_SOURCE ebo_bug.cc -mtune=generic -fpch-preprocess -o ebo_bug.ii
ignoring nonexistent directory
"/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../x86_64-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:

/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../include/c++/4.3.1

/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../include/c++/4.3.1/x86_64-unknown-linux-gnu

/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../include/c++/4.3.1/backward
 /usr/local/include
 /usr/local/gcc431/include
 /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include
 /usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
 /usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/cc1plus
-fpreprocessed ebo_bug.ii -quiet -dumpbase ebo_bug.cc -mtune=generic -auxbase
ebo_bug -version -o ebo_bug.s
GNU C++ (gcc431) version 4.3.1 (x86_64-unknown-linux-gnu)
compiled by GNU C version 4.3.1, GMP version 4.1.4, MPFR version 2.2.1.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 4926fc16e15403c044148a60354159ba
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
 as -V -Qy -o ebo_bug.o ebo_bug.s
GNU assembler version 2.17.50.0.6-6.el5 (x86_64-redhat-linux) using BFD version
2.17.50.0.6-6.el5 20061020
COMPILER_PATH=/usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/
LIBRARY_PATH=/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-shared-libgcc' '-mtune=generic'
 /usr/local/gcc431/libexec/gcc/x86_64-unknown-linux-gnu/4.3.1/collect2
--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2
/usr/lib/../lib64/crt1.o /usr/lib/../lib64/crti.o
/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/crtbegin.o
-L/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1
-L/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../../../lib64
-L/lib/../lib64 -L/usr/lib/../lib64
-L/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/../../.. ebo_bug.o
-lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/local/gcc431/lib/gcc/x86_64-unknown-linux-gnu/4.3.1/crtend.o
/usr/lib/../lib64/crtn.o


-- 
   Summary: Member variable of empty base optimized (EBO) class
appears on wrong offset
       Product: gcc
   Version: 4.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: david dot rosenborg at pantor dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37762