Skip to content

Commit cb0cb30

Browse files
committed
[clang][Interp] Reject static lambdas with captures
A version of llvm#74661 for the new interpreter. It didn't crash before, but we did emit a few non-sensical diagnostics.
1 parent d2672a5 commit cb0cb30

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

clang/lib/AST/Interp/ByteCodeEmitter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
6161
MD->getParent()->getCaptureFields(LC, LTC);
6262

6363
for (auto Cap : LC) {
64+
// Static lambdas cannot have any captures. If this one does,
65+
// it has already been diagnosed and we can only ignore it.
66+
if (MD->isStatic())
67+
return nullptr;
68+
6469
unsigned Offset = R->getField(Cap.second)->Offset;
6570
this->LambdaCaptures[Cap.first] = {
6671
Offset, Cap.second->getType()->isReferenceType()};

clang/test/AST/Interp/cxx23.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23 %s -fexperimental-new-constant-interpreter
55

66

7-
// expected23-no-diagnostics
8-
9-
107
/// FIXME: The new interpreter is missing all the 'control flows through...' diagnostics.
118

129
constexpr int f(int n) { // ref20-error {{constexpr function never produces a constant expression}} \
@@ -82,3 +79,27 @@ constexpr int k(int n) {
8279
return m;
8380
}
8481
constexpr int k0 = k(0);
82+
83+
namespace StaticLambdas {
84+
constexpr auto static_capture_constexpr() {
85+
char n = 'n';
86+
return [n] static { return n; }(); // expected23-error {{a static lambda cannot have any captures}} \
87+
// expected20-error {{a static lambda cannot have any captures}} \
88+
// expected20-warning {{are a C++23 extension}} \
89+
// expected20-warning {{is a C++23 extension}} \
90+
// ref23-error {{a static lambda cannot have any captures}} \
91+
// ref20-error {{a static lambda cannot have any captures}} \
92+
// ref20-warning {{are a C++23 extension}} \
93+
// ref20-warning {{is a C++23 extension}}
94+
}
95+
static_assert(static_capture_constexpr()); // expected23-error {{static assertion expression is not an integral constant expression}} \
96+
// expected20-error {{static assertion expression is not an integral constant expression}} \
97+
// ref23-error {{static assertion expression is not an integral constant expression}} \
98+
// ref20-error {{static assertion expression is not an integral constant expression}}
99+
100+
constexpr auto capture_constexpr() {
101+
char n = 'n';
102+
return [n] { return n; }();
103+
}
104+
static_assert(capture_constexpr());
105+
}

0 commit comments

Comments
 (0)