Skip to content

Commit dabbb86

Browse files
committed
[clang][Interp] Fix stack peek offset for This ptr
Function::getArgSize() include both the instance and the RVO pointer, so we need to subtract here.
1 parent f8fe400 commit dabbb86

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
@@ -2263,13 +2263,17 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
22632263
}
22642264
} else {
22652265
assert(Initializing);
2266-
if (!isa<CXXMemberCallExpr>(E)) {
2267-
if (!this->emitDupPtr(E))
2268-
return false;
2269-
}
2266+
if (!this->emitDupPtr(E))
2267+
return false;
22702268
}
22712269
}
22722270

2271+
// Add the (optional, implicit) This pointer.
2272+
if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
2273+
if (!this->visit(MC->getImplicitObjectArgument()))
2274+
return false;
2275+
}
2276+
22732277
// Put arguments on the stack.
22742278
for (const auto *Arg : E->arguments()) {
22752279
if (!this->visit(Arg))
@@ -2326,22 +2330,6 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
23262330
return true;
23272331
}
23282332

2329-
template <class Emitter>
2330-
bool ByteCodeExprGen<Emitter>::VisitCXXMemberCallExpr(
2331-
const CXXMemberCallExpr *E) {
2332-
if (Initializing) {
2333-
// If we're initializing, the current stack top is the pointer to
2334-
// initialize, so dup that so this call has its own version.
2335-
if (!this->emitDupPtr(E))
2336-
return false;
2337-
}
2338-
2339-
if (!this->visit(E->getImplicitObjectArgument()))
2340-
return false;
2341-
2342-
return VisitCallExpr(E);
2343-
}
2344-
23452333
template <class Emitter>
23462334
bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr(
23472335
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)