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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits