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]
Other format: [Raw text]

[Bug c++/53225] static operator new in multiple inheritance carries incorrect type information for the class


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

--- Comment #6 from Thomas W. Lynch <dimitrisdad at gmail dot com> 2012-05-04 18:12:10 UTC ---
>> Part of the type information is the layout inside the class. The operator,
>> which has been copied into the child via inheritance, 
>
>No, inheritance doesn't mean anything is copied into the child, it means the
>function is visible in the scope of the child.

Data type provides information for offsets into fields and the functions that
work on the data. That is not part of the instance, it is separate and
distinct.  It is 'extrinsic' to an instance.

Before an instance is created the _compiler_ does operations on 'data type'. 
In the case of C++ nonvirtual inheritance the compiler copies the parent type
information (data actually), with modifications into the child *type*.  There
are other ways to do inheritance.  This is done at compile time and only
affects the type, not the instance.

So for example, if an parent class has a method, say increment(), that affects
a value to be found in a field at offset, say, 4.  and then that parent method
is inherited into the child, but the inherited field has moved, say now found
at offset 8,  the method is modified to access offset 8 - or to more
technically accurate its type information is modified, the control flow remains
identical. 

So yes, inheritance means a lot of copying and modifications are done to _type_
at _compile_time_.  After all this work is done at compile time, in static
typing, the type is embedded in the generated code, the unresolved part of type
is embedded as symbols to be linked in the link map, and the rest is thrown
away.  For some reason, this embedding for the inherited operator new is
incorrect.

There are phases in a static type compilation process, first the macro
expansion (templates and statics),  then the calculation of offsets for the
type stuff, then then code generation.  Now way down the line after linking and
loading we are running.  That is when our operator new gets called.  By that
time type issues are supposed to be settled - but as the code example reported
shows, for operator new in multiple inheritance with this version of g++ - it
has not been.

About the access - the original poster noted that uninitialized memory was
being used - uninitialized memory is bad to read, it is not bad to write ..
that is how it gets initialized after all.  And in cases of doing heap
management it is convention to put the size of the block above the allocation. 
This code example does that explicitly.   The standard says that the object
exists after new finishes, and this is true even in this example.  But even the
standard new operator writes to the memory it allocates before returning --
check it out, just walk in the debugger you can see it.

If you are going to outlaw writing to memory in new, then you will have to
outlaw the standard new as well.  That said, this code could be implemented by
calculating an offset from the pointer to the malloced block, just as the heap
code does ..

I apologize for the 'nonstandard' report per the a prior post, I will update
that this evening.


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