ariccio updated this revision to Diff 49674.
ariccio added a comment.
Added newly checked variants to the malloc checks.
(Running the check-all suite now, will update with results)
http://reviews.llvm.org/D17688
Files:
llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
llvm/tools/clang/test/Analysis/malloc.c
Index: llvm/tools/clang/test/Analysis/malloc.c
===================================================================
--- llvm/tools/clang/test/Analysis/malloc.c
+++ llvm/tools/clang/test/Analysis/malloc.c
@@ -13,9 +13,15 @@
void *reallocf(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
char *strdup(const char *s);
+wchar_t *wcsdup(const wchar_t *s);
char *strndup(const char *s, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
+// Windows variants
+char *_strdup(const char *strSource);
+wchar_t *_wcsdup(const wchar_t *strSource);
+void *_alloca(size_t size);
+
void myfoo(int *p);
void myfooint(int p);
char *fooRetPtr();
@@ -55,6 +61,10 @@
int *p = alloca(sizeof(int));
} // no warn
+void winAllocaTest() {
+ int *p = _alloca(sizeof(int));
+} // no warn
+
void allocaBuiltinTest() {
int *p = __builtin_alloca(sizeof(int));
} // no warn
@@ -210,6 +220,11 @@
int *p = alloca(0); // no warning
}
+void CheckUseZeroWinAllocatedNoWarn2() {
+ int *p = _alloca(0); // no warning
+}
+
+
void CheckUseZeroAllocatedNoWarn3() {
int *p = malloc(0);
int *q = realloc(p, 8); // no warning
@@ -233,6 +248,11 @@
return *p; // expected-warning {{Use of zero-allocated memory}}
}
+char CheckUseZeroWinAllocated2() {
+ char *p = _alloca(0);
+ return *p; // expected-warning {{Use of zero-allocated memory}}
+}
+
void UseZeroAllocated(int *p) {
if (p)
*p = 7; // expected-warning {{Use of zero-allocated memory}}
@@ -1076,6 +1096,21 @@
s2[validIndex + 1] = 'b';
} // expected-warning {{Potential leak of memory pointed to by}}
+void testWinStrdup(const char *s, unsigned validIndex) {
+ char *s2 = _strdup(s);
+ s2[validIndex + 1] = 'b';
+} // expected-warning {{Potential leak of memory pointed to by}}
+
+void testWcsdup(const wchar_t *s, unsigned validIndex) {
+ wchar_t *s2 = wcsdup(s);
+ s2[validIndex + 1] = 'b';
+} // expected-warning {{Potential leak of memory pointed to by}}
+
+void testWinWcsdup(const wchar_t *s, unsigned validIndex) {
+ wchar_t *s2 = _wcsdup(s);
+ s2[validIndex + 1] = 'b';
+} // expected-warning {{Potential leak of memory pointed to by}}
+
int testStrndup(const char *s, unsigned validIndex, unsigned size) {
char *s2 = strndup(s, size);
s2 [validIndex + 1] = 'b';
@@ -1091,6 +1126,24 @@
free(s2);
}
+void testWinStrdupContentIsDefined(const char *s, unsigned validIndex) {
+ char *s2 = _strdup(s);
+ char result = s2[1];// no warning
+ free(s2);
+}
+
+void testWcsdupContentIsDefined(const wchar_t *s, unsigned validIndex) {
+ wchar_t *s2 = wcsdup(s);
+ wchar_t result = s2[1];// no warning
+ free(s2);
+}
+
+void testWinWcsdupContentIsDefined(const wchar_t *s, unsigned validIndex) {
+ wchar_t *s2 = _wcsdup(s);
+ wchar_t result = s2[1];// no warning
+ free(s2);
+}
+
// ----------------------------------------------------------------------------
// Test the system library functions to which the pointer can escape.
// This tests false positive suppression.
@@ -1444,6 +1497,10 @@
return strdup(strdup(str)); // expected-warning{{leak}}
}
+char *testWinLeakWithinReturn(wchar_t *str) {
+ return _strdup(_strdup(str)); // expected-warning{{leak}}
+}
+
void passConstPtr(const char * ptr);
void testPassConstPointer() {
Index: llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -169,11 +169,12 @@
{
public:
MallocChecker()
- : II_alloca(nullptr), II_malloc(nullptr), II_free(nullptr),
- II_realloc(nullptr), II_calloc(nullptr), II_valloc(nullptr),
- II_reallocf(nullptr), II_strndup(nullptr), II_strdup(nullptr),
- II_kmalloc(nullptr), II_if_nameindex(nullptr),
- II_if_freenameindex(nullptr) {}
+ : II_alloca(nullptr), II_win_alloca(nullptr), II_malloc(nullptr),
+ II_free(nullptr), II_realloc(nullptr), II_calloc(nullptr),
+ 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) {}
/// In pessimistic mode, the checker assumes that it does not know which
/// functions might free the memory.
@@ -231,10 +232,11 @@
mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
- mutable IdentifierInfo *II_alloca, *II_malloc, *II_free, *II_realloc,
- *II_calloc, *II_valloc, *II_reallocf, *II_strndup,
- *II_strdup, *II_kmalloc, *II_if_nameindex,
- *II_if_freenameindex;
+ mutable IdentifierInfo *II_alloca, *II_win_alloca, *II_malloc, *II_free,
+ *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;
mutable Optional<uint64_t> KernelZeroFlagVal;
void initIdentifierInfo(ASTContext &C) const;
@@ -540,9 +542,15 @@
II_valloc = &Ctx.Idents.get("valloc");
II_strdup = &Ctx.Idents.get("strdup");
II_strndup = &Ctx.Idents.get("strndup");
+ II_wcsdup = &Ctx.Idents.get("wcsdup");
II_kmalloc = &Ctx.Idents.get("kmalloc");
II_if_nameindex = &Ctx.Idents.get("if_nameindex");
II_if_freenameindex = &Ctx.Idents.get("if_freenameindex");
+
+ //MSVC uses `_`-prefixed instead, so we check for them too.
+ II_win_strdup = &Ctx.Idents.get("_strdup");
+ II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
+ II_win_alloca = &Ctx.Idents.get("_alloca");
}
bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
@@ -585,7 +593,8 @@
if (Family == AF_Malloc && CheckAlloc) {
if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
- FunI == II_strndup || FunI == II_kmalloc)
+ FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
+ FunI == II_win_wcsdup || FunI == II_kmalloc)
return true;
}
@@ -600,7 +609,7 @@
}
if (Family == AF_Alloca && CheckAlloc) {
- if (FunI == II_alloca)
+ if (FunI == II_alloca || FunI == II_win_alloca)
return true;
}
}
@@ -789,11 +798,12 @@
State = ProcessZeroAllocation(C, CE, 1, State);
} else if (FunI == II_free) {
State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
- } else if (FunI == II_strdup) {
+ } else if (FunI == II_strdup || FunI == II_win_strdup ||
+ FunI == II_wcsdup || FunI == II_win_wcsdup) {
State = MallocUpdateRefState(C, CE, State);
} else if (FunI == II_strndup) {
State = MallocUpdateRefState(C, CE, State);
- } else if (FunI == II_alloca) {
+ } else if (FunI == II_alloca || FunI == II_win_alloca) {
State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
AF_Alloca);
State = ProcessZeroAllocation(C, CE, 0, State);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits