diff options
author | Anna Zaks <ganna@apple.com> | 2012-02-15 00:11:22 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-02-15 00:11:22 +0000 |
commit | d51574850eb0bd5c930eb42e57222a73beb7d1f7 (patch) | |
tree | 8609a4d885726e4dce7891208a92094492b925e9 | |
parent | c4cf13f7912c1e5336592434d314d4b5aebc78c6 (diff) | |
download | bcm5719-llvm-d51574850eb0bd5c930eb42e57222a73beb7d1f7.tar.gz bcm5719-llvm-d51574850eb0bd5c930eb42e57222a73beb7d1f7.zip |
[analyzer] Malloc Checker: add support for valloc + minor code
hardening.
llvm-svn: 150532
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 31 | ||||
-rw-r--r-- | clang/test/Analysis/malloc.c | 13 |
2 files changed, 32 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index d57e8a9f621..1191cf8d902 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -82,10 +82,12 @@ class MallocChecker : public Checker<check::DeadSymbols, mutable OwningPtr<BuiltinBug> BT_UseFree; mutable OwningPtr<BuiltinBug> BT_UseRelinquished; mutable OwningPtr<BuiltinBug> BT_BadFree; - mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc; + mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc, + *II_valloc; public: - MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {} + MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0), + II_valloc(0) {} /// In pessimistic mode, the checker assumes that it does not know which /// functions might free the memory. @@ -241,6 +243,8 @@ void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { II_realloc = &Ctx.Idents.get("realloc"); if (!II_calloc) II_calloc = &Ctx.Idents.get("calloc"); + if (!II_valloc) + II_valloc = &Ctx.Idents.get("valloc"); } bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { @@ -251,7 +255,7 @@ bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { // TODO: Add more here : ex: reallocf! if (FunI == II_malloc || FunI == II_free || - FunI == II_realloc || FunI == II_calloc) + FunI == II_realloc || FunI == II_calloc || FunI == II_valloc) return true; if (Filter.CMallocOptimistic && FD->hasAttrs() && @@ -267,23 +271,22 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) return; + initIdentifierInfo(C.getASTContext()); + IdentifierInfo *FunI = FD->getIdentifier(); + if (!FunI) + return; - if (FD->getIdentifier() == II_malloc) { + if (FunI == II_malloc || FunI == II_valloc) { MallocMem(C, CE); return; - } - if (FD->getIdentifier() == II_realloc) { + } else if (FunI == II_realloc) { ReallocMem(C, CE); return; - } - - if (FD->getIdentifier() == II_calloc) { + } else if (FunI == II_calloc) { CallocMem(C, CE); return; - } - - if (FD->getIdentifier() == II_free) { + }else if (FunI == II_free) { FreeMem(C, CE); return; } @@ -343,6 +346,10 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, // Get the return value. SVal retVal = state->getSVal(CE, C.getLocationContext()); + // We expect the malloc functions to return a pointer. + if (!isa<Loc>(retVal)) + return 0; + // Fill the region with the initialization value. state = state->bindDefault(retVal, Init); diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 0aa92912559..dce088e50d9 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -3,6 +3,7 @@ typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); +void *valloc(size_t); void free(void *); void *realloc(void *ptr, size_t size); void *calloc(size_t nmemb, size_t size); @@ -406,6 +407,18 @@ void mallocFailedOrNotLeak() { return; // expected-warning {{Allocated memory never released. Potential memory leak.}} } +int vallocTest() { + char *mem = valloc(12); + return 0; // expected-warning {{Allocated memory never released. Potential memory leak.}} +} + +void vallocEscapeFreeUse() { + int *p = valloc(12); + myfoo(p); + free(p); + myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}} +} + int *Gl; struct GlStTy { int *x; |