Skip to content

Conversation

@guillem-bartrina-sonarsource
Copy link
Contributor

@guillem-bartrina-sonarsource guillem-bartrina-sonarsource commented Nov 10, 2025

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.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer labels Nov 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 10, 2025

@llvm/pr-subscribers-clang

Author: None (guillem-bartrina-sonarsource)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/167341.diff

2 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp (+6-4)
  • (modified) clang/test/Analysis/std-variant-checker.cpp (+12-1)
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<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..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<char> (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<int>(*(std::variant<int, float>*)(uintptr_t)3.14f); // no crash
+}

@llvmbot
Copy link
Member

llvmbot commented Nov 10, 2025

@llvm/pr-subscribers-clang-static-analyzer-1

Author: None (guillem-bartrina-sonarsource)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/167341.diff

2 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp (+6-4)
  • (modified) clang/test/Analysis/std-variant-checker.cpp (+12-1)
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<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..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<char> (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<int>(*(std::variant<int, float>*)(uintptr_t)3.14f); // no crash
+}

@guillem-bartrina-sonarsource
Copy link
Contributor Author

@steakhal

@steakhal
Copy link
Contributor

I resign from reviews for the upcoming 2 weeks. Thank you

…rectly when type aliases are involved, causing crashes and FPs/FNs
@guillem-bartrina-sonarsource guillem-bartrina-sonarsource changed the title [analyzer] StdVariantChecker: fix crash when argument to std::get is UnknownVal [analyzer] StdVariantChecker: fix crashes and incorrect retrieval of template arguments Nov 12, 2025
@NagyDonat NagyDonat requested a review from spaits November 13, 2025 13:31
Copy link
Contributor

@spaits spaits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks!

Copy link
Contributor

@NagyDonat NagyDonat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the commit, crash fixes are always welcome :) LGTM, but let's wait a few days to see if @spaits (who authored this checker) has anything to add. (EDIT: Oh, I see that he reviewed the commit just a few minutes before my review. Feel free to merge the commit.)

@guillem-bartrina-sonarsource
Copy link
Contributor Author

Thanks @NagyDonat and @spaits for the comments. I don't have permission to merge this pull request, so I'll leave it to you. Have a nice day!

@NagyDonat NagyDonat merged commit fdbb888 into llvm:main Nov 17, 2025
10 checks passed
@steakhal
Copy link
Contributor

LGTM, thanks for the reviews and the patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:static analyzer clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants