Author: Timm Baeder Date: 2023-11-14T16:22:22+01:00 New Revision: 216dfd5ff0621791936ee2d208d686a9edc00db0
URL: https://github.com/llvm/llvm-project/commit/216dfd5ff0621791936ee2d208d686a9edc00db0 DIFF: https://github.com/llvm/llvm-project/commit/216dfd5ff0621791936ee2d208d686a9edc00db0.diff LOG: [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. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/Interp.h clang/test/AST/Interp/literals.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index c8d3c1243fc1094..70032cce2775148 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2269,13 +2269,17 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { } } else { assert(Initializing); - if (!isa<CXXMemberCallExpr>(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<CXXMemberCallExpr>(E)) { + if (!this->visit(MC->getImplicitObjectArgument())) + return false; + } + // Put arguments on the stack. for (const auto *Arg : E->arguments()) { if (!this->visit(Arg)) @@ -2332,22 +2336,6 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { return true; } -template <class Emitter> -bool ByteCodeExprGen<Emitter>::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 <class Emitter> bool ByteCodeExprGen<Emitter>::VisitCXXDefaultInitExpr( const CXXDefaultInitExpr *E) { diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index ec9b6bb1408453c..1c304caad5577ce 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -68,7 +68,6 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, 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 7dd415d6e460536..a133318cab50b25 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<Pointer>(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<Pointer>(ThisOffset); const CXXRecordDecl *DynamicDecl = diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index ba24955d14503be..68833ec2dc48adf 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits