From 948163b4986dfb5060c0dbd2e5910431640e56d1 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 15 Nov 2010 20:09:42 +0000 Subject: [PATCH] Relax assertion in SValuator so that we don't crash when analyzing a call via a function pointer that casts the return value to something completely different. While we need better reasoning here, we should definately not crash. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119177 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Checker/SValuator.cpp | 13 ++++++++++++- test/Analysis/misc-ps.m | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/Checker/SValuator.cpp b/lib/Checker/SValuator.cpp index 273e5742a8..a3bdcd7762 100644 --- a/lib/Checker/SValuator.cpp +++ b/lib/Checker/SValuator.cpp @@ -122,7 +122,18 @@ SVal SValuator::EvalCast(SVal val, QualType castTy, QualType originalTy) { // FIXME: We should handle the case where we strip off view layers to get // to a desugared type. - assert(Loc::IsLocType(castTy)); + if (!Loc::IsLocType(castTy)) { + // FIXME: There can be gross cases where one casts the result of a function + // (that returns a pointer) to some other value that happens to fit + // within that pointer value. We currently have no good way to + // model such operations. When this happens, the underlying operation + // is that the caller is reasoning about bits. Conceptually we are + // layering a "view" of a location on top of those bits. Perhaps + // we need to be more lazy about mutual possible views, even on an + // SVal? This may be necessary for bit-level reasoning as well. + return UnknownVal(); + } + // We get a symbolic function pointer for a dereference of a function // pointer, but it is of function type. Example: diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 9b923bf0f8..902bfb6aae 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1193,3 +1193,13 @@ void pr5272_test() { (*(struct pr5272*)0xBC000000).var2 += 2; // no-warning } +// Support casting the return value of function to another different type +// This previously caused a crash, although we likely need more precise +// reasoning here. +void* rdar8663544(); +typedef struct {} Val8663544; +Val8663544 bazR8663544() { + Val8663544(*func) () = (Val8663544(*) ()) rdar8663544; + return func(); +} + -- 2.40.0