llvm / llvm/llvm-project

[CSA] False positive: initialization of a `volatile` local from an lvalue is reported as a dead store

Open
#213,756 2 comments 0 reactions 0 assignees View on GitHub
clang:static analyzer false-positive
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Hi, I found a false positive in `deadcode.DeadStores`.

CSA reports the initialization of a `volatile` local variable as a dead store when the initializer reads through a pointer or a structured binding. A write to a volatile object is an observable side effect and must not be treated as dead merely because the object is not read later.

## Program

```cpp
#include

void from_constant() {
volatile int observed = 7;
}

void from_pointer() {
int source = 7;
int *p = &source;
volatile int observed = *p;
}

void from_structured_binding() {
int values[] = {3, 5};
auto [first, second] = values;
volatile int observed = first;
(void)second;
}

int main() {
from_constant();
from_pointer();
from_structured_binding();
std::puts("ok");
return 0;
}
```

The program compiles and runs normally, printing `ok`. All three initializations perform a volatile write.

## Comparison with the equivalent direct initialization

CSA correctly emits no `deadcode.DeadStores` warning when the volatile object is initialized directly:

```cpp
volatile int observed = 7; // no warning
```

Changing only the initializer to an lvalue read causes a warning:

```cpp
int source = 7;
int *p = &source;
volatile int observed = *p; // warning: value is never read
```

The structured-binding variant behaves the same way:

```cpp
auto [first, second] = values;
volatile int observed = first; // warning: value is never read
```

For dead-store purposes these cases are equivalent: initialization writes to a volatile object, so the write is observable regardless of whether the value is a literal, a pointer dereference, or a structured-binding lvalue.

## Actual result

CSA emits two `deadcode.DeadStores` warnings:

```text
Value stored to 'observed' during its initialization is never read
Value stored to 'observed' during its initialization is never read
```

The warnings point to the two declarations of `observed`.
No warning is emitted for `volatile int observed = 7;` in `from_constant()`.

## Expected result

`deadcode.DeadStores` should not report initialization of a volatile object, because the volatile write is itself observable. Whether the initializer is an lvalue read should not change that rule.

## Verification

Run CSA:

```sh
clang++ --analyze -std=c++17 \
-Xclang -analyzer-checker=deadcode.DeadStores \
-Xclang -analyzer-output=sarif \
-o volatile_lvalue_initialization_dead_store.sarif \
volatile_lvalue_initialization_dead_store.cpp
```

Version:

```text
clang version 24.0.0git (llvm-project 1cb7e838cd47ecad4050948c0c907ecb1f466ac3)
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the issue with the provided volatile_lvalue_initialization_dead_store.cpp program and the deadcode.DeadStores CSA checker command. Compare the checker’s handling of direct and lvalue-based volatile initialization; done means the pointer and structured-binding cases no longer emit dead-store warnings while the reproducer still runs normally.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.