Author: Timm Bäder Date: 2024-03-01T18:06:18+01:00 New Revision: 68516bfd2f086736dfd88374a11017276e61ad3d
URL: https://github.com/llvm/llvm-project/commit/68516bfd2f086736dfd88374a11017276e61ad3d DIFF: https://github.com/llvm/llvm-project/commit/68516bfd2f086736dfd88374a11017276e61ad3d.diff LOG: [clang][Interp] Lambda This captures can be non-pointers If they are captured by value. Added: Modified: clang/lib/AST/Interp/ByteCodeEmitter.cpp clang/lib/AST/Interp/ByteCodeEmitter.h clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/EvalEmitter.h clang/test/AST/Interp/lambda.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index 60d8afecb2b3bb..e1b954fcc68486 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -108,8 +108,12 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { this->LambdaCaptures[Cap.first] = { Offset, Cap.second->getType()->isReferenceType()}; } - if (LTC) - this->LambdaThisCapture = R->getField(LTC)->Offset; + if (LTC) { + QualType CaptureType = R->getField(LTC)->Decl->getType(); + this->LambdaThisCapture = {R->getField(LTC)->Offset, + CaptureType->isReferenceType() || + CaptureType->isPointerType()}; + } } } diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.h b/clang/lib/AST/Interp/ByteCodeEmitter.h index 03de286582c916..548769329b7f8c 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.h +++ b/clang/lib/AST/Interp/ByteCodeEmitter.h @@ -62,7 +62,7 @@ class ByteCodeEmitter { /// Lambda captures. llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures; /// Offset of the This parameter in a lambda record. - unsigned LambdaThisCapture = 0; + ParamOffset LambdaThisCapture{0, false}; /// Local descriptors. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 388da0e324c732..63ab80f59dac46 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2934,8 +2934,11 @@ bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { if (DiscardResult) return true; - if (this->LambdaThisCapture > 0) - return this->emitGetThisFieldPtr(this->LambdaThisCapture, E); + if (this->LambdaThisCapture.Offset > 0) { + if (this->LambdaThisCapture.IsPtr) + return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E); + return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E); + } return this->emitThis(E); } diff --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h index 5b02b992fef6f7..116f1d6fc134a7 100644 --- a/clang/lib/AST/Interp/EvalEmitter.h +++ b/clang/lib/AST/Interp/EvalEmitter.h @@ -73,7 +73,7 @@ class EvalEmitter : public SourceMapper { /// Lambda captures. llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures; /// Offset of the This parameter in a lambda record. - unsigned LambdaThisCapture = 0; + ParamOffset LambdaThisCapture{0, false}; /// Local descriptors. llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors; diff --git a/clang/test/AST/Interp/lambda.cpp b/clang/test/AST/Interp/lambda.cpp index a5e0d0f1fd9f48..d056bb304eeb30 100644 --- a/clang/test/AST/Interp/lambda.cpp +++ b/clang/test/AST/Interp/lambda.cpp @@ -235,3 +235,16 @@ namespace LambdaToAPValue { static_assert(g() == f(), ""); } } + +namespace ns2_capture_this_byval { + struct S { + int s; + constexpr S(int s) : s{s} { } + constexpr auto f(S o) { + return [*this,o] (auto a) { return s + o.s + a.s; }; + } + }; + + constexpr auto L = S{5}.f(S{10}); + static_assert(L(S{100}) == 115, ""); +} // end test_captures_1::ns2_capture_this_byval _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits