MTC updated this revision to Diff 151166.
MTC added a comment.

- Use `hasName` matcher to match the qualified name.
- Use the full name, like `std::basic_string<char>::c_str` instead of `c_str` 
to match the `c_str` method in `DanglingInternalBufferChecker.cpp`.




Repository:
  rC Clang

https://reviews.llvm.org/D48027

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
  lib/StaticAnalyzer/Core/CallEvent.cpp

Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -28,6 +28,7 @@
 #include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/ProgramPoint.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/CrossTU/CrossTranslationUnit.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
@@ -65,6 +66,7 @@
 
 using namespace clang;
 using namespace ento;
+using namespace clang::ast_matchers;
 
 QualType CallEvent::getResultType() const {
   ASTContext &Ctx = getState()->getStateManager().getContext();
@@ -256,11 +258,24 @@
     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 NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl());
+  if (!ND)
+    return false;
+
+  auto Matches =
+      match(namedDecl(hasName(CD.FuncName)).bind("match_qualified_name"), *ND,
+            LCtx->getAnalysisDeclContext()->getASTContext());
+
+  if (Matches.empty())
+    return false;
+
   return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
           CD.RequiredArgs == getNumArgs());
 }
Index: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
+++ lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
@@ -13,26 +13,28 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "AllocationState.h"
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "AllocationState.h"
+#include "llvm/ADT/SmallVector.h"
 
 using namespace clang;
 using namespace ento;
 
 namespace {
 
 class DanglingInternalBufferChecker : public Checker<check::DeadSymbols,
                                                      check::PostCall> {
-  CallDescription CStrFn;
+  const llvm::SmallVector<CallDescription, 4> CStrFnFamily = {
+    {"std::basic_string<char>::c_str"}, {"std::basic_string<char32_t>::c_str"},
+    {"std::basic_string<char16_t>::c_str"},
+    {"std::basic_string<wchar_t>::c_str"}};
 
 public:
-  DanglingInternalBufferChecker() : CStrFn("c_str") {}
-
   /// Record the connection between the symbol returned by c_str() and the
   /// corresponding string object region in the ProgramState. Mark the symbol
   /// released if the string object is destroyed.
@@ -65,7 +67,15 @@
 
   ProgramStateRef State = C.getState();
 
-  if (Call.isCalled(CStrFn)) {
+  auto isCStrFnFamilyCall = [&](const CallEvent &Call) -> bool {
+    for (auto CStrFn : CStrFnFamily) {
+      if (Call.isCalled(CStrFn))
+        return true;
+    }
+    return false;
+  };
+
+  if (isCStrFnFamilyCall(Call)) {
     SVal RawPtr = Call.getReturnValue();
     if (!RawPtr.isUnknown()) {
       State = State->set<RawPtrMap>(TypedR, RawPtr.getAsSymbol());
Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -79,6 +79,7 @@
 
   mutable IdentifierInfo *II = nullptr;
   mutable bool IsLookupDone = false;
+  // Represent the function name or method name, like "X" or "a::b::X".
   StringRef FuncName;
   unsigned RequiredArgs;
 
@@ -96,7 +97,11 @@
       : 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;
+  }
 };
 
 template<typename T = CallEvent>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to