Skip to content

[analyzer] Fix crash when casting the result of a malformed fptr call #111390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 9, 2024
Merged

[analyzer] Fix crash when casting the result of a malformed fptr call #111390

merged 1 commit into from
Oct 9, 2024

Conversation

steakhal
Copy link
Contributor

@steakhal steakhal commented Oct 7, 2024

Ideally, we wouldn't workaround our current cast-modeling, but the experimental "support-symbolic-integer-casts" is not finished so we need to live with our current modeling.

Ideally, we could probably bind UndefinedVal as the result of the call even without evaluating the call, as the result types mismatch between the static type of the CallExpr and the actually function that happens to be called.

Nevertheless, let's not crash.
https://compiler-explorer.com/z/WvcqK6MbY

CPP-5768

Ideally, we wouldn't workaround our current cast-modeling, but the
experimental "support-symbolic-integer-casts" is not finished so we need
to live with our current modeling.

Ideally, we could probably bind UndefinedVal as the result of the call
even without evaluating the call, as the result types mismatch between
the static type of the CallExpr and the actualy function that happens to
be called.

Nevertheless, let's not crash.

CPP-5768
@steakhal steakhal requested a review from NagyDonat October 7, 2024 15:07
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 7, 2024

@llvm/pr-subscribers-clang

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

Author: Balazs Benics (steakhal)

Changes

Ideally, we wouldn't workaround our current cast-modeling, but the experimental "support-symbolic-integer-casts" is not finished so we need to live with our current modeling.

Ideally, we could probably bind UndefinedVal as the result of the call even without evaluating the call, as the result types mismatch between the static type of the CallExpr and the actually function that happens to be called.

Nevertheless, let's not crash.
https://compiler-explorer.com/z/WvcqK6MbY

CPP-5768


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

2 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+6-6)
  • (modified) clang/test/Analysis/range_casts.c (+9)
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index cb5fcbade2cfc2..92e9d245520345 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -600,8 +600,9 @@ SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
   if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy))
     return evalCast(val, castTy, originalTy);
 
-  SymbolRef se = val.getAsSymbol();
-  if (!se) // Let evalCast handle non symbolic expressions.
+  auto AsNonLoc = val.getAs<NonLoc>();
+  SymbolRef AsSymbol = val.getAsSymbol();
+  if (!AsSymbol || !AsNonLoc) // Let evalCast handle non symbolic expressions.
     return evalCast(val, castTy, originalTy);
 
   // Find the maximum value of the target type.
@@ -613,15 +614,14 @@ SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
 
   // Check the range of the symbol being casted against the maximum value of the
   // target type.
-  NonLoc FromVal = val.castAs<NonLoc>();
   QualType CmpTy = getConditionType();
-  NonLoc CompVal =
-      evalBinOpNN(state, BO_LE, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>();
+  NonLoc CompVal = evalBinOpNN(state, BO_LE, *AsNonLoc, ToTypeMaxVal, CmpTy)
+                       .castAs<NonLoc>();
   ProgramStateRef IsNotTruncated, IsTruncated;
   std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
   if (!IsNotTruncated && IsTruncated) {
     // Symbol is truncated so we evaluate it as a cast.
-    return makeNonLoc(se, originalTy, castTy);
+    return makeNonLoc(AsSymbol, originalTy, castTy);
   }
   return evalCast(val, castTy, originalTy);
 }
diff --git a/clang/test/Analysis/range_casts.c b/clang/test/Analysis/range_casts.c
index b1967730bf8613..8a3b610fd63dc1 100644
--- a/clang/test/Analysis/range_casts.c
+++ b/clang/test/Analysis/range_casts.c
@@ -154,3 +154,12 @@ void f15(long foo)
   else
     clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
 }
+
+int *getIntPtr(void) {
+  extern int *intPtr;
+  return intPtr;
+}
+char call_malformed_fptr() {
+  int (*fptr)(void) = (int (*)(void))getIntPtr;
+  return fptr(); // no-crash
+}

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.

LGTM. Let's not crash.

@steakhal steakhal merged commit 068d76b into llvm:main Oct 9, 2024
12 checks passed
@steakhal steakhal deleted the bb/cpp-5768-eval-cast-crash branch October 9, 2024 09:40
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.

3 participants