[clang] [clang] Fix crash parsing delayed lambda default arguments (PR #213556)
Gauarv Chaudhary via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 12 09:46:59 PDT 2026
https://github.com/ANAMASGARD updated https://github.com/llvm/llvm-project/pull/213556
>From 48655deecf771b2248b73a008e293beaae1478ce Mon Sep 17 00:00:00 2001
From: Gaurav Chaudhary <chaudharygaurav2004 at gmail.com>
Date: Sun, 2 Aug 2026 22:26:23 +0530
Subject: [PATCH 1/2] [clang] Fix crash during delayed default argument parsing
Signed-off-by: Gaurav Chaudhary <chaudharygaurav2004 at gmail.com>
---
clang/lib/Sema/SemaExpr.cpp | 7 +++++--
clang/test/SemaCXX/GH213420.cpp | 12 ++++++++++++
2 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 clang/test/SemaCXX/GH213420.cpp
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 59b8c9b60663c..146dd7e78a27c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2125,8 +2125,11 @@ static Decl *getPredefinedExprDecl(Sema &S, DeclContext *DC) {
while (LSI != E && isa<CapturingScopeInfo>(*LSI) &&
!isa<LambdaScopeInfo>(*LSI))
++LSI;
- assert(LSI != E && "Should be in a lambda scope info");
- if (dyn_cast<LambdaScopeInfo>(*LSI)->BeforeCompoundStatement)
+ if (LSI == E || !isa<LambdaScopeInfo>(*LSI)) {
+ // The lambda scope may already be popped during delayed parsing.
+ return;
+ }
+ if (cast<LambdaScopeInfo>(*LSI)->BeforeCompoundStatement)
DC = DC->getParent();
++LSI;
}
diff --git a/clang/test/SemaCXX/GH213420.cpp b/clang/test/SemaCXX/GH213420.cpp
new file mode 100644
index 0000000000000..2d1b9f032e7e4
--- /dev/null
+++ b/clang/test/SemaCXX/GH213420.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-compatibility -verify \
+// RUN: -Wno-missing-declarations -Wno-unused-value %s
+
+void foo() {
+ [] {
+ struct { // expected-error {{anonymous structs and classes must be class members}}
+ void bar(int & = "") {} // expected-error {{non-const lvalue reference to type 'int' cannot bind}}
+ // expected-note at -1 {{passing argument to parameter here}}
+ // expected-error at -2 {{functions cannot be declared in an anonymous struct}}
+ };
+ };
+}
>From 3919452576d09a0c51e2c2c75ebacb53b4f63cea Mon Sep 17 00:00:00 2001
From: Gaurav Chaudhary <chaudharygaurav2004 at gmail.com>
Date: Wed, 12 Aug 2026 22:04:20 +0530
Subject: [PATCH 2/2] [clang] Fix crash parsing delayed lambda default
arguments
Skip non-LambdaScopeInfo frames in getPredefinedExprDecl so the
temporary FunctionScopeInfo pushed during delayed default-argument
parsing does not hide the enclosing LambdaScopeInfo. Restores the
assert and ensures __FUNCTION__ in lambda-local struct default args
resolves to the lambda operator() under -fms-compatibility.
Fixes #213420
Signed-off-by: Gaurav Chaudhary <chaudharygaurav2004 at gmail.com>
---
clang/lib/Sema/SemaExpr.cpp | 7 ++-----
clang/test/SemaCXX/GH213420.cpp | 23 +++++++++++++++++++++++
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0c2a88aa6de64..90e360e2b05fc 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2125,11 +2125,8 @@ static Decl *getPredefinedExprDecl(Sema &S, DeclContext *DC) {
while (LSI != E && isa<CapturingScopeInfo>(*LSI) &&
!isa<LambdaScopeInfo>(*LSI))
++LSI;
- if (LSI == E || !isa<LambdaScopeInfo>(*LSI)) {
- // The lambda scope may already be popped during delayed parsing.
- return;
- }
- if (cast<LambdaScopeInfo>(*LSI)->BeforeCompoundStatement)
+ assert(LSI != E && "Should be in a lambda scope info");
+ if (dyn_cast<LambdaScopeInfo>(*LSI)->BeforeCompoundStatement)
DC = DC->getParent();
++LSI;
}
diff --git a/clang/test/SemaCXX/GH213420.cpp b/clang/test/SemaCXX/GH213420.cpp
index 2d1b9f032e7e4..256d9e00539df 100644
--- a/clang/test/SemaCXX/GH213420.cpp
+++ b/clang/test/SemaCXX/GH213420.cpp
@@ -10,3 +10,26 @@ void foo() {
};
};
}
+
+// Verify __FUNCTION__ in a lambda-local struct default argument resolves to
+// the lambda's operator(), not the member function or enclosing function.
+void test_lambda_function_in_default_arg() {
+ (void)[] {
+ struct S {
+ void f2(const char *s = __FUNCTION__) {}
+ // expected-warning at -1 {{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
+ };
+ return 0;
+ }();
+}
+
+void test_lambda_function_size() {
+ (void)[] {
+ struct S {
+ char proof[sizeof(__FUNCTION__) == 11 ? 1 : -1];
+ void f2(const char *s = __FUNCTION__) {}
+ // expected-warning at -1 {{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}}
+ };
+ return 0;
+ }();
+}
More information about the cfe-commits
mailing list