[PATCH] D17688: Fix missed leak from MSVC specific allocation functions

Alexander Riccio via cfe-commits cfe-commits at lists.llvm.org
Sat Feb 27 21:56:55 PST 2016


ariccio created this revision.
ariccio added a subscriber: cfe-commits.

I've found & fixed a leak that Clang misses when compiling on Windows.

The leak was found by [[ https://samate.nist.gov/SARD/view_testcase.php?tID=149071 | SARD #149071 ]], mem1-bad.c. Clang misses it because MSVC uses _strdup instead of strdup. I've added an IdentifierInfo* for _strdup, and now Clang catches it. 

As a drive by fix, I added the wide character strdup variants (wcsdup, _wcsdup) and the MSVC version of alloca (_alloca).

I will add reviewers when check-all finishes.

http://reviews.llvm.org/D17688

Files:
  llvm/tools/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

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__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__strdup(nullptr), II_kmalloc(nullptr),
+        II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
+        II_wcsdup(nullptr), II__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__alloca, *II_malloc, *II_free,
+                         *II_realloc, *II_calloc, *II_valloc, *II_reallocf,
+                         *II_strndup, *II_strdup, *II__strdup, *II_kmalloc,
+                         *II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
+                         *II__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__strdup = &Ctx.Idents.get("_strdup");
+  II__wcsdup = &Ctx.Idents.get("_wcsdup");
+  II__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__strdup || FunI == II_strndup || FunI == II_wcsdup ||
+          FunI == II__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__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__strdup ||
+               FunI == II_wcsdup || FunI == II__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__alloca) {
       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
                            AF_Alloca);
       State = ProcessZeroAllocation(C, CE, 0, State);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17688.49308.patch
Type: text/x-patch
Size: 4088 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160228/fa7dd70d/attachment.bin>


More information about the cfe-commits mailing list