@@ -1640,6 +1640,9 @@ bool InitField(InterpState &S, CodePtr OpPC, uint32_t I) {
1640
1640
const Pointer &Ptr = S.Stk .peek <Pointer>();
1641
1641
if (!CheckRange (S, OpPC, Ptr, CSK_Field))
1642
1642
return false ;
1643
+ if (!CheckArray (S, OpPC, Ptr))
1644
+ return false ;
1645
+
1643
1646
const Pointer &Field = Ptr.atField (I);
1644
1647
Field.deref <T>() = Value;
1645
1648
Field.initialize ();
@@ -1652,6 +1655,9 @@ bool InitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I) {
1652
1655
const Pointer &Ptr = S.Stk .peek <Pointer>();
1653
1656
if (!CheckRange (S, OpPC, Ptr, CSK_Field))
1654
1657
return false ;
1658
+ if (!CheckArray (S, OpPC, Ptr))
1659
+ return false ;
1660
+
1655
1661
const Pointer &Field = Ptr.atField (I);
1656
1662
Field.deref <T>() = Value;
1657
1663
Field.activate ();
@@ -1663,7 +1669,13 @@ template <PrimType Name, class T = typename PrimConv<Name>::T>
1663
1669
bool InitBitField (InterpState &S, CodePtr OpPC, const Record::Field *F) {
1664
1670
assert (F->isBitField ());
1665
1671
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 );
1667
1679
1668
1680
if constexpr (needsAlloc<T>()) {
1669
1681
T Result = S.allocAP <T>(Value.bitWidth ());
@@ -1689,7 +1701,13 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC,
1689
1701
const Record::Field *F) {
1690
1702
assert (F->isBitField ());
1691
1703
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 );
1693
1711
1694
1712
if constexpr (needsAlloc<T>()) {
1695
1713
T Result = S.allocAP <T>(Value.bitWidth ());
@@ -1788,6 +1806,8 @@ inline bool GetPtrBase(InterpState &S, CodePtr OpPC, uint32_t Off) {
1788
1806
return false ;
1789
1807
1790
1808
if (!Ptr.isBlockPointer ()) {
1809
+ if (!Ptr.isIntegralPointer ())
1810
+ return false ;
1791
1811
S.Stk .push <Pointer>(Ptr.asIntPointer ().baseCast (S.getASTContext (), Off));
1792
1812
return true ;
1793
1813
}
@@ -1809,6 +1829,8 @@ inline bool GetPtrBasePop(InterpState &S, CodePtr OpPC, uint32_t Off,
1809
1829
return false ;
1810
1830
1811
1831
if (!Ptr.isBlockPointer ()) {
1832
+ if (!Ptr.isIntegralPointer ())
1833
+ return false ;
1812
1834
S.Stk .push <Pointer>(Ptr.asIntPointer ().baseCast (S.getASTContext (), Off));
1813
1835
return true ;
1814
1836
}
@@ -2437,9 +2459,17 @@ inline bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I) {
2437
2459
const Pointer &Ptr = S.Current ->getLocalPointer (Local.Offset );
2438
2460
2439
2461
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
+ }
2443
2473
return false ;
2444
2474
}
2445
2475
}
0 commit comments