Skip to content

Commit 68516bf

Browse files
committed
[clang][Interp] Lambda This captures can be non-pointers
If they are captured by value.
1 parent 64216ba commit 68516bf

File tree

5 files changed

+26
-6
lines changed

5 files changed

+26
-6
lines changed

clang/lib/AST/Interp/ByteCodeEmitter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
108108
this->LambdaCaptures[Cap.first] = {
109109
Offset, Cap.second->getType()->isReferenceType()};
110110
}
111-
if (LTC)
112-
this->LambdaThisCapture = R->getField(LTC)->Offset;
111+
if (LTC) {
112+
QualType CaptureType = R->getField(LTC)->Decl->getType();
113+
this->LambdaThisCapture = {R->getField(LTC)->Offset,
114+
CaptureType->isReferenceType() ||
115+
CaptureType->isPointerType()};
116+
}
113117
}
114118
}
115119

clang/lib/AST/Interp/ByteCodeEmitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class ByteCodeEmitter {
6262
/// Lambda captures.
6363
llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
6464
/// Offset of the This parameter in a lambda record.
65-
unsigned LambdaThisCapture = 0;
65+
ParamOffset LambdaThisCapture{0, false};
6666
/// Local descriptors.
6767
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
6868

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2934,8 +2934,11 @@ bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
29342934
if (DiscardResult)
29352935
return true;
29362936

2937-
if (this->LambdaThisCapture > 0)
2938-
return this->emitGetThisFieldPtr(this->LambdaThisCapture, E);
2937+
if (this->LambdaThisCapture.Offset > 0) {
2938+
if (this->LambdaThisCapture.IsPtr)
2939+
return this->emitGetThisFieldPtr(this->LambdaThisCapture.Offset, E);
2940+
return this->emitGetPtrThisField(this->LambdaThisCapture.Offset, E);
2941+
}
29392942

29402943
return this->emitThis(E);
29412944
}

clang/lib/AST/Interp/EvalEmitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class EvalEmitter : public SourceMapper {
7373
/// Lambda captures.
7474
llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
7575
/// Offset of the This parameter in a lambda record.
76-
unsigned LambdaThisCapture = 0;
76+
ParamOffset LambdaThisCapture{0, false};
7777
/// Local descriptors.
7878
llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
7979

clang/test/AST/Interp/lambda.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,16 @@ namespace LambdaToAPValue {
235235
static_assert(g() == f(), "");
236236
}
237237
}
238+
239+
namespace ns2_capture_this_byval {
240+
struct S {
241+
int s;
242+
constexpr S(int s) : s{s} { }
243+
constexpr auto f(S o) {
244+
return [*this,o] (auto a) { return s + o.s + a.s; };
245+
}
246+
};
247+
248+
constexpr auto L = S{5}.f(S{10});
249+
static_assert(L(S{100}) == 115, "");
250+
} // end test_captures_1::ns2_capture_this_byval

0 commit comments

Comments
 (0)