@@ -1857,8 +1857,23 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
1857
1857
else
1858
1858
S.Stk .push <Pointer>(V - O, Ptr.asIntPointer ().Desc );
1859
1859
return true ;
1860
+ } else if (Ptr.isFunctionPointer ()) {
1861
+ uint64_t O = static_cast <uint64_t >(Offset);
1862
+ uint64_t N;
1863
+ if constexpr (Op == ArithOp::Add)
1864
+ N = Ptr.getByteOffset () + O;
1865
+ else
1866
+ N = Ptr.getByteOffset () - O;
1867
+
1868
+ if (N > 1 )
1869
+ S.CCEDiag (S.Current ->getSource (OpPC), diag::note_constexpr_array_index)
1870
+ << N << /* non-array*/ true << 0 ;
1871
+ S.Stk .push <Pointer>(Ptr.asFunctionPointer ().getFunction (), N);
1872
+ return true ;
1860
1873
}
1861
1874
1875
+ assert (Ptr.isBlockPointer ());
1876
+
1862
1877
uint64_t MaxIndex = static_cast <uint64_t >(Ptr.getNumElems ());
1863
1878
uint64_t Index;
1864
1879
if (Ptr.isOnePastEnd ())
@@ -2024,10 +2039,15 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
2024
2039
return true ;
2025
2040
}
2026
2041
2027
- T A = LHS.isElementPastEnd () ? T::from (LHS.getNumElems ())
2028
- : T::from (LHS.getIndex ());
2029
- T B = RHS.isElementPastEnd () ? T::from (RHS.getNumElems ())
2030
- : T::from (RHS.getIndex ());
2042
+ T A = LHS.isBlockPointer ()
2043
+ ? (LHS.isElementPastEnd () ? T::from (LHS.getNumElems ())
2044
+ : T::from (LHS.getIndex ()))
2045
+ : T::from (LHS.getIntegerRepresentation ());
2046
+ T B = RHS.isBlockPointer ()
2047
+ ? (RHS.isElementPastEnd () ? T::from (RHS.getNumElems ())
2048
+ : T::from (RHS.getIndex ()))
2049
+ : T::from (RHS.getIntegerRepresentation ());
2050
+
2031
2051
return AddSubMulHelper<T, T::sub, std::minus>(S, OpPC, A.bitWidth (), A, B);
2032
2052
}
2033
2053
@@ -2905,8 +2925,15 @@ inline bool DecayPtr(InterpState &S, CodePtr OpPC) {
2905
2925
2906
2926
if constexpr (std::is_same_v<FromT, FunctionPointer> &&
2907
2927
std::is_same_v<ToT, Pointer>) {
2908
- S.Stk .push <Pointer>(OldPtr.getFunction ());
2928
+ S.Stk .push <Pointer>(OldPtr.getFunction (), OldPtr. getOffset () );
2909
2929
return true ;
2930
+ } else if constexpr (std::is_same_v<FromT, Pointer> &&
2931
+ std::is_same_v<ToT, FunctionPointer>) {
2932
+ if (OldPtr.isFunctionPointer ()) {
2933
+ S.Stk .push <FunctionPointer>(OldPtr.asFunctionPointer ().getFunction (),
2934
+ OldPtr.getByteOffset ());
2935
+ return true ;
2936
+ }
2910
2937
}
2911
2938
2912
2939
S.Stk .push <ToT>(ToT (OldPtr.getIntegerRepresentation (), nullptr ));
0 commit comments