[clang] [analyzer] Don't invalidate pointee of pointer-to-const on callback arguments (PR #225489)

Benedek Kaibas via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 15 08:47:26 PDT 2026


================
@@ -3886,22 +3814,130 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
     return true;
   }
 
-  // Handle cases where we know a buffer's /address/ can escape.
-  // Note that the above checks handle some special cases where we know that
-  // even though the address escapes, it's still our responsibility to free the
-  // buffer.
-  if (Call->argumentsMayEscape())
+  // 'int pthread_setspecific(ptheread_key k, const void *)' stores a
+  // value into thread local storage. The value can later be retrieved with
+  // 'void *ptheread_getspecific(pthread_key)'. So even thought the
+  // parameter is 'const void *', the region escapes through the call.
+  if (II->isStr("pthread_setspecific"))
+    return true;
+
+  // xpc_connection_set_context stores a value which can be retrieved later
+  // with xpc_connection_get_context.
+  if (II->isStr("xpc_connection_set_context"))
+    return true;
+
+  // __cxa_demangle can reallocate memory and can return the pointer to
+  // the input buffer.
+  if (II->isStr("__cxa_demangle"))
+    return true;
+
+  // NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
+  // be deallocated by NSMapRemove.
+  if (FName.starts_with("NS") && FName.contains("Insert"))
+    return true;
+
+  // Many CF containers allow objects to escape through custom
+  // allocators/deallocators upon container construction. (PR12101)
+  if (FName.starts_with("CF") || FName.starts_with("CG")) {
+    return FName.contains_insensitive("InsertValue") ||
+           FName.contains_insensitive("AddValue") ||
+           FName.contains_insensitive("SetValue") ||
+           FName.contains_insensitive("WithData") ||
+           FName.contains_insensitive("AppendValue") ||
+           FName.contains_insensitive("SetAttribute");
+  }
+  if (Call.hasNonZeroCallbackArg() || Call.hasVoidPointerToNonConstArg())
+    return true;
+  return false;
+}
+
+static bool mayEscapeThroughKnownObjCAPI(const CallEvent &Call,
+                                         SymbolRef &EscapingSymbol) {
+  // Check Objective-C messages by selector name.
+  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
----------------
benedekaibas wrote:

Applied changes here: [0379a58](https://github.com/llvm/llvm-project/pull/225489/commits/0379a588101730f0c5d3a83fd8652d17661a60c8)

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


More information about the cfe-commits mailing list