From acdc13cb00591e2ab2b168c7924d7eb57fa4808e Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Thu, 7 Feb 2013 23:05:43 +0000 Subject: [PATCH] [analyzer] Add pointer escape type param to checkPointerEscape callback The checkPointerEscape callback previously did not specify how a pointer escaped. This change includes an enum which describes the different ways a pointer may escape. This enum is passed to the checkPointerEscape callback when a pointer escapes. If the escape is due to a function call, the call is passed. This changes previous behavior where the call is passed as NULL if the escape was due to indirectly invalidating the region the pointer referenced. A patch by Branden Archer! llvm-svn: 174677 --- clang/include/clang/StaticAnalyzer/Core/Checker.h | 6 ++-- .../clang/StaticAnalyzer/Core/CheckerManager.h | 26 +++++++++++++++-- .../Checkers/CheckerDocumentation.cpp | 4 ++- .../lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 11 +++++-- .../Checkers/SimpleStreamChecker.cpp | 11 +++++-- clang/lib/StaticAnalyzer/Core/CheckerManager.cpp | 10 +++++-- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 11 ++++--- .../system-header-simulator-for-simple-stream.h | 6 ++++ .../test/Analysis/Inputs/system-header-simulator.h | 8 +++++ clang/test/Analysis/malloc.c | 34 ++++++++++++++++++++++ clang/test/Analysis/simple-stream-checks.c | 13 +++++++++ 11 files changed, 123 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/StaticAnalyzer/Core/Checker.h b/clang/include/clang/StaticAnalyzer/Core/Checker.h index a190e1f..82bac7d 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -323,10 +323,12 @@ class PointerEscape { _checkPointerEscape(void *checker, ProgramStateRef State, const InvalidatedSymbols &Escaped, - const CallEvent *Call) { + const CallEvent *Call, + PointerEscapeKind Kind) { return ((const CHECKER *)checker)->checkPointerEscape(State, Escaped, - Call); + Call, + Kind); } public: diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 2fd71dd..4353ebf 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -112,6 +112,26 @@ public: RET operator()() const { return Fn(Checker); } }; +/// \brief Describes the different reasons a pointer escapes +/// during analysis. +enum PointerEscapeKind { + /// A pointer escapes due to binding its value to a location + /// that the analyzer cannot track. + PSK_EscapeOnBind, + + /// The pointer has been passed to a function call directly. + PSK_DirectEscapeOnCall, + + /// The pointer has been passed to a function indirectly. + /// For example, the pointer is accessible through an + /// argument to a function. + PSK_IndirectEscapeOnCall, + + /// The reason for pointer escape is unknown. For example, + /// a region containing this pointer is invalidated. + PSK_EscapeOther +}; + class CheckerManager { const LangOptions LangOpts; @@ -330,7 +350,8 @@ public: ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, - const CallEvent *Call); + const CallEvent *Call, + PointerEscapeKind Kind); /// \brief Run checkers for handling assumptions on symbolic values. ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, @@ -420,7 +441,8 @@ public: typedef CheckerFn + const CallEvent *Call, + PointerEscapeKind Kind)> CheckPointerEscapeFunc; typedef CheckerFnmemP = malloc(12); } // missing warning +void testPassConstPointerIndirectlyStruct() { + struct HasPtr hp; + hp.p = malloc(10); + memcmp(&hp, &hp, sizeof(hp)); + return; // missing leak +} + +void testPassToSystemHeaderFunctionIndirectlyStruct() { + SomeStruct ss; + ss.p = malloc(1); + fakeSystemHeaderCall(&ss); +} // missing leak diff --git a/clang/test/Analysis/simple-stream-checks.c b/clang/test/Analysis/simple-stream-checks.c index 74794cc..1fb6de3 100644 --- a/clang/test/Analysis/simple-stream-checks.c +++ b/clang/test/Analysis/simple-stream-checks.c @@ -76,3 +76,16 @@ void SymbolDoesNotEscapeThoughStringAPIs(char *Data) { fputc(*Data, F); return; // expected-warning {{Opened file is never closed; potential resource leak}} } + +void passConstPointer(const FILE * F); +void testPassConstPointer() { + FILE *F = fopen("myfile.txt", "w"); + passConstPointer(F); + return; // expected-warning {{Opened file is never closed; potential resource leak}} +} + +void testPassToSystemHeaderFunctionIndirectly() { + FileStruct fs; + fs.p = fopen("myfile.txt", "w"); + fakeSystemHeaderCall(&fs); +} // expected leak warning -- 2.7.4