https://github.com/Praneeth740 updated https://github.com/llvm/llvm-project/pull/235529
>From 1d95da5f3a00e04f9d87ec79d9827e9212424b15 Mon Sep 17 00:00:00 2001 From: Praneeth <[email protected]> Date: Mon, 26 Oct 2026 02:50:30 +0530 Subject: [PATCH] [clang] Don't skip capture of parameters in default arguments The early return in tryCaptureVariable was meant for unevaluated operands but never checked for them, so lambdas in default arguments skipped capture analysis. Restrict it to unevaluated contexts. Fixes #233811 --- clang/lib/Sema/SemaExpr.cpp | 12 ++++++++++-- .../SemaCXX/lambda-as-default-parameter.cpp | 7 ++++++- .../lambda-default-arg-param-capture.cpp | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/lambda-default-arg-param-capture.cpp diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 43b0c86132172b..e0f87936d451cd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -20238,8 +20238,16 @@ bool Sema::tryCaptureVariable( // Exception: Function parameters are not tied to the function's DeclContext // until we enter the function definition. Capturing them anyway would result // in an out-of-bounds error while traversing DC and its parents. - if (isa<ParmVarDecl>(Var) && !VarDC->isFunctionOrMethod()) - return true; + + bool InDefaultArg = llvm::any_of( + ExprEvalContexts, [](const ExpressionEvaluationContextRecord &C) { + return isa_and_nonnull<ParmVarDecl>(C.ManglingContextDecl); + }); + if (isa<ParmVarDecl>(Var) && !VarDC->isFunctionOrMethod() && !InDefaultArg && + llvm::any_of(ExprEvalContexts, + [](const ExpressionEvaluationContextRecord &C) { + return C.isUnevaluated(); + })) return true; const auto *VD = dyn_cast<VarDecl>(Var); if (VD) { diff --git a/clang/test/SemaCXX/lambda-as-default-parameter.cpp b/clang/test/SemaCXX/lambda-as-default-parameter.cpp index 1f07a7f5644b7c..1c8ceaa806c60f 100644 --- a/clang/test/SemaCXX/lambda-as-default-parameter.cpp +++ b/clang/test/SemaCXX/lambda-as-default-parameter.cpp @@ -3,4 +3,9 @@ struct a; // expected-note {{forward declaration of 'a'}} \ expected-note {{forward declaration of 'a'}} void b(a c = [] { return c; }); // expected-error {{initialization of incomplete type 'a'}} \ - expected-error {{variable has incomplete type 'a'}} + expected-error {{variable has incomplete type 'a'}} \ + expected-error {{variable 'c' cannot be implicitly captured in a lambda with no capture-default specified}} \ + expected-note {{'c' declared here}} \ + expected-note {{lambda expression begins here}} \ + expected-note {{capture 'c' by reference}} \ + expected-note {{default capture by reference}} diff --git a/clang/test/SemaCXX/lambda-default-arg-param-capture.cpp b/clang/test/SemaCXX/lambda-default-arg-param-capture.cpp new file mode 100644 index 00000000000000..914c0f3754b5e6 --- /dev/null +++ b/clang/test/SemaCXX/lambda-default-arg-param-capture.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +int a(int g, int h = []{ return g; }()); // expected-error {{variable 'g' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{'g' declared here}} expected-note {{lambda expression begins here}} expected-note {{capture 'g' by value}} expected-note {{capture 'g' by reference}} expected-note {{default capture by value}} expected-note {{default capture by reference}} + +int e(int g, int h = [] { int g = 1; return g; }()); + +// Unevaluated operand in a trailing return type: still accepted. +auto u(int g) -> decltype([] { return g; }()); + +// A default argument is potentially evaluated even when the lambda sits in an +// unevaluated operand; GCC rejects these too. +int s1(int x, int h = sizeof([] { return x; }())); // expected-error {{variable 'x' cannot be implicitly captured in a lambda with no capture-default specified}} \ + expected-note {{'x' declared here}} \ + expected-note {{lambda expression begins here}} \ + expected-note {{capture 'x' by value}} \ + expected-note {{capture 'x' by reference}} \ + expected-note {{default capture by value}} \ + expected-note {{default capture by reference}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
