<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Tom,<div><br></div><div>Addressing the question about testing, I think that we should definitely include the tests for the stats checker. The checker itself is the means for testing so it's only natural to use it for testing. I think it is absolutely acceptable for someone to need to change the test after adding support for a new expression or increasing the code coverage.</div><div>(It would add a lot of benefit too. I spent hours yesterday tracking a code coverage issue (r151368), which could have been caught by the stats checker!)</div><div><br></div><div>If you think that some of the diagnostics will change a lot, you can use FileCheck instead of '-verify' to grep for only some of the output. (However, keeping in mind that the analyzer should be deterministic, I am not sure when this happens.)</div><div><br></div><div>A slightly outdated manual for FileCheck: </div><div>  <a href="http://llvm.org/cmds/FileCheck.html">http://llvm.org/cmds/FileCheck.html</a>.</div><div>Or take a look at some other tests using '// CHECK-NEXT:' and '// CHECK:':</div><div> - ./test/Analysis/malloc-plist.c</div><div> -./test/CodeGen/compound-literal.c</div><div><br></div><div>Anna.<br><div><div>On Feb 23, 2012, at 5:10 PM, Ted Kremenek wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">We probably should just add a general mechanism for holding onto ExplodedNodes, i.e., reference counts that say "this cannot be reclaimed".  There are various clients that want to do this, e.g. the IdempotentOperationsChecker.  In other words, this is a general problem we should just solve.  Having a general solution will allows us to aggressively trim the graph further without breaking various clients that depend on nodes staying around.<div><br></div><div>I wouldn't approach it by embedding a reference count in ExplodedNode, or if we did, just use a couple bits stolen from different fields.  If the count exceeds some threshold, we can just store the count in a side table in ExplodedGraph.</div><div><br></div><div>Note that in the common case the reference count we either be 0 or 1, depending on how we wanted to define the semantics (with "1" being for the ExplodedGraph is holding onto the node).<br><div><div><br><div><div>On Feb 23, 2012, at 4:59 PM, Anna Zaks <<a href="mailto:ganna@apple.com">ganna@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Thanks.<div><br></div><div>Looks like the node has been reclaimed and we are allocating a new one using the free memory.</div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span style="color: #8e0868">bool</span> ExplodedGraph::shouldCollect(<span style="color: #8e0868">const</span> <span style="color: #106241">ExplodedNode</span> *node) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// <span style="text-decoration: underline">Reclaimn</span> all nodes that match *all* the following criteria:</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">  <span style="color: #549172">//</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (1) 1 predecessor (that has one successor)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (2) 1 successor (that has one predecessor)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (3) The ProgramPoint is for a PostStmt.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (4) There is no 'tag' for the ProgramPoint.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (5) The 'store' is the same as the predecessor.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (6) The 'GDM' is the same as the predecessor.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (7) The LocationContext is the same as the predecessor.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>// (8) The PostStmt is for a non-consumed <span style="text-decoration: underline">Stmt</span> or <span style="text-decoration: underline">Expr</span>.</div></div><div><br></div><div>How about tagging the node? Would that solve the problem?</div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span style="color: #8e0868">- const</span> <span style="color: #106241">ExplodedNode</span> *node = Bldr.generateNode(S, Pred, Pred->getState());</div></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">  <span style="color: #2805ca">Engine</span>.addAbortedBlock(node, <span style="color: #2805ca">currentBuilderContext</span>->getBlock());</div><div><br></div></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(76, 9, 253); "><span style="color: #8e0868">+ static</span><span style="color: #000000"> </span><span style="color: #106241">SimpleProgramPointTag</span><span style="color: #000000"> Tag(</span>"Aborted: Unhandled symbol"<span style="color: #000000">);</span></div></div><div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span style="color: rgb(142, 8, 104); ">+ const</span> <span style="color: rgb(16, 98, 65); ">ExplodedNode</span> *node = Bldr.generateNode(S, Pred, Pred->getState(), false, &Tag);</div></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">  <span style="color: #2805ca">Engine</span>.addAbortedBlock(node, <span style="color: #2805ca">currentBuilderContext</span>->getBlock());</div></div><div><br></div><div>I did not give this much thought, but maybe we could use tags instead of the abortedBlocks list. </div><div>Anna.</div><div><div>On Feb 23, 2012, at 4:29 PM, Tom Care wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Sorry Anna yes I meant ProgramPoint.<div><br></div><div>I managed to reproduce the situation I was talking about in gdb, and I used a file in the LLVM tree so hopefully you can reproduce it.</div><div><br></div><div>I apologise for the wall of text! A brief run-through of what I did:</div><div>- added an assert to find when I cannot get a PostStmt from the ExplodedNode</div><div>- Tracked down an example to llvm/lib/Support/DeltaAlgorithm.cpp in function Search</div><div>- The third aborted block is the one that triggers my assertion.</div><div><br></div><div>In the gdb run-through below, you can see that when the aborted block is added (node=0x1075499b8, stmt=0x10680d8e8) that everything is as expected. I added a watchpoint for the ProgramPoint::Kind of the node. After a number of reads triggering it, we can see a write that changes the Location to a BlockEdge. At this point I did a backtrace. When the VisitEndAnalysis happens, we see that the same node=0x1075499b8 now has a BlockEdge as its Location and the stmt=0x10680d8e8 has been lost.</div><div><br></div><div>Let me know if you need any other information.</div><div><br></div><div>Tom</div><div><br></div><div>------------</div><div><br></div><div><div>Starting program: /Users/tcare/Projects/llvm-debug/bin/clang++ -cc1 -triple x86_64-apple-macosx10.7.0 -analyze -disable-free -main-file-name DeltaAlgorithm.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=unix -analyzer-checker=osx -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-output plist -w -pic-level 1 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -resource-dir /Users/tcare/Projects/llvm-debug/bin/../lib/clang/3.1 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /Users/tcare/Projects/llvm-analysis/include -I /Users/tcare/Projects/llvm-analysis/lib/Support -I /Users/tcare/Projects/llvm/include -I /Users/tcare/Projects/llvm/lib/Support -fmodule-cache-path /var/folders/cz/fgrz7bdd7mn19gj5hl3w25rw0000gn/T/clang-module-cache -Wno-unused-parameter -fdeprecated-macro -fdebug-compilation-dir /Users/tcare/Projects/llvm-analysis/lib/Support -ferror-limit 19 -fmessage-length 0 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-dispatch-method=mixed -fcxx-exceptions -fexceptions -fdiagnostics-show-option -analyzer-display-progress -analyzer-inline-call -analyzer-checker debug.Stats -analyzer-output=html -x c++ /Users/tcare/Projects/llvm/lib/Support/DeltaAlgorithm.cpp -analyze-function Search</div><div>ANALYZE: /Users/tcare/Projects/llvm/lib/Support/DeltaAlgorithm.cpp Search</div><div><br></div><div>Breakpoint 2, clang::ento::CoreEngine::addAbortedBlock (this=0x7fff5fbfce08, block=0x10733e400, node=0x1073cf268, stmt=0x10680d8e8) at CoreEngine.h:149</div><div>149<span class="Apple-tab-span" style="white-space:pre">        </span>    blocksAborted.push_back(std::make_pair(block, std::make_pair(node, stmt)));</div><div>(gdb) c</div><div>Continuing.</div><div><br></div><div>Breakpoint 2, clang::ento::CoreEngine::addAbortedBlock (this=0x7fff5fbfce08, block=0x10733f778, node=0x1075115a0, stmt=0x1072d0418) at CoreEngine.h:149</div><div>149<span class="Apple-tab-span" style="white-space:pre">  </span>    blocksAborted.push_back(std::make_pair(block, std::make_pair(node, stmt)));</div><div>(gdb) c</div><div>Continuing.</div><div><br></div><div>Breakpoint 2, clang::ento::CoreEngine::addAbortedBlock (this=0x7fff5fbfce08, block=0x10733e400, node=0x1075499b8, stmt=0x10680d8e8) at CoreEngine.h:149</div><div>149<span class="Apple-tab-span" style="white-space:pre">  </span>    blocksAborted.push_back(std::make_pair(block, std::make_pair(node, stmt)));</div><div>(gdb) p stmt->dump()</div><div>(CXXBindTemporaryExpr 0x10680d8e8 'class DeltaAlgorithm::changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >' (CXXTemporary 0x10680d8e0)</div><div>  (CXXMemberCallExpr 0x10680d870 'class DeltaAlgorithm::changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >'</div><div>    (MemberExpr 0x10680d7e8 '<bound member function type>' ->Delta 0x1072c80d0</div><div>      (CXXThisExpr 0x10680d7d0 'class llvm::DeltaAlgorithm *' this))</div><div>    (ImplicitCastExpr 0x10680d8a8 'const changeset_ty':'const class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >' lvalue <NoOp></div><div>      (DeclRefExpr 0x10680d820 'changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >' lvalue Var 0x1072d0700 'Complement' 'changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >'))</div><div>    (ImplicitCastExpr 0x10680d8c0 'const changesetlist_ty':'const class std::vector<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >, class std::allocator<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> > > >' lvalue <NoOp></div><div>      (DeclRefExpr 0x10680d848 'changesetlist_ty':'class std::vector<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >, class std::allocator<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> > > >' lvalue Var 0x1072d3020 'ComplementSets' 'changesetlist_ty':'class std::vector<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >, class std::allocator<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> > > >'))))</div><div>$2 = void</div><div>(gdb) p *node</div><div>$3 = {</div><div>  <llvm::FoldingSetImpl::Node> = {</div><div>    NextInFoldingSetBucket = 0x107423da0</div><div>  }, </div><div>  members of clang::ento::ExplodedNode: </div><div>  Location = {</div><div>    Data = {</div><div>      first = 0x10680d8e8, </div><div>      second = 0x0</div><div>    }, </div><div>    K = clang::ProgramPoint::PostStmtKind, </div><div>    L = 0x106580d30, </div><div>    Tag = 0x0</div><div>  }, </div><div>  State = {</div><div>    Obj = 0x1075498f8</div><div>  }, </div><div>  Preds = {</div><div>    P = 4417952112</div><div>  }, </div><div>  Succs = {</div><div>    P = 0</div><div>  }</div><div>}</div><div>(gdb) p &node->Location->K</div><div>$4 = ('clang::ProgramPoint::Kind' *) 0x1075499d0</div><div>(gdb) awatch *$4</div><div>Hardware access (read/write) watchpoint 3: *$4</div><div>(gdb) d 2</div><div>(gdb) c</div><div>Continuing.</div><div>Hardware access (read/write) watchpoint 3: *$4</div><div><br></div><div>Value = clang::ProgramPoint::PostStmtKind</div><div>0x00007fff92af4cde in memmove$VARIANT$sse42 ()</div><div>(gdb) </div><div>Continuing.</div><div>...several hits later...</div><div>Hardware access (read/write) watchpoint 3: *$4</div><div><br></div><div>Old value = clang::ProgramPoint::PostStmtKind</div><div>New value = clang::ProgramPoint::BlockEdgeKind</div><div>0x00007fff92af4ce4 in memmove$VARIANT$sse42 ()</div><div>(gdb) d 3</div><div>(gdb) bt</div><div>#0  0x00007fff92af4ce4 in memmove$VARIANT$sse42 ()</div><div>#1  0x0000000101090594 in clang::ento::ExplodedNode::ExplodedNode (this=0x1075499b8, loc=@0x7fff5fbfc4f8, state=@0x7fff5fbfc2f0, IsSink=false) at ExplodedGraph.h:122</div><div>#2  0x000000010108d1cc in clang::ento::ExplodedNode::ExplodedNode (this=0x1075499b8, loc=@0x7fff5fbfc4f8, state=<value temporarily unavailable, due to optimizations>, IsSink=false) at ExplodedGraph.h:125</div><div>#3  0x000000010108c160 in clang::ento::ExplodedGraph::getNode (this=0x10657eec0, L=@0x7fff5fbfc4f8, State=@0x7fff5fbfc438, IsSink=false, IsNew=0x7fff5fbfc44e) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp:257</div><div>#4  0x0000000101081992 in clang::ento::NodeBuilder::generateNodeImpl (this=0x7fff5fbfc6c8, Loc=@0x7fff5fbfc4f8, State=@0x7fff5fbfc4c0, FromN=0x107549a48, MarkAsSink=false) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:535</div><div>#5  0x0000000101081c96 in clang::ento::BranchNodeBuilder::generateNode (this=0x7fff5fbfc6c8, State=@0x7fff5fbfc5f0, branch=false, NodePred=0x107549a48) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:568</div><div>#6  0x0000000101097044 in clang::ento::ExprEngine::processBranch (this=0x7fff5fbfcdf0, Condition=0x10730a140, Term=0x10730b180, BldCtx=@0x7fff5fbfc8f0, Pred=0x107549a48, Dst=@0x7fff5fbfc888, DstT=0x10738d610, DstF=0x10738c528) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:1125</div><div>#7  0x00000001010812dd in clang::ento::CoreEngine::HandleBranch (this=0x7fff5fbfce08, Cond=0x10730a140, Term=0x10730b180, B=0x10738c770, Pred=0x107549a48) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:406</div><div>#8  0x0000000101081021 in clang::ento::CoreEngine::HandleBlockExit (this=0x7fff5fbfce08, B=0x10738c770, Pred=0x107549a48) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:388</div><div>#9  0x00000001010809e6 in clang::ento::CoreEngine::HandlePostStmt (this=0x7fff5fbfce08, B=0x10738c770, StmtIdx=1, Pred=0x107549a48) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:417</div><div>#10 0x000000010108027a in clang::ento::CoreEngine::ExecuteWorkList (this=0x7fff5fbfce08, L=0x106580d30, Steps=146026, InitState=@0x7fff5fbfcda0) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:228</div><div>#11 0x0000000100f3e0fd in clang::ento::ExprEngine::ExecuteWorkList (this=0x7fff5fbfcdf0, L=0x106580d30, Steps=150000) at ExprEngine.h:97</div><div>#12 0x0000000100f3d2bc in ActionExprEngine (C=@0x1065063a0, mgr=@0x10650d280, D=0x1072ceac0, ObjCGCEnabled=false) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:325</div><div>#13 0x0000000100f3d16f in RunPathSensitiveChecks (C=@0x1065063a0, mgr=@0x10650d280, D=0x1072ceac0) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:344</div><div>#14 0x0000000100f3cfd7 in (anonymous namespace)::AnalysisConsumer::HandleCode (this=0x1065063a0, D=0x1072ceac0) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:300</div><div>#15 0x0000000100f3c839 in (anonymous namespace)::AnalysisConsumer::HandleDeclContextDecl (this=0x1065063a0, C=@0x106829a00, D=0x1072ceac0) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:206</div><div>#16 0x0000000100f3c574 in (anonymous namespace)::AnalysisConsumer::HandleDeclContext (this=0x1065063a0, C=@0x106829a00, dc=0x10682c4f0) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:177</div><div>#17 0x0000000100f3c452 in (anonymous namespace)::AnalysisConsumer::HandleTranslationUnit (this=0x1065063a0, C=@0x106829a00) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:244</div><div>#18 0x0000000100634bb4 in clang::ParseAST (S=@0x106840200, PrintStats=false) at /Users/tcare/Projects/llvm/tools/clang/lib/Parse/ParseAST.cpp:106</div><div>#19 0x0000000100589488 in clang::ASTFrontendAction::ExecuteAction (this=0x106503ea0) at /Users/tcare/Projects/llvm/tools/clang/lib/Frontend/FrontendAction.cpp:414</div><div>#20 0x00000001005890d7 in clang::FrontendAction::Execute (this=0x106503ea0) at /Users/tcare/Projects/llvm/tools/clang/lib/Frontend/FrontendAction.cpp:334</div><div>#21 0x00000001005557b5 in clang::CompilerInstance::ExecuteAction (this=0x1065029b0, Act=@0x106503ea0) at /Users/tcare/Projects/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:653</div><div>#22 0x00000001000181cf in clang::ExecuteCompilerInvocation (Clang=0x1065029b0) at /Users/tcare/Projects/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:176</div><div>#23 0x0000000100009749 in cc1_main (ArgBegin=0x7fff5fbfea40, ArgEnd=0x7fff5fbfecb8, Argv0=0x106500d08 "/Users/tcare/Projects/llvm-debug/bin/clang++", MainAddr=0x100001a40) at /Users/tcare/Projects/llvm/tools/clang/tools/driver/cc1_main.cpp:165</div><div>#24 0x0000000100001c8d in main (argc_=81, argv_=0x7fff5fbff2b0) at /Users/tcare/Projects/llvm/tools/clang/tools/driver/driver.cpp:352</div><div>(gdb) c</div><div>Continuing.</div><div><br></div><div>Breakpoint 1, (anonymous namespace)::AnalyzerStatsChecker::emitAbortedStats (this=0x10650e050, Eng=@0x7fff5fbfcdf0, B=@0x7fff5fbfcfd8, SM=@0x106504c30) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp:170</div><div>170<span class="Apple-tab-span" style="white-space:pre">  </span>    const CoreEngine::AbortedStmtPair aborted = I->second;</div><div>(gdb) c</div><div>Continuing.</div><div><br></div><div>Breakpoint 1, (anonymous namespace)::AnalyzerStatsChecker::emitAbortedStats (this=0x10650e050, Eng=@0x7fff5fbfcdf0, B=@0x7fff5fbfcfd8, SM=@0x106504c30) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp:170</div><div>170<span class="Apple-tab-span" style="white-space:pre"> </span>    const CoreEngine::AbortedStmtPair aborted = I->second;</div><div>(gdb) c</div><div>Continuing.</div><div><br></div><div>Breakpoint 1, (anonymous namespace)::AnalyzerStatsChecker::emitAbortedStats (this=0x10650e050, Eng=@0x7fff5fbfcdf0, B=@0x7fff5fbfcfd8, SM=@0x106504c30) at /Users/tcare/Projects/llvm/tools/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp:170</div><div>170<span class="Apple-tab-span" style="white-space:pre"> </span>    const CoreEngine::AbortedStmtPair aborted = I->second;</div><div>(gdb) n </div><div>171<span class="Apple-tab-span" style="white-space:pre">       </span>    const LocationContext *LC = aborted.first->getLocationContext();</div><div>(gdb) n</div><div>173<span class="Apple-tab-span" style="white-space:pre">   </span>    const PostStmt *PS = aborted.first->getLocationAs<PostStmt>();</div><div>(gdb) n</div><div>174<span class="Apple-tab-span" style="white-space:pre">       </span>    assert(PS);</div><div>(gdb) p PS</div><div>$5 = (const 'clang::PostStmt' *) 0x0</div><div>(gdb) p aborted.first</div><div>$6 = (const 'clang::ento::ExplodedNode' *) 0x1075499b8</div><div>(gdb) p *aborted.first</div><div>$7 = {</div><div>  <llvm::FoldingSetImpl::Node> = {</div><div>    NextInFoldingSetBucket = 0x1067326a9</div><div>  }, </div><div>  members of clang::ento::ExplodedNode: </div><div>  Location = {</div><div>    Data = {</div><div>      first = 0x10738c770, </div><div>      second = 0x10738c528</div><div>    }, </div><div>    K = clang::ProgramPoint::BlockEdgeKind, </div><div>    L = 0x106584050, </div><div>    Tag = 0x0</div><div>  }, </div><div>  State = {</div><div>    Obj = 0x10755da98</div><div>  }, </div><div>  Preds = {</div><div>    P = 4417952328</div><div>  }, </div><div>  Succs = {</div><div>    P = 4417950920</div><div>  }</div><div>}</div><div>(gdb) p aborted->second</div><div>$8 = (const 'clang::Stmt' *) 0x10680d8e8</div><div><div>(gdb) p aborted->second->dump()</div><div>(CXXBindTemporaryExpr 0x10680d8e8 'class DeltaAlgorithm::changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >' (CXXTemporary 0x10680d8e0)</div><div>  (CXXMemberCallExpr 0x10680d870 'class DeltaAlgorithm::changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >'</div><div>    (MemberExpr 0x10680d7e8 '<bound member function type>' ->Delta 0x1072c80d0</div><div>      (CXXThisExpr 0x10680d7d0 'class llvm::DeltaAlgorithm *' this))</div><div>    (ImplicitCastExpr 0x10680d8a8 'const changeset_ty':'const class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >' lvalue <NoOp></div><div>      (DeclRefExpr 0x10680d820 'changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >' lvalue Var 0x1072d0700 'Complement' 'changeset_ty':'class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >'))</div><div>    (ImplicitCastExpr 0x10680d8c0 'const changesetlist_ty':'const class std::vector<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >, class std::allocator<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> > > >' lvalue <NoOp></div><div>      (DeclRefExpr 0x10680d848 'changesetlist_ty':'class std::vector<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >, class std::allocator<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> > > >' lvalue Var 0x1072d3020 'ComplementSets' 'changesetlist_ty':'class std::vector<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> >, class std::allocator<class std::set<unsigned int, struct std::less<unsigned int>, class std::allocator<unsigned int> > > >'))))</div><div>$9 = void</div></div><div><br></div><div><br></div><div><div>On 23/02/2012, at 11:26 PM, Anna Zaks wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Feb 23, 2012, at 1:50 PM, Tom Care wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>The reason I added a Stmt* was because the LocationContext of the node (which starts out as a PostStmt) can be overwritten to become a BlockEdge. The Stmt* pointer is lost in that case, and it becomes difficult to guess where the original Stmt was. Since we only add aborted blocks/nodes when a Stmt was unsupported, I thought that it was important to keep the original pointer to find out why we stopped.<br><br></div></blockquote><br><div>Tom, you must be talking about ProgramPoint/Location, not LocationContext, correct? Can you investigate where it gets overwritten? As far as I understand, it should never change, in fact, it's declared as const. We are only adding predecessors and successors to the ExplodedNodes; they should stay unchanged otherwise.</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span style="color: #8e0868">class</span> <span style="color: #106241">ExplodedNode</span> : <span style="color: #8e0868">public</span> llvm::FoldingSetNode {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">....</div></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>/// Location - The program location (within a function body) associated</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(84, 145, 114); "><span style="color: #000000">  </span>///  with this node.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; color: rgb(16, 98, 65); "><span style="color: #000000">  </span><span style="color: #8e0868">const</span><span style="color: #000000"> </span>ProgramPoint<span style="color: #000000"> </span><span style="color: #2805ca">Location</span><span style="color: #000000">;</span></div></div><br><blockquote type="cite"><div>Example of the new output:<br><br>/Users/tcare/Projects/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp:218:5: warning: The analyzer stopped at this point due to an unsupported statement of type CXXBindTemporaryExpr<br>    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;<br>    ^<br><br>/Users/tcare/Projects/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp:308:28: warning: The analyzer stopped because this block was visited too many times<br>  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {<br>                           ^<br><br>/Users/tcare/Projects/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp:934:11: warning: The analyzer stoppedat this point due to visitation limits<br>      if (T->isAnyPointerType() || T->isBlockPointerType())<br>          ^<br><br>(need to add a space in the last one)<br><br>I'm testing over all of LLVM/Clang right now as I am collecting data.<br><br>Tom<br><br>On 23/02/2012, at 6:04 PM, Anna Zaks wrote:<br><br><blockquote type="cite">On Feb 23, 2012, at 7:27 AM, Ted Kremenek wrote:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">Looks good to me.  Do you have an example of the new output?<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">On Feb 23, 2012, at 7:08 AM, Tom Care <<a href="mailto:tom.care@uqconnect.edu.au">tom.care@uqconnect.edu.au</a>> wrote:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">I made some changes to AnalyzerStatsChecker to make it a bit more useful. Changelog:<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> Improved the information output by AnalyzerStatsChecker. In addition to the analysis stats for Decls, AnalyzerStatsChecker now also outputs:<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> - Exhausted blocks and sinks, including their approximate location<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> - Aborted blocks and their statement locations<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> - When and where the analyzer reaches the max block limit<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> Some supporting infrastructure changes:<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> - CoreEngine now stores Stmt* with the ExplodedNode* in the aborted block data, since the node can change between generation and VisitEndAnalysis<br></blockquote></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">My understanding is that, here, we add a bit of overhead on every analyzes run to make stats more precise. <br></blockquote><blockquote type="cite">Could you elaborate/investigate a bit more on why it is absolutely necessary in this case? Is the ExplodedNode you are storing here deleted by the time you reach VisitEndAnalysis? (How is the node changed?)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> - Exposed 'block limit exceeded' tag to allow AnalyzerStatsChecker to detect a sink caused by exceeding the max visits for a block<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">Regarding test cases, any test case made for this checker would break quite frequently as the analyzer is changed. I can't think of a good way to solve this.<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Would be great if you could (manually) test this with -analyzer-inline-call.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">Been a while since my last commit, so a review is much appreciated :)<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">Tom<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><AnalyzerStatsChecker.patch>_______________________________________________<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">cfe-commits mailing list<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">_______________________________________________<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">cfe-commits mailing list<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><br><br></div></blockquote></div><br></div></blockquote></div><br></div></div></blockquote></div><br></div></div></blockquote></div><br></div></div></div></div></blockquote></div><br></div></body></html>