diff options
| author | Ted Kremenek <kremenek@apple.com> | 2010-03-23 01:37:12 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2010-03-23 01:37:12 +0000 |
| commit | a3ab0d7666b8e3d152bef934d7b734403567caeb (patch) | |
| tree | 08ec84d4a83bdf0db550abb33bc35bc2776171c4 /clang/lib/Sema | |
| parent | bb6f5af4a4bf72e90718ee7cc436349cccae002a (diff) | |
| download | bcm5719-llvm-a3ab0d7666b8e3d152bef934d7b734403567caeb.tar.gz bcm5719-llvm-a3ab0d7666b8e3d152bef934d7b734403567caeb.zip | |
For forward-declared static inline functions, delay CFG-based warnings until we
encounter a definition.
llvm-svn: 99243
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 28 | ||||
| -rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.h | 3 |
2 files changed, 23 insertions, 8 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index a044576f5d7..45b08db7e12 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -353,8 +353,14 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, // Only analyze 'static inline' functions when explicitly asked. if (!analyzeStaticInline && FD->isInlineSpecified() && - FD->getStorageClass() == FunctionDecl::Static) - return; + FD->getStorageClass() == FunctionDecl::Static) { + FD = FD->getCanonicalDecl(); + VisitFlag &visitFlag = VisitedFD[FD]; + if (visitFlag == Pending) + visitFlag = Visited; + else + return; + } } const Stmt *Body = D->getBody(); @@ -397,18 +403,26 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreParenCasts())) if (const FunctionDecl *calleeD = - dyn_cast<FunctionDecl>(DR->getDecl())) + dyn_cast<FunctionDecl>(DR->getDecl())) { + calleeD = calleeD->getCanonicalDecl(); if (calleeD->isInlineSpecified() && calleeD->getStorageClass() == FunctionDecl::Static) { // Have we analyzed this static inline function before? - unsigned &visited = VisitedFD[calleeD]; - if (!visited) { + VisitFlag &visitFlag = VisitedFD[calleeD]; + if (visitFlag == NotVisited) { // Mark the callee visited prior to analyzing it // so we terminate in case of recursion. - visited = 1; - IssueWarnings(DefaultPolicy, calleeD, QualType(), true); + if (calleeD->getBody()) { + visitFlag = Visited; + IssueWarnings(DefaultPolicy, calleeD, QualType(), true); + } + else { + // Delay warnings until we encounter the definition. + visitFlag = Pending; + } } } + } } } } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.h b/clang/lib/Sema/AnalysisBasedWarnings.h index 26e973a3f40..b5db8af198f 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.h +++ b/clang/lib/Sema/AnalysisBasedWarnings.h @@ -39,7 +39,8 @@ private: Sema &S; Policy DefaultPolicy; - llvm::DenseMap<const FunctionDecl*, unsigned> VisitedFD; + enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 }; + llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD; public: AnalysisBasedWarnings(Sema &s); |

