svf-tools 1.0.551 → 1.0.552

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -181,10 +181,10 @@ Static Private Member Functions</h2></td></tr>
181
181
  <p>Determines the strongly connected components of svfg following only edges labelled with object. partOf[n] = scc means nodes n is part of <a class="el" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html">SCC</a> scc. startingNodes contains the nodes to begin the search from. After completion, footprint will contain all edges which object appears on (as reached through the algorithm described above) sorted.</p>
182
182
  <p>This is not a general <a class="el" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html">SCC</a> detection but specifically for versioning, so edges to delta nodes are skipped as they are prelabelled. Edges to stores are also skipped to as they yield a new version (they cannot be part of an <a class="el" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html">SCC</a> containing more than themselves). Skipped edges still form part of the footprint. </p>
183
183
 
184
- <p class="definition">Definition at line <a class="el" href="VersionedFlowSensitive_8cpp_source.html#l00928">928</a> of file <a class="el" href="VersionedFlowSensitive_8cpp_source.html">VersionedFlowSensitive.cpp</a>.</p>
185
- <div class="fragment"><div class="line"><a name="l00933"></a><span class="lineno"> 933</span>&#160;{</div><div class="line"><a name="l00934"></a><span class="lineno"> 934</span>&#160; partOf.resize(svfg-&gt;<a class="code" href="classSVF_1_1GenericGraph.html#a8c8d16036008f87c7811586047599858">getTotalNodeNum</a>());</div><div class="line"><a name="l00935"></a><span class="lineno"> 935</span>&#160; std::fill(partOf.begin(), partOf.end(), -1);</div><div class="line"><a name="l00936"></a><span class="lineno"> 936</span>&#160; footprint.clear();</div><div class="line"><a name="l00937"></a><span class="lineno"> 937</span>&#160;</div><div class="line"><a name="l00938"></a><span class="lineno"> 938</span>&#160; std::vector&lt;NodeData&gt; nodeData(svfg-&gt;<a class="code" href="classSVF_1_1GenericGraph.html#a8c8d16036008f87c7811586047599858">getTotalNodeNum</a>(), { -1, -1, <span class="keyword">false</span>});</div><div class="line"><a name="l00939"></a><span class="lineno"> 939</span>&#160; std::stack&lt;const SVFGNode *&gt; stack;</div><div class="line"><a name="l00940"></a><span class="lineno"> 940</span>&#160;</div><div class="line"><a name="l00941"></a><span class="lineno"> 941</span>&#160; <span class="keywordtype">int</span> <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a> = 0;</div><div class="line"><a name="l00942"></a><span class="lineno"> 942</span>&#160; <span class="keywordtype">int</span> currentSCC = 0;</div><div class="line"><a name="l00943"></a><span class="lineno"> 943</span>&#160;</div><div class="line"><a name="l00944"></a><span class="lineno"> 944</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGNode.html">SVFGNode</a> *v : startingNodes)</div><div class="line"><a name="l00945"></a><span class="lineno"> 945</span>&#160; {</div><div class="line"><a name="l00946"></a><span class="lineno"> 946</span>&#160; <span class="keywordflow">if</span> (nodeData[v-&gt;getId()].index == -1)</div><div class="line"><a name="l00947"></a><span class="lineno"> 947</span>&#160; {</div><div class="line"><a name="l00948"></a><span class="lineno"> 948</span>&#160; <a class="code" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">visit</a>(vfs, <span class="keywordtype">object</span>, partOf, footprint, nodeData, stack, index, currentSCC, v);</div><div class="line"><a name="l00949"></a><span class="lineno"> 949</span>&#160; }</div><div class="line"><a name="l00950"></a><span class="lineno"> 950</span>&#160; }</div><div class="line"><a name="l00951"></a><span class="lineno"> 951</span>&#160;</div><div class="line"><a name="l00952"></a><span class="lineno"> 952</span>&#160; <span class="comment">// Make sure footprints with the same edges pass ==/hash the same.</span></div><div class="line"><a name="l00953"></a><span class="lineno"> 953</span>&#160; std::sort(footprint.begin(), footprint.end());</div><div class="line"><a name="l00954"></a><span class="lineno"> 954</span>&#160;</div><div class="line"><a name="l00955"></a><span class="lineno"> 955</span>&#160; <span class="keywordflow">return</span> currentSCC;</div><div class="line"><a name="l00956"></a><span class="lineno"> 956</span>&#160;}</div><div class="ttc" id="cJSON_8h_html_a750b5d744c39a06bfb13e6eb010e35d0"><div class="ttname"><a href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a></div><div class="ttdeci">int index</div><div class="ttdef"><b>Definition:</b> <a href="cJSON_8h_source.html#l00170">cJSON.h:170</a></div></div>
184
+ <p class="definition">Definition at line <a class="el" href="VersionedFlowSensitive_8cpp_source.html#l00954">954</a> of file <a class="el" href="VersionedFlowSensitive_8cpp_source.html">VersionedFlowSensitive.cpp</a>.</p>
185
+ <div class="fragment"><div class="line"><a name="l00959"></a><span class="lineno"> 959</span>&#160;{</div><div class="line"><a name="l00960"></a><span class="lineno"> 960</span>&#160; partOf.resize(svfg-&gt;<a class="code" href="classSVF_1_1GenericGraph.html#a8c8d16036008f87c7811586047599858">getTotalNodeNum</a>());</div><div class="line"><a name="l00961"></a><span class="lineno"> 961</span>&#160; std::fill(partOf.begin(), partOf.end(), -1);</div><div class="line"><a name="l00962"></a><span class="lineno"> 962</span>&#160; footprint.clear();</div><div class="line"><a name="l00963"></a><span class="lineno"> 963</span>&#160;</div><div class="line"><a name="l00964"></a><span class="lineno"> 964</span>&#160; std::vector&lt;NodeData&gt; nodeData(svfg-&gt;<a class="code" href="classSVF_1_1GenericGraph.html#a8c8d16036008f87c7811586047599858">getTotalNodeNum</a>(), { -1, -1, <span class="keyword">false</span>});</div><div class="line"><a name="l00965"></a><span class="lineno"> 965</span>&#160; std::stack&lt;const SVFGNode *&gt; stack;</div><div class="line"><a name="l00966"></a><span class="lineno"> 966</span>&#160;</div><div class="line"><a name="l00967"></a><span class="lineno"> 967</span>&#160; <span class="keywordtype">int</span> <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a> = 0;</div><div class="line"><a name="l00968"></a><span class="lineno"> 968</span>&#160; <span class="keywordtype">int</span> currentSCC = 0;</div><div class="line"><a name="l00969"></a><span class="lineno"> 969</span>&#160;</div><div class="line"><a name="l00970"></a><span class="lineno"> 970</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGNode.html">SVFGNode</a> *v : startingNodes)</div><div class="line"><a name="l00971"></a><span class="lineno"> 971</span>&#160; {</div><div class="line"><a name="l00972"></a><span class="lineno"> 972</span>&#160; <span class="keywordflow">if</span> (nodeData[v-&gt;getId()].index == -1)</div><div class="line"><a name="l00973"></a><span class="lineno"> 973</span>&#160; {</div><div class="line"><a name="l00974"></a><span class="lineno"> 974</span>&#160; <a class="code" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">visit</a>(vfs, <span class="keywordtype">object</span>, partOf, footprint, nodeData, stack, index, currentSCC, v);</div><div class="line"><a name="l00975"></a><span class="lineno"> 975</span>&#160; }</div><div class="line"><a name="l00976"></a><span class="lineno"> 976</span>&#160; }</div><div class="line"><a name="l00977"></a><span class="lineno"> 977</span>&#160;</div><div class="line"><a name="l00978"></a><span class="lineno"> 978</span>&#160; <span class="comment">// Make sure footprints with the same edges pass ==/hash the same.</span></div><div class="line"><a name="l00979"></a><span class="lineno"> 979</span>&#160; std::sort(footprint.begin(), footprint.end());</div><div class="line"><a name="l00980"></a><span class="lineno"> 980</span>&#160;</div><div class="line"><a name="l00981"></a><span class="lineno"> 981</span>&#160; <span class="keywordflow">return</span> currentSCC;</div><div class="line"><a name="l00982"></a><span class="lineno"> 982</span>&#160;}</div><div class="ttc" id="cJSON_8h_html_a750b5d744c39a06bfb13e6eb010e35d0"><div class="ttname"><a href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a></div><div class="ttdeci">int index</div><div class="ttdef"><b>Definition:</b> <a href="cJSON_8h_source.html#l00170">cJSON.h:170</a></div></div>
186
186
  <div class="ttc" id="classSVF_1_1GenericGraph_html_a8c8d16036008f87c7811586047599858"><div class="ttname"><a href="classSVF_1_1GenericGraph.html#a8c8d16036008f87c7811586047599858">SVF::GenericGraph::getTotalNodeNum</a></div><div class="ttdeci">u32_t getTotalNodeNum() const</div><div class="ttdoc">Get total number of node/edge. </div><div class="ttdef"><b>Definition:</b> <a href="GenericGraph_8h_source.html#l00418">GenericGraph.h:418</a></div></div>
