Author: guillem-bartrina-sonarsource
Date: 2025-11-17T13:00:10+01:00
New Revision: fdbb888db53f156699ba3a94d5a0ce2005fd6e3c

URL: 
https://github.com/llvm/llvm-project/commit/fdbb888db53f156699ba3a94d5a0ce2005fd6e3c
DIFF: 
https://github.com/llvm/llvm-project/commit/fdbb888db53f156699ba3a94d5a0ce2005fd6e3c.diff

LOG: [analyzer] StdVariantChecker: fix crashes and incorrect retrieval of 
template arguments (#167341)

Although very unusual, the SVal of the argument is not checked for
UnknownVal, so we may get a null pointer dereference.

In addition, the template arguments of the variant are retrieved
incorrectly when type aliases are involved, causing crashes and FPs/FNs.

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 db8bbee8761d5..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<ArrayRef<TemplateArgument>>
 getTemplateArgsFromVariant(const Type *VariantType) {
   const auto *TempSpecType = VariantType->getAs<TemplateSpecializationType>();
+  while (TempSpecType && TempSpecType->isTypeAlias())
+    TempSpecType =
+        TempSpecType->getAliasedType()->getAs<TemplateSpecializationType>();
   if (!TempSpecType)
     return {};
 
@@ -219,10 +222,12 @@ class StdVariantChecker : public Checker<eval::Call, 
check::RegionChanges> {
   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..5b256b0f60dd0 100644
--- a/clang/test/Analysis/std-variant-checker.cpp
+++ b/clang/test/Analysis/std-variant-checker.cpp
@@ -355,4 +355,31 @@ void nonInlineFunctionCallPtr() {
   char c = std::get<char> (v); // no-warning
   (void)a;
   (void)c;
-}
\ No newline at end of file
+}
+
+// 
----------------------------------------------------------------------------//
+// Misc
+// 
----------------------------------------------------------------------------//
+
+void unknownVal() {
+  // force the argument to be UnknownVal
+  (void)std::get<int>(*(std::variant<int, float>*)(int)3.14f); // no crash
+}
+
+template <typename T>
+using MyVariant = std::variant<int, float>;
+
+void typeAlias() {
+  MyVariant<bool> v;
+
+  (void)std::get<int>(v); // no-warning
+}
+
+template <template<typename> typename Container>
+using MySpecialVariant = std::variant<int, float>;
+
+void complexTypeAlias() {
+  MySpecialVariant<std::vector> v;
+
+  (void)std::get<int>(v); // no crash
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to