aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-11-12 23:40:29 +0000
committerAnna Zaks <ganna@apple.com>2012-11-12 23:40:29 +0000
commitd51db4935736fd943bfd46dfa74d41e9a3c2d41f (patch)
tree928fcb55fa1083e7b035c7cd63dac668f5cb0e0e /lib/StaticAnalyzer
parente7ce7094602ebb341220467c9a1d6643f45b9595 (diff)
[analyzer] Follow up to r167762 - precisely determine the adjustment
conditions. The adjustment is needed only in case of dynamic dispatch performed by the analyzer - when the runtime declaration is different from the static one. Document this explicitly in the code (by adding a helper). Also, use canonical Decls to avoid matching against the case where the definition is different from found declaration. This fix suppresses the testcase I added in r167762, so add another testcase to make sure we do test commit r167762. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167780 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 5b88a45495..2e47a9a61c 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -191,6 +191,15 @@ void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC,
currBldrCtx = 0;
}
+static bool isDifferentDeclUsedAtRuntime(CallEventRef<> Call,
+ const StackFrameContext *calleeCtx) {
+ const Decl *RuntimeCallee = calleeCtx->getDecl();
+ const Decl *StaticDecl = Call->getDecl();
+ if (!RuntimeCallee || !StaticDecl)
+ return false;
+ return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
+}
+
/// The call exit is simulated with a sequence of nodes, which occur between
/// CallExitBegin and CallExitEnd. The following operations occur between the
/// two program points:
@@ -230,9 +239,10 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
const LocationContext *LCtx = CEBNode->getLocationContext();
SVal V = state->getSVal(RS, LCtx);
- const Decl *Callee = calleeCtx->getDecl();
- if (Callee != Call->getDecl()) {
- QualType ReturnedTy = CallEvent::getDeclaredResultType(Callee);
+ // Ensure that the return type matches the type of the returned Expr.
+ if (isDifferentDeclUsedAtRuntime(Call, calleeCtx)) {
+ QualType ReturnedTy =
+ CallEvent::getDeclaredResultType(calleeCtx->getDecl());
if (!ReturnedTy.isNull()) {
if (const Expr *Ex = dyn_cast<Expr>(CE)) {
V = adjustReturnValue(V, Ex->getType(), ReturnedTy,