For forward-declared static inline functions, delay CFG-based warnings until we

encounter a definition.

llvm-svn: 99243
This commit is contained in:
Ted Kremenek 2010-03-23 01:37:12 +00:00
parent bb6f5af4a4
commit a3ab0d7666
3 changed files with 26 additions and 8 deletions

View File

@ -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;
}
}
}
}
}
}
}

View File

@ -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);

View File

@ -227,12 +227,15 @@ void test33() {
// when they are used.
static inline int si_has_missing_return() {} // no-warning
static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}}
static inline int si_forward();
static inline int si_has_missing_return_3(int x) {
if (x)
return si_has_missing_return_3(x+1);
} // expected-warning{{control may reach end of non-void function}}
int test_static_inline(int x) {
si_forward();
return x ? si_has_missing_return_2() : si_has_missing_return_3(x);
}
static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}}