]> granicus.if.org Git - clang/commit
[analyzer] Adjust the return type of an inlined devirtualized method call.
authorJordan Rose <jordan_rose@apple.com>
Wed, 3 Oct 2012 01:08:35 +0000 (01:08 +0000)
committerJordan Rose <jordan_rose@apple.com>
Wed, 3 Oct 2012 01:08:35 +0000 (01:08 +0000)
commit48314cf6a289bc5a082d8c769c58a38f924c93b7
tree92dfabfb6158e16e7ebf24b6c5bd4cb87ba6493d
parentaa66b08d2d8bbf05bae8c68f58724f754ab57b35
[analyzer] Adjust the return type of an inlined devirtualized method call.

In C++, overriding virtual methods are allowed to specify a covariant
return type -- that is, if the return type of the base method is an
object pointer type (or reference type), the overriding method's return
type can be a pointer to a subclass of the original type. The analyzer
was failing to take this into account when devirtualizing a method call,
and anything that relied on the return value having the proper type later
would crash.

In Objective-C, overriding methods are allowed to specify ANY return type,
meaning we can NEVER be sure that devirtualizing will give us a "safe"
return value. Of course, a program that does this will most likely crash
at runtime, but the analyzer at least shouldn't crash.

The solution is to check and see if the function/method being inlined is
the function that static binding would have picked. If not, check that
the return value has the same type. If the types don't match, see if we
can fix it with a derived-to-base cast (the C++ case). If we can't,
return UnknownVal to avoid crashing later.

<rdar://problem/12409977>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165079 91177308-0d34-0410-b5e6-96231b3b80d8
lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
test/Analysis/inline.cpp
test/Analysis/inlining/InlineObjCInstanceMethod.m