Open
Description
Compile the following with -fsanitize=undefined -O1
:
template <class T>
auto make() {
return T{};
}
template <class T>
struct box {
T t;
box() : t(make<T>()) {}
};
template <class A, class B>
struct pair : box<A>, box<B> {
};
struct A {};
template <class A>
struct B {
B() {
box<B>* pbox = reinterpret_cast<box<B>*>(this);
(void)static_cast<pair<A, B>*>(pbox);
}
};
int main() {
pair<A, B<A>> p;
}
Executing the following code results in:
/app/example.cpp:25:11: runtime error: downcast of address 0x7fff4fa07ff6 with insufficient space for an object of type 'pair<A, B<A>>'
0x7fff4fa07ff6: note: pointer points here
e7 fe c4 60 00 00 90 9d 42 13 15 7a 00 00 08 81 a0 4f ff 7f 00 00 98 ae e7 fe c4 60 00 00 60 4f
^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /app/example.cpp:25:11
The problem seems to happen when casting pointers to objects that are only partially constructed. The problem does not occur with -O0
, or if B
's constructor is [[clang::noinline]]
.
GCC's UB sanitizer accepts the code without complaint:
https://godbolt.org/z/1hzcMosov