Author: Balazs Benics Date: 2024-10-09T11:39:56+02:00 New Revision: 068d76b48093ccf8b55c4af6a6ccacfc1ce0ae53
URL: https://github.com/llvm/llvm-project/commit/068d76b48093ccf8b55c4af6a6ccacfc1ce0ae53 DIFF: https://github.com/llvm/llvm-project/commit/068d76b48093ccf8b55c4af6a6ccacfc1ce0ae53.diff LOG: [analyzer] Fix crash when casting the result of a malformed fptr call (#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 Added: Modified: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp clang/test/Analysis/range_casts.c Removed: ################################################################################ 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