================
@@ -255,4 +255,76 @@ template <typename T> static bool 
isRecordWithAttr(QualType Type) {
 bool isGslPointerType(QualType QT) { return isRecordWithAttr<PointerAttr>(QT); 
}
 bool isGslOwnerType(QualType QT) { return isRecordWithAttr<OwnerAttr>(QT); }
 
+bool isContainerInvalidationMethod(const CXXMethodDecl *MD) {
+  if (!MD)
+    return false;
+  const CXXRecordDecl *RD = MD->getParent();
+  if (!RD || !isInStlNamespace(RD))
+    return false;
+
+  StringRef ContainerName;
+  if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
+    ContainerName = CTSD->getSpecializedTemplate()->getName();
+  else if (RD->getIdentifier())
+    ContainerName = RD->getName();
+  else
+    return false;
+
+  static llvm::StringSet<> Containers = {
+      // Sequence
+      "vector", "basic_string", "deque", "list", "forward_list",
+      // Adaptors
+      "stack", "priority_queue", "queue",
+      // Associative
+      "set", "multiset", "map", "multimap",
+      // Unordered Associative
+      "unordered_set", "unordered_multiset", "unordered_map",
+      "unordered_multimap",
+      // C++23 Flat
+      "flat_map", "flat_set", "flat_multimap", "flat_multiset"};
+
+  if (!Containers.contains(ContainerName))
+    return false;
+
+  // Handle Operators via OverloadedOperatorKind
+  OverloadedOperatorKind OO = MD->getOverloadedOperator();
+  if (OO != OO_None) {
+    switch (OO) {
+    case OO_Equal:     // operator= : Always invalidates (Assignment)
+    case OO_PlusEqual: // operator+= : Append (String/Vector)
+      return true;
+    case OO_Subscript: // operator[] : Invalidation only for Maps
+                       // (Insert-or-access)
+    {
+      static llvm::StringSet<> MapContainers = {"map", "unordered_map",
+                                                "flat_map"};
+      return MapContainers.contains(ContainerName);
+    }
+    default:
+      return false;
+    }
+  }
+
+  if (!MD->getIdentifier())
+    return false;
+  static const llvm::StringSet<> InvalidatingMembers = {
+      // Basic Insertion/Emplacement
+      "push_front", "push_back", "emplace_front", "emplace_back", "insert",
+      "emplace", "push",
+      // Basic Removal/Clearing
+      "pop_front", "pop_back", "pop", "erase", "clear",
+      // Memory Management
+      "reserve", "resize", "shrink_to_fit",
+      // Assignment (Named)
+      "assign", "swap",
+      // String Specifics
+      "append", "replace",
+      // Forward List Specifics
+      "insert_after", "emplace_after", "erase_after",
+      // List/Forward_list Splicing & Merging
+      "splice", "splice_after", "merge", "remove", "remove_if", "unique",
----------------
Xazax-hun wrote:

I believe the list operations should not invalidate existing pointers. Most 
might no even invalidate the iterators. 

https://github.com/llvm/llvm-project/pull/179093
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to