[llvm-branch-commits] [clang] e23de94 - [analyzer] Fix StdVariantChecker crash on std::get with a non-ptr arg (#210167)
Douglas Yung via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jul 22 07:02:01 PDT 2026
Author: John Paul Jepko
Date: 2026-07-22T14:01:46Z
New Revision: e23de9497b1f3b44a7a6b8e9dc1002496485e242
URL: https://github.com/llvm/llvm-project/commit/e23de9497b1f3b44a7a6b8e9dc1002496485e242
DIFF: https://github.com/llvm/llvm-project/commit/e23de9497b1f3b44a7a6b8e9dc1002496485e242.diff
LOG: [analyzer] Fix StdVariantChecker crash on std::get with a non-ptr arg (#210167)
When `std::get` is called on a dereferenced integer-to-pointer cast, the
checker `alpha.core.StdVariant` crashes. Minimal reproducer:
```
std::get<int>(*(std::variant<int, char> *)11);
```
Godbolt reproducer - https://godbolt.org/z/4EKe1PrKb
The root cause is that `StdVariantChecker::handleStdGetCall()` calls
`SVal::getType()` on any non-unknown argument, then calls
`getPointeeType()` on the result while assuming it is a pointer type. In
the case of a concrete integer cast to a pointer and then dereferenced,
it is modeled as `loc::ConcreteInt`, whose recovered type is an integer.
`getPointeeType()` on such an input returns a null QualType, on which
`getTypePtr()` crashes.
Fix the crash by using the argument's static type rather than recovering
its SVal, eliminating the need to guard and call `getPointeeType()`.
(cherry picked from commit accd1ed5226b4a8009c33f0a6d1bcfe58902f69e)
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
clang/test/Analysis/std-variant-checker.cpp
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
index e46eddf3804b2..c63717c52c0d6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
@@ -222,12 +222,7 @@ class StdVariantChecker : public Checker<eval::Call, check::RegionChanges> {
bool handleStdGetCall(const CallEvent &Call, CheckerContext &C) const {
ProgramStateRef State = C.getState();
- SVal ArgSVal = Call.getArgSVal(0);
- if (ArgSVal.isUnknown())
- return false;
-
- const auto &ArgType =
- ArgSVal.getType(C.getASTContext())->getPointeeType().getTypePtr();
+ const auto *ArgType = Call.getArgExpr(0)->getType().getTypePtr();
// We have to make sure that the argument is an std::variant.
// There is another std::get with std::pair argument
if (!isStdVariant(ArgType))
diff --git a/clang/test/Analysis/std-variant-checker.cpp b/clang/test/Analysis/std-variant-checker.cpp
index 5b256b0f60dd0..452ea41f2a669 100644
--- a/clang/test/Analysis/std-variant-checker.cpp
+++ b/clang/test/Analysis/std-variant-checker.cpp
@@ -366,6 +366,10 @@ void unknownVal() {
(void)std::get<int>(*(std::variant<int, float>*)(int)3.14f); // no crash
}
+void concreteAddress() {
+ (void)std::get<int>(*(std::variant<int, char>*)11); // no crash
+}
+
template <typename T>
using MyVariant = std::variant<int, float>;
More information about the llvm-branch-commits
mailing list