[clang] [analyzer] Fix crash when casting the result of a malformed fptr call (PR #111390)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 08:08:03 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-static-analyzer-1
Author: Balazs Benics (steakhal)
<details>
<summary>Changes</summary>
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
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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/111390
More information about the cfe-commits
mailing list