diff options
author | Anna Zaks <ganna@apple.com> | 2012-11-12 23:40:29 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-11-12 23:40:29 +0000 |
commit | d51db4935736fd943bfd46dfa74d41e9a3c2d41f (patch) | |
tree | 928fcb55fa1083e7b035c7cd63dac668f5cb0e0e /lib/StaticAnalyzer | |
parent | e7ce7094602ebb341220467c9a1d6643f45b9595 (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.cpp | 16 |
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, |