https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/107073
>From 5edd9a9abe019af2a14ccf9fbf43858f4141071b Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Tue, 3 Sep 2024 11:25:27 +0200 Subject: [PATCH 1/3] [Clang] Treat default template argument as constant expressions We only check that a default argument is a converted constant expression when using the default argument. However, when parsing a default argument, we need to make sure to parse it as a constant expression such as not ODR-use variables. (otherwise, we would try to capture default template arguments of generic lambdas) Fixes #107048 --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Parse/ParseTemplate.cpp | 2 ++ clang/test/SemaCXX/cxx2a-template-lambdas.cpp | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fc940db4813948..e15414b994a36b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -339,6 +339,7 @@ Bug Fixes to C++ Support - Template parameter names are considered in the name lookup of out-of-line class template specialization right before its declaration context. (#GH64082) - Fixed a constraint comparison bug for friend declarations. (#GH78101) +- Clang no longer tries to capture default argument of template arguments of generic lambdas (#GH107048) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 6ecfc15757f3d4..b80999f1b92e7f 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -960,6 +960,8 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { EnterExpressionEvaluationContext ConstantEvaluated( Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseInitializer()); + if (DefaultArg.isUsable()) + DefaultArg = Actions.ActOnConstantExpression(DefaultArg); if (DefaultArg.isInvalid()) SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); } diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp index fff524e77d3bf4..ec373f30876295 100644 --- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp +++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp @@ -97,3 +97,22 @@ void foo() { } #endif + +#if __cplusplus >= 202002L +void GH107048() { + constexpr int x{}; + const int y{}; + auto b = []<int=x, int=y>{}; + using A = decltype([]<int=x>{}); + + int z; // expected-note {{'z' declared here}} + auto c = []<int t=z>{ + // expected-error@-1 {{no matching function for call to object of type}} \ + // expected-error@-1 {{variable 'z' cannot be implicitly captured in a lambda with no capture-default specified}} \ + // expected-note@-1 {{lambda expression begins here}} \ + // expected-note@-1 4{{capture}} \ + // expected-note@-1 {{candidate template ignored: substitution failure: reference to local variable 'z' declared in enclosing function}} + return t; + }(); +} +#endif >From b98c94e765656dcf1120ad1ec72b9c4c191ffefd Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Tue, 3 Sep 2024 14:29:29 +0200 Subject: [PATCH 2/3] address review comments --- clang/lib/Parse/ParseTemplate.cpp | 4 +--- clang/test/SemaCXX/cxx2a-template-lambdas.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index b80999f1b92e7f..de29652abbfd95 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -959,9 +959,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { ++CurTemplateDepthTracker; EnterExpressionEvaluationContext ConstantEvaluated( Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); - DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseInitializer()); - if (DefaultArg.isUsable()) - DefaultArg = Actions.ActOnConstantExpression(DefaultArg); + DefaultArg = Actions.ActOnConstantExpression(ParseInitializer()); if (DefaultArg.isInvalid()) SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); } diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp index ec373f30876295..34718f9e180f50 100644 --- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp +++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp @@ -106,7 +106,7 @@ void GH107048() { using A = decltype([]<int=x>{}); int z; // expected-note {{'z' declared here}} - auto c = []<int t=z>{ + auto c = []<int t=z>{ // expected-error@-1 {{no matching function for call to object of type}} \ // expected-error@-1 {{variable 'z' cannot be implicitly captured in a lambda with no capture-default specified}} \ // expected-note@-1 {{lambda expression begins here}} \ @@ -114,5 +114,12 @@ void GH107048() { // expected-note@-1 {{candidate template ignored: substitution failure: reference to local variable 'z' declared in enclosing function}} return t; }(); + + struct S {}; + constexpr S s; // expected-note {{'s' declared here}} + auto class_type = []<S=s>{}; + // expected-error@-1 {{variable 's' cannot be implicitly captured in a lambda with no capture-default specified}} \ + // expected-note@-1 {{lambda expression begins here}} \ + // expected-note@-1 4{{capture}} } #endif >From 00672c5ce874a2823507d69125c1a5e47c2a0f4e Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Wed, 4 Sep 2024 09:16:54 +0200 Subject: [PATCH 3/3] add tests --- clang/test/SemaCXX/cxx2a-template-lambdas.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp index 34718f9e180f50..00ba291fbd1981 100644 --- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp +++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp @@ -99,7 +99,10 @@ void foo() { #endif #if __cplusplus >= 202002L -void GH107048() { +namespace { +struct S {}; +constexpr S gs; +void f() { constexpr int x{}; const int y{}; auto b = []<int=x, int=y>{}; @@ -115,11 +118,16 @@ void GH107048() { return t; }(); - struct S {}; + auto class_type_global = []<S=gs>{}; + + static constexpr S static_s; + auto class_type_static = []<S=static_s>{}; + constexpr S s; // expected-note {{'s' declared here}} auto class_type = []<S=s>{}; // expected-error@-1 {{variable 's' cannot be implicitly captured in a lambda with no capture-default specified}} \ // expected-note@-1 {{lambda expression begins here}} \ // expected-note@-1 4{{capture}} } +} #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits