diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index fed64f1b042..e21dde1f826 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -881,7 +881,17 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { return; // Check if we are returning a symbol. - SymbolRef Sym = C.getState()->getSVal(E, C.getLocationContext()).getAsSymbol(); + SVal RetVal = C.getState()->getSVal(E, C.getLocationContext()); + SymbolRef Sym = RetVal.getAsSymbol(); + if (!Sym) + // If we are returning a field of the allocated struct or an array element, + // the callee could still free the memory. + // TODO: This logic should be a part of generic symbol escape callback. + if (const MemRegion *MR = RetVal.getAsRegion()) + if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR)) + if (const SymbolicRegion *BMR = + dyn_cast<SymbolicRegion>(MR->getBaseRegion())) + Sym = BMR->getSymbol(); if (!Sym) return; |