187
- <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_1_1SCC_html_af7ba77d72962b930a8107752e259008b"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">SVF::VersionedFlowSensitive::SCC::visit</a></div><div class="ttdeci">static void visit(VersionedFlowSensitive *vfs, const NodeID object, std::vector&lt; int &gt; &amp;partOf, std::vector&lt; const IndirectSVFGEdge *&gt; &amp;footprint, std::vector&lt; NodeData &gt; &amp;nodeData, std::stack&lt; const SVFGNode *&gt; &amp;stack, int &amp;index, int &amp;currentSCC, const SVFGNode *v)</div><div class="ttdoc">Called by detectSCCs then called recursively. </div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00958">VersionedFlowSensitive.cpp:958</a></div></div>
187
+ <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_1_1SCC_html_af7ba77d72962b930a8107752e259008b"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">SVF::VersionedFlowSensitive::SCC::visit</a></div><div class="ttdeci">static void visit(VersionedFlowSensitive *vfs, const NodeID object, std::vector&lt; int &gt; &amp;partOf, std::vector&lt; const IndirectSVFGEdge *&gt; &amp;footprint, std::vector&lt; NodeData &gt; &amp;nodeData, std::stack&lt; const SVFGNode *&gt; &amp;stack, int &amp;index, int &amp;currentSCC, const SVFGNode *v)</div><div class="ttdoc">Called by detectSCCs then called recursively. </div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00984">VersionedFlowSensitive.cpp:984</a></div></div>
188
188
  <div class="ttc" id="classSVF_1_1VFGNode_html"><div class="ttname"><a href="classSVF_1_1VFGNode.html">SVF::VFGNode</a></div><div class="ttdef"><b>Definition:</b> <a href="VFGNode_8h_source.html#l00046">VFGNode.h:46</a></div></div>
