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

Zhijie Wang via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue May 5 00:38:26 PDT 2026


================
@@ -273,6 +284,19 @@ void FactsGenerator::VisitMemberExpr(const MemberExpr *ME) {
     CurrentBlockFacts.push_back(FactMgr.createFact<OriginFlowFact>(
         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");
+      UF->setUsedOrigins(Dst);
+      UseFacts[ME] = UF;
+      UseFacts.erase(ME->getBase());
+    }
----------------
aeft wrote:

The corresponding tests are `struct_field_safe` and `struct_field_safe2`.   
  
But it seems like this is not a good and general solution. The core problem here is that I extended the UseFact transfer function from pointee chain traversal to tree traversal. And in some cases (one example is `derived_field_safe`), the remedy doesn't work. I may add a more specific fix here (e.g., fix `derived_field_safe`), but this is more like a band-aid than a principled design. I am thinking whether the long-term solution is that we carefully decide which UseFact to emit.  
  
For example, to avoid FP in `struct_field_safe`, instead of emitting one broad UseFact at `s` and relying on this narrow logic to rewrite it to `s.inner`, each visitor would emit its own narrow UseFact: `VisitDeclRefExpr` emits one at `s`'s origin, `VisitMemberExpr(s.inner)` emits another at `s.inner`'s origin, and the transfer function stops recursing into the subtree. The two UseFacts coexist; siblings of `s.inner` are never targeted by any UseFact, so the FP disappears by construction.

https://github.com/llvm/llvm-project/pull/195603


More information about the llvm-branch-commits mailing list