[PATCH] D143109: [Sema] Push a LambdaScopeInfo before calling SubstDefaultArgument

Akira Hatanaka via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 1 14:02:51 PST 2023


ahatanak created this revision.
ahatanak added reviewers: tahonermann, erichkeane, aaron.ballman, shafik, Bigcheese, arphaman.
ahatanak added a project: clang.
Herald added a project: All.
ahatanak requested review of this revision.

This is needed to fix https://github.com/llvm/llvm-project/issues/60155.

An assertion in `tryCaptureVariable` fails because `SubstDefaultArgument` pushes the context for the lambda's function operator, but the LambdaScopeInfo isn't being pushed to the stack.

It appears that the assertion started to fail in 4409a83c293537e22da046b54e9f69454cdd3dca <https://reviews.llvm.org/rG4409a83c293537e22da046b54e9f69454cdd3dca>, which delays instantiation of default arguments. By the time the default arguments are instantiated, which happens after `inherited::TransformLambdaExpr` is called, the lambda scope has already been popped.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143109

Files:
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaCXX/lambda-default-arg.cpp


Index: clang/test/SemaCXX/lambda-default-arg.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/lambda-default-arg.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only %s
+
+template <class T> bool test0() {
+  constexpr float a = 1e-5f;
+  return [=](float b = a) -> bool {
+    return a < 0;
+  }();
+}
+
+bool b0 = test0<int>();
+
+template <class T> bool test1() {
+  float a = 1e-5f;
+  return [=](float b = a) -> bool { // expected-error {{default argument references local variable 'a'}}
+    return a < 0;
+  }();
+}
+
+bool b1 = test1<int>();
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1348,6 +1348,13 @@
         Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
         // FIXME: Obtain the source location for the '=' token.
         SourceLocation EqualLoc = UninstExpr->getBeginLoc();
+
+        // Push an empty lambda scope. This is needed as SubstDefaultArgument
+        // pushes the context for the lambda's function call operator and we
+        // need to keep the contexts and the function scopes in sync.
+        getSema().PushLambdaScope();
+        Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
+
         if (SemaRef.SubstDefaultArgument(EqualLoc, PVD, TemplateArgs)) {
           // If substitution fails, the default argument is set to a
           // RecoveryExpr that wraps the uninstantiated default argument so


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143109.494060.patch
Type: text/x-patch
Size: 1610 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230201/547f0316/attachment.bin>


More information about the cfe-commits mailing list