svf-tools 1.0.986 → 1.0.988

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.986",
3
+ "version": "1.0.988",
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": {
@@ -319,7 +319,6 @@ private:
319
319
  const SVFFunction* realDefFun; /// the definition of a function across multiple modules
320
320
  std::vector<const SVFBasicBlock*> allBBs; /// all BasicBlocks of this function
321
321
  std::vector<const SVFArgument*> allArgs; /// all formal arguments of this function
322
- std::vector<std::string> annotations; /// annotations of this function
323
322
  SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function
324
323
 
325
324
  protected:
@@ -463,16 +462,6 @@ public:
463
462
  return !isNotRet;
464
463
  }
465
464
 
466
- inline const std::vector<std::string>& getAnnotations() const
467
- {
468
- return annotations;
469
- }
470
-
471
- inline void setAnnotations(std::vector<std::string>& annotations)
472
- {
473
- this->annotations = annotations;
474
- }
475
-
476
465
  inline void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const
477
466
  {
478
467
  return loopAndDom->getExitBlocksOfLoop(bb,exitbbs);
@@ -43,10 +43,14 @@ namespace SVF
43
43
 
44
44
  class ExtAPI
45
45
  {
46
+ friend class LLVMModuleSet;
46
47
  private:
47
48
 
48
49
  static ExtAPI *extOp;
49
50
 
51
+ // Map SVFFunction to its annotations
52
+ Map<const SVFFunction*, std::vector<std::string>> func2Annotations;
53
+
50
54
  // extapi.bc file path
51
55
  static std::string extBcPath;
52
56
 
@@ -67,6 +71,8 @@ public:
67
71
  // Get the annotation of (F)
68
72
  std::string getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation);
69
73
 
74
+ const std::vector<std::string>& getExtFuncAnnotations(const SVFFunction* fun);
75
+
70
76
  // Does (F) have some annotation?
71
77
  bool hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation);
72
78
 
@@ -94,6 +100,10 @@ public:
94
100
  // Should (F) be considered "external" (either not defined in the program
95
101
  // or a user-defined version of a known alloc or no-op)?
96
102
  bool is_ext(const SVFFunction *F);
103
+
104
+ private:
105
+ // Set the annotation of (F)
106
+ void setExtFuncAnnotations(const SVFFunction* fun, const std::vector<std::string>& funcAnnotations);
97
107
  };
98
108
  } // End namespace SVF
99
109
 
@@ -391,19 +391,13 @@ bool isExtCall(const ICFGNode* node);
391
391
 
392
392
  bool isHeapAllocExtCallViaArg(const CallICFGNode* cs);
393
393
 
394
- bool isHeapAllocExtCallViaArg(const SVFInstruction *inst);
395
-
396
- bool isHeapAllocExtCallViaRet(const SVFInstruction *inst);
397
394
 
398
395
  /// interfaces to be used externally
399
396
  bool isHeapAllocExtCallViaRet(const CallICFGNode* cs);
400
397
 
401
398
  bool isHeapAllocExtCall(const ICFGNode* cs);
402
399
 
403
- inline bool isHeapAllocExtCall(const SVFInstruction *inst)
404
- {
405
- return isHeapAllocExtCallViaRet(inst) || isHeapAllocExtCallViaArg(inst);
406
- }
400
+
407
401
 
408
402
  //@}
409
403
 
@@ -150,7 +150,7 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
150
150
  AbstractInterpretation::ExtAPIType extType = AbstractInterpretation::UNCLASSIFIED;
151
151
 
152
152
  // Determine the type of external memory API
153
- for (const std::string &annotation : call->getCalledFunction()->getAnnotations())
153
+ for (const std::string &annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(call->getCalledFunction()))
154
154
  {
155
155
  if (annotation.find("MEMCPY") != std::string::npos)
156
156
  extType = AbstractInterpretation::MEMCPY;
@@ -995,7 +995,6 @@ void AbstractInterpretation::initExtFunMap()
995
995
  checkpoints.erase(callNode);
996
996
  u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
997
997
  AbstractState&as = getAbsStateFromTrace(callNode);
998
- as[arg0].getInterval().meet_with(IntervalValue(1, 1));
999
998
  if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
1000
999
  {
1001
1000
  SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
@@ -1009,6 +1008,25 @@ void AbstractInterpretation::initExtFunMap()
1009
1008
  };
1010
1009
  func_map["svf_assert"] = sse_svf_assert;
1011
1010
 
1011
+ auto svf_assert_eq = [this](const CallICFGNode* callNode)
1012
+ {
1013
+ checkpoints.erase(callNode);
1014
+ u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
1015
+ u32_t arg1 = svfir->getValueNode(callNode->getArgument(1));
1016
+ AbstractState&as = getAbsStateFromTrace(callNode);
1017
+ if (as[arg0].getInterval().equals(as[arg1].getInterval()))
1018
+ {
1019
+ SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
1020
+ }
1021
+ else
1022
+ {
1023
+ SVFUtil::errs() <<"svf_assert_eq Fail. " << callNode->toString() << "\n";
1024
+ assert(false);
1025
+ }
1026
+ return;
1027
+ };
1028
+ func_map["svf_assert_eq"] = svf_assert_eq;
1029
+
1012
1030
  auto svf_print = [&](const CallICFGNode* callNode)
1013
1031
  {
1014
1032
  if (callNode->arg_size() < 2) return;
@@ -1017,11 +1035,38 @@ void AbstractInterpretation::initExtFunMap()
1017
1035
  std::string text = strRead(as, callNode->getArgument(1));
1018
1036
  assert(as.inVarToValTable(num_id) && "print() should pass integer");
1019
1037
  IntervalValue itv = as[num_id].getInterval();
1020
- std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString() << ", PrintVal: " << itv.toString() << std::endl;
1038
+ std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
1039
+ << ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
1021
1040
  return;
1022
1041
  };
1023
1042
  func_map["svf_print"] = svf_print;
1024
1043
 
1044
+ auto svf_set_value = [&](const CallICFGNode* callNode)
1045
+ {
1046
+ if (callNode->arg_size() < 2) return;
1047
+ AbstractState&as = getAbsStateFromTrace(callNode);
1048
+ AbstractValue& num = as[svfir->getValueNode(callNode->getArgument(0))];
1049
+ AbstractValue& lb = as[svfir->getValueNode(callNode->getArgument(1))];
1050
+ AbstractValue& ub = as[svfir->getValueNode(callNode->getArgument(2))];
1051
+ assert(lb.getInterval().is_numeral() && ub.getInterval().is_numeral());
1052
+ num.getInterval().set_to_top();
1053
+ num.getInterval().meet_with(IntervalValue(lb.getInterval().lb(), ub.getInterval().ub()));
1054
+ if (icfg->hasICFGNode(SVFUtil::cast<SVFInstruction>(callNode->getArgument(0))))
1055
+ {
1056
+ const ICFGNode* node = icfg->getICFGNode(SVFUtil::cast<SVFInstruction>(callNode->getArgument(0)));
1057
+ for (const SVFStmt* stmt: node->getSVFStmts())
1058
+ {
1059
+ if (SVFUtil::isa<LoadStmt>(stmt))
1060
+ {
1061
+ const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
1062
+ NodeID rhsId = load->getRHSVarID();
1063
+ as.storeValue(rhsId, num);
1064
+ }
1065
+ }
1066
+ }
1067
+ return;
1068
+ };
1069
+ func_map["set_value"] = svf_set_value;
1025
1070
 
1026
1071
  auto sse_scanf = [&](const CallICFGNode* callNode)
1027
1072
  {
@@ -1332,7 +1377,7 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
1332
1377
  assert(fun && "SVFFunction* is nullptr");
1333
1378
  ExtAPIType extType = UNCLASSIFIED;
1334
1379
  // get type of mem api
1335
- for (const std::string &annotation: fun->getAnnotations())
1380
+ for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun))
1336
1381
  {
1337
1382
  if (annotation.find("MEMCPY") != std::string::npos)
1338
1383
  extType = MEMCPY;
@@ -1708,8 +1753,27 @@ void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi)
1708
1753
  const ICFGNode* opICFGNode = phi->getOpICFGNode(i);
1709
1754
  if (hasAbsStateFromTrace(opICFGNode))
1710
1755
  {
1756
+ AbstractState tmpEs = abstractTrace[opICFGNode];
1711
1757
  AbstractState& opAs = getAbsStateFromTrace(opICFGNode);
1712
- rhs.join_with(opAs[curId]);
1758
+ const ICFGEdge* edge = icfg->getICFGEdge(opICFGNode, icfgNode, ICFGEdge::IntraCF);
1759
+ // if IntraEdge, check the condition, if it is feasible, join the value
1760
+ // if IntraEdge but not conditional edge, join the value
1761
+ // if not IntraEdge, join the value
1762
+ if (edge)
1763
+ {
1764
+ const IntraCFGEdge* intraEdge = SVFUtil::cast<IntraCFGEdge>(edge);
1765
+ if (intraEdge->getCondition())
1766
+ {
1767
+ if (isBranchFeasible(intraEdge, tmpEs))
1768
+ rhs.join_with(opAs[curId]);
1769
+ }
1770
+ else
1771
+ rhs.join_with(opAs[curId]);
1772
+ }
1773
+ else
1774
+ {
1775
+ rhs.join_with(opAs[curId]);
1776
+ }
1713
1777
  }