189
189
  </div><!-- fragment -->
190
190
  </div>
@@ -267,16 +267,16 @@ Static Private Member Functions</h2></td></tr>
267
267
 
268
268
  <p>Called by detectSCCs then called recursively. </p>
269
269
 
270
- <p class="definition">Definition at line <a class="el" href="VersionedFlowSensitive_8cpp_source.html#l00958">958</a> of file <a class="el" href="VersionedFlowSensitive_8cpp_source.html">VersionedFlowSensitive.cpp</a>.</p>
271
- <div class="fragment"><div class="line"><a name="l00967"></a><span class="lineno"> 967</span>&#160;{</div><div class="line"><a name="l00968"></a><span class="lineno"> 968</span>&#160; <span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> vId = v-&gt;<a class="code" href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">getId</a>();</div><div class="line"><a name="l00969"></a><span class="lineno"> 969</span>&#160;</div><div class="line"><a name="l00970"></a><span class="lineno"> 970</span>&#160; nodeData[vId].index = <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>;</div><div class="line"><a name="l00971"></a><span class="lineno"> 971</span>&#160; nodeData[vId].lowlink = <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>;</div><div class="line"><a name="l00972"></a><span class="lineno"> 972</span>&#160; ++<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>;</div><div class="line"><a name="l00973"></a><span class="lineno"> 973</span>&#160;</div><div class="line"><a name="l00974"></a><span class="lineno"> 974</span>&#160; stack.push(v);</div><div class="line"><a name="l00975"></a><span class="lineno"> 975</span>&#160; nodeData[vId].onStack = <span class="keyword">true</span>;</div><div class="line"><a name="l00976"></a><span class="lineno"> 976</span>&#160;</div><div class="line"><a name="l00977"></a><span class="lineno"> 977</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGEdge.html">SVFGEdge</a> *e : v-&gt;<a class="code" href="classSVF_1_1GenericNode.html#a2d9cd758d6f8c5189d9b90b74f43e009">getOutEdges</a>())</div><div class="line"><a name="l00978"></a><span class="lineno"> 978</span>&#160; {</div><div class="line"><a name="l00979"></a><span class="lineno"> 979</span>&#160; <span class="keyword">const</span> <a class="code" href="classSVF_1_1IndirectSVFGEdge.html">IndirectSVFGEdge</a> *ie = <a class="code" href="namespaceSVF_1_1SVFUtil.html#a8182be247907420db00837cef9bcfa70">SVFUtil::dyn_cast</a>&lt;<a class="code" href="classSVF_1_1IndirectSVFGEdge.html">IndirectSVFGEdge</a>&gt;(e);</div><div class="line"><a name="l00980"></a><span class="lineno"> 980</span>&#160; <span class="keywordflow">if</span> (!ie) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00981"></a><span class="lineno"> 981</span>&#160;</div><div class="line"><a name="l00982"></a><span class="lineno"> 982</span>&#160; <span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGNode.html">SVFGNode</a> *w = ie-&gt;<a class="code" href="classSVF_1_1GenericEdge.html#aeaa31a2c8479e831b36ce2e2582ceb86">getDstNode</a>();</div><div class="line"><a name="l00983"></a><span class="lineno"> 983</span>&#160; <span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> wId = w-&gt;<a class="code" href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">getId</a>();</div><div class="line"><a name="l00984"></a><span class="lineno"> 984</span>&#160;</div><div class="line"><a name="l00985"></a><span class="lineno"> 985</span>&#160; <span class="comment">// If object is not part of the edge, there is no edge from v to w.</span></div><div class="line"><a name="l00986"></a><span class="lineno"> 986</span>&#160; <span class="keywordflow">if</span> (!ie-&gt;<a class="code" href="classSVF_1_1IndirectSVFGEdge.html#a30aca718d25924f1babdf348bb0ace71">getPointsTo</a>().<a class="code" href="classSVF_1_1SparseBitVector.html#a112f2ede1240c95f9fe810f2882fab80">test</a>(<span class="keywordtype">object</span>)) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00987"></a><span class="lineno"> 987</span>&#160;</div><div class="line"><a name="l00988"></a><span class="lineno"> 988</span>&#160; <span class="comment">// Even if we don&#39;t count edges to stores and deltas for SCCs&#39; sake, they</span></div><div class="line"><a name="l00989"></a><span class="lineno"> 989</span>&#160; <span class="comment">// are relevant to the footprint as a propagation still occurs over such edges.</span></div><div class="line"><a name="l00990"></a><span class="lineno"> 990</span>&#160; footprint.push_back(ie);</div><div class="line"><a name="l00991"></a><span class="lineno"> 991</span>&#160;</div><div class="line"><a name="l00992"></a><span class="lineno"> 992</span>&#160; <span class="comment">// Ignore edges to delta nodes because they are prelabeled so cannot</span></div><div class="line"><a name="l00993"></a><span class="lineno"> 993</span>&#160; <span class="comment">// be part of the SCC v is in (already in nodesTodo from the prelabeled set).</span></div><div class="line"><a name="l00994"></a><span class="lineno"> 994</span>&#160; <span class="comment">// Similarly, store nodes.</span></div><div class="line"><a name="l00995"></a><span class="lineno"> 995</span>&#160; <span class="keywordflow">if</span> (vfs-&gt;<a class="code" href="classSVF_1_1VersionedFlowSensitive.html#a9f9b00551c157f42d1d995e8c4efb54b">delta</a>(wId) || vfs-&gt;<a class="code" href="classSVF_1_1VersionedFlowSensitive.html#aac920c9a5f13dd147e3c130425e005eb">isStore</a>(wId)) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00996"></a><span class="lineno"> 996</span>&#160;</div><div class="line"><a name="l00997"></a><span class="lineno"> 997</span>&#160; <span class="keywordflow">if</span> (nodeData[wId].<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a> == -1)</div><div class="line"><a name="l00998"></a><span class="lineno"> 998</span>&#160; {</div><div class="line"><a name="l00999"></a><span class="lineno"> 999</span>&#160; <a class="code" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">visit</a>(vfs, <span class="keywordtype">object</span>, partOf, footprint, nodeData, stack, <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>, currentSCC, w);</div><div class="line"><a name="l01000"></a><span class="lineno"> 1000</span>&#160; nodeData[vId].lowlink = std::min(nodeData[vId].lowlink, nodeData[wId].lowlink);</div><div class="line"><a name="l01001"></a><span class="lineno"> 1001</span>&#160; }</div><div class="line"><a name="l01002"></a><span class="lineno"> 1002</span>&#160; <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nodeData[wId].onStack)</div><div class="line"><a name="l01003"></a><span class="lineno"> 1003</span>&#160; {</div><div class="line"><a name="l01004"></a><span class="lineno"> 1004</span>&#160; nodeData[vId].lowlink = std::min(nodeData[vId].lowlink, nodeData[wId].<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>);</div><div class="line"><a name="l01005"></a><span class="lineno"> 1005</span>&#160; }</div><div class="line"><a name="l01006"></a><span class="lineno"> 1006</span>&#160; }</div><div class="line"><a name="l01007"></a><span class="lineno"> 1007</span>&#160;</div><div class="line"><a name="l01008"></a><span class="lineno"> 1008</span>&#160; <span class="keywordflow">if</span> (nodeData[vId].lowlink == nodeData[vId].<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>)</div><div class="line"><a name="l01009"></a><span class="lineno"> 1009</span>&#160; {</div><div class="line"><a name="l01010"></a><span class="lineno"> 1010</span>&#160; <span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGNode.html">SVFGNode</a> *w = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l01011"></a><span class="lineno"> 1011</span>&#160; <span class="keywordflow">do</span></div><div class="line"><a name="l01012"></a><span class="lineno"> 1012</span>&#160; {</div><div class="line"><a name="l01013"></a><span class="lineno"> 1013</span>&#160; w = stack.top();</div><div class="line"><a name="l01014"></a><span class="lineno"> 1014</span>&#160; stack.pop();</div><div class="line"><a name="l01015"></a><span class="lineno"> 1015</span>&#160; <span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> wId = w-&gt;<a class="code" href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">getId</a>();</div><div class="line"><a name="l01016"></a><span class="lineno"> 1016</span>&#160; nodeData[wId].onStack = <span class="keyword">false</span>;</div><div class="line"><a name="l01017"></a><span class="lineno"> 1017</span>&#160; partOf[wId] = currentSCC;</div><div class="line"><a name="l01018"></a><span class="lineno"> 1018</span>&#160; }</div><div class="line"><a name="l01019"></a><span class="lineno"> 1019</span>&#160; <span class="keywordflow">while</span> (w != v);</div><div class="line"><a name="l01020"></a><span class="lineno"> 1020</span>&#160;</div><div class="line"><a name="l01021"></a><span class="lineno"> 1021</span>&#160; <span class="comment">// For the next SCC.</span></div><div class="line"><a name="l01022"></a><span class="lineno"> 1022</span>&#160; ++currentSCC;</div><div class="line"><a name="l01023"></a><span class="lineno"> 1023</span>&#160; }</div><div class="line"><a name="l01024"></a><span class="lineno"> 1024</span>&#160;}</div><div class="ttc" id="cJSON_8h_html_a750b5d744c39a06bfb13e6eb010e35d0"><div class="ttname"><a href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a></div><div class="ttdeci">int index</div><div class="ttdef"><b>Definition:</b> <a href="cJSON_8h_source.html#l00170">cJSON.h:170</a></div></div>
270
+ <p class="definition">Definition at line <a class="el" href="VersionedFlowSensitive_8cpp_source.html#l00984">984</a> of file <a class="el" href="VersionedFlowSensitive_8cpp_source.html">VersionedFlowSensitive.cpp</a>.</p>
271
+ <div class="fragment"><div class="line"><a name="l00993"></a><span class="lineno"> 993</span>&#160;{</div><div class="line"><a name="l00994"></a><span class="lineno"> 994</span>&#160; <span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> vId = v-&gt;<a class="code" href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">getId</a>();</div><div class="line"><a name="l00995"></a><span class="lineno"> 995</span>&#160;</div><div class="line"><a name="l00996"></a><span class="lineno"> 996</span>&#160; nodeData[vId].index = <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>;</div><div class="line"><a name="l00997"></a><span class="lineno"> 997</span>&#160; nodeData[vId].lowlink = <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>;</div><div class="line"><a name="l00998"></a><span class="lineno"> 998</span>&#160; ++<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>;</div><div class="line"><a name="l00999"></a><span class="lineno"> 999</span>&#160;</div><div class="line"><a name="l01000"></a><span class="lineno"> 1000</span>&#160; stack.push(v);</div><div class="line"><a name="l01001"></a><span class="lineno"> 1001</span>&#160; nodeData[vId].onStack = <span class="keyword">true</span>;</div><div class="line"><a name="l01002"></a><span class="lineno"> 1002</span>&#160;</div><div class="line"><a name="l01003"></a><span class="lineno"> 1003</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGEdge.html">SVFGEdge</a> *e : v-&gt;<a class="code" href="classSVF_1_1GenericNode.html#a2d9cd758d6f8c5189d9b90b74f43e009">getOutEdges</a>())</div><div class="line"><a name="l01004"></a><span class="lineno"> 1004</span>&#160; {</div><div class="line"><a name="l01005"></a><span class="lineno"> 1005</span>&#160; <span class="keyword">const</span> <a class="code" href="classSVF_1_1IndirectSVFGEdge.html">IndirectSVFGEdge</a> *ie = <a class="code" href="namespaceSVF_1_1SVFUtil.html#a8182be247907420db00837cef9bcfa70">SVFUtil::dyn_cast</a>&lt;<a class="code" href="classSVF_1_1IndirectSVFGEdge.html">IndirectSVFGEdge</a>&gt;(e);</div><div class="line"><a name="l01006"></a><span class="lineno"> 1006</span>&#160; <span class="keywordflow">if</span> (!ie) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l01007"></a><span class="lineno"> 1007</span>&#160;</div><div class="line"><a name="l01008"></a><span class="lineno"> 1008</span>&#160; <span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGNode.html">SVFGNode</a> *w = ie-&gt;<a class="code" href="classSVF_1_1GenericEdge.html#aeaa31a2c8479e831b36ce2e2582ceb86">getDstNode</a>();</div><div class="line"><a name="l01009"></a><span class="lineno"> 1009</span>&#160; <span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> wId = w-&gt;<a class="code" href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">getId</a>();</div><div class="line"><a name="l01010"></a><span class="lineno"> 1010</span>&#160;</div><div class="line"><a name="l01011"></a><span class="lineno"> 1011</span>&#160; <span class="comment">// If object is not part of the edge, there is no edge from v to w.</span></div><div class="line"><a name="l01012"></a><span class="lineno"> 1012</span>&#160; <span class="keywordflow">if</span> (!ie-&gt;<a class="code" href="classSVF_1_1IndirectSVFGEdge.html#a30aca718d25924f1babdf348bb0ace71">getPointsTo</a>().<a class="code" href="classSVF_1_1SparseBitVector.html#a112f2ede1240c95f9fe810f2882fab80">test</a>(<span class="keywordtype">object</span>)) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l01013"></a><span class="lineno"> 1013</span>&#160;</div><div class="line"><a name="l01014"></a><span class="lineno"> 1014</span>&#160; <span class="comment">// Even if we don&#39;t count edges to stores and deltas for SCCs&#39; sake, they</span></div><div class="line"><a name="l01015"></a><span class="lineno"> 1015</span>&#160; <span class="comment">// are relevant to the footprint as a propagation still occurs over such edges.</span></div><div class="line"><a name="l01016"></a><span class="lineno"> 1016</span>&#160; footprint.push_back(ie);</div><div class="line"><a name="l01017"></a><span class="lineno"> 1017</span>&#160;</div><div class="line"><a name="l01018"></a><span class="lineno"> 1018</span>&#160; <span class="comment">// Ignore edges to delta nodes because they are prelabeled so cannot</span></div><div class="line"><a name="l01019"></a><span class="lineno"> 1019</span>&#160; <span class="comment">// be part of the SCC v is in (already in nodesTodo from the prelabeled set).</span></div><div class="line"><a name="l01020"></a><span class="lineno"> 1020</span>&#160; <span class="comment">// Similarly, store nodes.</span></div><div class="line"><a name="l01021"></a><span class="lineno"> 1021</span>&#160; <span class="keywordflow">if</span> (vfs-&gt;<a class="code" href="classSVF_1_1VersionedFlowSensitive.html#a9f9b00551c157f42d1d995e8c4efb54b">delta</a>(wId) || vfs-&gt;<a class="code" href="classSVF_1_1VersionedFlowSensitive.html#aac920c9a5f13dd147e3c130425e005eb">isStore</a>(wId)) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l01022"></a><span class="lineno"> 1022</span>&#160;</div><div class="line"><a name="l01023"></a><span class="lineno"> 1023</span>&#160; <span class="keywordflow">if</span> (nodeData[wId].<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a> == -1)</div><div class="line"><a name="l01024"></a><span class="lineno"> 1024</span>&#160; {</div><div class="line"><a name="l01025"></a><span class="lineno"> 1025</span>&#160; <a class="code" href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">visit</a>(vfs, <span class="keywordtype">object</span>, partOf, footprint, nodeData, stack, <a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>, currentSCC, w);</div><div class="line"><a name="l01026"></a><span class="lineno"> 1026</span>&#160; nodeData[vId].lowlink = std::min(nodeData[vId].lowlink, nodeData[wId].lowlink);</div><div class="line"><a name="l01027"></a><span class="lineno"> 1027</span>&#160; }</div><div class="line"><a name="l01028"></a><span class="lineno"> 1028</span>&#160; <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nodeData[wId].onStack)</div><div class="line"><a name="l01029"></a><span class="lineno"> 1029</span>&#160; {</div><div class="line"><a name="l01030"></a><span class="lineno"> 1030</span>&#160; nodeData[vId].lowlink = std::min(nodeData[vId].lowlink, nodeData[wId].<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>);</div><div class="line"><a name="l01031"></a><span class="lineno"> 1031</span>&#160; }</div><div class="line"><a name="l01032"></a><span class="lineno"> 1032</span>&#160; }</div><div class="line"><a name="l01033"></a><span class="lineno"> 1033</span>&#160;</div><div class="line"><a name="l01034"></a><span class="lineno"> 1034</span>&#160; <span class="keywordflow">if</span> (nodeData[vId].lowlink == nodeData[vId].<a class="code" href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>)</div><div class="line"><a name="l01035"></a><span class="lineno"> 1035</span>&#160; {</div><div class="line"><a name="l01036"></a><span class="lineno"> 1036</span>&#160; <span class="keyword">const</span> <a class="code" href="classSVF_1_1VFGNode.html">SVFGNode</a> *w = <span class="keyword">nullptr</span>;</div><div class="line"><a name="l01037"></a><span class="lineno"> 1037</span>&#160; <span class="keywordflow">do</span></div><div class="line"><a name="l01038"></a><span class="lineno"> 1038</span>&#160; {</div><div class="line"><a name="l01039"></a><span class="lineno"> 1039</span>&#160; w = stack.top();</div><div class="line"><a name="l01040"></a><span class="lineno"> 1040</span>&#160; stack.pop();</div><div class="line"><a name="l01041"></a><span class="lineno"> 1041</span>&#160; <span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> wId = w-&gt;<a class="code" href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">getId</a>();</div><div class="line"><a name="l01042"></a><span class="lineno"> 1042</span>&#160; nodeData[wId].onStack = <span class="keyword">false</span>;</div><div class="line"><a name="l01043"></a><span class="lineno"> 1043</span>&#160; partOf[wId] = currentSCC;</div><div class="line"><a name="l01044"></a><span class="lineno"> 1044</span>&#160; }</div><div class="line"><a name="l01045"></a><span class="lineno"> 1045</span>&#160; <span class="keywordflow">while</span> (w != v);</div><div class="line"><a name="l01046"></a><span class="lineno"> 1046</span>&#160;</div><div class="line"><a name="l01047"></a><span class="lineno"> 1047</span>&#160; <span class="comment">// For the next SCC.</span></div><div class="line"><a name="l01048"></a><span class="lineno"> 1048</span>&#160; ++currentSCC;</div><div class="line"><a name="l01049"></a><span class="lineno"> 1049</span>&#160; }</div><div class="line"><a name="l01050"></a><span class="lineno"> 1050</span>&#160;}</div><div class="ttc" id="cJSON_8h_html_a750b5d744c39a06bfb13e6eb010e35d0"><div class="ttname"><a href="cJSON_8h.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a></div><div class="ttdeci">int index</div><div class="ttdef"><b>Definition:</b> <a href="cJSON_8h_source.html#l00170">cJSON.h:170</a></div></div>
272
272
  <div class="ttc" id="namespaceSVF_html_a43a65e0d33af3c743294f7a1139d2301"><div class="ttname"><a href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">SVF::NodeID</a></div><div class="ttdeci">unsigned NodeID</div><div class="ttdef"><b>Definition:</b> <a href="MTAResultValidator_8h_source.html#l00019">MTAResultValidator.h:19</a></div></div>
