VS2005: implicit upcast from std::auto_ptr<Derived> to std::auto_ptr<Base> yields invalid pointer when Base is not the first base class of Derived - by Pavel Minaev [MSFT]

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 319580 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 12/24/2007 2:34:06 AM
Access Restriction Public


Consider the following inheritance hierarchy:

struct Base1 { int x; };
struct Base2 { int y; };
struct Derived : Base1, Base2 {};

Now, every object of class Derived has two subobjects, and subobject of class Base2 is (typically) located at a non-zero offset inside the object.

Now, consider this code:

std::auto_ptr<Derived> createDerived() { return std::auto_ptr<Derived>(new Derived); }
std::auto_ptr<Base2> base2(createDerived());

This is perfectly valid ISO C++, and the intent of the second line is to implicitly convert a pointer to a derived class to a pointer to one of its bases. This is indeed what it does in VS2003 and VS2008, but VS2005 handles this case differently: it allows the conversion, but internally, uses a mechanism analogous to reinterpret_cast to convert from Derived* to Base2*. While the result of the operation is still of of type Base2*, it actually points to the beginning of the Derived object, and not at the correct offset of the Base2 subobject within it. Naturally, this renders the pointer invalid, but it is very hard to catch. In the example above, trying to access Base2::y through the returned pointer would actually access Base1::x of that same Derived object. When both base classes have virtual methods, this results in vtable confusion, so wrong methods get called.

This seems to be related to other bugs filed against std::auto_ptr in VS2005, such as the issues with its operator= - the cuplrit is the same conversion through void* in std::auto_ptr_ref. However, since this is a distinct case not mentioned before, and since, unlike previously mentioned cases, it actually renders a valid stantard-compliant C++ code non-working, I believe this deserves a separate bug with a higher criticality.

Sign in to post a comment.
Posted by Pavel Minaev [MSFT] on 1/10/2008 at 1:38 AM
I am aware that this is fixed in VS2008. We have no plans to migrate to VS2008 for production code yet, though. Are there plans to fix it in VS2005?
Posted by Pavel Minaev [MSFT] on 1/9/2008 at 8:37 PM
I am aware that this is fixed in VS2008. We have no plans to migrate to VS2008 for production code yet, though. Are there plans to fix it in VS2005?
Posted by Microsoft on 1/9/2008 at 6:21 PM

Thanks for reporting this bug in VC8 SP1. It was fixed in VC9 RTM.

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by Microsoft on 12/24/2007 at 5:19 PM
Thanks for your feedback. We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you,
Visual Studio Product Team