[llvm-branch-commits] [clang] [LifetimeSafety] Track per-field origins for record types (PR #195603)

Utkarsh Saxena via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jun 1 07:14:01 PDT 2026


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


More information about the llvm-branch-commits mailing list