273
273
  <div class="ttc" id="classSVF_1_1SparseBitVector_html_a112f2ede1240c95f9fe810f2882fab80"><div class="ttname"><a href="classSVF_1_1SparseBitVector.html#a112f2ede1240c95f9fe810f2882fab80">SVF::SparseBitVector::test</a></div><div class="ttdeci">bool test(unsigned Idx) const</div><div class="ttdef"><b>Definition:</b> <a href="SparseBitVector_8h_source.html#l00706">SparseBitVector.h:706</a></div></div>
274
- <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_html_aac920c9a5f13dd147e3c130425e005eb"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive.html#aac920c9a5f13dd147e3c130425e005eb">SVF::VersionedFlowSensitive::isStore</a></div><div class="ttdeci">virtual bool isStore(const NodeID l) const</div><div class="ttdoc">Returns true if l is a store node. </div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00429">VersionedFlowSensitive.cpp:429</a></div></div>
275
- <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_html_a9f9b00551c157f42d1d995e8c4efb54b"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive.html#a9f9b00551c157f42d1d995e8c4efb54b">SVF::VersionedFlowSensitive::delta</a></div><div class="ttdeci">virtual bool delta(const NodeID l) const</div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00406">VersionedFlowSensitive.cpp:406</a></div></div>
274
+ <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_html_aac920c9a5f13dd147e3c130425e005eb"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive.html#aac920c9a5f13dd147e3c130425e005eb">SVF::VersionedFlowSensitive::isStore</a></div><div class="ttdeci">virtual bool isStore(const NodeID l) const</div><div class="ttdoc">Returns true if l is a store node. </div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00455">VersionedFlowSensitive.cpp:455</a></div></div>
275
+ <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_html_a9f9b00551c157f42d1d995e8c4efb54b"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive.html#a9f9b00551c157f42d1d995e8c4efb54b">SVF::VersionedFlowSensitive::delta</a></div><div class="ttdeci">virtual bool delta(const NodeID l) const</div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00432">VersionedFlowSensitive.cpp:432</a></div></div>
276
276
  <div class="ttc" id="classSVF_1_1VFGEdge_html"><div class="ttname"><a href="classSVF_1_1VFGEdge.html">SVF::VFGEdge</a></div><div class="ttdef"><b>Definition:</b> <a href="VFGEdge_8h_source.html#l00044">VFGEdge.h:44</a></div></div>
277
277
  <div class="ttc" id="classSVF_1_1GenericEdge_html_aeaa31a2c8479e831b36ce2e2582ceb86"><div class="ttname"><a href="classSVF_1_1GenericEdge.html#aeaa31a2c8479e831b36ce2e2582ceb86">SVF::GenericEdge::getDstNode</a></div><div class="ttdeci">NodeType * getDstNode() const</div><div class="ttdef"><b>Definition:</b> <a href="GenericGraph_8h_source.html#l00093">GenericGraph.h:93</a></div></div>
278
278
  <div class="ttc" id="classSVF_1_1GenericNode_html_a2d9cd758d6f8c5189d9b90b74f43e009"><div class="ttname"><a href="classSVF_1_1GenericNode.html#a2d9cd758d6f8c5189d9b90b74f43e009">SVF::GenericNode::getOutEdges</a></div><div class="ttdeci">const GEdgeSetTy &amp; getOutEdges() const</div><div class="ttdef"><b>Definition:</b> <a href="GenericGraph_8h_source.html#l00182">GenericGraph.h:182</a></div></div>
279
- <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_1_1SCC_html_af7ba77d72962b930a8107752e259008b"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">SVF::VersionedFlowSensitive::SCC::visit</a></div><div class="ttdeci">static void visit(VersionedFlowSensitive *vfs, const NodeID object, std::vector&lt; int &gt; &amp;partOf, std::vector&lt; const IndirectSVFGEdge *&gt; &amp;footprint, std::vector&lt; NodeData &gt; &amp;nodeData, std::stack&lt; const SVFGNode *&gt; &amp;stack, int &amp;index, int &amp;currentSCC, const SVFGNode *v)</div><div class="ttdoc">Called by detectSCCs then called recursively. </div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00958">VersionedFlowSensitive.cpp:958</a></div></div>
279
+ <div class="ttc" id="classSVF_1_1VersionedFlowSensitive_1_1SCC_html_af7ba77d72962b930a8107752e259008b"><div class="ttname"><a href="classSVF_1_1VersionedFlowSensitive_1_1SCC.html#af7ba77d72962b930a8107752e259008b">SVF::VersionedFlowSensitive::SCC::visit</a></div><div class="ttdeci">static void visit(VersionedFlowSensitive *vfs, const NodeID object, std::vector&lt; int &gt; &amp;partOf, std::vector&lt; const IndirectSVFGEdge *&gt; &amp;footprint, std::vector&lt; NodeData &gt; &amp;nodeData, std::stack&lt; const SVFGNode *&gt; &amp;stack, int &amp;index, int &amp;currentSCC, const SVFGNode *v)</div><div class="ttdoc">Called by detectSCCs then called recursively. </div><div class="ttdef"><b>Definition:</b> <a href="VersionedFlowSensitive_8cpp_source.html#l00984">VersionedFlowSensitive.cpp:984</a></div></div>
280
280
  <div class="ttc" id="classSVF_1_1GenericNode_html_ac3e55ef37aefb411ea4c87b1aa3b1895"><div class="ttname"><a href="classSVF_1_1GenericNode.html#ac3e55ef37aefb411ea4c87b1aa3b1895">SVF::GenericNode::getId</a></div><div class="ttdeci">NodeID getId() const</div><div class="ttdoc">Get ID. </div><div class="ttdef"><b>Definition:</b> <a href="GenericGraph_8h_source.html#l00169">GenericGraph.h:169</a></div></div>
281
281
  <div class="ttc" id="namespaceSVF_1_1SVFUtil_html_a8182be247907420db00837cef9bcfa70"><div class="ttname"><a href="namespaceSVF_1_1SVFUtil.html#a8182be247907420db00837cef9bcfa70">SVF::SVFUtil::dyn_cast</a></div><div class="ttdeci">LLVM_NODISCARD std::enable_if&lt;!is_simple_type&lt; Y &gt;::value, typename cast_retty&lt; X, const Y &gt;::ret_type &gt;::type dyn_cast(const Y &amp;Val)</div><div class="ttdef"><b>Definition:</b> <a href="Casting_8h_source.html#l00343">Casting.h:343</a></div></div>
282
282
  <div class="ttc" id="classSVF_1_1IndirectSVFGEdge_html"><div class="ttname"><a href="classSVF_1_1IndirectSVFGEdge.html">SVF::IndirectSVFGEdge</a></div><div class="ttdef"><b>Definition:</b> <a href="SVFGEdge_8h_source.html#l00042">SVFGEdge.h:42</a></div></div>
@@ -123,15 +123,29 @@ void VersionedFlowSensitive::meldLabel(void)
123
123
 
124
124
  assert(Options::VersioningThreads > 0 && "VFS::meldLabel: number of versioning threads must be > 0!");
