diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 195af664c13da..ccfd35b4171b6 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2263,13 +2263,17 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { } } else { assert(Initializing); - if (!isa(E)) { - if (!this->emitDupPtr(E)) - return false; - } + if (!this->emitDupPtr(E)) + return false; } } + // Add the (optional, implicit) This pointer. + if (const auto *MC = dyn_cast(E)) { + if (!this->visit(MC->getImplicitObjectArgument())) + return false; + } + // Put arguments on the stack. for (const auto *Arg : E->arguments()) { if (!this->visit(Arg)) @@ -2326,22 +2330,6 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { return true; } -template -bool ByteCodeExprGen::VisitCXXMemberCallExpr( - const CXXMemberCallExpr *E) { - if (Initializing) { - // If we're initializing, the current stack top is the pointer to - // initialize, so dup that so this call has its own version. - if (!this->emitDupPtr(E)) - return false; - } - - if (!this->visit(E->getImplicitObjectArgument())) - return false; - - return VisitCallExpr(E); -} - template bool ByteCodeExprGen::VisitCXXDefaultInitExpr( const CXXDefaultInitExpr *E) { diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 83986d3dd579e..7f832d93e3a2f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -68,7 +68,6 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E); bool VisitCallExpr(const CallExpr *E); bool VisitBuiltinCallExpr(const CallExpr *E); - bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *E); bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E); bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E); bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 7dd415d6e4605..a133318cab50b 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1855,7 +1855,7 @@ inline bool CheckGlobalCtor(InterpState &S, CodePtr OpPC) { inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func) { if (Func->hasThisPointer()) { size_t ThisOffset = - Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0); + Func->getArgSize() - (Func->hasRVO() ? primSize(PT_Ptr) : 0); const Pointer &ThisPtr = S.Stk.peek(ThisOffset); @@ -1904,7 +1904,7 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func) { assert(Func->hasThisPointer()); assert(Func->isVirtual()); size_t ThisOffset = - Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0); + Func->getArgSize() - (Func->hasRVO() ? primSize(PT_Ptr) : 0); Pointer &ThisPtr = S.Stk.peek(ThisOffset); const CXXRecordDecl *DynamicDecl = diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index ba24955d14503..68833ec2dc48a 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -1062,6 +1062,14 @@ namespace DiscardExprs { } static_assert(foo<3>() == 3, ""); + struct ATemp { + consteval ATemp ret_a() const { return ATemp{}; } + }; + + void test() { + int k = (ATemp().ret_a(), 0); + } + #pragma clang diagnostic pop } #endif