[DRAFT] [clang] translate if constexpr and constant expressions by their compile-time value - #2166
Draft
VladimirMakaev wants to merge 1 commit into
Draft
VladimirMakaev wants to merge 1 commit into
VladimirMakaev wants to merge 1 commit into
Conversation
VladimirMakaev
force-pushed
the
clang-constexpr-if
branch
from
October 3, 2026 21:52
b574efd to
19a7718
Compare
…ile-time value
The frontend translated `if constexpr` as a run-time `if`, and constant expressions (case labels,
enumerators, `consteval` calls) as run-time code. When a condition reads untranslated library
code, Pulse explores the branch that clang discarded.
```cpp
#include <limits>
template <typename T>
int* if_signed(int* p) {
if constexpr (std::numeric_limits<T>::is_signed) {
return p;
} else {
return nullptr;
}
}
void deref_unsigned_bad(int* p) {
*if_signed<unsigned>(p) = 1; // Infer missed: null dereference
}
```
The clang plugin now exports `IfStmt::isConstexpr()` and the integer value of a `ConstantExpr`,
which the frontend translates. It drops the discarded branch rather than pruning it, so checkers
that are not path-sensitive ignore it too (RacerD no longer reports lock consistency violations
for locks in disabled branches), and locals read only there are not dead stores. Enumerator
initializers that call functions no longer leave a dangling identifier. Code using magic_enum is
analyzed 3x to 30x faster when its headers are inside `--project-root`.
## Test plan
New tests in `cpp/{frontend,pulse}-17`, `cpp/{frontend,pulse,liveness}-20` and the plugin's
`constant_expr.cpp`. Enumerators become literals in `c/frontend/enumeration`;
`c/bufferoverrun/global.c` loses a false positive and gains CONDITION_ALWAYS_TRUE/FALSE
expectations (disabled by default).
VladimirMakaev
force-pushed
the
clang-constexpr-if
branch
from
October 5, 2026 06:53
19a7718 to
9687c19
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The frontend translated
if constexpras a run-timeif, and constant expressions (case labels,enumerators,
constevalcalls) as run-time code. When a condition reads untranslated librarycode, Pulse explores the branch that clang discarded.
The clang plugin now exports
IfStmt::isConstexpr()and the integer value of aConstantExpr,which the frontend translates. It drops the discarded branch rather than pruning it, so checkers
that are not path-sensitive ignore it too (RacerD no longer reports lock consistency violations
for locks in disabled branches), and locals read only there are not dead stores. Enumerator
initializers that call functions no longer leave a dangling identifier. Code using magic_enum is
analyzed 3x to 30x faster when its headers are inside
--project-root.Test plan
New tests in
cpp/{frontend,pulse}-17,cpp/{frontend,pulse,liveness}-20and the plugin'sconstant_expr.cpp. Enumerators become literals inc/frontend/enumeration;c/bufferoverrun/global.closes a false positive and gains CONDITION_ALWAYS_TRUE/FALSEexpectations (disabled by default).