[CSA] False positive: initialization of a `volatile` local from an lvalue is reported as a dead store
- 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
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