r366391 - [analyzer] MallocChecker: Prevent Integer Set Library false positives
Csaba Dabis via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 17 17:03:56 PDT 2019
Author: charusso
Date: Wed Jul 17 17:03:55 2019
New Revision: 366391
URL: http://llvm.org/viewvc/llvm-project?rev=366391&view=rev
Log:
[analyzer] MallocChecker: Prevent Integer Set Library false positives
Summary:
Integer Set Library using retain-count based allocation which is not
modeled in MallocChecker.
Reviewed By: NoQ
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64680
Added:
cfe/trunk/test/Analysis/retain-count-alloc.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=366391&r1=366390&r2=366391&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Wed Jul 17 17:03:55 2019
@@ -17,6 +17,7 @@
#include "clang/AST/ParentMap.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -359,6 +360,11 @@ private:
/// Check if the memory associated with this symbol was released.
bool isReleased(SymbolRef Sym, CheckerContext &C) const;
+ /// See if deallocation happens in a suspicious context. If so, escape the
+ /// pointers that otherwise would have been deallocated and return true.
+ bool suppressDeallocationsInSuspiciousContexts(const CallExpr *CE,
+ CheckerContext &C) const;
+
bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
@@ -877,6 +883,9 @@ void MallocChecker::checkPostStmt(const
State = ProcessZeroAllocation(C, CE, 0, State);
State = ProcessZeroAllocation(C, CE, 1, State);
} else if (FunI == II_free || FunI == II_g_free || FunI == II_kfree) {
+ if (suppressDeallocationsInSuspiciousContexts(CE, C))
+ return;
+
State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
} else if (FunI == II_strdup || FunI == II_win_strdup ||
FunI == II_wcsdup || FunI == II_win_wcsdup) {
@@ -2532,6 +2541,35 @@ bool MallocChecker::isReleased(SymbolRef
return (RS && RS->isReleased());
}
+bool MallocChecker::suppressDeallocationsInSuspiciousContexts(
+ const CallExpr *CE, CheckerContext &C) const {
+ if (CE->getNumArgs() == 0)
+ return false;
+
+ StringRef FunctionStr = "";
+ if (const auto *FD = dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
+ if (const Stmt *Body = FD->getBody())
+ if (Body->getBeginLoc().isValid())
+ FunctionStr =
+ Lexer::getSourceText(CharSourceRange::getTokenRange(
+ {FD->getBeginLoc(), Body->getBeginLoc()}),
+ C.getSourceManager(), C.getLangOpts());
+
+ // We do not model the Integer Set Library's retain-count based allocation.
+ if (!FunctionStr.contains("__isl_"))
+ return false;
+
+ ProgramStateRef State = C.getState();
+
+ for (const Expr *Arg : CE->arguments())
+ if (SymbolRef Sym = C.getSVal(Arg).getAsSymbol())
+ if (const RefState *RS = State->get<RegionState>(Sym))
+ State = State->set<RegionState>(Sym, RefState::getEscaped(RS));
+
+ C.addTransition(State);
+ return true;
+}
+
bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
const Stmt *S) const {
@@ -2833,7 +2871,6 @@ ProgramStateRef MallocChecker::checkPoin
if (const RefState *RS = State->get<RegionState>(sym)) {
if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) &&
CheckRefState(RS)) {
- State = State->remove<RegionState>(sym);
State = State->set<RegionState>(sym, RefState::getEscaped(RS));
}
}
Added: cfe/trunk/test/Analysis/retain-count-alloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-count-alloc.cpp?rev=366391&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/retain-count-alloc.cpp (added)
+++ cfe/trunk/test/Analysis/retain-count-alloc.cpp Wed Jul 17 17:03:55 2019
@@ -0,0 +1,37 @@
+// RUN: %clang_analyze_cc1 \
+// RUN: -analyzer-checker=core,unix.Malloc \
+// RUN: -verify %s
+
+// expected-no-diagnostics: We do not model Integer Set Library's retain-count
+// based allocation. If any of the parameters has an
+// '__isl_' prefixed macro definition we escape every
+// of them when we are about to 'free()' something.
+
+#define __isl_take
+#define __isl_keep
+
+struct Object { int Ref; };
+void free(void *);
+
+Object *copyObj(__isl_keep Object *O) {
+ O->Ref++;
+ return O;
+}
+
+void freeObj(__isl_take Object *O) {
+ if (--O->Ref > 0)
+ return;
+
+ free(O); // Here we notice that the parameter contains '__isl_', escape it.
+}
+
+void useAfterFree(__isl_take Object *A) {
+ if (!A)
+ return;
+
+ Object *B = copyObj(A);
+ freeObj(B);
+
+ A->Ref = 13;
+ // no-warning: 'Use of memory after it is freed' was here.
+}
More information about the cfe-commits
mailing list