[PATCH] Fix crash in CFGReachabilityAnalysis triggered by IdempotentOperationChecker.

Alexander Kornienko alexfh at google.com
Thu Dec 19 05:14:54 PST 2013


  I've spent some more time on this and came up with a way to extend current
  tests to model the condition, that leads to this crash. I've also included a
  fix, which relies on the assumption, that it is fine that there are blocks from
  different CFGs in `CoreEngine::blocksExhausted`.

  Without the fix the newly added test crashes:

    CFGReachabilityAnalysis.cpp:28: bool clang::CFGReverseBlockReachabilityAnalysis::isReachable(const clang::CFGBlock *, const clang::CFGBlock *): Assertion `Src->getParent() == Dst->getParent()' failed.
    0  clang           0x0000000001d6472e llvm::sys::PrintStackTrace(_IO_FILE*) + 46
    1  clang           0x0000000001d649eb
    2  clang           0x0000000001d64c5e
    3  libpthread.so.0 0x00002b23f2206cb0
    4  libc.so.6       0x00002b23f2e75425 gsignal + 53
    5  libc.so.6       0x00002b23f2e78b8b abort + 379
    6  libc.so.6       0x00002b23f2e6e0ee
    7  libc.so.6       0x00002b23f2e6e192
    8  clang           0x0000000003322896 clang::CFGReverseBlockReachabilityAnalysis::isReachable(clang::CFGBlock const*, clang::CFGBlock const*) + 102
    9  clang           0x0000000002022e81
    10 clang           0x0000000002022705
    11 clang           0x0000000002022438
    12 clang           0x00000000021f415a
    13 clang           0x00000000021f0f97 clang::ento::CheckerManager::runCheckersForEndAnalysis(clang::ento::ExplodedGraph&, clang::ento::BugReporter&, clang::ento::ExprEngine&) + 119
    14 clang           0x0000000002223d54 clang::ento::ExprEngine::processEndWorklist(bool) + 68
    15 clang           0x000000000220ee18 clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) + 1112
    16 clang           0x0000000001f9b7ad
    17 clang           0x0000000001f65246
    18 clang           0x0000000001f65014
    19 clang           0x0000000001f64925
    20 clang           0x0000000001f6458a
    21 clang           0x0000000001f634e9
    22 clang           0x0000000002b5b37d clang::ParseAST(clang::Sema&, bool, bool) + 813
    23 clang           0x0000000001e529d9 clang::ASTFrontendAction::ExecuteAction() + 345
    24 clang           0x0000000001e524ff clang::FrontendAction::Execute() + 191
    25 clang           0x0000000001e1c5a0 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 800
    26 clang           0x0000000001f5dcf8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1048
    27 clang           0x00000000008ca29a cc1_main(char const**, char const**, char const*, void*) + 698
    28 clang           0x00000000008c21a2 main + 802
    29 libc.so.6       0x00002b23f2e6076d __libc_start_main + 237
    30 clang           0x00000000008c1d45


  Is it fine to commit it like this?

Hi krememek,

http://llvm-reviews.chandlerc.com/D2427

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2427?vs=6162&id=6183#toc

Files:
  lib/Analysis/CFGReachabilityAnalysis.cpp
  lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
  test/Analysis/idempotent-operations.c

Index: lib/Analysis/CFGReachabilityAnalysis.cpp
===================================================================
--- lib/Analysis/CFGReachabilityAnalysis.cpp
+++ lib/Analysis/CFGReachabilityAnalysis.cpp
@@ -23,7 +23,9 @@
   : analyzed(cfg.getNumBlockIDs(), false) {}
 
 bool CFGReverseBlockReachabilityAnalysis::isReachable(const CFGBlock *Src,
-                                          const CFGBlock *Dst) {
+                                                      const CFGBlock *Dst) {
+  // Blocks must be from the same CFG.
+  assert(Src->getParent() == Dst->getParent());
 
   const unsigned DstBlockID = Dst->getBlockID();
   
Index: lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
+++ lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
@@ -541,7 +541,7 @@
                                                       const CoreEngine &CE) {
 
   CFGReverseBlockReachabilityAnalysis *CRA = AC->getCFGReachablityAnalysis();
-  
+
   // Test for reachability from any aborted blocks to this block
   typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
   for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
@@ -556,16 +556,18 @@
     // While technically reachable, it means we aborted the analysis on
     // a path that included that block.
     const CFGBlock *destBlock = BE.getDst();
-    if (destBlock == CB || CRA->isReachable(destBlock, CB))
+    if (destBlock == CB || (destBlock->getParent() == CB->getParent() &&
+                            CRA->isReachable(destBlock, CB)))
       return false;
   }
 
   // Test for reachability from blocks we just gave up on.
   typedef CoreEngine::BlocksAborted::const_iterator AbortedIterator;
   for (AbortedIterator I = CE.blocks_aborted_begin(),
        E = CE.blocks_aborted_end(); I != E; ++I) {
     const CFGBlock *destBlock = I->first;
-    if (destBlock == CB || CRA->isReachable(destBlock, CB))
+    if (destBlock == CB || (destBlock->getParent() == CB->getParent() &&
+                            CRA->isReachable(destBlock, CB)))
       return false;
   }
   
Index: test/Analysis/idempotent-operations.c
===================================================================
--- test/Analysis/idempotent-operations.c
+++ test/Analysis/idempotent-operations.c
@@ -78,6 +78,21 @@
   }
 }
 
+// Regression test for a crash while calling isReachable on blocks from
+// different CFGs.
+void bailout2() {
+  int result = 4;
+  result = result; // expected-warning {{Assigned value is always the same as the existing value}}
+
+  for (unsigned bg = 0; bg < 1024; bg ++) {
+    result = bg * result; // no-warning
+  }
+}
+void call_bailout2() {
+  for (int i = 0; i < 10; ++i)
+    bailout2();
+}
+
 // Relaxed liveness - check that we don't kill liveness at assignments
 typedef unsigned uintptr_t;
 void kill_at_assign() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2427.3.patch
Type: text/x-patch
Size: 2955 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131219/6018add8/attachment.bin>


More information about the cfe-commits mailing list