[clang] [Sema] Preserve ContainsUnexpandedParameterPack in TransformLambdaExpr (PR #86265)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 18 19:19:40 PDT 2024


================
@@ -14636,6 +14645,20 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
                                     /*IsInstantiation*/ true);
   SavedContext.pop();
 
+  // Parts other than the capture e.g. the lambda body might still contain a
+  // pattern that an outer fold expression would expand.
+  //
+  // We don't have a way to propagate up the ContainsUnexpandedParameterPack
+  // flag from a Stmt, so we have to revisit the lambda.
+  if (!LSICopy.ContainsUnexpandedParameterPack) {
+    llvm::SmallVector<UnexpandedParameterPack> UnexpandedPacks;
+    getSema().collectUnexpandedParameterPacksFromLambda(NewCallOperator,
+                                                        UnexpandedPacks);
+    // FIXME: Should we call Sema::DiagnoseUnexpandedParameterPacks() instead?
+    // Unfortunately, that requires the LambdaScopeInfo to exist, which has been
+    // removed by ActOnFinishFunctionBody().
+    LSICopy.ContainsUnexpandedParameterPack = !UnexpandedPacks.empty();
+  }
----------------
zyn0217 wrote:

That function attracts me because we seem to 1. always call it after collecting unexpanded packs; 2. also set the `LSI->ContainsUnexpandedParameterPack` flag there. However, this would probably be unnecessary if we called it during parsing.

> Also, I am not sure what you mean by leaving it as an NFC.

I was wondering if we could add an additional flag to `ActOnFinishFunctionBody()` so that we remove the scope info on the caller's own. (e.g. we could do that at the end of `TransformLambdaExpr`.) This way, we could also avoid copying LSI around the lines above. (I had intended to call `ContainsUnexpandedParameterPack()` afterward; again, even if the call is unnecessary, we still could benefit from the refactoring because we don't need to copy LSI.)

> but I don't think the solution is to simply teach ActOnFinishFunctionBody not to pop the function scope.

Can you say more? I think the FIXME is suggesting another way to avoid copying LSI, but that doesn't necessarily mean tweaking `ActOnFinishFunctionBody` is impossible?

https://github.com/llvm/llvm-project/pull/86265


More information about the cfe-commits mailing list