svf-tools 1.0.481 → 1.0.482
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/SVF-doxygen/html/html/AndersenSCD_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/AndersenSFR_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/AndersenSFR_8h_source.html +1 -1
- package/SVF-doxygen/html/html/AndersenStat_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/Andersen_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/Andersen_8h_source.html +6 -6
- package/SVF-doxygen/html/html/CFLAlias_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/CFLAlias_8h_source.html +1 -1
- package/SVF-doxygen/html/html/CFLGraphBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/CHGBuilder_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/CHG_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/CPPUtil_8cpp_source.html +14 -15
- package/SVF-doxygen/html/html/CPPUtil_8h_source.html +14 -14
- package/SVF-doxygen/html/html/ConsG_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/ContextDDA_8cpp_source.html +13 -13
- package/SVF-doxygen/html/html/ContextDDA_8h_source.html +7 -7
- package/SVF-doxygen/html/html/DCHG_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/DDAClient_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/DDAPass_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/DDAStat_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/DDAVFSolver_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ExeState_8cpp_source.html +6 -6
- package/SVF-doxygen/html/html/ExeState_8h_source.html +2 -2
- package/SVF-doxygen/html/html/FSMPTA_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/FSMPTA_8h_source.html +4 -4
- package/SVF-doxygen/html/html/FlowDDA_8h_source.html +12 -12
- package/SVF-doxygen/html/html/FlowSensitiveStat_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/FlowSensitive_8cpp.html +0 -1
- package/SVF-doxygen/html/html/FlowSensitive_8cpp_source.html +32 -38
- package/SVF-doxygen/html/html/FlowSensitive_8h_source.html +66 -67
- package/SVF-doxygen/html/html/IRAnnotator_8h_source.html +3 -3
- package/SVF-doxygen/html/html/IRGraph_8cpp_source.html +6 -6
- package/SVF-doxygen/html/html/LLVMLoopAnalysis_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/LLVMModule_8h_source.html +2 -7
- package/SVF-doxygen/html/html/LeakChecker_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MTAAnnotator_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MTA_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/MemRegion_8cpp_source.html +6 -6
- package/SVF-doxygen/html/html/MemSSA_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/OfflineConsG_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/Options_8cpp_source.html +17 -21
- package/SVF-doxygen/html/html/Options_8h_source.html +13 -16
- package/SVF-doxygen/html/html/PCG_8h_source.html +3 -3
- package/SVF-doxygen/html/html/PTAStat_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/PathCondAllocator_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/PointerAnalysisImpl_8cpp_source.html +21 -22
- package/SVF-doxygen/html/html/PointerAnalysisImpl_8h_source.html +17 -17
- package/SVF-doxygen/html/html/PointerAnalysis_8cpp.html +0 -1
- package/SVF-doxygen/html/html/PointerAnalysis_8cpp_source.html +64 -69
- package/SVF-doxygen/html/html/PointerAnalysis_8h_source.html +109 -110
- package/SVF-doxygen/html/html/SVFGBuilder_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/SVFGBuilder_8h_source.html +3 -3
- package/SVF-doxygen/html/html/SVFG_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/SVFIRBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/SVFIR_8cpp_source.html +12 -12
- package/SVF-doxygen/html/html/SVFIR_8h_source.html +9 -9
- package/SVF-doxygen/html/html/SVFVariables_8cpp_source.html +26 -32
- package/SVF-doxygen/html/html/SVFVariables_8h.html +0 -6
- package/SVF-doxygen/html/html/SVFVariables_8h_source.html +109 -130
- package/SVF-doxygen/html/html/SaberAnnotator_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/SaberSVFGBuilder_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/SrcSnkDDA_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/Steensgaard_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ThreadCallGraph_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/TypeAnalysis_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/TypeAnalysis_8h_source.html +5 -5
- package/SVF-doxygen/html/html/VFGNode_8h_source.html +1 -1
- package/SVF-doxygen/html/html/VFG_8cpp_source.html +9 -9
- package/SVF-doxygen/html/html/VFG_8h_source.html +1 -1
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp_source.html +16 -16
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8h_source.html +4 -4
- package/SVF-doxygen/html/html/WPAPass_8cpp.html +0 -1
- package/SVF-doxygen/html/html/WPAPass_8cpp_source.html +16 -19
- package/SVF-doxygen/html/html/WPAPass_8h_source.html +6 -6
- package/SVF-doxygen/html/html/annotated.html +248 -253
- package/SVF-doxygen/html/html/classSVF_1_1ActualParmVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ActualRetVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1AliasDDAClient.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1Andersen-members.html +173 -174
- package/SVF-doxygen/html/html/classSVF_1_1Andersen.html +27 -29
- package/SVF-doxygen/html/html/classSVF_1_1AndersenBase-members.html +146 -147
- package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +17 -19
- package/SVF-doxygen/html/html/classSVF_1_1AndersenHCD-members.html +185 -186
- package/SVF-doxygen/html/html/classSVF_1_1AndersenHCD.html +7 -8
- package/SVF-doxygen/html/html/classSVF_1_1AndersenHLCD-members.html +189 -190
- package/SVF-doxygen/html/html/classSVF_1_1AndersenHLCD.html +6 -7
- package/SVF-doxygen/html/html/classSVF_1_1AndersenLCD-members.html +180 -181
- package/SVF-doxygen/html/html/classSVF_1_1AndersenLCD.html +8 -9
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSCD-members.html +182 -183
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSCD.html +11 -12
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR-members.html +185 -186
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR.html +8 -9
- package/SVF-doxygen/html/html/classSVF_1_1AndersenStat.html +11 -11
- package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff-members.html +177 -178
- package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff.html +8 -9
- package/SVF-doxygen/html/html/classSVF_1_1ArgumentVFGNode.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl-members.html +103 -104
- package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl.html +42 -48
- package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1BinaryOPVFGNode.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1CFLAlias-members.html +73 -74
- package/SVF-doxygen/html/html/classSVF_1_1CFLAlias.html +13 -14
- package/SVF-doxygen/html/html/classSVF_1_1CFLGraphBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1CHGBuilder.html +13 -13
- package/SVF-doxygen/html/html/classSVF_1_1CHGraph.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1CmpVFGNode.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1CondPTAImpl-members.html +94 -95
- package/SVF-doxygen/html/html/classSVF_1_1CondPTAImpl.html +26 -28
- package/SVF-doxygen/html/html/classSVF_1_1ContextDDA-members.html +163 -164
- package/SVF-doxygen/html/html/classSVF_1_1ContextDDA.html +33 -35
- package/SVF-doxygen/html/html/classSVF_1_1DCHGraph.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1DDAClient.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1DDAPass.html +15 -15
- package/SVF-doxygen/html/html/classSVF_1_1DDAStat.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1DDAVFSolver.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1DummyObjVar-members.html +72 -75
- package/SVF-doxygen/html/html/classSVF_1_1DummyObjVar.html +16 -27
- package/SVF-doxygen/html/html/classSVF_1_1DummyObjVar.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1DummyValVar-members.html +70 -73
- package/SVF-doxygen/html/html/classSVF_1_1DummyValVar.html +17 -20
- package/SVF-doxygen/html/html/classSVF_1_1ExeState.html +6 -6
- package/SVF-doxygen/html/html/classSVF_1_1FIObjVar-members.html +72 -75
- package/SVF-doxygen/html/html/classSVF_1_1FIObjVar.html +18 -29
- package/SVF-doxygen/html/html/classSVF_1_1FIObjVar.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1FSMPTA-members.html +112 -114
- package/SVF-doxygen/html/html/classSVF_1_1FSMPTA.html +12 -15
- package/SVF-doxygen/html/html/classSVF_1_1FlowDDA-members.html +163 -164
- package/SVF-doxygen/html/html/classSVF_1_1FlowDDA.html +25 -27
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive-members.html +106 -108
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.html +234 -314
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +43 -43
- package/SVF-doxygen/html/html/classSVF_1_1FormalParmVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FormalRetVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FunptrDDAClient.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1GepObjVar-members.html +77 -80
- package/SVF-doxygen/html/html/classSVF_1_1GepObjVar.html +38 -49
- package/SVF-doxygen/html/html/classSVF_1_1GepObjVar.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1GepValVar-members.html +73 -76
- package/SVF-doxygen/html/html/classSVF_1_1GepValVar.html +28 -31
- package/SVF-doxygen/html/html/classSVF_1_1ICFGPrinter.html +9 -9
- package/SVF-doxygen/html/html/classSVF_1_1IRGraph.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1InterPHIVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1IntraPHIVFGNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1LLVMLoopAnalysis.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1LLVMModuleSet-members.html +44 -45
- package/SVF-doxygen/html/html/classSVF_1_1LLVMModuleSet.html +4 -45
- package/SVF-doxygen/html/html/classSVF_1_1LeakChecker.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MRGenerator.html +14 -14
- package/SVF-doxygen/html/html/classSVF_1_1MTA.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1MTASVFGBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MemSSA.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1NullPtrVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ObjVar-members.html +71 -74
- package/SVF-doxygen/html/html/classSVF_1_1ObjVar.html +30 -42
- package/SVF-doxygen/html/html/classSVF_1_1ObjVar.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1Options-members.html +104 -107
- package/SVF-doxygen/html/html/classSVF_1_1Options.html +13 -94
- package/SVF-doxygen/html/html/classSVF_1_1PCG.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1PHIVFGNode.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1PTAStat.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1PathCondAllocator.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis-members.html +69 -70
- package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis.html +302 -319
- package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1RetPN-members.html +70 -73
- package/SVF-doxygen/html/html/classSVF_1_1RetPN.html +18 -21
- package/SVF-doxygen/html/html/classSVF_1_1SVFG.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1SVFGBuilder.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFIR.html +18 -18
- package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFVar-members.html +73 -76
- package/SVF-doxygen/html/html/classSVF_1_1SVFVar.html +84 -99
- package/SVF-doxygen/html/html/classSVF_1_1SVFVar.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1SaberAnnotator.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SaberSVFGBuilder.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1SrcSnkDDA.html +2 -3
- package/SVF-doxygen/html/html/classSVF_1_1Steensgaard-members.html +157 -158
- package/SVF-doxygen/html/html/classSVF_1_1Steensgaard.html +6 -7
- package/SVF-doxygen/html/html/classSVF_1_1TCT.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraph.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis-members.html +150 -151
- package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis.html +21 -23
- package/SVF-doxygen/html/html/classSVF_1_1UnaryOPVFGNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1VFG.html +9 -9
- package/SVF-doxygen/html/html/classSVF_1_1ValVar-members.html +69 -72
- package/SVF-doxygen/html/html/classSVF_1_1ValVar.html +23 -26
- package/SVF-doxygen/html/html/classSVF_1_1VarArgPN-members.html +70 -73
- package/SVF-doxygen/html/html/classSVF_1_1VarArgPN.html +18 -21
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive-members.html +125 -127
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive.html +44 -48
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat.html +31 -31
- package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver.html +6 -7
- package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver.png +0 -0
- package/SVF-doxygen/html/html/classSVF_1_1WPAPass.html +38 -40
- package/SVF-doxygen/html/html/classSVF_1_1WPASolver.html +17 -15
- package/SVF-doxygen/html/html/classSVF_1_1WPASolver.png +0 -0
- package/SVF-doxygen/html/html/classes.html +104 -105
- package/SVF-doxygen/html/html/dir_66541c162fd98954e2c32089ba9a721f.html +0 -4
- package/SVF-doxygen/html/html/dir_ea25a8a5b2904424d8a51916f8b475b2.html +0 -4
- package/SVF-doxygen/html/html/files.html +12 -16
- package/SVF-doxygen/html/html/functions_0x7e.html +0 -6
- package/SVF-doxygen/html/html/functions_a.html +8 -30
- package/SVF-doxygen/html/html/functions_b.html +8 -12
- package/SVF-doxygen/html/html/functions_c.html +24 -54
- package/SVF-doxygen/html/html/functions_d.html +1 -13
- package/SVF-doxygen/html/html/functions_e.html +1 -2
- package/SVF-doxygen/html/html/functions_eval_c.html +0 -9
- package/SVF-doxygen/html/html/functions_eval_f.html +0 -3
- package/SVF-doxygen/html/html/functions_f.html +19 -24
- package/SVF-doxygen/html/html/functions_func.html +6 -25
- package/SVF-doxygen/html/html/functions_func_0x7e.html +0 -6
- package/SVF-doxygen/html/html/functions_func_b.html +1 -5
- package/SVF-doxygen/html/html/functions_func_c.html +20 -37
- package/SVF-doxygen/html/html/functions_func_d.html +0 -6
- package/SVF-doxygen/html/html/functions_func_e.html +2 -3
- package/SVF-doxygen/html/html/functions_func_f.html +1 -5
- package/SVF-doxygen/html/html/functions_func_g.html +8 -48
- package/SVF-doxygen/html/html/functions_func_i.html +5 -15
- package/SVF-doxygen/html/html/functions_func_p.html +2 -16
- package/SVF-doxygen/html/html/functions_func_s.html +6 -19
- package/SVF-doxygen/html/html/functions_func_t.html +0 -6
- package/SVF-doxygen/html/html/functions_func_u.html +0 -4
- package/SVF-doxygen/html/html/functions_func_v.html +0 -3
- package/SVF-doxygen/html/html/functions_g.html +12 -55
- package/SVF-doxygen/html/html/functions_i.html +11 -21
- package/SVF-doxygen/html/html/functions_l.html +8 -14
- package/SVF-doxygen/html/html/functions_m.html +0 -6
- package/SVF-doxygen/html/html/functions_n.html +0 -36
- package/SVF-doxygen/html/html/functions_o.html +12 -20
- package/SVF-doxygen/html/html/functions_p.html +9 -31
- package/SVF-doxygen/html/html/functions_s.html +15 -31
- package/SVF-doxygen/html/html/functions_t.html +8 -18
- package/SVF-doxygen/html/html/functions_u.html +2 -9
- package/SVF-doxygen/html/html/functions_v.html +7 -10
- package/SVF-doxygen/html/html/functions_vars_a.html +0 -3
- package/SVF-doxygen/html/html/functions_vars_c.html +0 -6
- package/SVF-doxygen/html/html/functions_vars_d.html +0 -6
- package/SVF-doxygen/html/html/functions_vars_g.html +0 -3
- package/SVF-doxygen/html/html/functions_vars_l.html +0 -6
- package/SVF-doxygen/html/html/functions_vars_m.html +0 -6
- package/SVF-doxygen/html/html/functions_vars_n.html +0 -36
- package/SVF-doxygen/html/html/functions_vars_o.html +0 -12
- package/SVF-doxygen/html/html/functions_vars_p.html +0 -4
- package/SVF-doxygen/html/html/functions_vars_s.html +0 -3
- package/SVF-doxygen/html/html/functions_vars_t.html +0 -6
- package/SVF-doxygen/html/html/functions_vars_u.html +0 -3
- package/SVF-doxygen/html/html/functions_w.html +10 -6
- package/SVF-doxygen/html/html/globals_func_g.html +0 -3
- package/SVF-doxygen/html/html/globals_func_i.html +2 -7
- package/SVF-doxygen/html/html/globals_g.html +2 -5
- package/SVF-doxygen/html/html/globals_i.html +4 -7
- package/SVF-doxygen/html/html/globals_r.html +3 -3
- package/SVF-doxygen/html/html/globals_s.html +9 -7
- package/SVF-doxygen/html/html/hierarchy.html +13 -19
- package/SVF-doxygen/html/html/namespaceSVF.html +0 -10
- package/SVF-doxygen/html/html/namespaceSVF_1_1cppUtil.html +36 -38
- package/SVF-doxygen/html/html/search/all_1.js +1 -8
- package/SVF-doxygen/html/html/search/all_10.js +19 -21
- package/SVF-doxygen/html/html/search/all_12.js +1 -1
- package/SVF-doxygen/html/html/search/all_13.js +12 -17
- package/SVF-doxygen/html/html/search/all_14.js +8 -12
- package/SVF-doxygen/html/html/search/all_15.js +5 -6
- package/SVF-doxygen/html/html/search/all_16.js +4 -5
- package/SVF-doxygen/html/html/search/all_17.js +1 -1
- package/SVF-doxygen/html/html/search/all_1b.js +0 -2
- package/SVF-doxygen/html/html/search/all_2.js +0 -1
- package/SVF-doxygen/html/html/search/all_3.js +2 -11
- package/SVF-doxygen/html/html/search/all_4.js +0 -4
- package/SVF-doxygen/html/html/search/all_5.js +2 -2
- package/SVF-doxygen/html/html/search/all_6.js +2 -6
- package/SVF-doxygen/html/html/search/all_7.js +3 -16
- package/SVF-doxygen/html/html/search/all_9.js +5 -8
- package/SVF-doxygen/html/html/search/all_c.js +4 -6
- package/SVF-doxygen/html/html/search/all_d.js +4 -6
- package/SVF-doxygen/html/html/search/all_e.js +3 -15
- package/SVF-doxygen/html/html/search/all_f.js +0 -4
- package/SVF-doxygen/html/html/search/classes_10.js +1 -2
- package/SVF-doxygen/html/html/search/classes_2.js +0 -3
- package/SVF-doxygen/html/html/search/classes_5.js +0 -1
- package/SVF-doxygen/html/html/search/enumvalues_2.js +0 -3
- package/SVF-doxygen/html/html/search/enumvalues_5.js +0 -1
- package/SVF-doxygen/html/html/search/files_5.js +0 -2
- package/SVF-doxygen/html/html/search/files_e.js +1 -3
- package/SVF-doxygen/html/html/search/functions_0.js +1 -7
- package/SVF-doxygen/html/html/search/functions_1.js +0 -1
- package/SVF-doxygen/html/html/search/functions_11.js +2 -6
- package/SVF-doxygen/html/html/search/functions_12.js +2 -3
- package/SVF-doxygen/html/html/search/functions_13.js +4 -4
- package/SVF-doxygen/html/html/search/functions_14.js +0 -1
- package/SVF-doxygen/html/html/search/functions_17.js +0 -2
- package/SVF-doxygen/html/html/search/functions_2.js +2 -6
- package/SVF-doxygen/html/html/search/functions_3.js +0 -2
- package/SVF-doxygen/html/html/search/functions_4.js +1 -1
- package/SVF-doxygen/html/html/search/functions_5.js +1 -2
- package/SVF-doxygen/html/html/search/functions_6.js +3 -15
- package/SVF-doxygen/html/html/search/functions_8.js +4 -7
- package/SVF-doxygen/html/html/search/functions_f.js +12 -13
- package/SVF-doxygen/html/html/search/variables_1.js +0 -1
- package/SVF-doxygen/html/html/search/variables_10.js +1 -2
- package/SVF-doxygen/html/html/search/variables_13.js +0 -1
- package/SVF-doxygen/html/html/search/variables_14.js +3 -5
- package/SVF-doxygen/html/html/search/variables_15.js +1 -2
- package/SVF-doxygen/html/html/search/variables_3.js +0 -2
- package/SVF-doxygen/html/html/search/variables_4.js +0 -2
- package/SVF-doxygen/html/html/search/variables_5.js +1 -1
- package/SVF-doxygen/html/html/search/variables_7.js +0 -1
- package/SVF-doxygen/html/html/search/variables_c.js +1 -3
- package/SVF-doxygen/html/html/search/variables_d.js +1 -3
- package/SVF-doxygen/html/html/search/variables_e.js +2 -14
- package/SVF-doxygen/html/html/search/variables_f.js +0 -4
- package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01ConstraintGraph_01_5_01_4.html +1 -1
- package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01IRGraph_01_5_01_4.html +3 -3
- package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01OfflineConsG_01_5_01_4.html +1 -1
- package/SVF-doxygen/html/html/svf-ex_8cpp.html +4 -4
- package/SVF-doxygen/html/html/svf-ex_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/wpa_8cpp.html +1 -1
- package/SVF-doxygen/html/html/wpa_8cpp_source.html +1 -1
- package/build.sh +1 -28
- package/include/MemoryModel/PointerAnalysis.h +0 -1
- package/include/MemoryModel/SVFVariables.h +11 -140
- package/include/SVF-FE/LLVMModule.h +0 -24
- package/include/Util/Options.h +0 -7
- package/include/WPA/FlowSensitive.h +0 -4
- package/lib/MemoryModel/PointerAnalysis.cpp +4 -22
- package/lib/MemoryModel/PointerAnalysisImpl.cpp +1 -1
- package/lib/MemoryModel/SVFVariables.cpp +1 -28
- package/lib/SVF-FE/CPPUtil.cpp +0 -7
- package/lib/Util/Options.cpp +0 -24
- package/lib/WPA/FlowSensitive.cpp +1 -75
- package/lib/WPA/WPAPass.cpp +0 -4
- package/package.json +1 -1
- package/include/WPA/FlowSensitiveTBHC.h +0 -122
- package/include/WPA/TypeBasedHeapCloning.h +0 -188
- package/lib/WPA/FlowSensitiveTBHC.cpp +0 -695
- package/lib/WPA/TypeBasedHeapCloning.cpp +0 -795
|
@@ -1,795 +0,0 @@
|
|
|
1
|
-
//===- TypeBasedHeapCloning.cpp -- Type filter/type-based heap cloning base ------------//
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
* TypeBasedHeapCloning.cpp
|
|
5
|
-
*
|
|
6
|
-
* Created on: Feb 08, 2020
|
|
7
|
-
* Author: Mohamad Barbar
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
#include "SVF-FE/CPPUtil.h"
|
|
11
|
-
#include "SVF-FE/BasicTypes.h"
|
|
12
|
-
#include "WPA/TypeBasedHeapCloning.h"
|
|
13
|
-
#include "MemoryModel/PointerAnalysisImpl.h"
|
|
14
|
-
|
|
15
|
-
using namespace SVF;
|
|
16
|
-
|
|
17
|
-
const DIType *TypeBasedHeapCloning::undefType = nullptr;
|
|
18
|
-
|
|
19
|
-
const std::string TypeBasedHeapCloning::derefFnName = "deref";
|
|
20
|
-
const std::string TypeBasedHeapCloning::mangledDerefFnName = "_Z5derefv";
|
|
21
|
-
|
|
22
|
-
TypeBasedHeapCloning::TypeBasedHeapCloning(BVDataPTAImpl *pta)
|
|
23
|
-
{
|
|
24
|
-
this->pta = pta;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
void TypeBasedHeapCloning::setDCHG(DCHGraph *dchg)
|
|
28
|
-
{
|
|
29
|
-
this->dchg = dchg;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
void TypeBasedHeapCloning::setPAG(SVFIR *pag)
|
|
33
|
-
{
|
|
34
|
-
ppag = pag;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
bool TypeBasedHeapCloning::isBlkObjOrConstantObj(NodeID o) const
|
|
38
|
-
{
|
|
39
|
-
if (isClone(o)) o = cloneToOriginalObj.at(o);
|
|
40
|
-
return SVFUtil::isa<ObjVar>(ppag->getGNode(o)) && ppag->isBlkObjOrConstantObj(o);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
bool TypeBasedHeapCloning::isBase(const DIType *a, const DIType *b) const
|
|
44
|
-
{
|
|
45
|
-
assert(dchg && "TBHC: DCHG not set!");
|
|
46
|
-
return dchg->isBase(a, b, true);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
bool TypeBasedHeapCloning::isClone(NodeID o) const
|
|
50
|
-
{
|
|
51
|
-
return cloneToOriginalObj.find(o) != cloneToOriginalObj.end();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
void TypeBasedHeapCloning::setType(NodeID o, const DIType *t)
|
|
55
|
-
{
|
|
56
|
-
objToType.insert({o, t});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const DIType *TypeBasedHeapCloning::getType(NodeID o) const
|
|
60
|
-
{
|
|
61
|
-
assert(objToType.find(o) != objToType.end() && "TBHC: object has no type?");
|
|
62
|
-
return objToType.at(o);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
void TypeBasedHeapCloning::setAllocationSite(NodeID o, NodeID site)
|
|
66
|
-
{
|
|
67
|
-
objToAllocation.insert({o, site});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
NodeID TypeBasedHeapCloning::getAllocationSite(NodeID o) const
|
|
71
|
-
{
|
|
72
|
-
assert(objToAllocation.find(o) != objToAllocation.end() && "TBHC: object has no allocation site?");
|
|
73
|
-
return objToAllocation.at(o);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const NodeBS TypeBasedHeapCloning::getObjsWithClones(void)
|
|
77
|
-
{
|
|
78
|
-
NodeBS objs;
|
|
79
|
-
for (std::pair<NodeID, NodeBS> oc : objToClones)
|
|
80
|
-
{
|
|
81
|
-
objs.set(oc.first);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return objs;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
void TypeBasedHeapCloning::addClone(NodeID o, NodeID c)
|
|
88
|
-
{
|
|
89
|
-
objToClones[o].set(c);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const NodeBS &TypeBasedHeapCloning::getClones(NodeID o)
|
|
93
|
-
{
|
|
94
|
-
return objToClones[o];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
void TypeBasedHeapCloning::setOriginalObj(NodeID c, NodeID o)
|
|
98
|
-
{
|
|
99
|
-
cloneToOriginalObj.insert({c, o});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
NodeID TypeBasedHeapCloning::getOriginalObj(NodeID c) const
|
|
103
|
-
{
|
|
104
|
-
if (isClone(c))
|
|
105
|
-
{
|
|
106
|
-
assert(cloneToOriginalObj.find(c) != cloneToOriginalObj.end()
|
|
107
|
-
&& "TBHC: original object not set for clone?");
|
|
108
|
-
return cloneToOriginalObj.at(c);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return c;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
PointsTo &TypeBasedHeapCloning::getFilterSet(NodeID loc)
|
|
115
|
-
{
|
|
116
|
-
return locToFilterSet[loc];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
void TypeBasedHeapCloning::addGepToObj(NodeID gep, NodeID base, unsigned offset)
|
|
120
|
-
{
|
|
121
|
-
objToGeps[base].set(gep);
|
|
122
|
-
const PAGNode *baseNode = ppag->getGNode(base);
|
|
123
|
-
assert(baseNode && "TBHC: given bad base node?");
|
|
124
|
-
const ObjVar *baseObj = SVFUtil::dyn_cast<ObjVar>(baseNode);
|
|
125
|
-
assert(baseObj && "TBHC: non-object given for base?");
|
|
126
|
-
// We can use the base or the gep mem. obj.; should be identical.
|
|
127
|
-
const MemObj *baseMemObj = baseObj->getMemObj();
|
|
128
|
-
|
|
129
|
-
objToGeps[base].set(gep);
|
|
130
|
-
memObjToGeps[baseMemObj][offset].set(gep);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const NodeBS &TypeBasedHeapCloning::getGepObjsFromMemObj(const MemObj *memObj, unsigned offset)
|
|
134
|
-
{
|
|
135
|
-
return memObjToGeps[memObj][offset];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const NodeBS &TypeBasedHeapCloning::getGepObjs(NodeID base)
|
|
139
|
-
{
|
|
140
|
-
return objToGeps[base];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const NodeBS TypeBasedHeapCloning::getGepObjClones(NodeID base, unsigned offset)
|
|
144
|
-
{
|
|
145
|
-
assert(dchg && "TBHC: DCHG not set!");
|
|
146
|
-
// Set of GEP objects we will return.
|
|
147
|
-
NodeBS geps;
|
|
148
|
-
|
|
149
|
-
PAGNode *node = ppag->getGNode(base);
|
|
150
|
-
assert(node && "TBHC: base object node does not exist.");
|
|
151
|
-
ObjVar *baseNode = SVFUtil::dyn_cast<ObjVar>(node);
|
|
152
|
-
assert(baseNode && "TBHC: base \"object\" node is not an object.");
|
|
153
|
-
|
|
154
|
-
// totalOffset is the offset from the real base (i.e. base of base),
|
|
155
|
-
// offset is the offset into base, whether it is a field itself or not.
|
|
156
|
-
s32_t totalOffset = offset;
|
|
157
|
-
if (const GepObjVar *baseGep = SVFUtil::dyn_cast<GepObjVar>(baseNode))
|
|
158
|
-
{
|
|
159
|
-
totalOffset += baseGep->getConstantFieldIdx();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const DIType *baseType = getType(base);
|
|
163
|
-
|
|
164
|
-
// First field? Just return the whole object; same thing.
|
|
165
|
-
// For arrays, we want things to work as normal because an array *object* is more
|
|
166
|
-
// like a pointer than a struct object.
|
|
167
|
-
if (offset == 0 && baseType->getTag() != dwarf::DW_TAG_array_type)
|
|
168
|
-
{
|
|
169
|
-
// The base object is the 0 gep object.
|
|
170
|
-
addGepToObj(base, base, 0);
|
|
171
|
-
geps.set(base);
|
|
172
|
-
return geps;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (baseNode->getMemObj()->isFieldInsensitive())
|
|
176
|
-
{
|
|
177
|
-
// If it's field-insensitive, the base represents everything.
|
|
178
|
-
geps.set(base);
|
|
179
|
-
return geps;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Caching on offset would improve performance but it seems minimal.
|
|
183
|
-
const NodeBS &gepObjs = getGepObjs(base);
|
|
184
|
-
for (NodeID gep : gepObjs)
|
|
185
|
-
{
|
|
186
|
-
PAGNode *node = ppag->getGNode(gep);
|
|
187
|
-
assert(node && "TBHC: expected gep node doesn't exist.");
|
|
188
|
-
assert((SVFUtil::isa<GepObjVar>(node) || SVFUtil::isa<FIObjVar>(node))
|
|
189
|
-
&& "TBHC: expected a GEP or FI object.");
|
|
190
|
-
|
|
191
|
-
if (GepObjVar *gepNode = SVFUtil::dyn_cast<GepObjVar>(node))
|
|
192
|
-
{
|
|
193
|
-
if (gepNode->getConstantFieldIdx() == totalOffset)
|
|
194
|
-
{
|
|
195
|
-
geps.set(gep);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else
|
|
199
|
-
{
|
|
200
|
-
// Definitely a FIObj (asserted), but we don't want to add it if
|
|
201
|
-
// the object is field-sensitive because in that case it actually
|
|
202
|
-
// represents the 0th field, not the whole object.
|
|
203
|
-
if (baseNode->getMemObj()->isFieldInsensitive())
|
|
204
|
-
{
|
|
205
|
-
geps.set(gep);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (geps.empty())
|
|
211
|
-
{
|
|
212
|
-
// No gep node has even be created, so create one.
|
|
213
|
-
NodeID newGep;
|
|
214
|
-
LocationSet newLS;
|
|
215
|
-
// fldIdx is what is returned by getConstantFieldIdx.
|
|
216
|
-
newLS.setFldIdx(totalOffset);
|
|
217
|
-
|
|
218
|
-
if (isClone(base))
|
|
219
|
-
{
|
|
220
|
-
// Don't use ppag->getGepObjVar because base and it's original object
|
|
221
|
-
// have the same memory object which is the key SVFIR uses.
|
|
222
|
-
newGep = addCloneGepObjNode(baseNode->getMemObj(), newLS);
|
|
223
|
-
}
|
|
224
|
-
else
|
|
225
|
-
{
|
|
226
|
-
newGep = ppag->getGepObjVar(base, newLS);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (GepObjVar *gep = SVFUtil::dyn_cast<GepObjVar>(ppag->getGNode(newGep)))
|
|
230
|
-
{
|
|
231
|
-
gep->setBaseNode(base);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
addGepToObj(newGep, base, totalOffset);
|
|
235
|
-
const DIType *newGepType = nullptr;
|
|
236
|
-
if (baseType->getTag() == dwarf::DW_TAG_array_type || baseType->getTag() == dwarf::DW_TAG_pointer_type)
|
|
237
|
-
{
|
|
238
|
-
if (const DICompositeType *arrayType = SVFUtil::dyn_cast<DICompositeType>(baseType))
|
|
239
|
-
{
|
|
240
|
-
// Array access.
|
|
241
|
-
newGepType = arrayType->getBaseType();
|
|
242
|
-
}
|
|
243
|
-
else if (const DIDerivedType *ptrType = SVFUtil::dyn_cast<DIDerivedType>(baseType))
|
|
244
|
-
{
|
|
245
|
-
// Pointer access.
|
|
246
|
-
newGepType = ptrType->getBaseType();
|
|
247
|
-
}
|
|
248
|
-
assert(newGepType && "TBHC: newGepType is neither DIComposite nor DIDerived");
|
|
249
|
-
|
|
250
|
-
// Get the canonical type because we got the type from the DIType infrastructure directly.
|
|
251
|
-
newGepType = dchg->getCanonicalType(newGepType);
|
|
252
|
-
}
|
|
253
|
-
else
|
|
254
|
-
{
|
|
255
|
-
// Must be a struct/class.
|
|
256
|
-
// Don't use totalOffset because we're operating on the Gep object which is our parent
|
|
257
|
-
// (i.e. field of some base, not the base itself).
|
|
258
|
-
newGepType = dchg->getFieldType(getType(base), offset);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
setType(newGep, newGepType);
|
|
262
|
-
// We call the object created in the non-TBHC analysis the original object.
|
|
263
|
-
setOriginalObj(newGep, ppag->getGepObjVar(baseNode->getId(), offset));
|
|
264
|
-
setAllocationSite(newGep, 0);
|
|
265
|
-
|
|
266
|
-
geps.set(newGep);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return geps;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
bool TypeBasedHeapCloning::init(NodeID loc, NodeID p, const DIType *tildet, bool reuse, bool gep)
|
|
273
|
-
{
|
|
274
|
-
assert(dchg && "TBHC: DCHG not set!");
|
|
275
|
-
bool changed = false;
|
|
276
|
-
|
|
277
|
-
const PointsTo &pPt = pta->getPts(p);
|
|
278
|
-
// The points-to set we will populate in the loop to fill pPt.
|
|
279
|
-
PointsTo pNewPt;
|
|
280
|
-
|
|
281
|
-
PointsTo &filterSet = getFilterSet(loc);
|
|
282
|
-
for (NodeID o : pPt)
|
|
283
|
-
{
|
|
284
|
-
// If it's been filtered before, it'll be filtered again.
|
|
285
|
-
if (filterSet.test(o)) continue;
|
|
286
|
-
|
|
287
|
-
PAGNode *obj = ppag->getGNode(o);
|
|
288
|
-
assert(obj && "TBHC: pointee object does not exist in SVFIR?");
|
|
289
|
-
const DIType *tp = getType(o); // tp is t'
|
|
290
|
-
|
|
291
|
-
// When an object is field-insensitive, we can't filter on any of the fields' types.
|
|
292
|
-
// i.e. a pointer of the field type can safely access an object of the base/struct
|
|
293
|
-
// type if that object is field-insensitive.
|
|
294
|
-
bool fieldInsensitive = false;
|
|
295
|
-
std::vector<const DIType *> fieldTypes;
|
|
296
|
-
if (ObjVar *obj = SVFUtil::dyn_cast<ObjVar>(ppag->getGNode(o)))
|
|
297
|
-
{
|
|
298
|
-
fieldInsensitive = obj->getMemObj()->isFieldInsensitive();
|
|
299
|
-
if (tp != nullptr && (tp->getTag() == dwarf::DW_TAG_structure_type
|
|
300
|
-
|| tp->getTag() == dwarf::DW_TAG_class_type))
|
|
301
|
-
{
|
|
302
|
-
fieldTypes = dchg->getFieldTypes(tp);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const Set<const DIType *> &aggs = dchg->isAgg(tp)
|
|
307
|
-
? dchg->getAggs(tp) : Set<const DIType *>();
|
|
308
|
-
|
|
309
|
-
NodeID prop;
|
|
310
|
-
bool filter = false;
|
|
311
|
-
if (tp == undefType)
|
|
312
|
-
{
|
|
313
|
-
// o is uninitialised.
|
|
314
|
-
// GEP objects should never be uninitialised; type assigned at creation.
|
|
315
|
-
assert(!isGep(obj) && "TBHC: GEP object is untyped!");
|
|
316
|
-
prop = cloneObject(o, tildet, false);
|
|
317
|
-
++numInit;
|
|
318
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGInit;
|
|
319
|
-
}
|
|
320
|
-
else if (fieldInsensitive && tp && dchg->isFieldOf(tildet, tp))
|
|
321
|
-
{
|
|
322
|
-
// Field-insensitive object but the instruction is operating on a field.
|
|
323
|
-
prop = o;
|
|
324
|
-
++numTBWU;
|
|
325
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGTBWU;
|
|
326
|
-
}
|
|
327
|
-
else if (gep && aggs.find(tildet) != aggs.end())
|
|
328
|
-
{
|
|
329
|
-
// SVF treats two consecutive GEPs as children to the same load/store.
|
|
330
|
-
// Special case for aggregates.
|
|
331
|
-
// SVF will transform (for example)
|
|
332
|
-
// `1: s = get struct element X from array a; 2: f = get field of struct Y from s;`
|
|
333
|
-
// to `1: s = get struct element X from array a; 2: f = get field of struct Y from a;`
|
|
334
|
-
// so we want the second instruction to be operating on an object of type
|
|
335
|
-
// 'Struct S', not 'Array of S'.
|
|
336
|
-
prop = cloneObject(o, tildet, false);
|
|
337
|
-
++numAgg;
|
|
338
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGAgg;
|
|
339
|
-
}
|
|
340
|
-
else if (isBase(tp, tildet) && tp != tildet
|
|
341
|
-
&& (reuse || dchg->isFirstField(tp, tildet) || (!reuse && pta->isHeapMemObj(o))))
|
|
342
|
-
{
|
|
343
|
-
// Downcast.
|
|
344
|
-
// One of three conditions:
|
|
345
|
-
// - !reuse && heap: because downcasts should not happen to stack/globals.
|
|
346
|
-
// - isFirstField because ^ can happen because when we take the field of a
|
|
347
|
-
// struct that is a struct, we get its first field, then it may downcast
|
|
348
|
-
// back to the struct at another GEP.
|
|
349
|
-
// TODO: this can probably be solved more cleanly.
|
|
350
|
-
// - reuse: because it can happen to stack/heap objects.
|
|
351
|
-
prop = cloneObject(o, tildet, reuse);
|
|
352
|
-
++numTBSSU;
|
|
353
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGTBSSU;
|
|
354
|
-
}
|
|
355
|
-
else if (isBase(tildet, tp))
|
|
356
|
-
{
|
|
357
|
-
// Upcast.
|
|
358
|
-
prop = o;
|
|
359
|
-
++numTBWU;
|
|
360
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGTBWU;
|
|
361
|
-
}
|
|
362
|
-
else if (tildet != tp && reuse)
|
|
363
|
-
{
|
|
364
|
-
// Reuse.
|
|
365
|
-
prop = cloneObject(o, tildet, true);
|
|
366
|
-
++numReuse;
|
|
367
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGReuse;
|
|
368
|
-
}
|
|
369
|
-
else
|
|
370
|
-
{
|
|
371
|
-
// Some spurious objects will be filtered.
|
|
372
|
-
filter = true;
|
|
373
|
-
prop = o;
|
|
374
|
-
++numTBSU;
|
|
375
|
-
if (!pta->isHeapMemObj(o) && !SVFUtil::isa<DummyObjVar>(obj)) ++numSGTBSU;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (prop != o)
|
|
379
|
-
{
|
|
380
|
-
// If we cloned, we want to keep o in p's PTS but filter it (ignore it later).
|
|
381
|
-
pNewPt.set(o);
|
|
382
|
-
filterSet.set(o);
|
|
383
|
-
// TODO: hack, sound but imprecise and unclean.
|
|
384
|
-
// In the aggs case there is a difference between it being good for
|
|
385
|
-
// arrays and structs. For now, just propagate both the clone and the original
|
|
386
|
-
// object till a cleaner solution is found.
|
|
387
|
-
if (gep && aggs.find(tildet) != aggs.end())
|
|
388
|
-
{
|
|
389
|
-
filterSet.reset(o);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
pNewPt.set(prop);
|
|
394
|
-
|
|
395
|
-
if (filter)
|
|
396
|
-
{
|
|
397
|
-
filterSet.set(o);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (pPt != pNewPt)
|
|
402
|
-
{
|
|
403
|
-
// Seems fast enough to perform in the naive way.
|
|
404
|
-
pta->clearFullPts(p);
|
|
405
|
-
pta->unionPts(p, pNewPt);
|
|
406
|
-
changed = true;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return changed;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
NodeID TypeBasedHeapCloning::cloneObject(NodeID o, const DIType *type, bool)
|
|
413
|
-
{
|
|
414
|
-
NodeID clone;
|
|
415
|
-
const PAGNode *obj = ppag->getGNode(o);
|
|
416
|
-
if (const GepObjVar *gepObj = SVFUtil::dyn_cast<GepObjVar>(obj))
|
|
417
|
-
{
|
|
418
|
-
const NodeBS &clones = getGepObjClones(gepObj->getBaseNode(), gepObj->getConstantFieldIdx());
|
|
419
|
-
// TODO: a bit of repetition.
|
|
420
|
-
for (NodeID clone : clones)
|
|
421
|
-
{
|
|
422
|
-
if (getType(clone) == type)
|
|
423
|
-
{
|
|
424
|
-
return clone;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
clone = addCloneGepObjNode(gepObj->getMemObj(), gepObj->getLocationSet());
|
|
429
|
-
|
|
430
|
-
// The base needs to know about the new clone.
|
|
431
|
-
addGepToObj(clone, gepObj->getBaseNode(), gepObj->getConstantFieldIdx());
|
|
432
|
-
|
|
433
|
-
addClone(o, clone);
|
|
434
|
-
addClone(getOriginalObj(o), clone);
|
|
435
|
-
// The only instance of original object of a Gep object being retrieved is for
|
|
436
|
-
// IN sets and gepToSVFGRetriever in FSTBHC, so we don't care that clone comes
|
|
437
|
-
// from o (we can get that by checking the base and offset).
|
|
438
|
-
setOriginalObj(clone, getOriginalObj(o));
|
|
439
|
-
CloneGepObjVar *cloneGepObj = SVFUtil::dyn_cast<CloneGepObjVar>(ppag->getGNode(clone));
|
|
440
|
-
cloneGepObj->setBaseNode(gepObj->getBaseNode());
|
|
441
|
-
}
|
|
442
|
-
else if (SVFUtil::isa<FIObjVar>(obj) || SVFUtil::isa<DummyObjVar>(obj))
|
|
443
|
-
{
|
|
444
|
-
o = getOriginalObj(o);
|
|
445
|
-
// Check there isn't an appropriate clone already.
|
|
446
|
-
const NodeBS &clones = getClones(o);
|
|
447
|
-
for (NodeID clone : clones)
|
|
448
|
-
{
|
|
449
|
-
if (getType(clone) == type)
|
|
450
|
-
{
|
|
451
|
-
return clone;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
if (const FIObjVar *fiObj = SVFUtil::dyn_cast<FIObjVar>(obj))
|
|
456
|
-
{
|
|
457
|
-
clone = addCloneFIObjNode(fiObj->getMemObj());
|
|
458
|
-
}
|
|
459
|
-
else
|
|
460
|
-
{
|
|
461
|
-
const DummyObjVar *dummyObj = SVFUtil::dyn_cast<DummyObjVar>(obj);
|
|
462
|
-
clone = addCloneDummyObjNode(dummyObj->getMemObj());
|
|
463
|
-
}
|
|
464
|
-
// We checked above that it's an FIObj or a DummyObj.
|
|
465
|
-
|
|
466
|
-
// Tracking object<->clone mappings.
|
|
467
|
-
addClone(o, clone);
|
|
468
|
-
setOriginalObj(clone, o);
|
|
469
|
-
}
|
|
470
|
-
else
|
|
471
|
-
{
|
|
472
|
-
assert(false && "FSTBHC: trying to clone unhandled object");
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// Clone's metadata. This can be shared between Geps/otherwise.
|
|
476
|
-
setType(clone, type);
|
|
477
|
-
setAllocationSite(clone, getAllocationSite(o));
|
|
478
|
-
|
|
479
|
-
backPropagate(clone);
|
|
480
|
-
|
|
481
|
-
return clone;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
const MDNode *TypeBasedHeapCloning::getRawCTirMetadata(const Value *v)
|
|
485
|
-
{
|
|
486
|
-
assert(v != nullptr && "TBHC: trying to get metadata from nullptr!");
|
|
487
|
-
|
|
488
|
-
const MDNode *mdNode = nullptr;
|
|
489
|
-
if (const Instruction *inst = SVFUtil::dyn_cast<Instruction>(v))
|
|
490
|
-
{
|
|
491
|
-
mdNode = inst->getMetadata(cppUtil::ctir::derefMDName);
|
|
492
|
-
}
|
|
493
|
-
else if (const GlobalObject *go = SVFUtil::dyn_cast<GlobalObject>(v))
|
|
494
|
-
{
|
|
495
|
-
mdNode = go->getMetadata(cppUtil::ctir::derefMDName);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Will be nullptr if metadata isn't there.
|
|
499
|
-
return mdNode;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
NodeID TypeBasedHeapCloning::addCloneDummyObjNode(const MemObj *mem)
|
|
503
|
-
{
|
|
504
|
-
NodeID id = NodeIDAllocator::get()->allocateObjectId();
|
|
505
|
-
return ppag->addObjNode(nullptr, new CloneDummyObjVar(id, mem), id);
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
NodeID TypeBasedHeapCloning::addCloneGepObjNode(const MemObj *mem, const LocationSet &l)
|
|
509
|
-
{
|
|
510
|
-
NodeID id = NodeIDAllocator::get()->allocateObjectId();
|
|
511
|
-
return ppag->addObjNode(mem->getValue(), new CloneGepObjVar(mem, id, l), id);
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
NodeID TypeBasedHeapCloning::addCloneFIObjNode(const MemObj *mem)
|
|
515
|
-
{
|
|
516
|
-
NodeID id = NodeIDAllocator::get()->allocateObjectId();
|
|
517
|
-
return ppag->addObjNode(mem->getValue(), new CloneFIObjVar(mem->getValue(), id, mem), id);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
const DIType *TypeBasedHeapCloning::getTypeFromCTirMetadata(const Value *v)
|
|
521
|
-
{
|
|
522
|
-
assert(v != nullptr && "TBHC: trying to get type from nullptr!");
|
|
523
|
-
|
|
524
|
-
const MDNode *mdNode = getRawCTirMetadata(v);
|
|
525
|
-
if (mdNode == nullptr)
|
|
526
|
-
{
|
|
527
|
-
return nullptr;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const DIType *type = SVFUtil::dyn_cast<DIType>(mdNode);
|
|
531
|
-
if (type == nullptr)
|
|
532
|
-
{
|
|
533
|
-
SVFUtil::errs() << "TBHC: bad ctir metadata type\n";
|
|
534
|
-
return nullptr;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
return dchg->getCanonicalType(type);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
bool TypeBasedHeapCloning::isGep(const PAGNode *n) const
|
|
541
|
-
{
|
|
542
|
-
assert(n != nullptr && "TBHC: testing if null is a GEP object!");
|
|
543
|
-
return SVFUtil::isa<GepObjVar>(n);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
/// Returns true if the function name matches MAYALIAS, NOALIAS, etc.
|
|
547
|
-
static bool isAliasTestFunction(std::string name)
|
|
548
|
-
{
|
|
549
|
-
return name == PointerAnalysis::aliasTestMayAlias
|
|
550
|
-
|| name == PointerAnalysis::aliasTestMayAliasMangled
|
|
551
|
-
|| name == PointerAnalysis::aliasTestNoAlias
|
|
552
|
-
|| name == PointerAnalysis::aliasTestNoAliasMangled
|
|
553
|
-
|| name == PointerAnalysis::aliasTestPartialAlias
|
|
554
|
-
|| name == PointerAnalysis::aliasTestPartialAliasMangled
|
|
555
|
-
|| name == PointerAnalysis::aliasTestMustAlias
|
|
556
|
-
|| name == PointerAnalysis::aliasTestMustAliasMangled
|
|
557
|
-
|| name == PointerAnalysis::aliasTestFailMayAlias
|
|
558
|
-
|| name == PointerAnalysis::aliasTestFailMayAliasMangled
|
|
559
|
-
|| name == PointerAnalysis::aliasTestFailNoAlias
|
|
560
|
-
|| name == PointerAnalysis::aliasTestFailNoAliasMangled;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
void TypeBasedHeapCloning::validateTBHCTests(SVFModule*)
|
|
564
|
-
{
|
|
565
|
-
const LLVMModuleSet *llvmModuleSet = LLVMModuleSet::getLLVMModuleSet();
|
|
566
|
-
for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
|
|
567
|
-
{
|
|
568
|
-
const SVFIR::CallSiteSet &callSites = ppag->getCallSiteSet();
|
|
569
|
-
for (const CallICFGNode *cbn : callSites)
|
|
570
|
-
{
|
|
571
|
-
const CallSite &cs = SVFUtil::getLLVMCallSite(cbn->getCallSite());
|
|
572
|
-
const Function *fn = cs.getCalledFunction();
|
|
573
|
-
if (fn == nullptr || !isAliasTestFunction(fn->getName().str()))
|
|
574
|
-
{
|
|
575
|
-
continue;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// We have a test call,
|
|
579
|
-
// We want the store which stores to the pointer in question (i.e. operand of the
|
|
580
|
-
// store is the pointer, and the store itself is the dereference).
|
|
581
|
-
const StoreInst *ps = nullptr, *qs = nullptr;
|
|
582
|
-
// Check: currInst is a deref call, so p/q is prevInst.
|
|
583
|
-
|
|
584
|
-
// Find p.
|
|
585
|
-
const Instruction *prevInst = nullptr;
|
|
586
|
-
const Instruction *currInst = cs.getInstruction();
|
|
587
|
-
do
|
|
588
|
-
{
|
|
589
|
-
if (const CallInst *ci = SVFUtil::dyn_cast<CallInst>(currInst))
|
|
590
|
-
{
|
|
591
|
-
std::string calledFnName = ci->getCalledFunction()->getName().str();
|
|
592
|
-
if (calledFnName == derefFnName || calledFnName == mangledDerefFnName)
|
|
593
|
-
{
|
|
594
|
-
const StoreInst *si = SVFUtil::dyn_cast<StoreInst>(prevInst);
|
|
595
|
-
assert(si && "TBHC: validation macro not producing stores?");
|
|
596
|
-
ps = si;
|
|
597
|
-
break;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
prevInst = currInst;
|
|
602
|
-
currInst = currInst->getNextNonDebugInstruction();
|
|
603
|
-
}
|
|
604
|
-
while (currInst != nullptr);
|
|
605
|
-
|
|
606
|
-
// Repeat for q.
|
|
607
|
-
while (currInst != nullptr)
|
|
608
|
-
{
|
|
609
|
-
// while loop, not do-while, because we need to the next instruction (current
|
|
610
|
-
// instruction is the first deref()).
|
|
611
|
-
prevInst = currInst;
|
|
612
|
-
currInst = currInst->getNextNonDebugInstruction();
|
|
613
|
-
|
|
614
|
-
if (const CallInst *ci = SVFUtil::dyn_cast<CallInst>(currInst))
|
|
615
|
-
{
|
|
616
|
-
std::string calledFnName = ci->getCalledFunction()->getName().str();
|
|
617
|
-
if (calledFnName == derefFnName || calledFnName == mangledDerefFnName)
|
|
618
|
-
{
|
|
619
|
-
const StoreInst *si = SVFUtil::dyn_cast<StoreInst>(prevInst);
|
|
620
|
-
assert(si && "TBHC: validation macro not producing stores?");
|
|
621
|
-
qs = si;
|
|
622
|
-
break;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
assert(ps != nullptr && qs != nullptr && "TBHC: malformed alias test?");
|
|
628
|
-
NodeID p = ppag->getValueNode(ps->getPointerOperand()),
|
|
629
|
-
q = ppag->getValueNode(qs->getPointerOperand());
|
|
630
|
-
const DIType *pt = getTypeFromCTirMetadata(ps), *qt = getTypeFromCTirMetadata(qs);
|
|
631
|
-
|
|
632
|
-
// Now filter both points-to sets according to the type of the value.
|
|
633
|
-
const PointsTo &pPts = pta->getPts(p), &qPts = pta->getPts(q);
|
|
634
|
-
PointsTo pPtsFiltered, qPtsFiltered;
|
|
635
|
-
for (NodeID o : pPts)
|
|
636
|
-
{
|
|
637
|
-
if (getType(o) != undefType && isBase(pt, getType(o)))
|
|
638
|
-
{
|
|
639
|
-
pPtsFiltered.set(o);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
for (NodeID o : qPts)
|
|
644
|
-
{
|
|
645
|
-
if (getType(o) != undefType && isBase(qt, getType(o)))
|
|
646
|
-
{
|
|
647
|
-
qPtsFiltered.set(o);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
BVDataPTAImpl *bvpta = SVFUtil::dyn_cast<BVDataPTAImpl>(pta);
|
|
652
|
-
assert(bvpta && "TBHC: need a BVDataPTAImpl for TBHC alias testing.");
|
|
653
|
-
AliasResult res = bvpta->alias(pPtsFiltered, qPtsFiltered);
|
|
654
|
-
|
|
655
|
-
bool passed = false;
|
|
656
|
-
std::string testName = "";
|
|
657
|
-
if (fn->getName() == PointerAnalysis::aliasTestMayAlias
|
|
658
|
-
|| fn->getName() == PointerAnalysis::aliasTestMayAliasMangled)
|
|
659
|
-
{
|
|
660
|
-
passed = res == AliasResult::MayAlias || res == AliasResult::MustAlias;
|
|
661
|
-
testName = PointerAnalysis::aliasTestMayAlias;
|
|
662
|
-
}
|
|
663
|
-
else if (fn->getName() == PointerAnalysis::aliasTestNoAlias
|
|
664
|
-
|| fn->getName() == PointerAnalysis::aliasTestNoAliasMangled)
|
|
665
|
-
{
|
|
666
|
-
passed = res == AliasResult::NoAlias;
|
|
667
|
-
testName = PointerAnalysis::aliasTestNoAlias;
|
|
668
|
-
}
|
|
669
|
-
else if (fn->getName() == PointerAnalysis::aliasTestMustAlias
|
|
670
|
-
|| fn->getName() == PointerAnalysis::aliasTestMustAliasMangled)
|
|
671
|
-
{
|
|
672
|
-
passed = res == AliasResult::MustAlias || res == AliasResult::MayAlias;
|
|
673
|
-
testName = PointerAnalysis::aliasTestMustAlias;
|
|
674
|
-
}
|
|
675
|
-
else if (fn->getName() == PointerAnalysis::aliasTestPartialAlias
|
|
676
|
-
|| fn->getName() == PointerAnalysis::aliasTestPartialAliasMangled)
|
|
677
|
-
{
|
|
678
|
-
passed = res == AliasResult::MayAlias || res == AliasResult::PartialAlias;
|
|
679
|
-
testName = PointerAnalysis::aliasTestPartialAlias;
|
|
680
|
-
}
|
|
681
|
-
else if (fn->getName() == PointerAnalysis::aliasTestFailMayAlias
|
|
682
|
-
|| fn->getName() == PointerAnalysis::aliasTestFailMayAliasMangled)
|
|
683
|
-
{
|
|
684
|
-
passed = res != AliasResult::MayAlias && res != AliasResult::MustAlias && res != AliasResult::PartialAlias;
|
|
685
|
-
testName = PointerAnalysis::aliasTestFailMayAlias;
|
|
686
|
-
}
|
|
687
|
-
else if (fn->getName() == PointerAnalysis::aliasTestFailNoAlias
|
|
688
|
-
|| fn->getName() == PointerAnalysis::aliasTestFailNoAliasMangled)
|
|
689
|
-
{
|
|
690
|
-
passed = res != AliasResult::NoAlias;
|
|
691
|
-
testName = PointerAnalysis::aliasTestFailNoAlias;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
SVFUtil::outs() << "[" << pta->PTAName() << "] Checking " << testName << "\n";
|
|
695
|
-
OutStream &msgStream = passed ? SVFUtil::outs() : SVFUtil::errs();
|
|
696
|
-
msgStream << (passed ? SVFUtil::sucMsg("\t SUCCESS") : SVFUtil::errMsg("\t FAILURE"))
|
|
697
|
-
<< " : " << testName
|
|
698
|
-
<< " check <id:" << p << ", id:" << q << "> "
|
|
699
|
-
<< "at (" << SVFUtil::getSourceLoc(cs.getInstruction()) << ")\n";
|
|
700
|
-
if (!passed)
|
|
701
|
-
assert(false && "test case failed!");
|
|
702
|
-
|
|
703
|
-
if (pPtsFiltered.empty())
|
|
704
|
-
{
|
|
705
|
-
msgStream << SVFUtil::wrnMsg("\t WARNING")
|
|
706
|
-
<< " : pts(" << p << ") is empty\n";
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
if (qPtsFiltered.empty())
|
|
710
|
-
{
|
|
711
|
-
msgStream << SVFUtil::wrnMsg("\t WARNING")
|
|
712
|
-
<< " : pts(" << q << ") is empty\n";
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
if (testName == PointerAnalysis::aliasTestMustAlias)
|
|
716
|
-
{
|
|
717
|
-
msgStream << SVFUtil::wrnMsg("\t WARNING")
|
|
718
|
-
<< " : MUSTALIAS tests are actually MAYALIAS tests\n";
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
if (testName == PointerAnalysis::aliasTestPartialAlias)
|
|
722
|
-
{
|
|
723
|
-
msgStream << SVFUtil::wrnMsg("\t WARNING")
|
|
724
|
-
<< " : PARTIALALIAS tests are actually MAYALIAS tests\n";
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
msgStream.flush();
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
void TypeBasedHeapCloning::dumpStats(void)
|
|
733
|
-
{
|
|
734
|
-
std::string indent = "";
|
|
735
|
-
SVFUtil::outs() << "@@@@@@@@@ TBHC STATISTICS @@@@@@@@@\n";
|
|
736
|
-
indent = " ";
|
|
737
|
-
|
|
738
|
-
// Print clones with their types.
|
|
739
|
-
SVFUtil::outs() << indent << "=== Original objects to clones ===\n";
|
|
740
|
-
indent = " ";
|
|
741
|
-
unsigned totalClones = 0;
|
|
742
|
-
const NodeBS objs = getObjsWithClones();
|
|
743
|
-
for (NodeID o : objs)
|
|
744
|
-
{
|
|
745
|
-
const NodeBS &clones = getClones(o);
|
|
746
|
-
if (clones.count() == 0) continue;
|
|
747
|
-
|
|
748
|
-
totalClones += clones.count();
|
|
749
|
-
SVFUtil::outs() << indent
|
|
750
|
-
<< " " << o << " : "
|
|
751
|
-
<< "(" << clones.count() << ")"
|
|
752
|
-
<< "[ ";
|
|
753
|
-
bool first = true;
|
|
754
|
-
for (NodeID c : clones)
|
|
755
|
-
{
|
|
756
|
-
if (!first)
|
|
757
|
-
{
|
|
758
|
-
SVFUtil::outs() << ", ";
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
SVFUtil::outs() << c
|
|
762
|
-
<< "{"
|
|
763
|
-
<< dchg->diTypeToStr(getType(c))
|
|
764
|
-
<< "}";
|
|
765
|
-
first = false;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
SVFUtil::outs() << " ]\n";
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
indent = " ";
|
|
772
|
-
SVFUtil::outs() << indent
|
|
773
|
-
<< "Total: " << ppag->getObjectNodeNum() + ppag->getFieldObjNodeNum() + totalClones
|
|
774
|
-
<< " (" << totalClones << " clones)\n";
|
|
775
|
-
SVFUtil::outs() << indent << "==================================\n";
|
|
776
|
-
|
|
777
|
-
SVFUtil::outs() << indent << "INITIALISE : " << numInit << "\n";
|
|
778
|
-
SVFUtil::outs() << indent << "TBWU : " << numTBWU << "\n";
|
|
779
|
-
SVFUtil::outs() << indent << "TBSSU : " << numTBSSU << "\n";
|
|
780
|
-
SVFUtil::outs() << indent << "TBSU : " << numTBSU << "\n";
|
|
781
|
-
SVFUtil::outs() << indent << "REUSE : " << numReuse << "\n";
|
|
782
|
-
SVFUtil::outs() << indent << "AGG CASE : " << numAgg << "\n";
|
|
783
|
-
|
|
784
|
-
SVFUtil::outs() << "\n";
|
|
785
|
-
SVFUtil::outs() << indent << "STACK/GLOBAL OBJECTS\n";
|
|
786
|
-
indent = " ";
|
|
787
|
-
SVFUtil::outs() << indent << "INITIALISE : " << numSGInit << "\n";
|
|
788
|
-
SVFUtil::outs() << indent << "TBWU : " << numSGTBWU << "\n";
|
|
789
|
-
SVFUtil::outs() << indent << "TBSSU : " << numSGTBSSU << "\n";
|
|
790
|
-
SVFUtil::outs() << indent << "TBSU : " << numSGTBSU << "\n";
|
|
791
|
-
SVFUtil::outs() << indent << "REUSE : " << numSGReuse << "\n";
|
|
792
|
-
SVFUtil::outs() << indent << "AGG CASE : " << numSGAgg << "\n";
|
|
793
|
-
|
|
794
|
-
SVFUtil::outs() << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n";
|
|
795
|
-
}
|