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 <benicsbal...@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 +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits