From c38d7952b2ac8fe73ee82f11019b12b07a739520 Mon Sep 17 00:00:00 2001 From: Anton Yartsev Date: Tue, 3 Mar 2015 22:58:46 +0000 Subject: [PATCH] [analyzer] unix.Malloc: preserve AllocaRegion bound to __builtin_alloca(). Binding __builtin_alloca() return value to the symbolic value kills previous binding to a AllocaRegion established by the core.BuiltinFunctions checker. Other checkers may rely upon this information. Rollback handling of __builtin_alloca() to the way prior to r229850. llvm-svn: 231160 --- .../lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 30 ++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 0930808..c2ace7b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -161,10 +161,10 @@ class MallocChecker : public Checker BT_FreeAlloca[CK_NumCheckKinds]; mutable std::unique_ptr BT_MismatchedDealloc; mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds]; - mutable IdentifierInfo *II_alloca, *II_alloca_builtin, *II_malloc, *II_free, - *II_realloc, *II_calloc, *II_valloc, *II_reallocf, - *II_strndup, *II_strdup, *II_kmalloc, *II_if_nameindex, + 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 Optional KernelZeroFlagVal; @@ -508,7 +508,6 @@ void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { if (II_malloc) return; II_alloca = &Ctx.Idents.get("alloca"); - II_alloca_builtin = &Ctx.Idents.get("__builtin_alloca"); II_malloc = &Ctx.Idents.get("malloc"); II_free = &Ctx.Idents.get("free"); II_realloc = &Ctx.Idents.get("realloc"); @@ -577,7 +576,7 @@ bool MallocChecker::isCMemFunction(const FunctionDecl *FD, } if (Family == AF_Alloca && CheckAlloc) { - if (FunI == II_alloca || FunI == II_alloca_builtin) + if (FunI == II_alloca) return true; } } @@ -763,7 +762,7 @@ void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { State = MallocUpdateRefState(C, CE, State); } else if (FunI == II_strndup) { State = MallocUpdateRefState(C, CE, State); - } else if (FunI == II_alloca || FunI == II_alloca_builtin) { + } else if (FunI == II_alloca) { State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Alloca); } else if (isStandardNewDelete(FD, C.getASTContext())) { @@ -1248,7 +1247,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, const MemSpaceRegion *MS = R->getMemorySpace(); - // Parameters, locals, statics and globals shouldn't be freed. + // Parameters, locals, statics, globals, and memory returned by + // __builtin_alloca() shouldn't be freed. if (!(isa(MS) || isa(MS))) { // FIXME: at the time this code was written, malloc() regions were // represented by conjured symbols, which are all in UnknownSpaceRegion. @@ -1257,8 +1257,12 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, // Of course, free() can work on memory allocated outside the current // function, so UnknownSpaceRegion is always a possibility. // False negatives are better than false positives. - - ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr); + + if (isa(R)) + ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange()); + else + ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr); + return nullptr; } -- 2.7.4