Fix polymorphic WeakRef bug
This commit is contained in:
@@ -41,6 +41,26 @@ struct AnotherDerived : public Base {
|
||||
: Base(base_v), another_value(another_v) {}
|
||||
int get_value() const override { return base_value * another_value; }
|
||||
};
|
||||
|
||||
// Classes to test polymorphic pointer address changes
|
||||
struct Interface1 {
|
||||
int interface1_data = 1;
|
||||
virtual ~Interface1() = default;
|
||||
virtual int get_interface1() const { return interface1_data; }
|
||||
};
|
||||
|
||||
struct Interface2 {
|
||||
int interface2_data = 2;
|
||||
virtual ~Interface2() = default;
|
||||
virtual int get_interface2() const { return interface2_data; }
|
||||
};
|
||||
|
||||
// Multiple inheritance - this will cause pointer address changes
|
||||
struct MultipleInheritance : public Interface1, public Interface2 {
|
||||
int own_data;
|
||||
explicit MultipleInheritance(int data) : own_data(data) {}
|
||||
int get_own_data() const { return own_data; }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
TEST_CASE("Ref basic functionality") {
|
||||
@@ -444,6 +464,37 @@ TEST_CASE("Polymorphic edge cases") {
|
||||
CHECK(base_ref_from_weak->get_value() == 10); // 5 + 5
|
||||
CHECK(base_ref_from_weak.get() == derived_ref.get());
|
||||
}
|
||||
|
||||
SUBCASE("multiple inheritance pointer address bug test") {
|
||||
auto multi_ref = make_ref<MultipleInheritance>(42);
|
||||
|
||||
// Get pointers to different base classes - these will have different
|
||||
// addresses
|
||||
Interface1 *interface1_ptr = multi_ref.get();
|
||||
Interface2 *interface2_ptr = multi_ref.get();
|
||||
MultipleInheritance *multi_ptr = multi_ref.get();
|
||||
|
||||
// Verify that pointers are indeed different (demonstrating the issue)
|
||||
CHECK(static_cast<void *>(interface1_ptr) !=
|
||||
static_cast<void *>(interface2_ptr));
|
||||
|
||||
// Create WeakRef to Interface2 (which has a different pointer address)
|
||||
WeakRef<Interface2> weak_interface2 = multi_ref.as_weak();
|
||||
|
||||
// Lock should return the correct Interface2 pointer, not miscalculated one
|
||||
auto locked_interface2 = weak_interface2.lock();
|
||||
CHECK(locked_interface2);
|
||||
CHECK(locked_interface2.get() ==
|
||||
interface2_ptr); // This might fail due to the bug!
|
||||
CHECK(locked_interface2->get_interface2() == 2);
|
||||
|
||||
// Also test Interface1
|
||||
WeakRef<Interface1> weak_interface1 = multi_ref.as_weak();
|
||||
auto locked_interface1 = weak_interface1.lock();
|
||||
CHECK(locked_interface1);
|
||||
CHECK(locked_interface1.get() == interface1_ptr); // This might also fail!
|
||||
CHECK(locked_interface1->get_interface1() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Should be run with asan or valgrind
|
||||
|
||||
Reference in New Issue
Block a user