This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

bug 3820, empty base & TYPE_NONCOPIED_PARTS


Hi,
There's a problem with empty bases, as shown by the attached test
case.

An empty class with no bases gets a single field appended to it, and
included in TYPE_NONCOPIED_PARTS. An empty class with a single empty
base class does not get any such field, and has no TYPE_NONCOPIED_PARTS.
When that is used as a base or member of some other class, such that
it overlays a valid field, the assignment operator will do the wrong
thing and clobber overlayed field. TYPE_NONCOPIED_PARTS does not
work for bases, and I'm not sure as to how to make it so. It all
looks overly complicated in gcc/expr.c, which is where that is dealt
with by preserving the values, and then restoring them.
TYPE_NONCOPIED_PARTS is undocumented and AFAICT only used by g++.
It is the elide_constructors in build_over_call (cp/call.c) that has a
comment about how it is supposed to work.

One solution is for build_assign_ref to skip empty bases and fields,
but the problem might be lurking elsewhere too. I'm hoping that if
we DTRT in build_assign_ref & possibly ctors & dtors, then 
NONCOPIED_PARTS can go away with suitable tweaking of the problematic
code in build_over_call.

If we have a non-empty class that ends in an empty object, we don't
allow that end padding to be overlaid by something else, when being
used as a base of field of some other class - do we?

The only use of TYPE_NONCOPIED_PARTS I find is to do with empty bases.

thoughts?

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
struct Empty {};

struct Inter : Empty {};

int now = 0;

struct NonPod
{
  int m;

  NonPod () {m = 0x12345678;}
  NonPod (int m_) {m = m_;}
  NonPod &operator= (NonPod const &src) {now = m; m = src.m;}
  NonPod (NonPod const &src) {m = src.m;}
};


struct A : Inter
{
  A (int c) {m = c;}
  
  NonPod m;
};

int main ()
{
  A a (0x12131415);
  int was = a.m.m;
  
  a = 0x22232425;

  return was != now;
  
}

  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]