Skip to content

Commit 068d76b

Browse files
authored
[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
1 parent b2edeb5 commit 068d76b

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

clang/lib/StaticAnalyzer/Core/SValBuilder.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,9 @@ SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
600600
if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy))
601601
return evalCast(val, castTy, originalTy);
602602

603-
SymbolRef se = val.getAsSymbol();
604-
if (!se) // Let evalCast handle non symbolic expressions.
603+
auto AsNonLoc = val.getAs<NonLoc>();
604+
SymbolRef AsSymbol = val.getAsSymbol();
605+
if (!AsSymbol || !AsNonLoc) // Let evalCast handle non symbolic expressions.
605606
return evalCast(val, castTy, originalTy);
606607

607608
// Find the maximum value of the target type.
@@ -613,15 +614,14 @@ SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
613614

614615
// Check the range of the symbol being casted against the maximum value of the
615616
// target type.
616-
NonLoc FromVal = val.castAs<NonLoc>();
617617
QualType CmpTy = getConditionType();
618-
NonLoc CompVal =
619-
evalBinOpNN(state, BO_LE, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>();
618+
NonLoc CompVal = evalBinOpNN(state, BO_LE, *AsNonLoc, ToTypeMaxVal, CmpTy)
619+
.castAs<NonLoc>();
620620
ProgramStateRef IsNotTruncated, IsTruncated;
621621
std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
622622
if (!IsNotTruncated && IsTruncated) {
623623
// Symbol is truncated so we evaluate it as a cast.
624-
return makeNonLoc(se, originalTy, castTy);
624+
return makeNonLoc(AsSymbol, originalTy, castTy);
625625
}
626626
return evalCast(val, castTy, originalTy);
627627
}

clang/test/Analysis/range_casts.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,12 @@ void f15(long foo)
154154
else
155155
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
156156
}
157+
158+
int *getIntPtr(void) {
159+
extern int *intPtr;
160+
return intPtr;
161+
}
162+
char call_malformed_fptr() {
163+
int (*fptr)(void) = (int (*)(void))getIntPtr;
164+
return fptr(); // no-crash
165+
}

0 commit comments

Comments
 (0)