This is an archive of the discontinued LLVM Phabricator instance.

[clang] Correctly handle by-reference capture with an initializer that is a pack expansion in lambdas.
ClosedPublic

Authored by massberg on Dec 1 2022, 9:06 AM.

Details

Summary

Ensure that the correct information whether an init-capture of a lambda
is passed by reference or by copy. This information is already computed
and has to be passed to the place where NewInitCaptureType is
created.

Before this fix it has been checked whether the VarDecl is a reference
type. This doesn't work for packed expansions, as the information
whether it is passed by reference or by copy is stored at the pattern of
a PackExpansionType and not at the type itself.

However, as the information has been already computed, we just have to
pass it.

Add test that lambda captures with var decls which are reference types
are created in the AST.

Fixes #49266

Diff Detail

Event Timeline

massberg created this revision.Dec 1 2022, 9:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 1 2022, 9:06 AM
massberg requested review of this revision.Dec 1 2022, 9:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 1 2022, 9:06 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
massberg updated this revision to Diff 479579.Dec 2 2022, 3:10 AM

Add a diagnostics test for pack expansions to check if args are passed by reference and not by value.

massberg updated this revision to Diff 479581.Dec 2 2022, 3:23 AM

Remove unnecessary code from test.

ilya-biryukov added inline comments.Dec 2 2022, 4:47 AM
clang/lib/Sema/TreeTransform.h
13152

Could we use C->getCaptureKind() == LCK_ByRef instead?

It seems like that was the intention of the function in the first place (that's was the other callsite from the parser is doing): pass what was written by the user and let the function figure out how to actually build the types.
Normally we want to unify the code that parser uses for non-dependent code and the tree-transforms where possible.

massberg added inline comments.Dec 5 2022, 6:45 AM
clang/lib/Sema/TreeTransform.h
13152

C-getCaptureKind is equal to LCK_ByCopy, even if the expansion pack is passed by refernece.

massberg added inline comments.Dec 6 2022, 3:24 AM
clang/lib/Sema/TreeTransform.h
13152

I will check if this is by error and if it should be set to LCK_ByRef in case of references to pack expansions.

massberg updated this revision to Diff 480475.Dec 6 2022, 6:59 AM

Moved check if we have a pack expansion with reference type to Sema::BuildLambdaExpr.

I'm still not sure if this is the right place, or if From.isCopyCapture() should be false for pack expansions with refernece types.

massberg updated this revision to Diff 480518.Dec 6 2022, 9:16 AM

Instead of lokking if there is a pack expansion pass the already computed information whether we have a by ref or a by copy type.

massberg updated this revision to Diff 480800.Dec 7 2022, 12:52 AM

Simplify code and update description.

massberg edited the summary of this revision. (Show Details)Dec 7 2022, 12:54 AM
massberg added inline comments.
clang/lib/Sema/TreeTransform.h
13152

I have fixed the code and updated the description.

ilya-biryukov accepted this revision.Dec 7 2022, 2:02 AM

Thanks, LGTM!

clang/include/clang/Sema/Sema.h
7101

NIT 1: naming, this should be in UpperCamelCase
NIT 2: maybe rename to ByRef? It might be a bit confusing to talk about types here as the idea is to actually pass information about the syntax. Types can be inspected by looking at Var.

This revision is now accepted and ready to land.Dec 7 2022, 2:02 AM
This revision was landed with ongoing or failed builds.Dec 7 2022, 7:01 AM
This revision was automatically updated to reflect the committed changes.