From e6a800f0aa4d040d9618da1ca98cc7a53a951520 Mon Sep 17 00:00:00 2001 From: guillem-bartrina-sonarsource Date: Mon, 10 Nov 2025 17:35:54 +0100 Subject: [PATCH 1/2] StdVariantChecker: fix crash when argument to std::get is UnknownVal --- .../StaticAnalyzer/Checkers/StdVariantChecker.cpp | 10 ++++++---- clang/test/Analysis/std-variant-checker.cpp | 13 ++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp index db8bbee8761d5..805f64f4804cf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp @@ -219,10 +219,12 @@ class StdVariantChecker : public Checker { bool handleStdGetCall(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); - const auto &ArgType = Call.getArgSVal(0) - .getType(C.getASTContext()) - ->getPointeeType() - .getTypePtr(); + SVal ArgSVal = Call.getArgSVal(0); + if (ArgSVal.isUnknown()) + return false; + + const auto &ArgType = + ArgSVal.getType(C.getASTContext())->getPointeeType().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 7f136c06b19cc..fbb69327e1de5 100644 --- a/clang/test/Analysis/std-variant-checker.cpp +++ b/clang/test/Analysis/std-variant-checker.cpp @@ -355,4 +355,15 @@ void nonInlineFunctionCallPtr() { char c = std::get (v); // no-warning (void)a; (void)c; -} \ No newline at end of file +} + +// ----------------------------------------------------------------------------// +// Misc +// ----------------------------------------------------------------------------// + +using uintptr_t = unsigned long long; + +void unknownVal() { + // force the argument to be UnknownVal + (void)std::get(*(std::variant*)(uintptr_t)3.14f); // no crash +} From 14ef26cafbcb4ca53c46b0989c52783396492dd6 Mon Sep 17 00:00:00 2001 From: guillem-bartrina-sonarsource Date: Wed, 12 Nov 2025 12:10:09 +0100 Subject: [PATCH 2/2] StdVariantChecker: the variant template arguments are retrieved incorrectly when type aliases are involved, causing crashes and FPs/FNs --- .../Checkers/StdVariantChecker.cpp | 3 +++ clang/test/Analysis/std-variant-checker.cpp | 22 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp index 805f64f4804cf..c5dad610bef53 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp @@ -90,6 +90,9 @@ bool isStdVariant(const Type *Type) { static std::optional> getTemplateArgsFromVariant(const Type *VariantType) { const auto *TempSpecType = VariantType->getAs(); + while (TempSpecType && TempSpecType->isTypeAlias()) + TempSpecType = + TempSpecType->getAliasedType()->getAs(); if (!TempSpecType) return {}; diff --git a/clang/test/Analysis/std-variant-checker.cpp b/clang/test/Analysis/std-variant-checker.cpp index fbb69327e1de5..5b256b0f60dd0 100644 --- a/clang/test/Analysis/std-variant-checker.cpp +++ b/clang/test/Analysis/std-variant-checker.cpp @@ -361,9 +361,25 @@ void nonInlineFunctionCallPtr() { // Misc // ----------------------------------------------------------------------------// -using uintptr_t = unsigned long long; - void unknownVal() { // force the argument to be UnknownVal - (void)std::get(*(std::variant*)(uintptr_t)3.14f); // no crash + (void)std::get(*(std::variant*)(int)3.14f); // no crash +} + +template +using MyVariant = std::variant; + +void typeAlias() { + MyVariant v; + + (void)std::get(v); // no-warning +} + +template typename Container> +using MySpecialVariant = std::variant; + +void complexTypeAlias() { + MySpecialVariant v; + + (void)std::get(v); // no crash }