|
@@ -174,7 +174,10 @@ public:
|
|
|
II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr),
|
|
|
II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr),
|
|
|
II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
|
|
|
- II_wcsdup(nullptr), II_win_wcsdup(nullptr) {}
|
|
|
+ II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr),
|
|
|
+ II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr),
|
|
|
+ II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr),
|
|
|
+ II_g_free(nullptr), II_g_memdup(nullptr) {}
|
|
|
|
|
|
/// In pessimistic mode, the checker assumes that it does not know which
|
|
|
/// functions might free the memory.
|
|
@@ -236,7 +239,9 @@ private:
|
|
|
*II_realloc, *II_calloc, *II_valloc, *II_reallocf,
|
|
|
*II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc,
|
|
|
*II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
|
|
|
- *II_win_wcsdup;
|
|
|
+ *II_win_wcsdup, *II_g_malloc, *II_g_malloc0,
|
|
|
+ *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0,
|
|
|
+ *II_g_try_realloc, *II_g_free, *II_g_memdup;
|
|
|
mutable Optional<uint64_t> KernelZeroFlagVal;
|
|
|
|
|
|
void initIdentifierInfo(ASTContext &C) const;
|
|
@@ -554,6 +559,16 @@ void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
|
|
|
II_win_strdup = &Ctx.Idents.get("_strdup");
|
|
|
II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
|
|
|
II_win_alloca = &Ctx.Idents.get("_alloca");
|
|
|
+
|
|
|
+ // Glib
|
|
|
+ II_g_malloc = &Ctx.Idents.get("g_malloc");
|
|
|
+ II_g_malloc0 = &Ctx.Idents.get("g_malloc0");
|
|
|
+ II_g_realloc = &Ctx.Idents.get("g_realloc");
|
|
|
+ II_g_try_malloc = &Ctx.Idents.get("g_try_malloc");
|
|
|
+ II_g_try_malloc0 = &Ctx.Idents.get("g_try_malloc0");
|
|
|
+ II_g_try_realloc = &Ctx.Idents.get("g_try_realloc");
|
|
|
+ II_g_free = &Ctx.Idents.get("g_free");
|
|
|
+ II_g_memdup = &Ctx.Idents.get("g_memdup");
|
|
|
}
|
|
|
|
|
|
bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
|
|
@@ -589,7 +604,8 @@ bool MallocChecker::isCMemFunction(const FunctionDecl *FD,
|
|
|
initIdentifierInfo(C);
|
|
|
|
|
|
if (Family == AF_Malloc && CheckFree) {
|
|
|
- if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
|
|
|
+ if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf ||
|
|
|
+ FunI == II_g_free)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -597,7 +613,11 @@ bool MallocChecker::isCMemFunction(const FunctionDecl *FD,
|
|
|
if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
|
|
|
FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
|
|
|
FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
|
|
|
- FunI == II_win_wcsdup || FunI == II_kmalloc)
|
|
|
+ FunI == II_win_wcsdup || FunI == II_kmalloc ||
|
|
|
+ FunI == II_g_malloc || FunI == II_g_malloc0 ||
|
|
|
+ FunI == II_g_realloc || FunI == II_g_try_malloc ||
|
|
|
+ FunI == II_g_try_malloc0 || FunI == II_g_try_realloc ||
|
|
|
+ FunI == II_g_memdup)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -762,7 +782,7 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
|
|
|
initIdentifierInfo(C.getASTContext());
|
|
|
IdentifierInfo *FunI = FD->getIdentifier();
|
|
|
|
|
|
- if (FunI == II_malloc) {
|
|
|
+ if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) {
|
|
|
if (CE->getNumArgs() < 1)
|
|
|
return;
|
|
|
if (CE->getNumArgs() < 3) {
|
|
@@ -791,7 +811,8 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
|
|
|
return;
|
|
|
State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
|
|
|
State = ProcessZeroAllocation(C, CE, 0, State);
|
|
|
- } else if (FunI == II_realloc) {
|
|
|
+ } else if (FunI == II_realloc || FunI == II_g_realloc ||
|
|
|
+ FunI == II_g_try_realloc) {
|
|
|
State = ReallocMem(C, CE, false, State);
|
|
|
State = ProcessZeroAllocation(C, CE, 1, State);
|
|
|
} else if (FunI == II_reallocf) {
|
|
@@ -801,7 +822,7 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
|
|
|
State = CallocMem(C, CE, State);
|
|
|
State = ProcessZeroAllocation(C, CE, 0, State);
|
|
|
State = ProcessZeroAllocation(C, CE, 1, State);
|
|
|
- } else if (FunI == II_free) {
|
|
|
+ } else if (FunI == II_free || FunI == II_g_free) {
|
|
|
State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
|
|
|
} else if (FunI == II_strdup || FunI == II_win_strdup ||
|
|
|
FunI == II_wcsdup || FunI == II_win_wcsdup) {
|
|
@@ -841,6 +862,18 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
|
|
|
AF_IfNameIndex);
|
|
|
} else if (FunI == II_if_freenameindex) {
|
|
|
State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
|
|
|
+ } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) {
|
|
|
+ if (CE->getNumArgs() < 1)
|
|
|
+ return;
|
|
|
+ SValBuilder &svalBuilder = C.getSValBuilder();
|
|
|
+ SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
|
|
|
+ State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State);
|
|
|
+ State = ProcessZeroAllocation(C, CE, 0, State);
|
|
|
+ } else if (FunI == II_g_memdup) {
|
|
|
+ if (CE->getNumArgs() < 2)
|
|
|
+ return;
|
|
|
+ State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State);
|
|
|
+ State = ProcessZeroAllocation(C, CE, 1, State);
|
|
|
}
|
|
|
}
|
|
|
|