Skip to content

Commit 4581e5a

Browse files
authored
[clang][bytecode][NFC] Don't push anything in OffsetHelper (#147550)
Instead, return the new Pointer. This was weird before because some callers had to get the value from the stack again to perform further operations.
1 parent 9d3b60d commit 4581e5a

File tree

1 file changed

+60
-45
lines changed

1 file changed

+60
-45
lines changed

clang/lib/AST/ByteCode/Interp.h

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,34 +2066,32 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {
20662066
//===----------------------------------------------------------------------===//
20672067

20682068
template <class T, ArithOp Op>
2069-
bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
2070-
const Pointer &Ptr, bool IsPointerArith = false) {
2069+
std::optional<Pointer> OffsetHelper(InterpState &S, CodePtr OpPC,
2070+
const T &Offset, const Pointer &Ptr,
2071+
bool IsPointerArith = false) {
20712072
// A zero offset does not change the pointer.
2072-
if (Offset.isZero()) {
2073-
S.Stk.push<Pointer>(Ptr);
2074-
return true;
2075-
}
2073+
if (Offset.isZero())
2074+
return Ptr;
20762075

20772076
if (IsPointerArith && !CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) {
20782077
// The CheckNull will have emitted a note already, but we only
20792078
// abort in C++, since this is fine in C.
20802079
if (S.getLangOpts().CPlusPlus)
2081-
return false;
2080+
return std::nullopt;
20822081
}
20832082

20842083
// Arrays of unknown bounds cannot have pointers into them.
20852084
if (!CheckArray(S, OpPC, Ptr))
2086-
return false;
2085+
return std::nullopt;
20872086

20882087
// This is much simpler for integral pointers, so handle them first.
20892088
if (Ptr.isIntegralPointer()) {
20902089
uint64_t V = Ptr.getIntegerRepresentation();
20912090
uint64_t O = static_cast<uint64_t>(Offset) * Ptr.elemSize();
20922091
if constexpr (Op == ArithOp::Add)
2093-
S.Stk.push<Pointer>(V + O, Ptr.asIntPointer().Desc);
2092+
return Pointer(V + O, Ptr.asIntPointer().Desc);
20942093
else
2095-
S.Stk.push<Pointer>(V - O, Ptr.asIntPointer().Desc);
2096-
return true;
2094+
return Pointer(V - O, Ptr.asIntPointer().Desc);
20972095
} else if (Ptr.isFunctionPointer()) {
20982096
uint64_t O = static_cast<uint64_t>(Offset);
20992097
uint64_t N;
@@ -2105,8 +2103,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
21052103
if (N > 1)
21062104
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_array_index)
21072105
<< N << /*non-array*/ true << 0;
2108-
S.Stk.push<Pointer>(Ptr.asFunctionPointer().getFunction(), N);
2109-
return true;
2106+
return Pointer(Ptr.asFunctionPointer().getFunction(), N);
21102107
}
21112108

21122109
assert(Ptr.isBlockPointer());
@@ -2156,7 +2153,7 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
21562153
}
21572154

21582155
if (Invalid && S.getLangOpts().CPlusPlus)
2159-
return false;
2156+
return std::nullopt;
21602157

21612158
// Offset is valid - compute it on unsigned.
21622159
int64_t WideIndex = static_cast<int64_t>(Index);
@@ -2172,15 +2169,11 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
21722169
// we don't get here.
21732170
if (Result == 0 && Ptr.isOnePastEnd()) {
21742171
if (Ptr.getFieldDesc()->isArray())
2175-
S.Stk.push<Pointer>(Ptr.atIndex(0));
2176-
else
2177-
S.Stk.push<Pointer>(Ptr.asBlockPointer().Pointee,
2178-
Ptr.asBlockPointer().Base);
2179-
return true;
2172+
return Ptr.atIndex(0);
2173+
return Pointer(Ptr.asBlockPointer().Pointee, Ptr.asBlockPointer().Base);
21802174
}
21812175

2182-
S.Stk.push<Pointer>(Ptr.atIndex(static_cast<uint64_t>(Result)));
2183-
return true;
2176+
return Ptr.atIndex(static_cast<uint64_t>(Result));
21842177
}
21852178

21862179
template <PrimType Name, class T = typename PrimConv<Name>::T>
@@ -2189,16 +2182,26 @@ bool AddOffset(InterpState &S, CodePtr OpPC) {
21892182
Pointer Ptr = S.Stk.pop<Pointer>();
21902183
if (Ptr.isBlockPointer())
21912184
Ptr = Ptr.expand();
2192-
return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr,
2193-
/*IsPointerArith=*/true);
2185+
2186+
if (std::optional<Pointer> Result = OffsetHelper<T, ArithOp::Add>(
2187+
S, OpPC, Offset, Ptr, /*IsPointerArith=*/true)) {
2188+
S.Stk.push<Pointer>(*Result);
2189+
return true;
2190+
}
2191+
return false;
21942192
}
21952193

21962194
template <PrimType Name, class T = typename PrimConv<Name>::T>
21972195
bool SubOffset(InterpState &S, CodePtr OpPC) {
21982196
const T &Offset = S.Stk.pop<T>();
21992197
const Pointer &Ptr = S.Stk.pop<Pointer>();
2200-
return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr,
2201-
/*IsPointerArith=*/true);
2198+
2199+
if (std::optional<Pointer> Result = OffsetHelper<T, ArithOp::Sub>(
2200+
S, OpPC, Offset, Ptr, /*IsPointerArith=*/true)) {
2201+
S.Stk.push<Pointer>(*Result);
2202+
return true;
2203+
}
2204+
return false;
22022205
}
22032206

22042207
template <ArithOp Op>
@@ -2218,12 +2221,13 @@ static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC,
22182221

22192222
// Now the current Ptr again and a constant 1.
22202223
OneT One = OneT::from(1);
2221-
if (!OffsetHelper<OneT, Op>(S, OpPC, One, P, /*IsPointerArith=*/true))
2222-
return false;
2223-
2224-
// Store the new value.
2225-
Ptr.deref<Pointer>() = S.Stk.pop<Pointer>();
2226-
return true;
2224+
if (std::optional<Pointer> Result =
2225+
OffsetHelper<OneT, Op>(S, OpPC, One, P, /*IsPointerArith=*/true)) {
2226+
// Store the new value.
2227+
Ptr.deref<Pointer>() = *Result;
2228+
return true;
2229+
}
2230+
return false;
22272231
}
22282232

22292233
static inline bool IncPtr(InterpState &S, CodePtr OpPC) {
@@ -2925,16 +2929,22 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
29252929

29262930
if (Offset.isZero()) {
29272931
if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) {
2928-
S.Stk.push<Pointer>(Ptr.atIndex(0));
2929-
} else {
2930-
S.Stk.push<Pointer>(Ptr);
2932+
S.Stk.push<Pointer>(Ptr.atIndex(0).narrow());
2933+
return true;
29312934
}
2932-
} else {
2933-
if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
2934-
return false;
2935+
S.Stk.push<Pointer>(Ptr);
2936+
return true;
2937+
}
2938+
2939+
assert(!Offset.isZero());
2940+
2941+
if (std::optional<Pointer> Result =
2942+
OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr)) {
2943+
S.Stk.push<Pointer>(Result->narrow());
2944+
return true;
29352945
}
29362946

2937-
return NarrowPtr(S, OpPC);
2947+
return false;
29382948
}
29392949

29402950
template <PrimType Name, class T = typename PrimConv<Name>::T>
@@ -2949,16 +2959,21 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
29492959

29502960
if (Offset.isZero()) {
29512961
if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) {
2952-
S.Stk.push<Pointer>(Ptr.atIndex(0));
2953-
} else {
2954-
S.Stk.push<Pointer>(Ptr);
2962+
S.Stk.push<Pointer>(Ptr.atIndex(0).narrow());
2963+
return true;
29552964
}
2956-
} else {
2957-
if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
2958-
return false;
2965+
S.Stk.push<Pointer>(Ptr);
2966+
return true;
29592967
}
29602968

2961-
return NarrowPtr(S, OpPC);
2969+
assert(!Offset.isZero());
2970+
2971+
if (std::optional<Pointer> Result =
2972+
OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr)) {
2973+
S.Stk.push<Pointer>(Result->narrow());
2974+
return true;
2975+
}
2976+
return false;
29622977
}
29632978

29642979
template <PrimType Name, class T = typename PrimConv<Name>::T>

0 commit comments

Comments
 (0)