1714
1778
  }
1715
1779
  as[res] = rhs;
@@ -1810,181 +1874,209 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp)
1810
1874
  AbstractState& as = getAbsStateFromTrace(cmp->getICFGNode());
1811
1875
  u32_t op0 = cmp->getOpVarID(0);
1812
1876
  u32_t op1 = cmp->getOpVarID(1);
1813
- if (!as.inVarToValTable(op0)) as[op0] = IntervalValue::top();
1814
- if (!as.inVarToValTable(op1)) as[op1] = IntervalValue::top();
1815
- u32_t res = cmp->getResID();
1816
- if (as.inVarToValTable(op0) && as.inVarToValTable(op1))
1877
+ // if it is address
1878
+ if (as.inVarToAddrsTable(op0) && as.inVarToAddrsTable(op1))
1817
1879
  {
1818
1880
  IntervalValue resVal;
1819
- if (as[op0].isInterval() && as[op1].isInterval())
1881
+ AddressValue addrOp0 = as[op0].getAddrs();
1882
+ AddressValue addrOp1 = as[op1].getAddrs();
1883
+ u32_t res = cmp->getResID();
1884
+ if (addrOp0.equals(addrOp1))
1820
1885
  {
1821
- IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
1822
- //AbstractValue
1823
- auto predicate = cmp->getPredicate();
1824
- switch (predicate)
1825
- {
1826
- case CmpStmt::ICMP_EQ:
1827
- case CmpStmt::FCMP_OEQ:
1828
- case CmpStmt::FCMP_UEQ:
1829
- resVal = (lhs == rhs);
1830
- // resVal = (lhs.getInterval() == rhs.getInterval());
1831
- break;
1832
- case CmpStmt::ICMP_NE:
1833
- case CmpStmt::FCMP_ONE:
1834
- case CmpStmt::FCMP_UNE:
1835
- resVal = (lhs != rhs);
1836
- break;
1837
- case CmpStmt::ICMP_UGT:
1838
- case CmpStmt::ICMP_SGT:
1839
- case CmpStmt::FCMP_OGT:
1840
- case CmpStmt::FCMP_UGT:
1841
- resVal = (lhs > rhs);
1842
- break;
1843
- case CmpStmt::ICMP_UGE:
1844
- case CmpStmt::ICMP_SGE:
1845
- case CmpStmt::FCMP_OGE:
1846
- case CmpStmt::FCMP_UGE:
1847
- resVal = (lhs >= rhs);
1848
- break;
1849
- case CmpStmt::ICMP_ULT:
1850
- case CmpStmt::ICMP_SLT:
1851
- case CmpStmt::FCMP_OLT:
1852
- case CmpStmt::FCMP_ULT:
1853
- resVal = (lhs < rhs);
1854
- break;
1855
- case CmpStmt::ICMP_ULE:
1856
- case CmpStmt::ICMP_SLE:
1857
- case CmpStmt::FCMP_OLE:
1858
- case CmpStmt::FCMP_ULE:
1859
- resVal = (lhs <= rhs);
1860
- break;
1861
- case CmpStmt::FCMP_FALSE:
1862
- resVal = IntervalValue(0, 0);
1863
- break;
1864
- case CmpStmt::FCMP_TRUE:
1865
- resVal = IntervalValue(1, 1);
1866
- break;
1867
- default:
1868
- {
1869
- assert(false && "undefined compare: ");
1870
- }
1871
- }
1872
- as[res] = resVal;
1886
+ resVal = IntervalValue(1, 1);
1873
1887
  }
1874
- else if (as[op0].isAddr() && as[op1].isAddr())
1888
+ else if (addrOp0.hasIntersect(addrOp1))
1875
1889
  {
1876
- AddressValue &lhs = as[op0].getAddrs(), &rhs = as[op1].getAddrs();
1877
- auto predicate = cmp->getPredicate();
1878
- switch (predicate)
1879
- {
1880
- case CmpStmt::ICMP_EQ:
1881
- case CmpStmt::FCMP_OEQ:
1882
- case CmpStmt::FCMP_UEQ:
1890
+ resVal = IntervalValue(0, 1);
1891
+ }
1892
+ else
1893
+ {
1894
+ resVal = IntervalValue(0, 0);
1895
+ }
1896
+ as[res] = resVal;
1897
+ }
1898
+ else
1899
+ {
1900
+ if (!as.inVarToValTable(op0))
1901
+ as[op0] = IntervalValue::top();
1902
+ if (!as.inVarToValTable(op1))
1903
+ as[op1] = IntervalValue::top();
1904
+ u32_t res = cmp->getResID();
1905
+ if (as.inVarToValTable(op0) && as.inVarToValTable(op1))
1906
+ {
1907
+ IntervalValue resVal;
1908
+ if (as[op0].isInterval() && as[op1].isInterval())
1883
1909
  {
1884
- if (lhs.hasIntersect(rhs))
1885
- {
1886
- resVal = IntervalValue(0, 1);
1887
- }
1888
- else if (lhs.empty() && rhs.empty())
1889
- {
1890
- resVal = IntervalValue(1, 1);
1891
- }
1892
- else
1910
+ IntervalValue &lhs = as[op0].getInterval(),
1911
+ &rhs = as[op1].getInterval();
1912
+ // AbstractValue
1913
+ auto predicate = cmp->getPredicate();
1914
+ switch (predicate)
1893
1915
  {
1916
+ case CmpStmt::ICMP_EQ:
1917
+ case CmpStmt::FCMP_OEQ:
1918
+ case CmpStmt::FCMP_UEQ:
1919
+ resVal = (lhs == rhs);
1920
+ // resVal = (lhs.getInterval() == rhs.getInterval());
1921
+ break;
1922
+ case CmpStmt::ICMP_NE:
1923
+ case CmpStmt::FCMP_ONE:
1924
+ case CmpStmt::FCMP_UNE:
1925
+ resVal = (lhs != rhs);
1926
+ break;
1927
+ case CmpStmt::ICMP_UGT:
1928
+ case CmpStmt::ICMP_SGT:
1929
+ case CmpStmt::FCMP_OGT:
1930
+ case CmpStmt::FCMP_UGT:
1931
+ resVal = (lhs > rhs);
1932
+ break;
1933
+ case CmpStmt::ICMP_UGE:
1934
+ case CmpStmt::ICMP_SGE:
1935
+ case CmpStmt::FCMP_OGE:
1936
+ case CmpStmt::FCMP_UGE:
1937
+ resVal = (lhs >= rhs);
1938
+ break;
1939
+ case CmpStmt::ICMP_ULT:
1940
+ case CmpStmt::ICMP_SLT:
1941
+ case CmpStmt::FCMP_OLT:
1942
+ case CmpStmt::FCMP_ULT:
1943
+ resVal = (lhs < rhs);
1944
+ break;
1945
+ case CmpStmt::ICMP_ULE:
1946
+ case CmpStmt::ICMP_SLE:
1947
+ case CmpStmt::FCMP_OLE:
1948
+ case CmpStmt::FCMP_ULE:
1949
+ resVal = (lhs <= rhs);
1950
+ break;
1951
+ case CmpStmt::FCMP_FALSE:
1894
1952
  resVal = IntervalValue(0, 0);
1895
- }
1896
- break;
1897
- }
1898
- case CmpStmt::ICMP_NE:
1899
- case CmpStmt::FCMP_ONE:
1900
- case CmpStmt::FCMP_UNE:
1901
- {
1902
- if (lhs.hasIntersect(rhs))
1903
- {
1904
- resVal = IntervalValue(0, 1);
1905
- }
1906
- else if (lhs.empty() && rhs.empty())
1953
+ break;
1954
+ case CmpStmt::FCMP_TRUE:
1955
+ resVal = IntervalValue(1, 1);
1956
+ break;
1957
+ default:
1907
1958
  {
1908
- resVal = IntervalValue(0, 0);
1959
+ assert(false && "undefined compare: ");
1909
1960
  }
1910
- else
1911
- {
1912
- resVal = IntervalValue(1, 1);
1913
1961
  }
1914
- break;
1962
+ as[res] = resVal;
1915
1963
  }
1916
- case CmpStmt::ICMP_UGT:
1917
- case CmpStmt::ICMP_SGT:
1918
- case CmpStmt::FCMP_OGT:
1919
- case CmpStmt::FCMP_UGT:
1964
+ else if (as[op0].isAddr() && as[op1].isAddr())
1920
1965
  {
1921
- if (lhs.size() == 1 && rhs.size() == 1)
1966
+ AddressValue &lhs = as[op0].getAddrs(),
1967
+ &rhs = as[op1].getAddrs();
1968
+ auto predicate = cmp->getPredicate();
1969
+ switch (predicate)
1922
1970
  {
1923
- resVal = IntervalValue(*lhs.begin() > *rhs.begin());
1924
- }
1925
- else
1971
+ case CmpStmt::ICMP_EQ:
1972
+ case CmpStmt::FCMP_OEQ:
1973
+ case CmpStmt::FCMP_UEQ:
1926
1974
  {
1927
- resVal = IntervalValue(0, 1);
1975
+ if (lhs.hasIntersect(rhs))
1976
+ {
1977
+ resVal = IntervalValue(0, 1);
1978
+ }
1979
+ else if (lhs.empty() && rhs.empty())
1980
+ {
1981
+ resVal = IntervalValue(1, 1);
1982
+ }
1983
+ else
1984
+ {
1985
+ resVal = IntervalValue(0, 0);
1986
+ }
1987
+ break;
1928
1988
  }
1929
- break;
1930
- }
1931
- case CmpStmt::ICMP_UGE:
1932
- case CmpStmt::ICMP_SGE:
1933
- case CmpStmt::FCMP_OGE:
1934
- case CmpStmt::FCMP_UGE:
1935
- {
1936
- if (lhs.size() == 1 && rhs.size() == 1)
1989
+ case CmpStmt::ICMP_NE:
1990
+ case CmpStmt::FCMP_ONE:
1991
+ case CmpStmt::FCMP_UNE:
1937
1992
  {
1938
- resVal = IntervalValue(*lhs.begin() >= *rhs.begin());
1993
+ if (lhs.hasIntersect(rhs))
1994
+ {
1995
+ resVal = IntervalValue(0, 1);
1996
+ }
1997
+ else if (lhs.empty() && rhs.empty())
1998
+ {
1999
+ resVal = IntervalValue(0, 0);
2000
+ }
2001
+ else
2002
+ {
2003
+ resVal = IntervalValue(1, 1);
2004
+ }
2005
+ break;
1939
2006
  }
1940
- else
2007
+ case CmpStmt::ICMP_UGT:
2008
+ case CmpStmt::ICMP_SGT:
2009
+ case CmpStmt::FCMP_OGT:
2010
+ case CmpStmt::FCMP_UGT:
1941
2011
  {
1942
- resVal = IntervalValue(0, 1);
2012
+ if (lhs.size() == 1 && rhs.size() == 1)
2013
+ {
2014
+ resVal = IntervalValue(*lhs.begin() > *rhs.begin());
2015
+ }
2016
+ else
2017
+ {
2018
+ resVal = IntervalValue(0, 1);
2019
+ }
2020
+ break;
1943
2021
  }
1944
- break;
1945
- }
1946
- case CmpStmt::ICMP_ULT:
1947
- case CmpStmt::ICMP_SLT:
1948
- case CmpStmt::FCMP_OLT:
1949
- case CmpStmt::FCMP_ULT:
1950
- {
1951
- if (lhs.size() == 1 && rhs.size() == 1)
2022
+ case CmpStmt::ICMP_UGE:
2023
+ case CmpStmt::ICMP_SGE:
2024
+ case CmpStmt::FCMP_OGE:
2025
+ case CmpStmt::FCMP_UGE:
1952
2026
  {
1953
- resVal = IntervalValue(*lhs.begin() < *rhs.begin());
2027
+ if (lhs.size() == 1 && rhs.size() == 1)
2028
+ {
2029
+ resVal = IntervalValue(*lhs.begin() >= *rhs.begin());
2030
+ }
2031
+ else
2032
+ {
2033
+ resVal = IntervalValue(0, 1);
2034
+ }
2035
+ break;
1954
2036
  }
1955
- else
2037
+ case CmpStmt::ICMP_ULT:
2038
+ case CmpStmt::ICMP_SLT:
2039
+ case CmpStmt::FCMP_OLT:
2040
+ case CmpStmt::FCMP_ULT:
1956
2041
  {
1957
- resVal = IntervalValue(0, 1);
2042
+ if (lhs.size() == 1 && rhs.size() == 1)
2043
+ {
2044
+ resVal = IntervalValue(*lhs.begin() < *rhs.begin());
2045
+ }
2046
+ else
2047
+ {
2048
+ resVal = IntervalValue(0, 1);
2049
+ }
2050
+ break;
1958
2051
  }
1959
- break;
1960
- }
1961
- case CmpStmt::ICMP_ULE:
1962
- case CmpStmt::ICMP_SLE:
1963
- case CmpStmt::FCMP_OLE:
1964
- case CmpStmt::FCMP_ULE:
1965
- {
1966
- if (lhs.size() == 1 && rhs.size() == 1)
2052
+ case CmpStmt::ICMP_ULE:
2053
+ case CmpStmt::ICMP_SLE:
2054
+ case CmpStmt::FCMP_OLE:
2055
+ case CmpStmt::FCMP_ULE:
1967
2056
  {
1968
- resVal = IntervalValue(*lhs.begin() <= *rhs.begin());
2057
+ if (lhs.size() == 1 && rhs.size() == 1)
2058
+ {
2059
+ resVal = IntervalValue(*lhs.begin() <= *rhs.begin());
2060
+ }
2061
+ else
2062
+ {
2063
+ resVal = IntervalValue(0, 1);
2064
+ }
2065
+ break;
1969
2066
  }
1970
- else
2067
+ case CmpStmt::FCMP_FALSE:
2068
+ resVal = IntervalValue(0, 0);
2069
+ break;
2070
+ case CmpStmt::FCMP_TRUE:
2071
+ resVal = IntervalValue(1, 1);
2072
+ break;
2073
+ default:
1971
2074
  {
1972
- resVal = IntervalValue(0, 1);
2075
+ assert(false && "undefined compare: ");
1973
2076
  }
1974
- break;
1975
- }
1976
- case CmpStmt::FCMP_FALSE:
1977
- resVal = IntervalValue(0, 0);
1978
- break;
1979
- case CmpStmt::FCMP_TRUE:
1980
- resVal = IntervalValue(1, 1);
1981
- break;
1982
- default:
1983
- {
1984
- assert(false && "undefined compare: ");
1985
- }
2077
+ }
2078
+ as[res] = resVal;
1986
2079
  }
1987
- as[res] = resVal;
1988
2080
  }
