Skip to content

Commit b8cc85b

Browse files
committed
[clang][Interp] Limit lambda capture lazy visting to actual captures
Check this by looking at the VarDecl.
1 parent 9eb8a13 commit b8cc85b

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3895,12 +3895,13 @@ bool ByteCodeExprGen<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
38953895
return this->emitGetThisFieldPtr(Offset, E);
38963896
return this->emitGetPtrThisField(Offset, E);
38973897
} else if (const auto *DRE = dyn_cast<DeclRefExpr>(E);
3898-
DRE && DRE->refersToEnclosingVariableOrCapture() &&
3899-
isa<VarDecl>(D)) {
3900-
if (!this->visitVarDecl(cast<VarDecl>(D)))
3901-
return false;
3902-
// Retry.
3903-
return this->visitDeclRef(D, E);
3898+
DRE && DRE->refersToEnclosingVariableOrCapture()) {
3899+
if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture()) {
3900+
if (!this->visitVarDecl(cast<VarDecl>(D)))
3901+
return false;
3902+
// Retry.
3903+
return this->visitDeclRef(D, E);
3904+
}
39043905
}
39053906

39063907
// Try to lazily visit (or emit dummy pointers for) declarations

clang/test/AST/Interp/lambda.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,16 @@ namespace CaptureDefaults {
267267

268268
constexpr auto t4 = ([x=42]() consteval { return x; }());
269269
static_assert(t4 == 42, "");
270+
271+
namespace InvalidCapture {
272+
273+
int &f(int *p);
274+
char &f(...);
275+
void g() {
276+
int n = -1; // both-note {{declared here}}
277+
[=] {
278+
int arr[n]; // both-warning {{variable length arrays in C++ are a Clang extension}} \
279+
both-note {{read of non-const variable 'n' is not allowed in a constant expression}}
280+
} ();
281+
}
282+
}

0 commit comments

Comments
 (0)