================
@@ -274,6 +289,21 @@ void FactsGenerator::VisitMemberExpr(const MemberExpr *ME)
{
Dst->getOriginID(), Src->getOriginID(),
/*Kill=*/true));
}
+
+ // Narrow the UseFact's liveness coverage to the accessed field's
+ // subtree.
+ //
+ // E.g., for `(void)s.inner`, without narrowing, the UseFact at `s`
+ // would keep `s.v`'s subtree live and falsely flag a UAF when a loan
+ // held by `s.v` has already expired.
+ if (UseFact *UF = UseFacts.lookup(ME->getBase())) {
+ assert(!UseFacts.contains(ME) && "ME already has a UseFact");
+ OriginNode *NewUsedOrigins =
+ doesDeclHaveStorage(FD) ? Dst->getPointeeChild() : Dst;
+ UF->setUsedOrigins(NewUsedOrigins);
+ UseFacts[ME] = UF;
+ UseFacts.erase(ME->getBase());
----------------
usx95 wrote:
Yeah. I think you are right. That might be the right abstraction to deal with
this.
The policy could be:
1. l-values getting converted to an r-value is considered a read/GEN.
2. all arguments to a function are considered read (i.e., crossing the function
boundary).
This should help avoid us having to do such post-cleanups (e.g., LHS of
assignments).
Definitely a separate PR.
https://github.com/llvm/llvm-project/pull/195603
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits