@@ -1640,6 +1640,9 @@ bool InitField(InterpState &S, CodePtr OpPC, uint32_t I) {
16401640 const Pointer &Ptr = S.Stk .peek <Pointer>();
16411641 if (!CheckRange (S, OpPC, Ptr, CSK_Field))
16421642 return false ;
1643+ if (!CheckArray (S, OpPC, Ptr))
1644+ return false ;
1645+
16431646 const Pointer &Field = Ptr.atField (I);
16441647 Field.deref <T>() = Value;
16451648 Field.initialize ();
@@ -1652,6 +1655,9 @@ bool InitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I) {
16521655 const Pointer &Ptr = S.Stk .peek <Pointer>();
16531656 if (!CheckRange (S, OpPC, Ptr, CSK_Field))
16541657 return false ;
1658+ if (!CheckArray (S, OpPC, Ptr))
1659+ return false ;
1660+
16551661 const Pointer &Field = Ptr.atField (I);
16561662 Field.deref <T>() = Value;
16571663 Field.activate ();
@@ -1663,7 +1669,13 @@ template <PrimType Name, class T = typename PrimConv<Name>::T>
16631669bool InitBitField (InterpState &S, CodePtr OpPC, const Record::Field *F) {
16641670 assert (F->isBitField ());
16651671 const T &Value = S.Stk .pop <T>();
1666- const Pointer &Field = S.Stk .peek <Pointer>().atField (F->Offset );
1672+ const Pointer &Ptr = S.Stk .peek <Pointer>();
1673+ if (!CheckRange (S, OpPC, Ptr, CSK_Field))
1674+ return false ;
1675+ if (!CheckArray (S, OpPC, Ptr))
1676+ return false ;
1677+
1678+ const Pointer &Field = Ptr.atField (F->Offset );
16671679
16681680 if constexpr (needsAlloc<T>()) {
16691681 T Result = S.allocAP <T>(Value.bitWidth ());
@@ -1689,7 +1701,13 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC,
16891701 const Record::Field *F) {
16901702 assert (F->isBitField ());
16911703 const T &Value = S.Stk .pop <T>();
1692- const Pointer &Field = S.Stk .peek <Pointer>().atField (F->Offset );
1704+ const Pointer &Ptr = S.Stk .peek <Pointer>();
1705+ if (!CheckRange (S, OpPC, Ptr, CSK_Field))
1706+ return false ;
1707+ if (!CheckArray (S, OpPC, Ptr))
1708+ return false ;
1709+
1710+ const Pointer &Field = Ptr.atField (F->Offset );
16931711
16941712 if constexpr (needsAlloc<T>()) {
16951713 T Result = S.allocAP <T>(Value.bitWidth ());
@@ -1788,6 +1806,8 @@ inline bool GetPtrBase(InterpState &S, CodePtr OpPC, uint32_t Off) {
17881806 return false ;
17891807
17901808 if (!Ptr.isBlockPointer ()) {
1809+ if (!Ptr.isIntegralPointer ())
1810+ return false ;
17911811 S.Stk .push <Pointer>(Ptr.asIntPointer ().baseCast (S.getASTContext (), Off));
17921812 return true ;
17931813 }
@@ -1809,6 +1829,8 @@ inline bool GetPtrBasePop(InterpState &S, CodePtr OpPC, uint32_t Off,
18091829 return false ;
18101830
18111831 if (!Ptr.isBlockPointer ()) {
1832+ if (!Ptr.isIntegralPointer ())
1833+ return false ;
18121834 S.Stk .push <Pointer>(Ptr.asIntPointer ().baseCast (S.getASTContext (), Off));
18131835 return true ;
18141836 }
@@ -2437,9 +2459,17 @@ inline bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I) {
24372459 const Pointer &Ptr = S.Current ->getLocalPointer (Local.Offset );
24382460
24392461 if (Ptr.getLifetime () == Lifetime::Ended) {
2440- auto *D = cast<NamedDecl>(Ptr.getFieldDesc ()->asDecl ());
2441- S.FFDiag (D->getLocation (), diag::note_constexpr_destroy_out_of_lifetime)
2442- << D->getNameAsString ();
2462+ // Try to use the declaration for better diagnostics
2463+ if (const Decl *D = Ptr.getDeclDesc ()->asDecl ()) {
2464+ auto *ND = cast<NamedDecl>(D);
2465+ S.FFDiag (ND->getLocation (),
2466+ diag::note_constexpr_destroy_out_of_lifetime)
2467+ << ND->getNameAsString ();
2468+ } else {
2469+ S.FFDiag (Ptr.getDeclDesc ()->getLocation (),
2470+ diag::note_constexpr_destroy_out_of_lifetime)
2471+ << Ptr.toDiagnosticString (S.getASTContext ());
2472+ }
24432473 return false ;
24442474 }
24452475 }
0 commit comments