125
125
 
126
- // Nodes which have at least one object on them given a prelabel.
127
- std::vector<const SVFGNode *> prelabeledNodes;
126
+ // Nodes which have at least one object on them given a prelabel + the Andersen's points-to
127
+ // set of interest so we don't keep calling getPts. For Store nodes, we'll fill that in, for
128
+ // MR nodes, we won't as its getPointsTo is cheap.
129
+ // TODO: preferably we cache both for ease and to avoid the dyn_cast/isa, but Andersen's points-to
130
+ // sets are PointsTo and MR's sets are NodeBS, which are incompatible types. Maybe when we can
131
+ // use std::option.
132
+ std::vector<std::pair<const SVFGNode *, const PointsTo *>> prelabeledNodes;
128
133
  // Fast query for the above.
129
134
  std::vector<bool> isPrelabeled(svfg->getTotalNodeNum(), false);
130
135
  while (!vWorklist.empty())
131
136
  {
132
137
  const NodeID n = vWorklist.pop();
133
- prelabeledNodes.push_back(svfg->getSVFGNode(n));
134
138
  isPrelabeled[n] = true;
139
+
140
+ const SVFGNode *sn = svfg->getSVFGNode(n);
141
+ const PointsTo *nPts = nullptr;
142
+ if (const StoreSVFGNode *store = SVFUtil::dyn_cast<StoreSVFGNode>(sn))
143
+ {
144
+ const NodeID p = store->getPAGDstNodeID();
145
+ nPts = &(this->ander->getPts(p));
146
+ }
147
+
148
+ prelabeledNodes.push_back(std::make_pair(sn, nPts));
135
149
  }
