================
@@ -664,20 +664,66 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
     return CurrExpr->getSourceRange() != LastExpr->getSourceRange();
   }
 
+  bool shouldCarryHiddenLifetimeBound(const Expr *HiddenExpr,
----------------
iitianpushkar wrote:

No, we cannot directly match them because even after `IgnoreImpCasts()` or 
`IgnoreUnlessSpelledInSource()`, those can still be different Expr.

For e.g. :
```cpp
template <typename T> struct [[gsl::Pointer]] Pointer {
  Pointer(const T &bar [[clang::lifetimebound]]);
};

void nested_local_pointer() {
  Pointer<Pointer<Pointer<Bar>>> ppp;
  Pointer<Pointer<Bar>> pp;
  Pointer<Bar> p;
  {
    Bar v;
    p = Pointer(v);     // expected-warning {{local variable 'v' does not live 
long enough}}
    pp = Pointer(p);    // expected-note {{local variable 'p' aliases the 
storage of local variable 'v' because parameter 'bar' is marked 
'lifetimebound'}}
    ppp = Pointer(pp);  // expected-note {{local variable 'pp' aliases the 
storage of local variable 'v'}}
  }                     // expected-note {{local variable 'v' is destroyed 
here}}
  use(***ppp);          // expected-note {{later used here}}
}
```

For `pp = Pointer(p)`, the hidden lifetimebound step can correspond to the 
constructor expression Pointer(p) while the visible expression being explained 
is the `argument p`.
That is why the current check compares source ranges instead, after normalizing 
with `IgnoreImpCasts`, it accepts either the same source range or a hidden 
expression range that directly wraps the visible expression range.

https://github.com/llvm/llvm-project/pull/206337
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to