[cfe-commits] r67822 - in /cfe/trunk: include/clang/Analysis/PathDiagnostic.h lib/Analysis/BugReporter.cpp lib/Frontend/PlistDiagnostics.cpp
Ted Kremenek
kremenek at apple.com
Thu Mar 26 22:06:10 PDT 2009
Author: kremenek
Date: Fri Mar 27 00:06:10 2009
New Revision: 67822
URL: http://llvm.org/viewvc/llvm-project?rev=67822&view=rev
Log:
BugReporter:
- Added an internal helper class 'PathDiagnosticBuilder' which now bundles the
'ExecutionContinues' methods.
- Added preliminary diagnostics for short-circuit '&&' and '||'
Modified:
cfe/trunk/include/clang/Analysis/PathDiagnostic.h
cfe/trunk/lib/Analysis/BugReporter.cpp
cfe/trunk/lib/Frontend/PlistDiagnostics.cpp
Modified: cfe/trunk/include/clang/Analysis/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathDiagnostic.h?rev=67822&r1=67821&r2=67822&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathDiagnostic.h (original)
+++ cfe/trunk/include/clang/Analysis/PathDiagnostic.h Fri Mar 27 00:06:10 2009
@@ -41,6 +41,8 @@
const DiagnosticInfo &Info);
virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0;
+
+ virtual bool supportsLogicalOpControlFlow() const { return false; }
};
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=67822&r1=67821&r2=67822&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Fri Mar 27 00:06:10 2009
@@ -85,38 +85,58 @@
// Diagnostics for 'execution continues on line XXX'.
//===----------------------------------------------------------------------===//
-static FullSourceLoc ExecutionContinues(SourceManager& SMgr,
- const ExplodedNode<GRState>* N,
- const Decl& D,
- bool* OutHasStmt = 0) {
+namespace {
+class VISIBILITY_HIDDEN PathDiagnosticBuilder {
+ SourceManager &SMgr;
+ const Decl& CodeDecl;
+ PathDiagnosticClient *PDC;
+public:
+ PathDiagnosticBuilder(SourceManager &smgr, const Decl& codedecl,
+ PathDiagnosticClient *pdc)
+ : SMgr(smgr), CodeDecl(codedecl), PDC(pdc) {}
+
+ FullSourceLoc ExecutionContinues(const ExplodedNode<GRState>* N,
+ bool* OutHasStmt = 0);
+
+ FullSourceLoc ExecutionContinues(llvm::raw_string_ostream& os,
+ const ExplodedNode<GRState>* N);
+
+ bool supportsLogicalOpControlFlow() const {
+ return PDC ? PDC->supportsLogicalOpControlFlow() : true;
+ }
+};
+} // end anonymous namespace
+
+FullSourceLoc
+PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N,
+ bool* OutHasStmt) {
if (Stmt *S = GetNextStmt(N)) {
if (OutHasStmt) *OutHasStmt = true;
return FullSourceLoc(S->getLocStart(), SMgr);
}
else {
if (OutHasStmt) *OutHasStmt = false;
- return FullSourceLoc(D.getBody()->getRBracLoc(), SMgr);
+ return FullSourceLoc(CodeDecl.getBody()->getRBracLoc(), SMgr);
}
}
-static FullSourceLoc ExecutionContinues(llvm::raw_string_ostream& os,
- SourceManager& SMgr,
- const ExplodedNode<GRState>* N,
- const Decl& D) {
-
+FullSourceLoc
+PathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream& os,
+ const ExplodedNode<GRState>* N) {
+
// Slow, but probably doesn't matter.
if (os.str().empty())
os << ' ';
bool hasStmt;
- FullSourceLoc Loc = ExecutionContinues(SMgr, N, D, &hasStmt);
+ FullSourceLoc Loc = ExecutionContinues(N, &hasStmt);
if (hasStmt)
os << "Execution continues on line "
- << SMgr.getInstantiationLineNumber(Loc) << '.';
+ << SMgr.getInstantiationLineNumber(Loc) << '.';
else
os << "Execution jumps to the end of the "
- << (isa<ObjCMethodDecl>(D) ? "method" : "function") << '.';
+ << (isa<ObjCMethodDecl>(CodeDecl) ? "method" : "function") << '.';
return Loc;
}
@@ -719,6 +739,8 @@
ASTContext& Ctx = getContext();
SourceManager& SMgr = Ctx.getSourceManager();
NodeMapClosure NMC(BackMap.get());
+ PathDiagnosticBuilder PDB(SMgr, getStateManager().getCodeDecl(),
+ getPathDiagnosticClient());
while (NextNode) {
N = NextNode;
@@ -819,8 +841,7 @@
}
else {
os << "'Default' branch taken. ";
- End = ExecutionContinues(os, SMgr, N,
- getStateManager().getCodeDecl());
+ End = PDB.ExecutionContinues(os, N);
}
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
@@ -832,13 +853,13 @@
case Stmt::ContinueStmtClass: {
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
- FullSourceLoc End =
- ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl());
+ FullSourceLoc End = PDB.ExecutionContinues(os, N);
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
break;
}
+ // Determine control-flow for ternary '?'.
case Stmt::ConditionalOperatorClass: {
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
@@ -849,28 +870,59 @@
else
os << "true";
- FullSourceLoc End =
- ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
+ FullSourceLoc End = PDB.ExecutionContinues(N);
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
break;
}
+ // Determine control-flow for short-circuited '&&' and '||'.
+ case Stmt::BinaryOperatorClass: {
+ if (!PDB.supportsLogicalOpControlFlow())
+ break;
+
+ BinaryOperator *B = cast<BinaryOperator>(T);
+ std::string sbuf;
+ llvm::raw_string_ostream os(sbuf);
+ os << "Left side of '";
+
+ if (B->getOpcode() == BinaryOperator::LAnd) {
+ os << "&&";
+ }
+ else {
+ assert(B->getOpcode() == BinaryOperator::LOr);
+ os << "||";
+ }
+
+ os << "' is ";
+ if (*(Src->succ_begin()+1) == Dst)
+ os << (B->getOpcode() == BinaryOperator::LAnd
+ ? "false" : "true");
+ else
+ os << (B->getOpcode() == BinaryOperator::LAnd
+ ? "true" : "false");
+
+ PathDiagnosticLocation Start(B->getLHS(), SMgr);
+ PathDiagnosticLocation End = PDB.ExecutionContinues(N);
+
+ PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+ os.str()));
+ break;
+ }
+
case Stmt::DoStmtClass: {
if (*(Src->succ_begin()) == Dst) {
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
os << "Loop condition is true. ";
- FullSourceLoc End =
- ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl());
+ FullSourceLoc End = PDB.ExecutionContinues(os, N);
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
- FullSourceLoc End =
- ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
+ FullSourceLoc End = PDB.ExecutionContinues(N);
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Loop condition is false. Exiting loop"));
}
@@ -885,15 +937,12 @@
llvm::raw_string_ostream os(sbuf);
os << "Loop condition is false. ";
- FullSourceLoc End =
- ExecutionContinues(os, SMgr, N, getStateManager().getCodeDecl());
-
+ FullSourceLoc End = PDB.ExecutionContinues(os, N);
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
os.str()));
}
else {
- FullSourceLoc End =
- ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
+ FullSourceLoc End = PDB.ExecutionContinues(N);
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Loop condition is true. Entering loop body"));
@@ -903,9 +952,7 @@
}
case Stmt::IfStmtClass: {
- FullSourceLoc End =
- ExecutionContinues(SMgr, N, getStateManager().getCodeDecl());
-
+ FullSourceLoc End = PDB.ExecutionContinues(N);
if (*(Src->succ_begin()+1) == Dst)
PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
"Taking false branch"));
Modified: cfe/trunk/lib/Frontend/PlistDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PlistDiagnostics.cpp?rev=67822&r1=67821&r2=67822&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/Frontend/PlistDiagnostics.cpp Fri Mar 27 00:06:10 2009
@@ -38,7 +38,9 @@
public:
PlistDiagnostics(const std::string& prefix);
~PlistDiagnostics();
- void HandlePathDiagnostic(const PathDiagnostic* D);
+ void HandlePathDiagnostic(const PathDiagnostic* D);
+
+ bool supportsLogicalOpControlFlow() const { return true; }
};
} // end anonymous namespace
More information about the cfe-commits
mailing list