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 +1 -1
- package/svf/include/SVFIR/SVFValue.h +0 -11
- package/svf/include/Util/ExtAPI.h +10 -0
- package/svf/include/Util/SVFUtil.h +1 -7
- package/svf/lib/AE/Svfexe/AEDetector.cpp +1 -1
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +247 -155
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -2
- package/svf/lib/Util/ExtAPI.cpp +33 -10
- package/svf/lib/Util/SVFUtil.cpp +0 -15
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -58
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +10 -19
- package/svf-llvm/lib/CHGBuilder.cpp +2 -2
- package/svf-llvm/lib/LLVMModule.cpp +216 -230
- package/svf-llvm/lib/LLVMUtil.cpp +32 -228
- package/svf-llvm/lib/ObjTypeInference.cpp +2 -2
- package/svf-llvm/lib/SVFIRBuilder.cpp +0 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +5 -6
- package/svf-llvm/lib/extapi.c +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
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
|
-
|
|
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()
|
|
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()
|
|
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:
|
|
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
|
-
|
|
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
|
|
1814
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
1888
|
+
else if (addrOp0.hasIntersect(addrOp1))
|
|
1875
1889
|
{
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
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
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
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
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
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
|
-
|
|
1959
|
+
assert(false && "undefined compare: ");
|
|
1909
1960
|
}
|
|
1910
|
-
else
|
|
1911
|
-
{
|
|
1912
|
-
resVal = IntervalValue(1, 1);
|
|
1913
1961
|
}
|
|
1914
|
-
|
|
1962
|
+
as[res] = resVal;
|
|
1915
1963
|
}
|
|
1916
|
-
|
|
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
|
-
|
|
1966
|
+
AddressValue &lhs = as[op0].getAddrs(),
|
|
1967
|
+
&rhs = as[op1].getAddrs();
|
|
1968
|
+
auto predicate = cmp->getPredicate();
|
|
1969
|
+
switch (predicate)
|
|
1922
1970
|
{
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1971
|
+
case CmpStmt::ICMP_EQ:
|
|
1972
|
+
case CmpStmt::FCMP_OEQ:
|
|
1973
|
+
case CmpStmt::FCMP_UEQ:
|
|
1926
1974
|
{
|
|
1927
|
-
|
|
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
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2007
|
+
case CmpStmt::ICMP_UGT:
|
|
2008
|
+
case CmpStmt::ICMP_SGT:
|
|
2009
|
+
case CmpStmt::FCMP_OGT:
|
|
2010
|
+
case CmpStmt::FCMP_UGT:
|
|
1941
2011
|
{
|
|
1942
|
-
|
|
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
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2037
|
+
case CmpStmt::ICMP_ULT:
|
|
2038
|
+
case CmpStmt::ICMP_SLT:
|
|
2039
|
+
case CmpStmt::FCMP_OLT:
|
|
2040
|
+
case CmpStmt::FCMP_ULT:
|
|
1956
2041
|
{
|
|
1957
|
-
|
|
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
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2075
|
+
assert(false && "undefined compare: ");
|
|
1973
2076
|
}
|
|
1974
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|