core: The padding in ancestor classes may be used in descendants
This appeared on the radar, in an expanded type:
class Spell_AdjustVital : public SpellActionType {
public:
/* class SpellActionType {
public:
void SpellActionType(class SpellActionType *, const class SpellActionType &);
int ()(void) * * _vptr.SpellActionType; /* 0 8 */
void SpellActionType(class SpellActionType *, int);
virtual void ~SpellActionType(class SpellActionType *, int);
virtual int Cast(class SpellActionType *, class CUnit &, const class SpellType &, class CUnit * &, const Vec2i &);
virtual void Parse(class SpellActionType *, struct lua_State *, int, int);
const int ModifyManaCaster; /* 8 4 */
/* vtable has 2 entries: {
[2] = Cast((null)),
[3] = Parse((null)),
} */ } <ancestor>; */ /* 0 16 */
/* XXX last struct has 4 bytes of padding */
/* XXX 65532 bytes hole, try to pack */
void Spell_AdjustVital(class Spell_AdjustVital *);
virtual int Cast(class Spell_AdjustVital *, class CUnit &, const class SpellType &, class CUnit * &, const Vec2i &);
virtual void Parse(class Spell_AdjustVital *, lua_State *, int, int);
int HP; /* 12 4 */
int Mana; /* 16 4 */
int Shield; /* 20 4 */
int MaxMultiCast; /* 24 4 */
virtual void ~Spell_AdjustVital(class Spell_AdjustVital *, int);
/* vtable has 2 entries: {
[2] = Cast((null)),
[3] = Parse((null)),
} */
/* size: 32, cachelines: 1, members: 5 */
/* sum members: 32, holes: 1, sum holes: 65532 */
/* padding: 4 */
/* paddings: 1, sum paddings: 4 */
/* last cacheline: 32 bytes */
/* BRAIN FART ALERT! 32 bytes != 32 (member bytes) + 0 (member bits) + 65532 (byte holes) + 0 (bit holes), diff = -524288 bits */
};
So the ancestor class (DW_TAG_inheritance) 'class SpellActionType' has 4
bytes of padding (the sum of its members is 12 bytes but its sizeof is
16) and then the first DW_TAG_member in the descendant, 'class Spell_AdjustVital'
is at offset 12, meaning it is using the padding from the ancestor.
Take that into account, with it now we have, unexpanded:
$ pahole -C Spell_AdjustVital objects/spell_adjustvital.cpp.o
class Spell_AdjustVital : public SpellActionType {
public:
/* class SpellActionType <ancestor>; */ /* 0 16 */
/* XXX last struct has 4 bytes of padding */
void Spell_AdjustVital(class Spell_AdjustVital *);
virtual int Cast(class Spell_AdjustVital *, class CUnit &, const class SpellType &, class CUnit * &, const Vec2i &);
virtual void Parse(class Spell_AdjustVital *, lua_State *, int, int);
/* Bitfield combined with next fields */
int HP; /* 12 4 */
int Mana; /* 16 4 */
int Shield; /* 20 4 */
int MaxMultiCast; /* 24 4 */
virtual void ~Spell_AdjustVital(class Spell_AdjustVital *, int);
/* vtable has 2 entries: {
[2] = Cast((null)),
[3] = Parse((null)),
} */
/* size: 32, cachelines: 1, members: 5 */
/* padding: 4 */
/* paddings: 1, sum paddings: 4 */
/* last cacheline: 32 bytes */
};
$
Reported-by: Matthias Schwarzott <zzam@gentoo.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>