136
150
 
137
151
  // Delta, delta source, store, and load nodes, which require versions during
@@ -180,20 +194,21 @@ void VersionedFlowSensitive::meldLabel(void)
180
194
  // For starting nodes, we only need those which did prelabeling for o specifically.
181
195
  // TODO: maybe we should move this to prelabel with a map (o -> starting nodes).
182
196
  std::vector<const SVFGNode *> osStartingNodes;
183
- for (const SVFGNode *sn : prelabeledNodes)
197
+ for (std::pair<const SVFGNode *, const PointsTo *> snPts : prelabeledNodes)
184
198
  {
185
- if (const StoreSVFGNode *store = SVFUtil::dyn_cast<StoreSVFGNode>(sn))
199
+ const SVFGNode *sn = snPts.first;
200
+ const PointsTo *pts = snPts.second;
201
+ if (pts != nullptr)
186
202
  {
187
- const NodeID p = store->getPAGDstNodeID();
188
- if (this->ander->getPts(p).test(o)) osStartingNodes.push_back(sn);
203
+ if (pts->test(o)) osStartingNodes.push_back(sn);
189
204
  }
190
- else if (delta(sn->getId()))
205
+ else if (const MRSVFGNode *mr = SVFUtil::dyn_cast<MRSVFGNode>(sn))
191
206
  {
192
- const MRSVFGNode *mr = SVFUtil::dyn_cast<MRSVFGNode>(sn);
193
- if (mr != nullptr)
194
- {
195
- if (mr->getPointsTo().test(o)) osStartingNodes.push_back(sn);
196
- }
207
+ if (mr->getPointsTo().test(o)) osStartingNodes.push_back(sn);
208
+ }
209
+ else
210
+ {
211
+ assert(false && "VFS::meldLabel: unexpected prelabeled node!");
197
212
  }
198
213
  }
199
214
 
@@ -234,10 +249,21 @@ void VersionedFlowSensitive::meldLabel(void)
234
249
  // SVFG nodes of interest -- those part of an SCC from the starting nodes.
235
250
  std::vector<NodeID> todoList;
236
251
  unsigned bit = 0;
237
- for (NodeID n = 0; n < partOf.size(); ++n)
252
+ // To calculate reachable nodes, we can see what nodes n exist where
253
+ // partOf[n] != -1. Since the SVFG can be large this can be expensive.
254
+ // Instead, we can gather this from the edges in the footprint and
255
+ // the starting nodes (incase such nodes have no edges).
256
+ // TODO: should be able to do this better: too many redundant inserts.
257
+ Set<NodeID> reachableNodes;
258
+ for (const SVFGNode *sn : osStartingNodes) reachableNodes.insert(sn->getId());
259
+ for (const SVFGEdge *se : footprint)
238
260
  {
239
- if (partOf[n] == -1) continue;
261
+ reachableNodes.insert(se->getSrcNode()->getId());
262
+ reachableNodes.insert(se->getDstNode()->getId());
263
+ }
240
264
 
265
+ for (const NodeID n : reachableNodes)
266
+ {
241
267
  if (isPrelabeled[n])
242
268
  {
243
269
  if (this->isStore(n)) storesYieldedMeldVersion[n].set(bit);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.551",
3
+ "version": "1.0.552",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {