yronglin marked an inline comment as done.
yronglin added inline comments.

================
Comment at: clang/lib/Sema/SemaExprCXX.cpp:8901-8914
+  // [P2718R0] Lifetime extension in range-based for loops.
+  //
+  // 6.7.7 [class.temporary] p5:
+  // There are four contexts in which temporaries are destroyed at a different
+  // point than the end of the full-expression.
+  //
+  // 6.7.7 [class.temporary] p6:
----------------
yronglin wrote:
> hubert.reinterpretcast wrote:
> > yronglin wrote:
> > > rsmith wrote:
> > > > This isn't the right way to model the behavior here -- the presence or 
> > > > absence of an `ExprWithCleanups` is just a convenience to tell 
> > > > consumers of the AST whether they should expect to see cleanups later 
> > > > or not, and doesn't carry an implication of affecting the actual 
> > > > temporary lifetimes and storage durations.
> > > > 
> > > > The outcome that we should be aiming to reach is that all 
> > > > `MaterializeTemporaryExpr`s created as part of processing the 
> > > > for-range-initializer are marked as being lifetime-extended by the 
> > > > for-range variable. Probably the simplest way to handle that would be 
> > > > to track the current enclosing for-range-initializer variable in the 
> > > > `ExpressionEvaluationContextRecord`, and whenever a 
> > > > `MaterializeTemporaryExpr` is created, if there is a current enclosing 
> > > > for-range-initializer, mark that `MaterializeTemporaryExpr` as being 
> > > > lifetime-extended by it.
> > > Awesome! Thanks a lot for your advice, this is very helpful! I want to 
> > > take a longer look at it.
> > As mentioned in D139586, `CXXDefaultArgExpr`s may need additional handling. 
> > Similarly for `CXXDefaultInitExpr`s.
> Thanks for your tips! I have a question that what's the correct way to extent 
> the lifetime of `CXXBindTemporaryExpr`? Can I just `materialize` the 
> temporary? It may replaced by `MaterializeTemporaryExpr`, and then I can mark 
> it as being lifetime-extended by the for-range variable.
Eg.
```
void f() {
  int v[] = {42, 17, 13};
  Mutex m;
  for (int x : static_cast<void>(LockGuard(m)), v) // lock released in C++ 2020
  {
    LockGuard guard(m); // OK in C++ 2020, now deadlocks
  }
}
```
```
BinaryOperator 0x135036220 'int[3]' lvalue ','
|-CXXStaticCastExpr 0x1350361d0 'void' static_cast<void> <ToVoid>
| `-CXXFunctionalCastExpr 0x135036198 'LockGuard':'struct LockGuard' functional 
cast to LockGuard <ConstructorConversion>
|   `-CXXBindTemporaryExpr 0x135036178 'LockGuard':'struct LockGuard' 
(CXXTemporary 0x135036178)
|     `-CXXConstructExpr 0x135036140 'LockGuard':'struct LockGuard' 'void 
(Mutex &)'
|       `-DeclRefExpr 0x135035e18 'Mutex':'class Mutex' lvalue Var 0x135035b40 
'm' 'Mutex':'class Mutex'
`-DeclRefExpr 0x135036200 'int[3]' lvalue Var 0x135035928 'v' 'int[3]'
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D153701/new/

https://reviews.llvm.org/D153701

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to