MTC created this revision. MTC added reviewers: xazax.hun, NoQ, george.karpenkov. Herald added subscribers: mikhail.ramalho, a.sidorin, rnkovacs, szepet.
`CallDecription` can only handle function for the time being. If we want to match c++ method, we can only use method name to match and can't improve the matching accuracy through the qualifiers. Repository: rC Clang https://reviews.llvm.org/D48027 Files: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h lib/StaticAnalyzer/Core/CallEvent.cpp Index: lib/StaticAnalyzer/Core/CallEvent.cpp =================================================================== --- lib/StaticAnalyzer/Core/CallEvent.cpp +++ lib/StaticAnalyzer/Core/CallEvent.cpp @@ -60,6 +60,7 @@ #include "llvm/Support/raw_ostream.h" #include <cassert> #include <utility> +#include <iostream> #define DEBUG_TYPE "static-analyzer-call-event" @@ -256,11 +257,18 @@ 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 auto *ND = dyn_cast_or_null<NamedDecl>(getDecl()); + if (!ND) + return false; + if (!CD.matchQualifiedName(ND->getQualifiedNameAsString())) + return false; return (CD.RequiredArgs == CallDescription::NoArgRequirement || CD.RequiredArgs == getNumArgs()); } Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -45,6 +45,7 @@ #include <cassert> #include <limits> #include <utility> +#include <iostream> namespace clang { @@ -79,6 +80,8 @@ mutable IdentifierInfo *II = nullptr; mutable bool IsLookupDone = false; + // Represent the function name or method name, like "c_str" or + // "std::string::c_str". StringRef FuncName; unsigned RequiredArgs; @@ -96,7 +99,25 @@ : FuncName(FuncName), RequiredArgs(RequiredArgs) {} /// Get the name of the function that this object matches. - StringRef getFunctionName() const { return FuncName; } + StringRef getFunctionName() const { + auto QualifierNamePair = FuncName.rsplit("::"); + return QualifierNamePair.second.empty() ? QualifierNamePair.first + : QualifierNamePair.second; + } + + bool matchQualifiedName(llvm::StringRef QualifiedName) const { + llvm::SmallVector<llvm::StringRef, 2> Names; + // Split the function name with the separator "::". + FuncName.split(Names, "::"); + + // FIXME: Since there is no perfect way to get the qualified name without + // template argument, we can only use a fuzzy matching approach. + for (auto item : Names) + if (QualifiedName.find(item) == StringRef::npos) + return false; + + return true; + } }; template<typename T = CallEvent>
Index: lib/StaticAnalyzer/Core/CallEvent.cpp =================================================================== --- lib/StaticAnalyzer/Core/CallEvent.cpp +++ lib/StaticAnalyzer/Core/CallEvent.cpp @@ -60,6 +60,7 @@ #include "llvm/Support/raw_ostream.h" #include <cassert> #include <utility> +#include <iostream> #define DEBUG_TYPE "static-analyzer-call-event" @@ -256,11 +257,18 @@ 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 auto *ND = dyn_cast_or_null<NamedDecl>(getDecl()); + if (!ND) + return false; + if (!CD.matchQualifiedName(ND->getQualifiedNameAsString())) + return false; return (CD.RequiredArgs == CallDescription::NoArgRequirement || CD.RequiredArgs == getNumArgs()); } Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -45,6 +45,7 @@ #include <cassert> #include <limits> #include <utility> +#include <iostream> namespace clang { @@ -79,6 +80,8 @@ mutable IdentifierInfo *II = nullptr; mutable bool IsLookupDone = false; + // Represent the function name or method name, like "c_str" or + // "std::string::c_str". StringRef FuncName; unsigned RequiredArgs; @@ -96,7 +99,25 @@ : FuncName(FuncName), RequiredArgs(RequiredArgs) {} /// Get the name of the function that this object matches. - StringRef getFunctionName() const { return FuncName; } + StringRef getFunctionName() const { + auto QualifierNamePair = FuncName.rsplit("::"); + return QualifierNamePair.second.empty() ? QualifierNamePair.first + : QualifierNamePair.second; + } + + bool matchQualifiedName(llvm::StringRef QualifiedName) const { + llvm::SmallVector<llvm::StringRef, 2> Names; + // Split the function name with the separator "::". + FuncName.split(Names, "::"); + + // FIXME: Since there is no perfect way to get the qualified name without + // template argument, we can only use a fuzzy matching approach. + for (auto item : Names) + if (QualifiedName.find(item) == StringRef::npos) + return false; + + return true; + } }; template<typename T = CallEvent>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits