================
@@ -3068,11 +3107,217 @@ void MallocChecker::checkDeadSymbols(SymbolReaper 
&SymReaper,
   C.addTransition(state->set<RegionState>(RS), N);
 }
 
+static QualType canonicalStrip(QualType QT) {
+  return QT.getCanonicalType().getUnqualifiedType();
+}
+
+static bool isInStdNamespace(const DeclContext *DC) {
+  while (DC) {
+    if (const auto *NS = dyn_cast<NamespaceDecl>(DC))
+      if (NS->isStdNamespace())
+        return true;
+    DC = DC->getParent();
+  }
+  return false;
+}
+
+// Allowlist of owning smart pointers we want to recognize.
+// Start with unique_ptr and shared_ptr. (intentionally exclude weak_ptr)
+static bool isSmartOwningPtrType(QualType QT) {
+  QT = canonicalStrip(QT);
+
+  // First try TemplateSpecializationType (for std smart pointers)
+  const auto *TST = QT->getAs<TemplateSpecializationType>();
+  if (TST) {
+    const TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();
+    if (!TD)
+      return false;
+
+    const auto *ND = dyn_cast_or_null<NamedDecl>(TD->getTemplatedDecl());
+    if (!ND)
+      return false;
+
+    // Check if it's in std namespace
+    const DeclContext *DC = ND->getDeclContext();
+    if (!isInStdNamespace(DC))
+      return false;
+
+    StringRef Name = ND->getName();
+    return Name == "unique_ptr" || Name == "shared_ptr";
+  }
+
+  // Also try RecordType (for custom smart pointer implementations)
+  const auto *RT = QT->getAs<RecordType>();
+  if (RT) {
+    const auto *RD = RT->getDecl();
+    if (RD) {
+      StringRef Name = RD->getName();
+      if (Name == "unique_ptr" || Name == "shared_ptr") {
+        // Accept any custom unique_ptr or shared_ptr implementation
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static void collectDirectSmartOwningPtrFieldRegions(
+    const MemRegion *Base, QualType RecQT, CheckerContext &C,
+    SmallVectorImpl<const MemRegion *> &Out) {
+  if (!Base)
+    return;
+  const auto *CRD = RecQT->getAsCXXRecordDecl();
+  if (!CRD)
+    return;
+
+  for (const FieldDecl *FD : CRD->fields()) {
+    if (!isSmartOwningPtrType(FD->getType()))
+      continue;
+    SVal L = C.getState()->getLValue(FD, loc::MemRegionVal(Base));
+    if (const MemRegion *FR = L.getAsRegion())
+      Out.push_back(FR);
+  }
----------------
steakhal wrote:

So we iterate fields. What about fields from base classes?
Will they be enumerated here?

https://github.com/llvm/llvm-project/pull/152751
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to