summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CallEvent.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index b1688184d87..3ba68d4cdd2 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -359,11 +359,38 @@ bool CallEvent::isCalled(const CallDescription &CD) const {
return false;
if (!CD.IsLookupDone) {
CD.IsLookupDone = true;
- CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName);
+ CD.II = &getState()->getStateManager().getContext().Idents.get(
+ CD.getFunctionName());
}
const IdentifierInfo *II = getCalleeIdentifier();
if (!II || II != CD.II)
return false;
+
+ const Decl *D = getDecl();
+ // If CallDescription provides prefix names, use them to improve matching
+ // accuracy.
+ if (CD.QualifiedName.size() > 1 && D) {
+ const DeclContext *Ctx = D->getDeclContext();
+ std::vector<StringRef> QualifiedName = CD.QualifiedName;
+ QualifiedName.pop_back();
+ for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
+ if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {
+ if (!QualifiedName.empty() && ND->getName() == QualifiedName.back())
+ QualifiedName.pop_back();
+ continue;
+ }
+
+ if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {
+ if (!QualifiedName.empty() && RD->getName() == QualifiedName.back())
+ QualifiedName.pop_back();
+ continue;
+ }
+ }
+
+ if (!QualifiedName.empty())
+ return false;
+ }
+
return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
CD.RequiredArgs == getNumArgs());
}
OpenPOWER on IntegriCloud