[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