Can you static_cast to derived class pointer in base class constructor, if the derived class is polymorphic?

141 views Asked by At

Imagine following code with CRTP and polymorphism:

template <typename Derived>
class CRTP {
   public:
   // in real code, the result of this cast is saved in another class 
    CRTP() { static_cast<Derived*>(this); }
};

class MyClass : public CRTP<MyClass> {
    virtual void foo(){};
};

int main() { 
    MyClass m; 
}

After reading Can you static_cast "this" to a derived class in a base class constructor then use the result later? and standard ([expr.static.cast]#12, [basic.life]#6, [class.cdtor]), I believe this is fine as long as the pointer and reference are not used aside from being saved to variable. However, UndefinedBehaviourSanitizer disagrees (see it on godbolt):

/app/example.cpp:4:14: runtime error: downcast of address 0x7ffdc5ba6df8 which does not point to an object of type 'MyClass'
0x7ffdc5ba6df8: note: object has invalid vptr
 fd 7f 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  83 00 04 1e ba 7f 00 00  80 8b 20 1e
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr

The error is gone if Derived is not polymorphic.

Is it just a false positive from UBSan or is there anything in the standard that changes the situation in case of polymorphic classes?


For reference, my real code looks more like this: https://godbolt.org/z/f9sePhv73. I store a reference to the Derived class in another class (not using in it constructor), and MyClass also inherits a mixin that makes it virtual, so it's not too simple to get rid of vptr.

0

There are 0 answers