@@ -1699,6 +1699,50 @@ bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize,
16991699 return Call (S, OpPC, F, VarArgSize);
17001700}
17011701
1702+ bool StartLifetime (InterpState &S, CodePtr OpPC) {
1703+ const auto &Ptr = S.Stk .peek <Pointer>();
1704+ if (!CheckDummy (S, OpPC, Ptr, AK_Destroy))
1705+ return false ;
1706+
1707+ Ptr.startLifetime ();
1708+ return true ;
1709+ }
1710+
1711+ // FIXME: It might be better to the recursing as part of the generated code for
1712+ // a destructor?
1713+ static void endLifetimeRecurse (const Pointer &Ptr) {
1714+ Ptr.endLifetime ();
1715+ if (const Record *R = Ptr.getRecord ()) {
1716+ for (const Record::Field &Fi : R->fields ())
1717+ endLifetimeRecurse (Ptr.atField (Fi.Offset ));
1718+ return ;
1719+ }
1720+
1721+ if (const Descriptor *FieldDesc = Ptr.getFieldDesc ();
1722+ FieldDesc->isCompositeArray ()) {
1723+ for (unsigned I = 0 ; I != FieldDesc->getNumElems (); ++I)
1724+ endLifetimeRecurse (Ptr.atIndex (I).narrow ());
1725+ }
1726+ }
1727+
1728+ // / Ends the lifetime of the peek'd pointer.
1729+ bool EndLifetime (InterpState &S, CodePtr OpPC) {
1730+ const auto &Ptr = S.Stk .peek <Pointer>();
1731+ if (!CheckDummy (S, OpPC, Ptr, AK_Destroy))
1732+ return false ;
1733+ endLifetimeRecurse (Ptr);
1734+ return true ;
1735+ }
1736+
1737+ // / Ends the lifetime of the pop'd pointer.
1738+ bool EndLifetimePop (InterpState &S, CodePtr OpPC) {
1739+ const auto &Ptr = S.Stk .pop <Pointer>();
1740+ if (!CheckDummy (S, OpPC, Ptr, AK_Destroy))
1741+ return false ;
1742+ endLifetimeRecurse (Ptr);
1743+ return true ;
1744+ }
1745+
17021746bool CheckNewTypeMismatch (InterpState &S, CodePtr OpPC, const Expr *E,
17031747 std::optional<uint64_t > ArraySize) {
17041748 const Pointer &Ptr = S.Stk .peek <Pointer>();
@@ -1711,8 +1755,16 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
17111755 return false ;
17121756 if (!CheckDummy (S, OpPC, Ptr, AK_Construct))
17131757 return false ;
1714- if (!CheckLifetime (S, OpPC, Ptr, AK_Construct))
1715- return false ;
1758+
1759+ // CheckLifetime for this and all base pointers.
1760+ for (Pointer P = Ptr;;) {
1761+ if (!CheckLifetime (S, OpPC, P, AK_Construct)) {
1762+ return false ;
1763+ }
1764+ if (P.isRoot ())
1765+ break ;
1766+ P = P.getBase ();
1767+ }
17161768 if (!CheckExtern (S, OpPC, Ptr))
17171769 return false ;
17181770 if (!CheckRange (S, OpPC, Ptr, AK_Construct))
0 commit comments