1989
2081
  }
1990
2082
  }
@@ -2052,8 +2144,8 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2052
2144
  return IntervalValue::top(); // TODO: may have better solution
2053
2145
  };
2054
2146
 
2055
- auto getTruncValue = [](const AbstractState& as, const SVF::SVFVar* var,
2056
- const SVFType* dstType)
2147
+ auto getTruncValue = [&](const AbstractState& as, const SVF::SVFVar* var,
2148
+ const SVFType* dstType)
2057
2149
  {
2058
2150
  const IntervalValue& itv = as[var->getId()].getInterval();
2059
2151
  if(itv.isBottom()) return itv;
@@ -2070,7 +2162,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2070
2162
  if (s8_lb > s8_ub)
2071
2163
  {
2072
2164
  // return range of s8
2073
- return IntervalValue::top();
2165
+ return this->getRangeLimitFromType(dstType);
2074
2166
  }
2075
2167
  return IntervalValue(s8_lb, s8_ub);
2076
2168
  }
@@ -2082,7 +2174,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2082
2174
  if (s16_lb > s16_ub)
2083
2175
  {
2084
2176
  // return range of s16
2085
- return IntervalValue::top();
2177
+ return this->getRangeLimitFromType(dstType);
2086
2178
  }
2087
2179
  return IntervalValue(s16_lb, s16_ub);
2088
2180
  }
@@ -2094,7 +2186,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2094
2186
  if (s32_lb > s32_ub)
2095
2187
  {
2096
2188
  // return range of s32
2097
- return IntervalValue::top();
2189
+ return this->getRangeLimitFromType(dstType);
2098
2190
  }
2099
2191
  return IntervalValue(s32_lb, s32_ub);
2100
2192
  }
@@ -549,7 +549,6 @@ cJSON* SVFIRWriter::contentToJson(const SVFFunction* value)
549
549
  F(realDefFun);
550
550
  F(allBBs);
551
551
  F(allArgs);
552
- F(annotations);
553
552
  #undef F
554
553
  return root;
555
554
  }
@@ -2357,7 +2356,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, SVFFunction* value)
2357
2356
  F(realDefFun);
2358
2357
  F(allBBs);
2359
2358
  F(allArgs);
2360
- F(annotations);
2361
2359
  #undef F
2362
2360
  }
2363
2361