[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 Sep 24 05:04:37 PDT 2026


================
@@ -3940,7 +3940,8 @@ ProgramStateRef MallocChecker::checkPointerEscapeAux(
 
     if (const RefState *RS = State->get<RegionState>(sym))
       if (RS->isAllocated() || RS->isAllocatedOfSizeZero())
-        if (!IsConstPointerEscape || checkIfNewOrNewArrayFamily(RS))
+        if (!IsConstPointerEscape || checkIfNewOrNewArrayFamily(RS) ||
+            (Call && Call->argumentsMayEscape()))
----------------
benedekaibas wrote:

Yes, there are multiple ones failing.

```text
# |   File /Users/benedekaibas/Documents/llvm-project/clang/test/Analysis/malloc.cpp Line 72: Potential leak of memory pointed to by 'x' [unix.Malloc]
# |   File /Users/benedekaibas/Documents/llvm-project/clang/test/Analysis/malloc.cpp Line 88: Potential leak of memory pointed to by 'x' [unix.Malloc]
```
Here is the link for it: https://github.com/llvm/llvm-project/blob/f96febaf2701fc5f1979a4e0b49bdd97cae3fdb6/clang/test/Analysis/malloc.cpp#L68

My fix also does not overcorrect into supressing genuine use-after-free's. I rewrote the test case to actually hit uaf and make sure that an inlined callback invocation still reports ua:
```cpp
void const_ptr_and_callback_def_param(int, const char* cs, int n, void (*f)(void*) = free) {
  char *s = const_cast<char *>(cs);
  void *stat_v = static_cast<void *>(s);
  f(stat_v);
}

void r11160612_3() {
  char *x = (char*)malloc(12);
  const_ptr_and_callback_def_param(0, x, 12);
  *x = 7;
}
```
(my fix works with this case)

There are also multiple other failures in `malloc.mm`:
```cpp
static void releaseDataCallback (void *info, const void *data, size_t size) {
#pragma unused (info, size)
  free((void*)data);
}

// Assume that functions which take a function pointer can free memory even if
// they are defined in system headers and take the const pointer to the
// allocated memory.
extern CGDataProviderRef UnknownFunWithCallback(void *info,
    const void *data, size_t size,
    CGDataProviderReleaseDataCallback releaseData)
    __attribute__((visibility("default")));
void testUnknownFunWithCallBack() { 
  void* b = calloc(8, 8);
  CGDataProviderRef p = UnknownFunWithCallback(0, b, 8*8, releaseDataCallback); // warning here
}
```

I have traced through all the cases and they are similar to each other. 

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


More information about the cfe-commits mailing list