llvm / llvm/llvm-project

[CSA] False negative: allocations reachable only through a destroyed owner are not reported

Open
#214,226 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

clang:static analyzer false-negative
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Hi, I found a family of false negatives in `cplusplus.NewDeleteLeaks`.

## Program

```cpp
struct Owner {
int *member;
Owner() : member(new int(42)) {}
};

void test() {
Owner *owner = new Owner;
delete owner;
}
```

`Owner` has no destructor that releases `member`. Deleting `owner` therefore makes the second allocation unreachable, but CSA emits no `cplusplus.NewDeleteLeaks` diagnostic.

The same behavior occurs for a linked-list child, pointer members inherited by a derived object, an omitted member in an explicit destructor, and objects stored in a dynamically allocated pointer array before only that array is deleted.

## CSA reproduction

```sh
clang++ --analyze \
-Xclang -analyzer-checker=cplusplus.NewDeleteLeaks \
owned_pointer_member_leak.cpp
```

## Comparison with related programs

A direct discarded allocation is reported:

```cpp
void direct_leak() {
new int(42); // warning: potential memory leak
}
```

The missed program stores the allocation only inside an owner object. After the owner is deleted, the member allocation is unreachable, but no leak is reported:

```cpp
struct Owner {
int *member;
Owner() : member(new int(42)) {}
};

void test() {
Owner *owner = new Owner;
delete owner; // no warning for owner->member
}
```

## Runtime confirmation

An instrumented variant that replaces global `operator new` and `operator delete` with allocation counters leaves exactly one allocation outstanding after deleting the owner. The assertion succeeds when the program is executed.

## Expected result

When an owner object is destroyed without releasing allocations that are only reachable through its fields, `cplusplus.NewDeleteLeaks` should report those allocations as leaks.

## Verification

CSA version:

```text
clang version 24.0.0git (https://github.com/llvm/llvm-project.git 1cb7e838cd47ecad4050948c0c907ecb1f466ac3)
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with clang++ and the cplusplus.NewDeleteLeaks checker on owned_pointer_member_leak.cpp. Compare the direct discarded allocation with the Owner example and the listed linked-list, inherited-member, explicit-destructor, and pointer-array cases. Done means the checker reports allocations that become unreachable when their owner is destroyed.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.