[clang] [LifetimeSafety] Detect use of a reference type as a use of underlying origin (PR #184295)

Gábor Horváth via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 8 06:59:30 PDT 2026


================
@@ -371,29 +366,38 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr,
   // assigned.
   RHSList = getRValueOrigins(RHSExpr, RHSList);
 
-  if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr))
-    markUseAsWrite(DRE_LHS);
+  if (const auto *DRE_LHS = dyn_cast<DeclRefExpr>(LHSExpr)) {
+    QualType QT = DRE_LHS->getDecl()->getType();
+    if (QT->isReferenceType() && hasOrigins(QT->getPointeeType())) {
+      // Writing through a reference uses the binding but overwrites the
+      // pointee. Model this as a Read of the outer origin (keeping the binding
+      // live) and a Write of the inner origins (killing the pointee's
+      // liveness).
+      if (UseFact *UF = UseFacts.lookup(DRE_LHS)) {
+        const OriginList *FullList = UF->getUsedOrigins();
+        assert(FullList);
+        UF->setUsedOrigins(FactMgr.getOriginMgr().createSingleOriginList(
+            FullList->getOuterOriginID()));
+        if (const OriginList *InnerList = FullList->peelOuterOrigin()) {
+          UseFact *WriteUF = FactMgr.createFact<UseFact>(DRE_LHS, InnerList);
+          WriteUF->markAsWritten();
+          CurrentBlockFacts.push_back(WriteUF);
+        }
+      }
+    } else if (!QT->isReferenceType()) {
+      markUseAsWrite(DRE_LHS);
+    }
----------------
Xazax-hun wrote:

Could we avoid repeating `QT->isReferenceType()`? Something like:

```suggestion
    if (QT->isReferenceType()) {
      if (hasOrigins(QT->getPointeeType()) {
        // Writing through a reference uses the binding but overwrites the
        // pointee. Model this as a Read of the outer origin (keeping the binding
        // live) and a Write of the inner origins (killing the pointee's
        // liveness).
        if (UseFact *UF = UseFacts.lookup(DRE_LHS)) {
          const OriginList *FullList = UF->getUsedOrigins();
          assert(FullList);
          UF->setUsedOrigins(FactMgr.getOriginMgr().createSingleOriginList(
              FullList->getOuterOriginID()));
          if (const OriginList *InnerList = FullList->peelOuterOrigin()) {
            UseFact *WriteUF = FactMgr.createFact<UseFact>(DRE_LHS, InnerList);
            WriteUF->markAsWritten();
            CurrentBlockFacts.push_back(WriteUF);
          }
        }
      }
    } else 
      markUseAsWrite(DRE_LHS);
```

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


More information about the cfe-commits mailing list