This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
bug 3820, empty base & TYPE_NONCOPIED_PARTS
- To: gcc-bugs at gcc dot gnu dot org
- Subject: bug 3820, empty base & TYPE_NONCOPIED_PARTS
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Tue, 31 Jul 2001 16:37:33 +0100
- CC: mark at codesourcery dot com, jason at redhat dot com
- Organization: Codesourcery LLC
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;
}