]> granicus.if.org Git - clang/commitdiff
Emit warnings for undefined control-flow.
authorTed Kremenek <kremenek@apple.com>
Fri, 14 Mar 2008 18:14:50 +0000 (18:14 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 14 Mar 2008 18:14:50 +0000 (18:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48368 91177308-0d34-0410-b5e6-96231b3b80d8

Analysis/GRExprEngine.cpp
Analysis/GRSimpleVals.cpp
Driver/ASTConsumers.cpp
include/clang/Analysis/PathSensitive/GRExprEngine.h

index b8892e3ee546d81091bb431d531b0269ca44aae0..70cd1871bccadf63797abfe9d805c833a4eda4bf 100644 (file)
@@ -1865,6 +1865,7 @@ void GRExprEngine::ViewGraph(bool trim) {
     AddSources(Src, undef_results_begin(), undef_results_end());
     AddSources(Src, bad_calls_begin(), bad_calls_end());
     AddSources(Src, undef_arg_begin(), undef_arg_end());
+    AddSources(Src, undef_branches_begin(), undef_branches_end());
     
     ViewGraph(&Src[0], &Src[0]+Src.size());
   }
index ee5a44c48ce508d8c1a91057b1ceb145a7aff53d..44429336a54e5a27bbfde14b2c9265d45ccf0736 100644 (file)
@@ -23,22 +23,33 @@ using namespace clang;
 namespace clang {
 
 template <typename ITERATOR>
-static inline const PostStmt& GetLocation(ITERATOR I) {
-  return cast<PostStmt>((*I)->getLocation());
+static inline ProgramPoint GetLocation(ITERATOR I) {
+  return (*I)->getLocation();
 }
   
 template <>
-inline const PostStmt& GetLocation(GRExprEngine::undef_arg_iterator I) {
-  return cast<PostStmt>(I->first->getLocation());
+inline ProgramPoint GetLocation(GRExprEngine::undef_arg_iterator I) {
+  return I->first->getLocation();
+}
+  
+static inline Stmt* GetStmt(const ProgramPoint& P) {
+  if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
+    return PS->getStmt();
+  }
+  else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
+    return BE->getSrc()->getTerminator();
+  }
+
+  assert (false && "Unsupported ProgramPoint.");
+  return NULL;
 }
 
 template <typename ITERATOR>
 static void EmitDiag(Diagnostic& Diag, SourceManager& SrcMgr,
                      unsigned ErrorDiag, ITERATOR I) {  
   
-  Expr* Exp = cast<Expr>(GetLocation(I).getStmt());
-  cast<Expr>(GetLocation(I).getStmt());  
-  Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag);    
+  Stmt* S = GetStmt(GetLocation(I));
+  Diag.Report(FullSourceLoc(S->getLocStart(), SrcMgr), ErrorDiag);    
 }
 
 
@@ -46,10 +57,10 @@ template <>
 static void EmitDiag(Diagnostic& Diag, SourceManager& SrcMgr,
                      unsigned ErrorDiag, GRExprEngine::undef_arg_iterator I) {
 
-  Expr* E1 = cast<Expr>(GetLocation(I).getStmt());
+  Stmt* S1 = GetStmt(GetLocation(I));
   Expr* E2 = cast<Expr>(I->second);
   
-  SourceLocation Loc = E1->getExprLoc();
+  SourceLocation Loc = S1->getLocStart();
   SourceRange R = E2->getSourceRange();
   Diag.Report(FullSourceLoc(Loc, SrcMgr), ErrorDiag, 0, 0, &R, 1);
 }
@@ -139,6 +150,11 @@ unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
               CheckerState->undef_arg_begin(),
               CheckerState->undef_arg_end(),
       "Pass-by-value argument in function or message expression is undefined.");
+  
+  EmitWarning(Diag, SrcMgr,
+              CheckerState->undef_branches_begin(),
+              CheckerState->undef_branches_end(),
+      "Branch condition evaluates to an uninitialized value.");
       
 #ifndef NDEBUG
   if (Visualize) CheckerState->ViewGraph(TrimGraph);
@@ -161,7 +177,8 @@ RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
   BasicValueFactory& BasicVals = Eng.getBasicVals();
   
   llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
-  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
+  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType() 
+                  || T->isObjCQualifiedIdType());
   V.extOrTrunc(Eng.getContext().getTypeSize(T));
   
   if (T->isPointerType())
@@ -174,7 +191,7 @@ RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
 
 RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
   
-  if (T->isPointerType() || T->isReferenceType())
+  if (T->isPointerType() || T->isReferenceType() || T->isObjCQualifiedIdType())
     return X;
   
   assert (T->isIntegerType());
index 20fd18cd063c5057a686228b198c65143a49bd90..e6a1ae4b70e12090e14b63f31abcb46996515bf7 100644 (file)
@@ -505,6 +505,9 @@ void CFGVisitor::HandleTopLevelDecl(Decl *D) {
     
     if (!MD->getBody())
       return;
+      
+    if (FName.size() > 0 && FName != MD->getSelector().getName())
+      return;
     
     if (printFuncDeclStart()) {
       DeclPrinter().PrintObjCMethodDecl(MD);
@@ -649,11 +652,11 @@ ASTConsumer* clang::CreateGRSimpleVals(Diagnostic &Diags,
 void GRSimpleValsVisitor::VisitCFG(CFG& C, Decl& CD) {
   
   SourceLocation Loc = CD.getLocation();
-  
+
   if (!Loc.isFileID() ||
        Loc.getFileID() != Ctx->getSourceManager().getMainFileID())
     return;
-  
+
   if (!Visualize) {
     
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(&CD)) {
@@ -662,8 +665,8 @@ void GRSimpleValsVisitor::VisitCFG(CFG& C, Decl& CD) {
                  << ' ';
     }
     else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(&CD)) {
-      llvm::cerr << "ANALYZE (ObjC Method): "
-        << MD->getSelector().getName() << ' '
+      llvm::cerr << "ANALYZE (ObjC Method): '"
+        << MD->getSelector().getName() << "' "
         << Ctx->getSourceManager().getSourceName(MD->getLocation())
         << ' ';
     }
index 0c3aa847e6fdc6a8ba5577a473f0021c5f0097f8..4e50745e2225893e22e638d32b94f9a234d4dd37 100644 (file)
@@ -204,6 +204,10 @@ public:
            UndefArgs.find(const_cast<NodeTy*>(N)) != UndefArgs.end();
   }
   
+  typedef UndefBranchesTy::iterator undef_branch_iterator;
+  undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
+  undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }  
+  
   typedef BadDerefTy::iterator null_deref_iterator;
   null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); }
   null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); }