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

Reply via email to