Skip to content

Commit 55066b8

Browse files
authored
[clang][bytecode] Compute pointer differences as 64bit integers (#137128)
And only convert to the target type after that.
1 parent 1ec22fa commit 55066b8

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

clang/lib/AST/ByteCode/Interp.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,16 +2161,22 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
21612161
}
21622162
}
21632163

2164-
T A = LHS.isBlockPointer()
2165-
? (LHS.isElementPastEnd() ? T::from(LHS.getNumElems())
2166-
: T::from(LHS.getIndex()))
2167-
: T::from(LHS.getIntegerRepresentation());
2168-
T B = RHS.isBlockPointer()
2169-
? (RHS.isElementPastEnd() ? T::from(RHS.getNumElems())
2170-
: T::from(RHS.getIndex()))
2171-
: T::from(RHS.getIntegerRepresentation());
2172-
2173-
return AddSubMulHelper<T, T::sub, std::minus>(S, OpPC, A.bitWidth(), A, B);
2164+
int64_t A64 =
2165+
LHS.isBlockPointer()
2166+
? (LHS.isElementPastEnd() ? LHS.getNumElems() : LHS.getIndex())
2167+
: LHS.getIntegerRepresentation();
2168+
2169+
int64_t B64 =
2170+
RHS.isBlockPointer()
2171+
? (RHS.isElementPastEnd() ? RHS.getNumElems() : RHS.getIndex())
2172+
: RHS.getIntegerRepresentation();
2173+
2174+
int64_t R64 = A64 - B64;
2175+
if (static_cast<int64_t>(T::from(R64)) != R64)
2176+
return handleOverflow(S, OpPC, R64);
2177+
2178+
S.Stk.push<T>(T::from(R64));
2179+
return true;
21742180
}
21752181

21762182
//===----------------------------------------------------------------------===//

clang/test/AST/ByteCode/i686.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fexperimental-new-constant-interpreter -verify=expected,both %s
2+
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -verify=ref,both %s
3+
4+
5+
char melchizedek[2200000000];
6+
typedef decltype(melchizedek[1] - melchizedek[0]) ptrdiff_t;
7+
constexpr ptrdiff_t d1 = &melchizedek[0x7fffffff] - &melchizedek[0];
8+
constexpr ptrdiff_t d2 = &melchizedek[0x80000000u] - &melchizedek[0]; // both-error {{constant expression}} \
9+
// both-note {{ 2147483648 }}
10+
constexpr ptrdiff_t d3 = &melchizedek[0] - &melchizedek[0x80000000u];
11+
constexpr ptrdiff_t d4 = &melchizedek[0] - &melchizedek[0x80000001u]; // both-error {{constant expression}} \
12+
// both-note {{ -2147483649 }}
13+
14+

0 commit comments

Comments
 (0)