[PATCH] D122768: [Clang][C++20] Support capturing structured bindings in lambdas
Corentin Jabot via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 29 04:30:28 PDT 2022
cor3ntin added inline comments.
================
Comment at: clang/lib/Analysis/AnalysisDeclContext.cpp:173
+ ValueDecl *VD = LC.getCapturedVar();
+ if (isSelfDecl(dyn_cast<VarDecl>(VD)))
return dyn_cast<ImplicitParamDecl>(VD);
----------------
erichkeane wrote:
> aaron.ballman wrote:
> > This looks dangerous -- `isSelfDecl()` uses the pointer variable in ways that would be Bad News for null pointers.
> Yep, `isSelfDecl` seems to do:
>
> `return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";`
>
> `isa` isn't nullptr safe, we have `isa_and_nonnull` for that (if we want to update `isSelfDecl`).
Using `isa_and_nonnull` looks like the best solution here
================
Comment at: clang/lib/Sema/SemaDecl.cpp:14594-14596
+ ValueDecl *VD = C.getCapturedVar();
+ if (VarDecl *Var = dyn_cast<VarDecl>(VD)) {
+ if (Var->isInitCapture())
----------------
erichkeane wrote:
>
I'm not sure I understood your suggestion.
The reason there is a local `ValueDecl` in addition of the `VarDecl` is because we use it Line 14660 just below.
But that was reworked when lifting isInitCapture in ValueDecl anyway.
================
Comment at: clang/lib/Sema/SemaExpr.cpp:16393
- VarDecl *Var = Cap.getVariable();
+ VarDecl *Var = cast<VarDecl>(Cap.getVariable());
Expr *CopyExpr = nullptr;
----------------
aaron.ballman wrote:
> Is `cast<>` safe here?
Yes, I added a comment to make that clear
================
Comment at: clang/lib/Sema/SemaExpr.cpp:18324
+
+ assert((isa<VarDecl>(Var) || isa<BindingDecl>(Var)) &&
+ "Only variables and structured bindings can be captured");
----------------
aaron.ballman wrote:
>
Fancy. The parentheses are still needed though, because C macros are amazing like that :)
================
Comment at: clang/lib/Sema/SemaExpr.cpp:18531
+ } else if ((BD = dyn_cast<BindingDecl>(Var))) {
+ ME = dyn_cast_or_null<MemberExpr>(BD->getBinding());
+ }
----------------
aaron.ballman wrote:
> Can this return nullptr?
I think so
```
/// Get the expression to which this declaration is bound. This may be null
/// in two different cases: while parsing the initializer for the
/// decomposition declaration, and when the initializer is type-dependent.
Expr *getBinding() const { return Binding; }
```
The initializer could be type dependant here, and so it could be null
================
Comment at: clang/lib/Sema/SemaExpr.cpp:18539
+ !S.isOpenMPCapturedDecl(Var))) {
+ FieldDecl *FD = dyn_cast_or_null<FieldDecl>(ME->getMemberDecl());
+ if (FD &&
----------------
aaron.ballman wrote:
> Can this return nullptr?
Yes, same thing as above
================
Comment at: clang/lib/Sema/SemaLambda.cpp:1208-1209
+ if (isa<BindingDecl>(Var)) {
+ Underlying = dyn_cast_or_null<VarDecl>(
+ cast<BindingDecl>(Var)->getDecomposedDecl());
+ } else
----------------
aaron.ballman wrote:
> Does `getDecomposedDecl()` ever actually return nullptr?
I don't think that's necessary indeed, nice catch
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D122768/new/
https://reviews.llvm.org/D122768
More information about the cfe-commits
mailing list