================
@@ -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