Skip to content

Fix pointer offset loss in OwnerPtr::Cast and ShadowPtr::Shadow under multiple inheritance - #10

Merged
zhuuuoyue merged 2 commits into
mainfrom
copilot/fix-pointer-offset-issue
Apr 8, 2026
Merged

Fix pointer offset loss in OwnerPtr::Cast and ShadowPtr::Shadow under multiple inheritance#10
zhuuuoyue merged 2 commits into
mainfrom
copilot/fix-pointer-offset-issue

Conversation

Copilot AI commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

When casting through a multiple-inheritance hierarchy, converting VT*void*VT2* via static_cast discards the pointer offset, producing an incorrect pointer and corrupting all member access on the result.

Root cause: ControlBlock::Data stored the pointer as void*, and Get() re-derived the typed pointer via static_cast<VT*>(void*). This loses the offset adjustment that compilers apply when navigating multiple-inheritance bases.

Fix: dual-pointer design (mirrors std::shared_ptr)

  • m_pTyped — a correctly-typed VT* added directly to both OwnerPtr and ShadowPtr, used exclusively for object access (Get(), ->, *)
  • ControlBlock::Data — unchanged; continues to hold the original allocation pointer for the deleter and acts as the liveness indicator for ShadowPtr

Key method updates:

  • Get() returns m_pTyped directly — no more static_cast from void*
  • Cast<VT2>() stores the dynamic_cast<VT2*>(m_pTyped) result in the new OwnerPtr's m_pTyped
  • Shadow<VT2>() propagates static_cast<VT2*>(m_pTyped) into the new ShadowPtr
  • All constructors, move/assignment operators, Transfer(), Release(), Swap(), Destroy(), and EnableShadowFromThis::ShadowFromThis() updated accordingly

Example (previously broken):

class BaseObject {
public:
    BaseObject(int v) : m_value(v) {}
    int GetValue() const { return m_value; }
private:
    int m_value;
};

class DerivedObject : public BaseObject, public SomeOtherBase { ... };

OwnerPtr<DerivedObject> d = OwnerPtr<DerivedObject>::Create(42);
OwnerPtr<BaseObject> b = d.Cast<BaseObject>();
b->GetValue(); // was: UB / wrong value; now: 42

Pre-existing compile errors also fixed (were blocking the build on GCC/Clang with C++17):

  • Duplicate using DeleterType = DT in OwnerPtr
  • Ordered comparisons of T* vs std::nullptr_t in ShadowPtr and OwnerPtr comparison operators (replaced with static_cast<ConstPointer>(nullptr))
  • Matching test assertion expressions updated to use a typed null pointer variable

Copilot AI linked an issue Apr 8, 2026 that may be closed by this pull request
@zhuuuoyue
zhuuuoyue marked this pull request as ready for review April 8, 2026 06:11
Copilot AI changed the title [WIP] Fix pointer offset issue in OwnerPtr cast Fix pointer offset loss in OwnerPtr::Cast and ShadowPtr::Shadow under multiple inheritance Apr 8, 2026
Copilot AI requested a review from zhuuuoyue April 8, 2026 06:26
@zhuuuoyue
zhuuuoyue merged commit 1a4c0cc into main Apr 8, 2026
1 check passed
@zhuuuoyue
zhuuuoyue deleted the copilot/fix-pointer-offset-issue branch April 8, 2026 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

使用单指针不能解决指针偏移的问题,cast 后出现错误

2 participants