[clang] [analyzer] Fix crash when casting the result of a malformed fptr call (PR #111390)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 08:07:40 PDT 2024
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/111390
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
>From fce8354901c8831408ee2dd46373401df6185e9d Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Mon, 7 Oct 2024 17:00:04 +0200
Subject: [PATCH] [analyzer] Fix crash when casting the result of a malformed
fptr call
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
---
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 12 ++++++------
clang/test/Analysis/range_casts.c | 9 +++++++++
2 files changed, 15 insertions(+), 6 deletions(-)
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
+}
More information about the cfe-commits
mailing list