Skip to content

Commit 216dfd5

Browse files
authored
[clang][Interp] Fix stack peek offset for This ptr (#70663)
`Function::getArgSize()` include both the instance and the RVO pointer, so we need to subtract here.
1 parent 94d6699 commit 216dfd5

File tree

4 files changed

+18
-23
lines changed

4 files changed

+18
-23
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,13 +2269,17 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
22692269
}
22702270
} else {
22712271
assert(Initializing);
2272-
if (!isa<CXXMemberCallExpr>(E)) {
2273-
if (!this->emitDupPtr(E))
2274-
return false;
2275-
}
2272+
if (!this->emitDupPtr(E))
2273+
return false;
22762274
}
22772275
}
22782276

2277+
// Add the (optional, implicit) This pointer.
2278+
if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
2279+
if (!this->visit(MC->getImplicitObjectArgument()))
2280+
return false;
2281+
}
2282+
22792283
// Put arguments on the stack.
22802284
for (const auto *Arg : E->arguments()) {
22812285
if (!this->visit(Arg))
@@ -2332,22 +2336,6 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
23322336
return true;
23332337
}
23342338

2335-
template <class Emitter>
2336-
bool ByteCodeExprGen<Emitter>::VisitCXXMemberCallExpr(
2337-
const CXXMemberCallExpr *E) {
2338-
if (Initializing) {
2339-
// If we're initializing, the current stack top is the pointer to
2340-
// initialize, so dup that so this call has its own version.
2341-
if (!this->emitDupPtr(E))
2342-
return false;
2343-
}
2344-
2345-
if (!this->visit(E->getImplicitObjectArgument()))
2346-
return false;
2347-
2348-
return VisitCallExpr(E);
2349-
}
2350-
23512339
template <class Emitter>
23522340
bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr(
23532341
const CXXDefaultInitExpr *E) {

clang/lib/AST/Interp/ByteCodeExprGen.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
6868
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E);
6969
bool VisitCallExpr(const CallExpr *E);
7070
bool VisitBuiltinCallExpr(const CallExpr *E);
71-
bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *E);
7271
bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E);
7372
bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E);
7473
bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);

clang/lib/AST/Interp/Interp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,7 +1855,7 @@ inline bool CheckGlobalCtor(InterpState &S, CodePtr OpPC) {
18551855
inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func) {
18561856
if (Func->hasThisPointer()) {
18571857
size_t ThisOffset =
1858-
Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
1858+
Func->getArgSize() - (Func->hasRVO() ? primSize(PT_Ptr) : 0);
18591859

18601860
const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
18611861

@@ -1904,7 +1904,7 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func) {
19041904
assert(Func->hasThisPointer());
19051905
assert(Func->isVirtual());
19061906
size_t ThisOffset =
1907-
Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0);
1907+
Func->getArgSize() - (Func->hasRVO() ? primSize(PT_Ptr) : 0);
19081908
Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
19091909

19101910
const CXXRecordDecl *DynamicDecl =

clang/test/AST/Interp/literals.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,14 @@ namespace DiscardExprs {
10621062
}
10631063
static_assert(foo<3>() == 3, "");
10641064

1065+
struct ATemp {
1066+
consteval ATemp ret_a() const { return ATemp{}; }
1067+
};
1068+
1069+
void test() {
1070+
int k = (ATemp().ret_a(), 0);
1071+
}
1072+
10651073
#pragma clang diagnostic pop
10661074
}
10671075
#endif

0 commit comments

Comments
 (0)