From a4a54a0fb0050b9b73b5529b6fb4a96c55992ea7 Mon Sep 17 00:00:00 2001 From: cubicYYY Date: Sun, 25 Aug 2024 02:49:16 +0800 Subject: [PATCH] Clang formatter and a workflow for checking All source codes are now formatted. `clang-format.sh` is now introduced and should be run for new commits. The `.clang-format` file is updated. It is now corresponding to a style like the status quo. The `.clang-format-ignore` file is created for future uses. --- .clang-format | 7 +- .clang-format-ignore | 0 .github/workflows/clang-format.yml | 16 + .github/workflows/svf-lib_publish.yml | 5 +- .gitignore | 2 + clang-format.sh | 1 + svf-llvm/include/SVF-LLVM/BasicTypes.h | 18 +- svf-llvm/include/SVF-LLVM/BreakConstantExpr.h | 11 +- svf-llvm/include/SVF-LLVM/CHGBuilder.h | 16 +- svf-llvm/include/SVF-LLVM/CppUtil.h | 22 +- svf-llvm/include/SVF-LLVM/DCHG.h | 90 +- .../include/SVF-LLVM/GEPTypeBridgeIterator.h | 61 +- svf-llvm/include/SVF-LLVM/ICFGBuilder.h | 19 +- svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h | 12 +- svf-llvm/include/SVF-LLVM/LLVMModule.h | 67 +- svf-llvm/include/SVF-LLVM/LLVMUtil.h | 74 +- svf-llvm/include/SVF-LLVM/ObjTypeInference.h | 64 +- svf-llvm/include/SVF-LLVM/SVFIRBuilder.h | 162 ++- .../include/SVF-LLVM/SymbolTableBuilder.h | 27 +- svf-llvm/lib/BreakConstantExpr.cpp | 75 +- svf-llvm/lib/CHGBuilder.cpp | 265 ++--- svf-llvm/lib/CppUtil.cpp | 259 ++--- svf-llvm/lib/DCHG.cpp | 382 ++++--- svf-llvm/lib/ICFGBuilder.cpp | 61 +- svf-llvm/lib/LLVMLoopAnalysis.cpp | 51 +- svf-llvm/lib/LLVMModule.cpp | 428 ++++---- svf-llvm/lib/LLVMUtil.cpp | 309 +++--- svf-llvm/lib/ObjTypeInference.cpp | 396 +++---- svf-llvm/lib/SVFIRBuilder.cpp | 455 ++++---- svf-llvm/lib/SVFIRExtAPI.cpp | 124 +-- svf-llvm/lib/SymbolTableBuilder.cpp | 285 ++--- svf-llvm/lib/extapi.c | 643 +++++------- svf-llvm/tools/AE/ae.cpp | 275 +++-- svf-llvm/tools/CFL/cfl.cpp | 15 +- svf-llvm/tools/DDA/dda.cpp | 23 +- svf-llvm/tools/Example/svf-ex.cpp | 34 +- svf-llvm/tools/LLVM2SVF/llvm2svf.cpp | 7 +- svf-llvm/tools/MTA/mta.cpp | 8 +- svf-llvm/tools/SABER/saber.cpp | 19 +- svf-llvm/tools/WPA/wpa.cpp | 5 +- svf/include/AE/Core/AbstractState.h | 125 +-- svf/include/AE/Core/AbstractValue.h | 16 +- svf/include/AE/Core/AddressValue.h | 39 +- svf/include/AE/Core/ICFGWTO.h | 12 +- svf/include/AE/Core/IntervalValue.h | 185 ++-- svf/include/AE/Core/NumericValue.h | 194 ++-- svf/include/AE/Core/RelExeState.h | 66 +- svf/include/AE/Core/RelationSolver.h | 28 +- .../AE/Svfexe/AbstractInterpretation.h | 246 ++--- svf/include/AE/Svfexe/BufOverflowChecker.h | 110 +- svf/include/AE/Svfexe/ICFGSimplification.h | 3 +- svf/include/CFL/CFGNormalizer.h | 28 +- svf/include/CFL/CFGrammar.h | 87 +- svf/include/CFL/CFLAlias.h | 40 +- svf/include/CFL/CFLBase.h | 23 +- svf/include/CFL/CFLGramGraphChecker.h | 12 +- svf/include/CFL/CFLGraphBuilder.h | 48 +- svf/include/CFL/CFLSVFGBuilder.h | 6 +- svf/include/CFL/CFLSolver.h | 73 +- svf/include/CFL/CFLStat.h | 5 +- svf/include/CFL/CFLVF.h | 5 +- svf/include/CFL/GrammarBuilder.h | 8 +- svf/include/DDA/ContextDDA.h | 43 +- svf/include/DDA/DDAClient.h | 29 +- svf/include/DDA/DDAPass.h | 20 +- svf/include/DDA/DDAVFSolver.h | 309 +++--- svf/include/DDA/FlowDDA.h | 33 +- svf/include/FastCluster/fastcluster.h | 1 - svf/include/Graphs/CDG.h | 162 ++- svf/include/Graphs/CFLGraph.h | 42 +- svf/include/Graphs/CHG.h | 91 +- svf/include/Graphs/CallGraph.h | 99 +- svf/include/Graphs/ConsG.h | 72 +- svf/include/Graphs/ConsGEdge.h | 158 ++- svf/include/Graphs/ConsGNode.h | 28 +- svf/include/Graphs/DOTGraphTraits.h | 56 +- svf/include/Graphs/GenericGraph.h | 109 +- svf/include/Graphs/GraphPrinter.h | 29 +- svf/include/Graphs/GraphTraits.h | 41 +- svf/include/Graphs/GraphWriter.h | 125 +-- svf/include/Graphs/ICFG.h | 99 +- svf/include/Graphs/ICFGEdge.h | 25 +- svf/include/Graphs/ICFGNode.h | 141 ++- svf/include/Graphs/ICFGStat.h | 27 +- svf/include/Graphs/IRGraph.h | 44 +- svf/include/Graphs/SCC.h | 106 +- svf/include/Graphs/SVFG.h | 123 +-- svf/include/Graphs/SVFGEdge.h | 75 +- svf/include/Graphs/SVFGNode.h | 123 +-- svf/include/Graphs/SVFGOPT.h | 67 +- svf/include/Graphs/SVFGStat.h | 107 +- svf/include/Graphs/ThreadCallGraph.h | 86 +- svf/include/Graphs/VFG.h | 223 ++-- svf/include/Graphs/VFGEdge.h | 77 +- svf/include/Graphs/VFGNode.h | 398 ++++--- svf/include/Graphs/WTO.h | 75 +- svf/include/MSSA/MSSAMuChi.h | 228 ++-- svf/include/MSSA/MemPartition.h | 19 +- svf/include/MSSA/MemRegion.h | 49 +- svf/include/MSSA/MemSSA.h | 79 +- svf/include/MSSA/SVFGBuilder.h | 6 +- svf/include/MTA/LockAnalysis.h | 104 +- svf/include/MTA/MHP.h | 130 ++- svf/include/MTA/MTA.h | 2 +- svf/include/MTA/MTAStat.h | 6 +- svf/include/MTA/TCT.h | 150 ++- svf/include/MemoryModel/AbstractPointsToDS.h | 57 +- svf/include/MemoryModel/AccessPath.h | 39 +- svf/include/MemoryModel/ConditionalPT.h | 202 ++-- svf/include/MemoryModel/MutablePointsToDS.h | 229 ++--- .../MemoryModel/PersistentPointsToCache.h | 108 +- .../MemoryModel/PersistentPointsToDS.h | 209 ++-- svf/include/MemoryModel/PointerAnalysis.h | 68 +- svf/include/MemoryModel/PointerAnalysisImpl.h | 114 +- svf/include/MemoryModel/PointsTo.h | 72 +- svf/include/MemoryModel/SVFLoop.h | 31 +- svf/include/SABER/DoubleFreeChecker.h | 9 +- svf/include/SABER/FileChecker.h | 9 +- svf/include/SABER/LeakChecker.h | 14 +- svf/include/SABER/ProgSlice.h | 81 +- svf/include/SABER/SaberCheckerAPI.h | 20 +- svf/include/SABER/SaberCondAllocator.h | 103 +- svf/include/SABER/SaberSVFGBuilder.h | 12 +- svf/include/SABER/SrcSnkDDA.h | 45 +- svf/include/SABER/SrcSnkSolver.h | 34 +- svf/include/SVFIR/PAGBuilderFromFile.h | 13 +- svf/include/SVFIR/SVFFileSystem.h | 222 ++-- svf/include/SVFIR/SVFIR.h | 183 ++-- svf/include/SVFIR/SVFModule.h | 3 +- svf/include/SVFIR/SVFStatements.h | 281 +++-- svf/include/SVFIR/SVFType.h | 58 +- svf/include/SVFIR/SVFValue.h | 320 +++--- svf/include/SVFIR/SVFVariables.h | 135 +-- svf/include/SVFIR/SymbolTableInfo.h | 72 +- svf/include/Util/Annotator.h | 59 +- svf/include/Util/BitVector.h | 12 +- svf/include/Util/CDGBuilder.h | 61 +- svf/include/Util/CallGraphBuilder.h | 13 +- svf/include/Util/Casting.h | 203 ++-- svf/include/Util/CommandLine.h | 80 +- svf/include/Util/CoreBitVector.h | 57 +- svf/include/Util/CxtStmt.h | 164 ++- svf/include/Util/DPItem.h | 228 ++-- svf/include/Util/ExtAPI.h | 25 +- svf/include/Util/GeneralType.h | 59 +- svf/include/Util/GraphReachSolver.h | 34 +- svf/include/Util/NodeIDAllocator.h | 39 +- svf/include/Util/Options.h | 10 +- svf/include/Util/PTAStat.h | 3 +- svf/include/Util/SVFBugReport.h | 199 ++-- svf/include/Util/SVFStat.h | 6 +- svf/include/Util/SVFUtil.h | 171 ++- svf/include/Util/SparseBitVector.h | 351 +++---- svf/include/Util/ThreadAPI.h | 66 +- svf/include/Util/WorkList.h | 59 +- svf/include/Util/Z3Expr.h | 106 +- svf/include/Util/cJSON.h | 456 ++++---- svf/include/Util/iterator.h | 227 ++-- svf/include/Util/iterator_range.h | 22 +- svf/include/WPA/Andersen.h | 100 +- svf/include/WPA/AndersenPWC.h | 29 +- svf/include/WPA/CSC.h | 27 +- svf/include/WPA/FlowSensitive.h | 77 +- svf/include/WPA/Steensgaard.h | 12 +- svf/include/WPA/TypeAnalysis.h | 15 +- svf/include/WPA/VersionedFlowSensitive.h | 48 +- svf/include/WPA/WPAFSSolver.h | 48 +- svf/include/WPA/WPAPass.h | 27 +- svf/include/WPA/WPASolver.h | 19 +- svf/include/WPA/WPAStat.h | 36 +- svf/lib/AE/Core/AbstractState.cpp | 62 +- svf/lib/AE/Core/RelExeState.cpp | 51 +- svf/lib/AE/Core/RelationSolver.cpp | 123 +-- svf/lib/AE/Svfexe/AbstractInterpretation.cpp | 614 +++++------ svf/lib/AE/Svfexe/BufOverflowChecker.cpp | 350 +++---- svf/lib/AE/Svfexe/ICFGSimplification.cpp | 23 +- svf/lib/CFL/CFGNormalizer.cpp | 127 +-- svf/lib/CFL/CFGrammar.cpp | 83 +- svf/lib/CFL/CFLAlias.cpp | 49 +- svf/lib/CFL/CFLBase.cpp | 12 +- svf/lib/CFL/CFLGraphBuilder.cpp | 245 +++-- svf/lib/CFL/CFLSVFGBuilder.cpp | 18 +- svf/lib/CFL/CFLSolver.cpp | 102 +- svf/lib/CFL/CFLStat.cpp | 5 +- svf/lib/CFL/CFLVF.cpp | 12 +- svf/lib/CFL/GrammarBuilder.cpp | 20 +- svf/lib/DDA/ContextDDA.cpp | 105 +- svf/lib/DDA/DDAClient.cpp | 74 +- svf/lib/DDA/DDAPass.cpp | 117 +-- svf/lib/DDA/DDAStat.cpp | 83 +- svf/lib/DDA/FlowDDA.cpp | 115 +-- svf/lib/FastCluster/fastcluster.cpp | 51 +- svf/lib/Graphs/CDG.cpp | 10 +- svf/lib/Graphs/CFLGraph.cpp | 31 +- svf/lib/Graphs/CHG.cpp | 94 +- svf/lib/Graphs/CallGraph.cpp | 110 +- svf/lib/Graphs/ConsG.cpp | 295 +++--- svf/lib/Graphs/GraphWriter.cpp | 18 +- svf/lib/Graphs/ICFG.cpp | 222 ++-- svf/lib/Graphs/IRGraph.cpp | 60 +- svf/lib/Graphs/SVFG.cpp | 452 ++++---- svf/lib/Graphs/SVFGOPT.cpp | 99 +- svf/lib/Graphs/SVFGReadWrite.cpp | 236 +++-- svf/lib/Graphs/SVFGStat.cpp | 126 +-- svf/lib/Graphs/ThreadCallGraph.cpp | 25 +- svf/lib/Graphs/VFG.cpp | 438 ++++---- svf/lib/MSSA/MemPartition.cpp | 60 +- svf/lib/MSSA/MemRegion.cpp | 257 ++--- svf/lib/MSSA/MemSSA.cpp | 233 ++--- svf/lib/MSSA/SVFGBuilder.cpp | 30 +- svf/lib/MTA/LockAnalysis.cpp | 238 ++--- svf/lib/MTA/MHP.cpp | 153 ++- svf/lib/MTA/MTA.cpp | 25 +- svf/lib/MTA/MTAStat.cpp | 53 +- svf/lib/MTA/TCT.cpp | 259 +++-- svf/lib/MemoryModel/AccessPath.cpp | 58 +- svf/lib/MemoryModel/PointerAnalysis.cpp | 185 ++-- svf/lib/MemoryModel/PointerAnalysisImpl.cpp | 168 ++- svf/lib/MemoryModel/PointsTo.cpp | 270 +++-- svf/lib/SABER/DoubleFreeChecker.cpp | 52 +- svf/lib/SABER/FileChecker.cpp | 12 +- svf/lib/SABER/LeakChecker.cpp | 124 +-- svf/lib/SABER/ProgSlice.cpp | 94 +- svf/lib/SABER/SaberCheckerAPI.cpp | 198 ++-- svf/lib/SABER/SaberCondAllocator.cpp | 194 ++-- svf/lib/SABER/SaberSVFGBuilder.cpp | 104 +- svf/lib/SABER/SrcSnkDDA.cpp | 112 +- svf/lib/SVFIR/PAGBuilderFromFile.cpp | 35 +- svf/lib/SVFIR/SVFFileSystem.cpp | 283 ++--- svf/lib/SVFIR/SVFIR.cpp | 207 ++-- svf/lib/SVFIR/SVFModule.cpp | 10 +- svf/lib/SVFIR/SVFStatements.cpp | 67 +- svf/lib/SVFIR/SVFType.cpp | 6 +- svf/lib/SVFIR/SVFValue.cpp | 87 +- svf/lib/SVFIR/SVFVariables.cpp | 35 +- svf/lib/SVFIR/SymbolTableInfo.cpp | 133 +-- svf/lib/Util/BitVector.cpp | 18 +- svf/lib/Util/CDGBuilder.cpp | 98 +- svf/lib/Util/CallGraphBuilder.cpp | 11 +- svf/lib/Util/CoreBitVector.cpp | 98 +- svf/lib/Util/ExtAPI.cpp | 50 +- svf/lib/Util/NodeIDAllocator.cpp | 123 +-- svf/lib/Util/Options.cpp | 971 +++++------------- svf/lib/Util/PTAStat.cpp | 39 +- svf/lib/Util/SVFBugReport.cpp | 214 ++-- svf/lib/Util/SVFStat.cpp | 84 +- svf/lib/Util/SVFUtil.cpp | 49 +- svf/lib/Util/ThreadAPI.cpp | 142 +-- svf/lib/Util/Z3Expr.cpp | 21 +- svf/lib/Util/cJSON.cpp | 588 +++++------ svf/lib/WPA/Andersen.cpp | 234 ++--- svf/lib/WPA/AndersenSCD.cpp | 65 +- svf/lib/WPA/AndersenSFR.cpp | 29 +- svf/lib/WPA/AndersenStat.cpp | 143 ++- svf/lib/WPA/AndersenWaveDiff.cpp | 25 +- svf/lib/WPA/CSC.cpp | 23 +- svf/lib/WPA/FlowSensitive.cpp | 207 ++-- svf/lib/WPA/FlowSensitiveStat.cpp | 85 +- svf/lib/WPA/Steensgaard.cpp | 61 +- svf/lib/WPA/TypeAnalysis.cpp | 47 +- svf/lib/WPA/VersionedFlowSensitive.cpp | 278 +++-- svf/lib/WPA/VersionedFlowSensitiveStat.cpp | 138 +-- svf/lib/WPA/WPAPass.cpp | 47 +- 263 files changed, 12399 insertions(+), 15947 deletions(-) create mode 100644 .clang-format-ignore create mode 100644 .github/workflows/clang-format.yml create mode 100755 clang-format.sh mode change 100755 => 100644 svf/include/Util/WorkList.h diff --git a/.clang-format b/.clang-format index 72e3e20ff..2405337df 100644 --- a/.clang-format +++ b/.clang-format @@ -2,5 +2,10 @@ BasedOnStyle: Microsoft PointerAlignment: Left IndentPPDirectives: AfterHash AllowShortFunctionsOnASingleLine: Empty -ColumnLimit: 80 +ColumnLimit: 120 AccessModifierOffset: -4 +AllowShortIfStatementsOnASingleLine: Always +AllowShortLoopsOnASingleLine: true +AllowShortBlocksOnASingleLine: false +BreakBeforeTernaryOperators: true +SortIncludes: false \ No newline at end of file diff --git a/.clang-format-ignore b/.clang-format-ignore new file mode 100644 index 000000000..e69de29bb diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 000000000..7d4f36c61 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,16 @@ +name: clang-format + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: DoozyX/clang-format-lint-action@v0.17 + with: + source: '.' + exclude: './cmake' + extensions: 'c,h,hh,cpp,hpp,cc' + clangFormatVersion: 17 + style: file diff --git a/.github/workflows/svf-lib_publish.yml b/.github/workflows/svf-lib_publish.yml index 3e64ac0fc..cc2d37473 100644 --- a/.github/workflows/svf-lib_publish.yml +++ b/.github/workflows/svf-lib_publish.yml @@ -33,7 +33,6 @@ jobs: if: runner.os == 'macOS' run: | ln -sfn /Applications/Xcode_${{ env.XCODE_VERSION }}.app /Applications/Xcode.app - brew install astyle - name: ubuntu-setup if: runner.os == 'Linux' run: | @@ -42,7 +41,6 @@ jobs: sudo apt-get update sudo apt-get install cmake gcc g++ nodejs doxygen graphviz libncurses5-dev libtinfo5 libzstd-dev sudo apt-get update - sudo apt-get install -y astyle - name: env-setup if: github.event_name == 'push' && github.repository == 'SVF-tools/SVF' run: | @@ -56,8 +54,7 @@ jobs: cd $GITHUB_WORKSPACE echo $(pwd) git pull - astyle --style=allman -n -r "*.h" "*.cpp" - if [ ! -z $FILES_CHANGED ]; then clang-format -i $FILES_CHANGED; fi + source ${{github.workspace}}/clang-format.sh git clone "https://github.com/SVF-tools/Test-Suite.git"; source ${{github.workspace}}/build.sh diff --git a/.gitignore b/.gitignore index 515c07537..215a32238 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ autoconf/ tests/result/ doxygen/ .* +!.github/ +!.clang-format-ignore !.config.in !.config.cmake.in !.gitignore diff --git a/clang-format.sh b/clang-format.sh new file mode 100755 index 000000000..ecf8de054 --- /dev/null +++ b/clang-format.sh @@ -0,0 +1 @@ +git ls-tree --full-tree --name-only -r HEAD | grep -e ".*\.\(c\|h\|hpp\|cc\|cpp\|hh\)\$" | grep -vf .clang-format-ignore | xargs clang-format -i -style=file --verbose \ No newline at end of file diff --git a/svf-llvm/include/SVF-LLVM/BasicTypes.h b/svf-llvm/include/SVF-LLVM/BasicTypes.h index 20cd8fc49..d0a6cc0eb 100644 --- a/svf-llvm/include/SVF-LLVM/BasicTypes.h +++ b/svf-llvm/include/SVF-LLVM/BasicTypes.h @@ -28,8 +28,8 @@ #include #include -#include //for gep iterator -#include // for GlobalVariable +#include //for gep iterator +#include // for GlobalVariable #include #include #include @@ -53,11 +53,11 @@ #include -#include // for WriteBitcodeToFile -#include /// for isBitcode -#include // IR reader for bit file -#include // for instruction visitor -#include // for inst iteration +#include // for WriteBitcodeToFile +#include /// for isBitcode +#include // IR reader for bit file +#include // for instruction visitor +#include // for inst iteration #include // for dwarf tags @@ -157,7 +157,7 @@ typedef llvm::CallBrInst CallBrInst; typedef llvm::ReturnInst ReturnInst; typedef llvm::CastInst CastInst; typedef llvm::CmpInst CmpInst; -typedef llvm::ExtractValueInst ExtractValueInst; +typedef llvm::ExtractValueInst ExtractValueInst; typedef llvm::ExtractElementInst ExtractElementInst; typedef llvm::GetElementPtrInst GetElementPtrInst; typedef llvm::InvokeInst InvokeInst; @@ -277,4 +277,4 @@ typedef llvm::succ_const_iterator succ_const_iterator; #endif } // End namespace SVF -#endif // SVF_FE_BASIC_TYPES_H +#endif // SVF_FE_BASIC_TYPES_H diff --git a/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h b/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h index c02bd55fa..f867f23ac 100644 --- a/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h +++ b/svf-llvm/include/SVF-LLVM/BreakConstantExpr.h @@ -41,10 +41,9 @@ class BreakConstantGEPs : public ModulePass { return "Remove Constant GEP Expressions"; } - virtual bool runOnModule (Module & M); + virtual bool runOnModule(Module& M); }; - // // Pass: MergeFunctionRets // @@ -65,19 +64,17 @@ class MergeFunctionRets : public ModulePass { return "unify function exit into one dummy exit basic block"; } - virtual bool runOnModule (Module & M) + virtual bool runOnModule(Module& M) { UnifyFunctionExit(M); return true; } inline void UnifyFunctionExit(Module& module) { - for (Module::const_iterator iter = module.begin(), eiter = module.end(); - iter != eiter; ++iter) + for (Module::const_iterator iter = module.begin(), eiter = module.end(); iter != eiter; ++iter) { const Function& fun = *iter; - if(fun.isDeclaration()) - continue; + if (fun.isDeclaration()) continue; getUnifyExit(fun)->runOnFunction(const_cast(fun)); } } diff --git a/svf-llvm/include/SVF-LLVM/CHGBuilder.h b/svf-llvm/include/SVF-LLVM/CHGBuilder.h index 6d3a6ef58..def2f9370 100644 --- a/svf-llvm/include/SVF-LLVM/CHGBuilder.h +++ b/svf-llvm/include/SVF-LLVM/CHGBuilder.h @@ -43,18 +43,15 @@ class CHGBuilder typedef CHGraph::CHNodeSetTy CHNodeSetTy; typedef CHGraph::WorkList WorkList; - CHGBuilder(CHGraph* c): chg(c) - { - - } + CHGBuilder(CHGraph* c) : chg(c) {} void buildCHG(); - void buildCHGNodes(const GlobalValue *V); + void buildCHGNodes(const GlobalValue* V); void buildCHGNodes(const Function* F); void buildCHGEdges(const Function* F); void buildInternalMaps(); - void readInheritanceMetadataFromModule(const Module &M); + void readInheritanceMetadataFromModule(const Module& M); - CHNode *createNode(const std::string& name); + CHNode* createNode(const std::string& name); void connectInheritEdgeViaCall(const Function* caller, const CallBase* cs); void connectInheritEdgeViaStore(const Function* caller, const StoreInst* store); @@ -62,12 +59,11 @@ class CHGBuilder void buildClassNameToAncestorsDescendantsMap(); const CHGraph::CHNodeSetTy& getInstancesAndDescendants(const std::string& className); - void analyzeVTables(const Module &M); + void analyzeVTables(const Module& M); void buildVirtualFunctionToIDMap(); void buildCSToCHAVtblsAndVfnsMap(); const CHNodeSetTy& getCSClasses(const CallBase* cs); - void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f); + void addFuncToFuncVector(CHNode::FuncVector& v, const Function* f); }; } // End namespace SVF - diff --git a/svf-llvm/include/SVF-LLVM/CppUtil.h b/svf-llvm/include/SVF-LLVM/CppUtil.h index f0ee9bbb9..6bca6b53e 100644 --- a/svf-llvm/include/SVF-LLVM/CppUtil.h +++ b/svf-llvm/include/SVF-LLVM/CppUtil.h @@ -53,7 +53,6 @@ struct DemangledName struct DemangledName demangle(const std::string& name); - Set getClsNamesInBrackets(const std::string& name); std::string getBeforeBrackets(const std::string& name); @@ -80,7 +79,7 @@ std::string getClassNameFromVtblObj(const std::string& vtblName); * * See https://github.com/SVF-tools/SVF/issues/1114 for more. */ -const ConstantStruct *getVtblStruct(const GlobalValue *vtbl); +const ConstantStruct* getVtblStruct(const GlobalValue* vtbl); bool isValVtbl(const Value* val); bool isVirtualCallSite(const CallBase* cs); @@ -129,34 +128,31 @@ bool VCallInCtorOrDtor(const CallBase* cs); * } * this and this1 are the same thisPtr in the constructor */ -bool isSameThisPtrInConstructor(const Argument* thisPtr1, - const Value* thisPtr2); +bool isSameThisPtrInConstructor(const Argument* thisPtr1, const Value* thisPtr2); /// extract class name from the c++ function name, e.g., constructor/destructors -Set extractClsNamesFromFunc(const Function *foo); +Set extractClsNamesFromFunc(const Function* foo); /// extract class names from template functions -Set extractClsNamesFromTemplate(const std::string &oname); +Set extractClsNamesFromTemplate(const std::string& oname); /// class sources can be heap allocation /// or functions where we can extract the class name (constructors/destructors or template functions) -bool isClsNameSource(const Value *val); +bool isClsNameSource(const Value* val); /// whether foo matches the mangler label -bool matchesLabel(const std::string &foo, const std::string &label); +bool matchesLabel(const std::string& foo, const std::string& label); /// whether foo is a cpp template function -bool isTemplateFunc(const Function *foo); +bool isTemplateFunc(const Function* foo); /// whether foo is a cpp dyncast function -bool isDynCast(const Function *foo); +bool isDynCast(const Function* foo); /// extract class name from cpp dyncast function std::string extractClsNameFromDynCast(const CallBase* callBase); -const Type *cppClsNameToType(const std::string &className); - - +const Type* cppClsNameToType(const std::string& className); /// Constants pertaining to CTir, for C and C++. /// TODO: move helper functions here too? diff --git a/svf-llvm/include/SVF-LLVM/DCHG.h b/svf-llvm/include/SVF-LLVM/DCHG.h index 4aa084132..e96320c1a 100644 --- a/svf-llvm/include/SVF-LLVM/DCHG.h +++ b/svf-llvm/include/SVF-LLVM/DCHG.h @@ -32,19 +32,16 @@ class DCHEdge : public GenericEdge public: enum { - INHERITANCE, // inheritance relation - INSTANCE, // template-instance relation - FIRST_FIELD, // src -ff-> dst => dst is first field of src - STD_DEF // Edges defined by the standard like (int -std-> char) + INHERITANCE, // inheritance relation + INSTANCE, // template-instance relation + FIRST_FIELD, // src -ff-> dst => dst is first field of src + STD_DEF // Edges defined by the standard like (int -std-> char) // We also make the char --> void edge a STD_DEF edge. }; typedef GenericNode::GEdgeSetTy DCHEdgeSetTy; - DCHEdge(DCHNode *src, DCHNode *dst, GEdgeFlag k = 0) - : GenericEdge(src, dst, k), offset(0) - { - } + DCHEdge(DCHNode* src, DCHNode* dst, GEdgeFlag k = 0) : GenericEdge(src, dst, k), offset(0) {} u32_t getConstantFieldIdx(void) const { @@ -91,9 +88,9 @@ class DCHNode : public GenericNode } } - ~DCHNode() { } + ~DCHNode() {} - const DIType *getType(void) const + const DIType* getType(void) const { return diType; } @@ -151,34 +148,34 @@ class DCHNode : public GenericNode } //@} - void addTypedef(const DIDerivedType *diTypedef) + void addTypedef(const DIDerivedType* diTypedef) { typedefs.insert(diTypedef); } - const Set &getTypedefs(void) const + const Set& getTypedefs(void) const { return typedefs; } - void setVTable(const SVFGlobalValue *vtbl) + void setVTable(const SVFGlobalValue* vtbl) { vtable = vtbl; } - const SVFGlobalValue *getVTable() const + const SVFGlobalValue* getVTable() const { return vtable; } /// Returns the vector of virtual function vectors. - const std::vector> &getVfnVectors(void) const + const std::vector>& getVfnVectors(void) const { return vfnVectors; } /// Return the nth virtual function vector in the vtable. - std::vector &getVfnVector(unsigned n) + std::vector& getVfnVector(unsigned n) { if (vfnVectors.size() < n + 1) { @@ -190,14 +187,14 @@ class DCHNode : public GenericNode private: /// Type of this node. - const DIType *diType; + const DIType* diType; /// Typedefs which map to this type. - Set typedefs; + Set typedefs; const SVFGlobalValue* vtable; std::string typeName; size_t flags; /// The virtual functions which this class actually defines/overrides. - std::vector primaryVTable; + std::vector primaryVTable; /// If a vtable is split into more than one vfn vector for multiple inheritance, /// 0 would be the primary base + this classes virtual functions, 1 would be /// the second parent, 2 would be third parent, etc. @@ -224,19 +221,18 @@ class DCHGraph : public CommonCHGraph, public GenericGraph static bool teq(const DIType* t1, const DIType* t2); /// Returns a human-readable version of the DIType. - static std::string diTypeToStr(const DIType *); + static std::string diTypeToStr(const DIType*); // Returns whether t is an array, a struct, a class, a union, or neither. static bool isAgg(const DIType* t); public: - DCHGraph(const SVFModule *svfMod) - : svfModule(svfMod), numTypes(0) // vfID(0), buildingCHGTime(0) { + DCHGraph(const SVFModule* svfMod) : svfModule(svfMod), numTypes(0) // vfID(0), buildingCHGTime(0) { { this->kind = DI; } - virtual ~DCHGraph() { }; + virtual ~DCHGraph(){}; /// Builds the CHG from DWARF debug information. extend determines /// whether to extend the CHG with first field edges. @@ -254,12 +250,12 @@ class DCHGraph : public CommonCHGraph, public GenericGraph return csHasVtblsBasedonCHA(cs); } - virtual const VFunSet &getCSVFsBasedonCHA(CallSite cs) override; + virtual const VFunSet& getCSVFsBasedonCHA(CallSite cs) override; virtual bool csHasVtblsBasedonCHA(CallBase* cs) { assert(false && "not supported"); - const DIType *type = getCanonicalType(getCSStaticType(cs)); + const DIType* type = getCanonicalType(getCSStaticType(cs)); if (!hasNode(type)) { return false; @@ -274,17 +270,17 @@ class DCHGraph : public CommonCHGraph, public GenericGraph abort(); } - virtual const VTableSet &getCSVtblsBasedonCHA(CallSite cs) override; - virtual void getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override; + virtual const VTableSet& getCSVtblsBasedonCHA(CallSite cs) override; + virtual void getVFnsFromVtbls(CallSite cs, const VTableSet& vtbls, VFunSet& virtualFunctions) override; /// Returns true if a is a transitive base of b. firstField determines /// whether to consider first-field edges. - virtual bool isBase(const DIType *a, const DIType *b, bool firstField); + virtual bool isBase(const DIType* a, const DIType* b, bool firstField); /// Returns true if f is a field of b (fields from getFieldTypes). - virtual bool isFieldOf(const DIType *f, const DIType *b); + virtual bool isFieldOf(const DIType* f, const DIType* b); - static inline bool classof(const CommonCHGraph *chg) + static inline bool classof(const CommonCHGraph* chg) { return chg->getKind() == DI; } @@ -295,7 +291,7 @@ class DCHGraph : public CommonCHGraph, public GenericGraph const DIType* getCanonicalType(const DIType* t); /// Returns the type of field number idx (flattened) in base. - const DIType *getFieldType(const DIType *base, unsigned idx) + const DIType* getFieldType(const DIType* base, unsigned idx) { base = getCanonicalType(base); if (base == nullptr) @@ -313,26 +309,24 @@ class DCHGraph : public CommonCHGraph, public GenericGraph if (base->getTag() == dwarf::DW_TAG_array_type) { - const DICompositeType* cbase = - SVFUtil::dyn_cast(base); + const DICompositeType* cbase = SVFUtil::dyn_cast(base); assert(cbase && "DCHG: bad DIComposite case"); return cbase->getBaseType(); } - if (!(base->getTag() == dwarf::DW_TAG_class_type || - base->getTag() == dwarf::DW_TAG_structure_type)) + if (!(base->getTag() == dwarf::DW_TAG_class_type || base->getTag() == dwarf::DW_TAG_structure_type)) { return nullptr; } assert(fieldTypes.find(base) != fieldTypes.end() && "DCHG: base not flattened!"); - std::vector &fields = fieldTypes[base]; + std::vector& fields = fieldTypes[base]; assert(fields.size() > idx && "DCHG: idx into struct larger than # fields!"); return getCanonicalType(fields[idx]); } /// Returns a vector of the types of all fields in base. - const std::vector &getFieldTypes(const DIType *base) + const std::vector& getFieldTypes(const DIType* base) { base = getCanonicalType(base); assert(fieldTypes.find(base) != fieldTypes.end() && "DCHG: base not flattened!"); @@ -340,7 +334,7 @@ class DCHGraph : public CommonCHGraph, public GenericGraph } // Returns the number of fields in base (length of getFieldTypes). - unsigned getNumFields(const DIType *base) + unsigned getNumFields(const DIType* base) { base = getCanonicalType(base); assert(fieldTypes.find(base) != fieldTypes.end() && "DCHG: base not flattened!"); @@ -348,7 +342,7 @@ class DCHGraph : public CommonCHGraph, public GenericGraph } /// Returns all the aggregates contained (transitively) in base. - const Set &getAggs(const DIType *base) + const Set& getAggs(const DIType* base) { base = getCanonicalType(base); assert(containingAggs.find(base) != containingAggs.end() && "DCHG: aggregates not gathered for base!"); @@ -414,7 +408,7 @@ class DCHGraph : public CommonCHGraph, public GenericGraph /// Retrieves the metadata associated with a *virtual* callsite. const DIType* getCSStaticType(CallBase* cs) const; - const DIType *getCSStaticType(CallSite cs) const + const DIType* getCSStaticType(CallSite cs) const { assert(false && "not supported!"); abort(); @@ -439,7 +433,6 @@ class DCHGraph : public CommonCHGraph, public GenericGraph return nullptr; } - /// Creates an edge between from t1 to t2. DCHEdge* addEdge(const DIType* t1, const DIType* t2, DCHEdge::GEdgeKind et); /// Returns the edge between t1 and t2 if it exists, returns nullptr otherwise. @@ -457,21 +450,24 @@ namespace SVF * GenericGraphTraits specializations for generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::DCHNode *NodeRef; + typedef SVF::DCHNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* DCHG_H_ */ diff --git a/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h b/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h index 4b4b59b32..64eb15df4 100644 --- a/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h +++ b/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h @@ -13,17 +13,17 @@ namespace llvm { -template +template class generic_bridge_gep_type_iterator : public std::iterator { - typedef std::iterator super; + typedef std::iterator super; ItTy OpIt; - PointerIntPair CurTy; + PointerIntPair CurTy; unsigned AddrSpace; generic_bridge_gep_type_iterator() {} -public: +public: static generic_bridge_gep_type_iterator begin(Type* Ty, ItTy It) { generic_bridge_gep_type_iterator I; @@ -32,8 +32,7 @@ class generic_bridge_gep_type_iterator : public std::iteratorgetPointerTo(AddrSpace); + if (CurTy.getInt()) return CurTy.getPointer()->getPointerTo(AddrSpace); return CurTy.getPointer(); } Type* getIndexedType() const { assert(false && "needs to be refactored"); - if ( CurTy.getInt() ) - return CurTy.getPointer(); + if (CurTy.getInt()) return CurTy.getPointer(); #if LLVM_VERSION_MAJOR >= 11 - Type* CT = CurTy.getPointer(); - if (auto ST = dyn_cast(CT)) - return ST->getTypeAtIndex(getOperand()); + Type* CT = CurTy.getPointer(); + if (auto ST = dyn_cast(CT)) return ST->getTypeAtIndex(getOperand()); else if (auto Array = dyn_cast(CT)) return Array->getElementType(); else if (auto Vector = dyn_cast(CT)) @@ -83,7 +79,7 @@ class generic_bridge_gep_type_iterator : public std::iterator( CurTy.getPointer() ); + CompositeType* CT = llvm::cast(CurTy.getPointer()); return CT->getTypeAtIndex(getOperand()); #endif } @@ -100,18 +96,16 @@ class generic_bridge_gep_type_iterator : public std::iterator(&**OpIt); } - generic_bridge_gep_type_iterator& operator++() { - if ( CurTy.getInt() ) + if (CurTy.getInt()) { CurTy.setInt(false); } #if LLVM_VERSION_MAJOR >= 11 - else if ( Type* CT = CurTy.getPointer() ) + else if (Type* CT = CurTy.getPointer()) { - if (auto ST = dyn_cast(CT)) - CurTy.setPointer(ST->getTypeAtIndex(getOperand())); + if (auto ST = dyn_cast(CT)) CurTy.setPointer(ST->getTypeAtIndex(getOperand())); else if (auto Array = dyn_cast(CT)) CurTy.setPointer(Array->getElementType()); else if (auto Vector = dyn_cast(CT)) @@ -120,7 +114,7 @@ class generic_bridge_gep_type_iterator : public std::iterator(CurTy.getPointer()) ) + else if (CompositeType* CT = dyn_cast(CurTy.getPointer())) { CurTy.setPointer(CT->getTypeAtIndex(getOperand())); } @@ -133,25 +127,23 @@ class generic_bridge_gep_type_iterator : public std::iterator bridge_gep_iterator; inline bridge_gep_iterator bridge_gep_begin(const User* GEP) { - auto *GEPOp = llvm::cast(GEP); - return bridge_gep_iterator::begin(GEPOp->getSourceElementType(), - llvm::cast(GEPOp->getPointerOperandType()->getScalarType())->getAddressSpace(), - GEP->op_begin() + 1); + auto* GEPOp = llvm::cast(GEP); + return bridge_gep_iterator::begin( + GEPOp->getSourceElementType(), + llvm::cast(GEPOp->getPointerOperandType()->getScalarType())->getAddressSpace(), + GEP->op_begin() + 1); } inline bridge_gep_iterator bridge_gep_end(const User* GEP) @@ -159,21 +151,20 @@ inline bridge_gep_iterator bridge_gep_end(const User* GEP) return bridge_gep_iterator::end(GEP->op_end()); } -inline bridge_gep_iterator bridge_gep_begin(const User &GEP) +inline bridge_gep_iterator bridge_gep_begin(const User& GEP) { - auto &GEPOp = llvm::cast(GEP); - return bridge_gep_iterator::begin( GEPOp.getSourceElementType(), - llvm::cast(GEPOp.getPointerOperandType()->getScalarType())->getAddressSpace(), - GEP.op_begin() + 1); + auto& GEPOp = llvm::cast(GEP); + return bridge_gep_iterator::begin( + GEPOp.getSourceElementType(), + llvm::cast(GEPOp.getPointerOperandType()->getScalarType())->getAddressSpace(), GEP.op_begin() + 1); } -inline bridge_gep_iterator bridge_gep_end(const User &GEP) +inline bridge_gep_iterator bridge_gep_end(const User& GEP) { return bridge_gep_iterator::end(GEP.op_end()); } -template -inline generic_bridge_gep_type_iterator bridge_gep_end( Type* /*Op0*/, ArrayRef A ) +template inline generic_bridge_gep_type_iterator bridge_gep_end(Type* /*Op0*/, ArrayRef A) { return generic_bridge_gep_type_iterator::end(A.end()); } diff --git a/svf-llvm/include/SVF-LLVM/ICFGBuilder.h b/svf-llvm/include/SVF-LLVM/ICFGBuilder.h index aa8d380d7..a83186233 100644 --- a/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +++ b/svf-llvm/include/SVF-LLVM/ICFGBuilder.h @@ -41,7 +41,6 @@ class ICFGBuilder { public: - typedef std::vector InstVec; typedef Set BBSet; @@ -51,20 +50,17 @@ class ICFGBuilder public: typedef FIFOWorkList WorkList; - ICFGBuilder(ICFG* i): icfg(i) - { - - } + ICFGBuilder(ICFG* i) : icfg(i) {} void build(SVFModule* svfModule); private: /// Create edges between ICFG nodes within a function ///@{ - void processFunEntry(const Function* fun, WorkList& worklist); + void processFunEntry(const Function* fun, WorkList& worklist); void processFunBody(WorkList& worklist); - void processFunExit(const Function* fun); + void processFunExit(const Function* fun); //@} void connectGlobalToProgEntry(SVFModule* svfModule); @@ -75,22 +71,21 @@ class ICFGBuilder /// Add/Get a basic block ICFGNode inline ICFGNode* getOrAddBlockICFGNode(const SVFInstruction* inst) { - if(SVFUtil::isNonInstricCallSite(inst)) - return getOrAddInterBlockICFGNode(inst); + if (SVFUtil::isNonInstricCallSite(inst)) return getOrAddInterBlockICFGNode(inst); else return getOrAddIntraBlockICFGNode(inst); } /// Create edges between ICFG nodes across functions - void addICFGInterEdges(const SVFInstruction* cs, const SVFFunction* callee); + void addICFGInterEdges(const SVFInstruction* cs, const SVFFunction* callee); /// Add a call node - inline CallICFGNode* getCallICFGNode(const SVFInstruction* cs) + inline CallICFGNode* getCallICFGNode(const SVFInstruction* cs) { return icfg->getCallICFGNode(cs); } /// Add a return node - inline RetICFGNode* getRetICFGNode(const SVFInstruction* cs) + inline RetICFGNode* getRetICFGNode(const SVFInstruction* cs) { return icfg->getRetICFGNode(cs); } diff --git a/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h b/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h index 21a5984b3..b553a77ab 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h +++ b/svf-llvm/include/SVF-LLVM/LLVMLoopAnalysis.h @@ -39,22 +39,22 @@ namespace SVF class LLVMLoopAnalysis { public: - /// Constructor - LLVMLoopAnalysis() = default;; + LLVMLoopAnalysis() = default; + ; /// Destructor virtual ~LLVMLoopAnalysis() = default; /// Build llvm loops based on LoopInfo analysis - virtual void buildLLVMLoops(SVFModule *mod, ICFG* icfg); + virtual void buildLLVMLoops(SVFModule* mod, ICFG* icfg); /// Start from here - virtual void build(ICFG *icfg); + virtual void build(ICFG* icfg); /// Build SVF loops based on llvm loops - virtual void buildSVFLoops(ICFG *icfg, std::vector &llvmLoops); + virtual void buildSVFLoops(ICFG* icfg, std::vector& llvmLoops); }; } // End namespace SVF -#endif //SVF_LLVMLOOPANALYSIS_H +#endif // SVF_LLVMLOOPANALYSIS_H diff --git a/svf-llvm/include/SVF-LLVM/LLVMModule.h b/svf-llvm/include/SVF-LLVM/LLVMModule.h index 72d9ff19b..c0267969c 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMModule.h +++ b/svf-llvm/include/SVF-LLVM/LLVMModule.h @@ -46,7 +46,6 @@ class LLVMModuleSet friend class SVFIRBuilder; public: - typedef std::vector FunctionSetType; typedef Map FunDeclToDefMapTy; typedef Map FunDefToDeclsMapTy; @@ -61,7 +60,7 @@ class LLVMModuleSet typedef Map SVFValue2LLVMValueMap; typedef Map LLVMType2SVFTypeMap; typedef Map Type2TypeInfoMap; - typedef Map> Fun2AnnoMap; + typedef Map> Fun2AnnoMap; private: static LLVMModuleSet* llvmModuleSet; @@ -76,7 +75,8 @@ class LLVMModuleSet FunDeclToDefMapTy FunDeclToDefMap; /// Function definition to function declaration map FunDefToDeclsMapTy FunDefToDeclsMap; - /// Record some "sse_" function declarations used in other ext function definition, e.g., svf_ext_foo(), and svf_ext_foo() used in app functions + /// Record some "sse_" function declarations used in other ext function definition, e.g., svf_ext_foo(), and + /// svf_ext_foo() used in app functions FunctionSetType ExtFuncsVec; /// Record annotations of function in extapi.bc Fun2AnnoMap ExtFun2Annotations; @@ -104,8 +104,7 @@ class LLVMModuleSet static inline LLVMModuleSet* getLLVMModuleSet() { - if (!llvmModuleSet) - llvmModuleSet = new LLVMModuleSet; + if (!llvmModuleSet) llvmModuleSet = new LLVMModuleSet; return llvmModuleSet; } @@ -138,12 +137,12 @@ class LLVMModuleSet return modules; } - Module *getModule(u32_t idx) const + Module* getModule(u32_t idx) const { return &getModuleRef(idx); } - Module &getModuleRef(u32_t idx) const + Module& getModuleRef(u32_t idx) const { assert(idx < getModuleNum() && "Out of range."); return modules[idx]; @@ -155,47 +154,46 @@ class LLVMModuleSet inline void addFunctionMap(const Function* func, SVFFunction* svfFunc) { LLVMFunc2SVFFunc[func] = svfFunc; - setValueAttr(func,svfFunc); + setValueAttr(func, svfFunc); } inline void addBasicBlockMap(const BasicBlock* bb, SVFBasicBlock* svfBB) { LLVMBB2SVFBB[bb] = svfBB; - setValueAttr(bb,svfBB); + setValueAttr(bb, svfBB); } inline void addInstructionMap(const Instruction* inst, SVFInstruction* svfInst) { LLVMInst2SVFInst[inst] = svfInst; - setValueAttr(inst,svfInst); + setValueAttr(inst, svfInst); } inline void addArgumentMap(const Argument* arg, SVFArgument* svfArg) { LLVMArgument2SVFArgument[arg] = svfArg; - setValueAttr(arg,svfArg); + setValueAttr(arg, svfArg); } inline void addGlobalValueMap(const GlobalValue* glob, SVFGlobalValue* svfglob) { - if (auto glob_var = llvm::dyn_cast(glob); - hasGlobalRep(glob_var)) + if (auto glob_var = llvm::dyn_cast(glob); hasGlobalRep(glob_var)) { glob = getGlobalRep(glob_var); } LLVMConst2SVFConst[glob] = svfglob; - setValueAttr(glob,svfglob); + setValueAttr(glob, svfglob); } inline void addConstantDataMap(const ConstantData* cd, SVFConstantData* svfcd) { LLVMConst2SVFConst[cd] = svfcd; - setValueAttr(cd,svfcd); + setValueAttr(cd, svfcd); } inline void addOtherConstantMap(const Constant* cons, SVFConstant* svfcons) { LLVMConst2SVFConst[cons] = svfcons; - setValueAttr(cons,svfcons); + setValueAttr(cons, svfcons); } inline void addOtherValueMap(const Value* ov, SVFOtherValue* svfov) { LLVMValue2SVFOtherValue[ov] = svfov; - setValueAttr(ov,svfov); + setValueAttr(ov, svfov); } SVFValue* getSVFValue(const Value* value); @@ -203,47 +201,46 @@ class LLVMModuleSet const Value* getLLVMValue(const SVFValue* value) const { SVFValue2LLVMValueMap::const_iterator it = SVFValue2LLVMValue.find(value); - assert(it!=SVFValue2LLVMValue.end() && "can't find corresponding llvm value!"); + assert(it != SVFValue2LLVMValue.end() && "can't find corresponding llvm value!"); return it->second; } inline SVFFunction* getSVFFunction(const Function* fun) const { LLVMFun2SVFFunMap::const_iterator it = LLVMFunc2SVFFunc.find(fun); - assert(it!=LLVMFunc2SVFFunc.end() && "SVF Function not found!"); + assert(it != LLVMFunc2SVFFunc.end() && "SVF Function not found!"); return it->second; } inline SVFBasicBlock* getSVFBasicBlock(const BasicBlock* bb) const { LLVMBB2SVFBBMap::const_iterator it = LLVMBB2SVFBB.find(bb); - assert(it!=LLVMBB2SVFBB.end() && "SVF BasicBlock not found!"); + assert(it != LLVMBB2SVFBB.end() && "SVF BasicBlock not found!"); return it->second; } inline SVFInstruction* getSVFInstruction(const Instruction* inst) const { LLVMInst2SVFInstMap::const_iterator it = LLVMInst2SVFInst.find(inst); - assert(it!=LLVMInst2SVFInst.end() && "SVF Instruction not found!"); + assert(it != LLVMInst2SVFInst.end() && "SVF Instruction not found!"); return it->second; } inline SVFArgument* getSVFArgument(const Argument* arg) const { LLVMArgument2SVFArgumentMap::const_iterator it = LLVMArgument2SVFArgument.find(arg); - assert(it!=LLVMArgument2SVFArgument.end() && "SVF Argument not found!"); + assert(it != LLVMArgument2SVFArgument.end() && "SVF Argument not found!"); return it->second; } inline SVFGlobalValue* getSVFGlobalValue(const GlobalValue* g) const { - if (auto glob_var = llvm::dyn_cast(g); - hasGlobalRep(glob_var)) + if (auto glob_var = llvm::dyn_cast(g); hasGlobalRep(glob_var)) { g = getGlobalRep(glob_var); } LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(g); - assert(it!=LLVMConst2SVFConst.end() && "SVF Global not found!"); + assert(it != LLVMConst2SVFConst.end() && "SVF Global not found!"); assert(SVFUtil::isa(it->second) && "not a SVFGlobal type!"); return SVFUtil::cast(it->second); } @@ -256,10 +253,11 @@ class LLVMModuleSet /// Remove unused function in extapi.bc module bool isCalledExtFunction(Function* func) { - /// if this function func defined in extapi.bc but never used in application code (without any corresponding declared functions). - if (func->getParent()->getName().str() == ExtAPI::getExtAPI()->getExtBcPath() - && FunDefToDeclsMap.find(func) == FunDefToDeclsMap.end() - && std::find(ExtFuncsVec.begin(), ExtFuncsVec.end(), func) == ExtFuncsVec.end()) + /// if this function func defined in extapi.bc but never used in application code (without any corresponding + /// declared functions). + if (func->getParent()->getName().str() == ExtAPI::getExtAPI()->getExtBcPath() && + FunDefToDeclsMap.find(func) == FunDefToDeclsMap.end() && + std::find(ExtFuncsVec.begin(), ExtFuncsVec.end(), func) == ExtFuncsVec.end()) { return true; } @@ -300,12 +298,10 @@ class LLVMModuleSet bool hasDeclaration(const Function* fun) const { - if(fun->isDeclaration() && !hasDefinition(fun)) - return false; + if (fun->isDeclaration() && !hasDefinition(fun)) return false; const Function* funDef = fun; - if(fun->isDeclaration() && hasDefinition(fun)) - funDef = getDefinition(fun); + if (fun->isDeclaration() && hasDefinition(fun)) funDef = getDefinition(fun); FunDefToDeclsMapTy::const_iterator it = FunDefToDeclsMap.find(funDef); return it != FunDefToDeclsMap.end(); @@ -314,8 +310,7 @@ class LLVMModuleSet const FunctionSetType& getDeclaration(const Function* fun) const { const Function* funDef = fun; - if(fun->isDeclaration() && hasDefinition(fun)) - funDef = getDefinition(fun); + if (fun->isDeclaration() && hasDefinition(fun)) funDef = getDefinition(fun); FunDefToDeclsMapTy::const_iterator it = FunDefToDeclsMap.find(funDef); assert(it != FunDefToDeclsMap.end() && "does not have a function definition (body)?"); @@ -329,7 +324,7 @@ class LLVMModuleSet return it != GlobalDefToRepMap.end(); } - GlobalVariable *getGlobalRep(const GlobalVariable* val) const + GlobalVariable* getGlobalRep(const GlobalVariable* val) const { GlobalDefToRepMapTy::const_iterator it = GlobalDefToRepMap.find(val); assert(it != GlobalDefToRepMap.end() && "has no rep?"); diff --git a/svf-llvm/include/SVF-LLVM/LLVMUtil.h b/svf-llvm/include/SVF-LLVM/LLVMUtil.h index 3ee9fce3e..af02612a0 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMUtil.h +++ b/svf-llvm/include/SVF-LLVM/LLVMUtil.h @@ -101,7 +101,8 @@ static inline Type* getPtrElementType(const PointerType* pty) #if (LLVM_VERSION_MAJOR < 14) return pty->getPointerElementType(); #elif (LLVM_VERSION_MAJOR < 17) - assert(!pty->isOpaque() && "Opaque Pointer is used, please recompile the source adding '-Xclang -no-opaque-pointers'"); + assert(!pty->isOpaque() && + "Opaque Pointer is used, please recompile the source adding '-Xclang -no-opaque-pointers'"); return pty->getNonOpaquePointerElementType(); #else assert(false && "llvm version 17+ only support opaque pointers!"); @@ -111,7 +112,6 @@ static inline Type* getPtrElementType(const PointerType* pty) /// Return size of this object based on LLVM value u32_t getNumOfElements(const Type* ety); - /// Return true if this value refers to a object bool isObject(const Value* ref); @@ -124,17 +124,14 @@ bool isUncalledFunction(const Function* fun); /// whether this is an argument in dead function inline bool ArgInDeadFunction(const Value* val) { - return SVFUtil::isa(val) - && isUncalledFunction(SVFUtil::cast(val)->getParent()); + return SVFUtil::isa(val) && isUncalledFunction(SVFUtil::cast(val)->getParent()); } //@} /// Return true if this is an argument of a program entry function (e.g. main) inline bool ArgInProgEntryFunction(const Value* val) { - return SVFUtil::isa(val) && - LLVMUtil::isProgEntryFunction( - SVFUtil::cast(val)->getParent()); + return SVFUtil::isa(val) && LLVMUtil::isProgEntryFunction(SVFUtil::cast(val)->getParent()); } /// Return true if this is value in a dead function (function without any caller) bool isPtrInUncalledFunction(const Value* value); @@ -151,10 +148,9 @@ inline bool isNoCallerFunction(const Function* fun) } /// Return true if the argument in a function does not have a caller -inline bool isArgOfUncalledFunction (const Value* val) +inline bool isArgOfUncalledFunction(const Value* val) { - return SVFUtil::isa(val) - && isNoCallerFunction(SVFUtil::cast(val)->getParent()); + return SVFUtil::isa(val) && isNoCallerFunction(SVFUtil::cast(val)->getParent()); } //@} @@ -166,8 +162,7 @@ bool basicBlockHasRetInst(const BasicBlock* bb); bool functionDoesNotRet(const Function* fun); /// Get reachable basic block from function entry -void getFunReachableBBs(const Function* svfFun, - std::vector& bbs); +void getFunReachableBBs(const Function* svfFun, std::vector& bbs); /// Strip off the constant casts const Value* stripConstantCasts(const Value* val); @@ -185,8 +180,7 @@ inline const ConstantExpr* isGepConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::GetElementPtr) - return constExpr; + if (constExpr->getOpcode() == Instruction::GetElementPtr) return constExpr; } return nullptr; } @@ -195,8 +189,7 @@ inline const ConstantExpr* isInt2PtrConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::IntToPtr) - return constExpr; + if (constExpr->getOpcode() == Instruction::IntToPtr) return constExpr; } return nullptr; } @@ -205,8 +198,7 @@ inline const ConstantExpr* isPtr2IntConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::PtrToInt) - return constExpr; + if (constExpr->getOpcode() == Instruction::PtrToInt) return constExpr; } return nullptr; } @@ -215,8 +207,7 @@ inline const ConstantExpr* isCastConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::BitCast) - return constExpr; + if (constExpr->getOpcode() == Instruction::BitCast) return constExpr; } return nullptr; } @@ -225,8 +216,7 @@ inline const ConstantExpr* isSelectConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::Select) - return constExpr; + if (constExpr->getOpcode() == Instruction::Select) return constExpr; } return nullptr; } @@ -235,11 +225,9 @@ inline const ConstantExpr* isTruncConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::Trunc || - constExpr->getOpcode() == Instruction::FPTrunc || - constExpr->getOpcode() == Instruction::ZExt || - constExpr->getOpcode() == Instruction::SExt || - constExpr->getOpcode() == Instruction::FPExt) + if (constExpr->getOpcode() == Instruction::Trunc || constExpr->getOpcode() == Instruction::FPTrunc || + constExpr->getOpcode() == Instruction::ZExt || constExpr->getOpcode() == Instruction::SExt || + constExpr->getOpcode() == Instruction::FPExt) return constExpr; } return nullptr; @@ -249,8 +237,7 @@ inline const ConstantExpr* isCmpConstantExpr(const Value* val) { if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { - if (constExpr->getOpcode() == Instruction::ICmp || - constExpr->getOpcode() == Instruction::FCmp) + if (constExpr->getOpcode() == Instruction::ICmp || constExpr->getOpcode() == Instruction::FCmp) return constExpr; } return nullptr; @@ -261,7 +248,7 @@ inline const ConstantExpr* isBinaryConstantExpr(const Value* val) if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { if ((constExpr->getOpcode() >= Instruction::BinaryOpsBegin) && - (constExpr->getOpcode() <= Instruction::BinaryOpsEnd)) + (constExpr->getOpcode() <= Instruction::BinaryOpsEnd)) return constExpr; } return nullptr; @@ -272,7 +259,7 @@ inline const ConstantExpr* isUnaryConstantExpr(const Value* val) if (const ConstantExpr* constExpr = SVFUtil::dyn_cast(val)) { if ((constExpr->getOpcode() >= Instruction::UnaryOpsBegin) && - (constExpr->getOpcode() <= Instruction::UnaryOpsEnd)) + (constExpr->getOpcode() <= Instruction::UnaryOpsEnd)) return constExpr; } return nullptr; @@ -281,27 +268,22 @@ inline const ConstantExpr* isUnaryConstantExpr(const Value* val) inline static DataLayout* getDataLayout(Module* mod) { - static DataLayout *dl = nullptr; - if (dl == nullptr) - dl = new DataLayout(mod); + static DataLayout* dl = nullptr; + if (dl == nullptr) dl = new DataLayout(mod); return dl; } /// Get the next instructions following control flow -void getNextInsts(const Instruction* curInst, - std::vector& instList); +void getNextInsts(const Instruction* curInst, std::vector& instList); /// Get the previous instructions following control flow -void getPrevInsts(const Instruction* curInst, - std::vector& instList); +void getPrevInsts(const Instruction* curInst, std::vector& instList); /// Get the next instructions following control flow -void getNextInsts(const Instruction* curInst, - std::vector& instList); +void getNextInsts(const Instruction* curInst, std::vector& instList); /// Get the previous instructions following control flow -void getPrevInsts(const Instruction* curInst, - std::vector& instList); +void getPrevInsts(const Instruction* curInst, std::vector& instList); /// Get num of BB's predecessors u32_t getBBPredecessorNum(const BasicBlock* BB); @@ -310,8 +292,7 @@ u32_t getBBPredecessorNum(const BasicBlock* BB); bool isIRFile(const std::string& filename); /// Parse argument for multi-module analysis -void processArguments(int argc, char** argv, int& arg_num, char** arg_value, - std::vector& moduleNameVec); +void processArguments(int argc, char** argv, int& arg_num, char** arg_value, std::vector& moduleNameVec); /// Helper method to get the size of the type from target data layout //@{ @@ -326,7 +307,7 @@ bool isIntrinsicInst(const Instruction* inst); bool isIntrinsicFun(const Function* func); /// Get all called funcions in a parent function -std::vector getCalledFunctions(const Function *F); +std::vector getCalledFunctions(const Function* F); void removeFunAnnotations(Set& removedFuncList); bool isUnusedGlobalVariable(const GlobalVariable& global); void removeUnusedGlobalVariables(Module* module); @@ -341,8 +322,7 @@ const SVFFunction* getFunction(const std::string& name); /// Return true if the value refers to constant data, e.g., i32 0 inline bool isConstDataOrAggData(const Value* val) { - return SVFUtil::isa(val); + return SVFUtil::isa(val); } /// find the unique defined global across multiple modules diff --git a/svf-llvm/include/SVF-LLVM/ObjTypeInference.h b/svf-llvm/include/SVF-LLVM/ObjTypeInference.h index 4aa64ae35..7909e23da 100644 --- a/svf-llvm/include/SVF-LLVM/ObjTypeInference.h +++ b/svf-llvm/include/SVF-LLVM/ObjTypeInference.h @@ -41,88 +41,82 @@ class ObjTypeInference { public: - typedef Set ValueSet; - typedef Map ValueToValueSet; + typedef Set ValueSet; + typedef Map ValueToValueSet; typedef ValueToValueSet ValueToInferSites; typedef ValueToValueSet ValueToSources; - typedef Map ValueToType; - typedef std::pair ValueBoolPair; - typedef Map> ValueToClassNames; - typedef Map> ObjToClsNameSources; - + typedef Map ValueToType; + typedef std::pair ValueBoolPair; + typedef Map> ValueToClassNames; + typedef Map> ObjToClsNameSources; private: - ValueToInferSites _valueToInferSites; // value inference site cache - ValueToType _valueToType; // value type cache - ValueToSources _valueToAllocs; // value allocations (stack, static, heap) cache - ValueToClassNames _thisPtrClassNames; // thisptr class name cache + ValueToInferSites _valueToInferSites; // value inference site cache + ValueToType _valueToType; // value type cache + ValueToSources _valueToAllocs; // value allocations (stack, static, heap) cache + ValueToClassNames _thisPtrClassNames; // thisptr class name cache ValueToSources _valueToAllocOrClsNameSources; // value alloc/clsname sources cache - ObjToClsNameSources _objToClsNameSources; // alloc clsname sources cache - + ObjToClsNameSources _objToClsNameSources; // alloc clsname sources cache public: - explicit ObjTypeInference() = default; ~ObjTypeInference() = default; - /// get or infer the type of the object pointed by the value - const Type *inferObjType(const Value *var); + const Type* inferObjType(const Value* var); /// validate type inference - void validateTypeCheck(const CallBase *cs); + void validateTypeCheck(const CallBase* cs); - void typeSizeDiffTest(const PointerType *oPTy, const Type *iTy, const Value *val); + void typeSizeDiffTest(const PointerType* oPTy, const Type* iTy, const Value* val); /// default type - const Type *defaultType(const Value *val); + const Type* defaultType(const Value* val); /// pointer type - inline const Type *ptrType() + inline const Type* ptrType() { return PointerType::getUnqual(getLLVMCtx()); } /// int8 type - inline const IntegerType *int8Type() + inline const IntegerType* int8Type() { return Type::getInt8Ty(getLLVMCtx()); } - LLVMContext &getLLVMCtx(); + LLVMContext& getLLVMCtx(); private: - /// forward infer the type of the object pointed by var - const Type *fwInferObjType(const Value *var); + const Type* fwInferObjType(const Value* var); /// backward collect all possible allocation sites (stack, static, heap) of var - Set& bwfindAllocOfVar(const Value *var); + Set& bwfindAllocOfVar(const Value* var); /// is allocation (stack, static, heap) - bool isAlloc(const SVF::Value *val); + bool isAlloc(const SVF::Value* val); public: /// select the largest (conservative) type from all types - const Type *selectLargestSizedType(Set &objTys); + const Type* selectLargestSizedType(Set& objTys); - u32_t objTyToNumFields(const Type *objTy); + u32_t objTyToNumFields(const Type* objTy); - u32_t getArgPosInCall(const CallBase *callBase, const Value *arg); + u32_t getArgPosInCall(const CallBase* callBase, const Value* arg); public: /// get or infer the class names of thisptr - Set &inferThisPtrClsName(const Value *thisPtr); + Set& inferThisPtrClsName(const Value* thisPtr); protected: - /// find all possible allocations or /// class name sources (e.g., constructors/destructors or template functions) starting from a value - Set &bwFindAllocOrClsNameSources(const Value *startValue); + Set& bwFindAllocOrClsNameSources(const Value* startValue); /// forward find class name sources starting from an allocation - Set &fwFindClsNameSources(const Value *startValue); + Set& fwFindClsNameSources(const Value* startValue); }; -} -#endif //SVF_OBJTYPEINFERENCE_H +} // namespace SVF +#endif // SVF_OBJTYPEINFERENCE_H diff --git a/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h b/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h index c6b77160b..3cdb2212c 100644 --- a/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +++ b/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h @@ -43,24 +43,20 @@ class SVFModule; /*! * SVFIR Builder to create SVF variables and statements and PAG */ -class SVFIRBuilder: public llvm::InstVisitor +class SVFIRBuilder : public llvm::InstVisitor { private: SVFIR* pag; SVFModule* svfModule; - const SVFBasicBlock* curBB; ///< Current basic block during SVFIR construction when visiting the module - const SVFValue* curVal; ///< Current Value during SVFIR construction when visiting the module + const SVFBasicBlock* curBB; ///< Current basic block during SVFIR construction when visiting the module + const SVFValue* curVal; ///< Current Value during SVFIR construction when visiting the module public: /// Constructor - SVFIRBuilder(SVFModule* mod): pag(SVFIR::getPAG()), svfModule(mod), curBB(nullptr),curVal(nullptr) - { - } + SVFIRBuilder(SVFModule* mod) : pag(SVFIR::getPAG()), svfModule(mod), curBB(nullptr), curVal(nullptr) {} /// Destructor - virtual ~SVFIRBuilder() - { - } + virtual ~SVFIRBuilder() {} /// Start building SVFIR here virtual SVFIR* build(); @@ -74,8 +70,7 @@ class SVFIRBuilder: public llvm::InstVisitor /// Initialize nodes and edges //@{ void initialiseNodes(); - void addEdge(NodeID src, NodeID dst, SVFStmt::PEDGEK kind, - APOffset offset = 0, Instruction* cs = nullptr); + void addEdge(NodeID src, NodeID dst, SVFStmt::PEDGEK kind, APOffset offset = 0, Instruction* cs = nullptr); // @} /// Sanity check for SVFIR @@ -102,38 +97,37 @@ class SVFIRBuilder: public llvm::InstVisitor } /// getReturnNode - Return the node representing the unique return value of a function. - inline NodeID getReturnNode(const SVFFunction *func) + inline NodeID getReturnNode(const SVFFunction* func) { return pag->getReturnNode(func); } /// getVarargNode - Return the node representing the unique variadic argument of a function. - inline NodeID getVarargNode(const SVFFunction *func) + inline NodeID getVarargNode(const SVFFunction* func) { return pag->getVarargNode(func); } //@} - /// Our visit overrides. //@{ // Instructions that cannot be folded away. - virtual void visitAllocaInst(AllocaInst &AI); - void visitPHINode(PHINode &I); - void visitStoreInst(StoreInst &I); - void visitLoadInst(LoadInst &I); - void visitGetElementPtrInst(GetElementPtrInst &I); - void visitCallInst(CallInst &I); - void visitInvokeInst(InvokeInst &II); - void visitCallBrInst(CallBrInst &I); + virtual void visitAllocaInst(AllocaInst& AI); + void visitPHINode(PHINode& I); + void visitStoreInst(StoreInst& I); + void visitLoadInst(LoadInst& I); + void visitGetElementPtrInst(GetElementPtrInst& I); + void visitCallInst(CallInst& I); + void visitInvokeInst(InvokeInst& II); + void visitCallBrInst(CallBrInst& I); void visitCallSite(CallBase* cs); - void visitReturnInst(ReturnInst &I); - void visitCastInst(CastInst &I); - void visitSelectInst(SelectInst &I); - void visitExtractValueInst(ExtractValueInst &EVI); - void visitBranchInst(BranchInst &I); - void visitSwitchInst(SwitchInst &I); - void visitInsertValueInst(InsertValueInst &I) + void visitReturnInst(ReturnInst& I); + void visitCastInst(CastInst& I); + void visitSelectInst(SelectInst& I); + void visitExtractValueInst(ExtractValueInst& EVI); + void visitBranchInst(BranchInst& I); + void visitSwitchInst(SwitchInst& I); + void visitInsertValueInst(InsertValueInst& I) { addBlackHoleAddrEdge(getValueNode(&I)); } @@ -141,9 +135,9 @@ class SVFIRBuilder: public llvm::InstVisitor // void visitTerminatorInst(TerminatorInst &TI) {} // void visitUnwindInst(UnwindInst &I) { /*returns void*/} - void visitBinaryOperator(BinaryOperator &I); - void visitUnaryOperator(UnaryOperator &I); - void visitCmpInst(CmpInst &I); + void visitBinaryOperator(BinaryOperator& I); + void visitUnaryOperator(UnaryOperator& I); + void visitCmpInst(CmpInst& I); /// TODO: var arguments need to be handled. /// https://llvm.org/docs/LangRef.html#id1911 @@ -157,37 +151,33 @@ class SVFIRBuilder: public llvm::InstVisitor /// Otherwise, this instruction is a no-op and returns the input void visitFreezeInst(FreezeInst& I); - void visitExtractElementInst(ExtractElementInst &I); + void visitExtractElementInst(ExtractElementInst& I); - void visitInsertElementInst(InsertElementInst &I) + void visitInsertElementInst(InsertElementInst& I) { addBlackHoleAddrEdge(getValueNode(&I)); } - void visitShuffleVectorInst(ShuffleVectorInst &I) + void visitShuffleVectorInst(ShuffleVectorInst& I) { addBlackHoleAddrEdge(getValueNode(&I)); } - void visitLandingPadInst(LandingPadInst &I) + void visitLandingPadInst(LandingPadInst& I) { addBlackHoleAddrEdge(getValueNode(&I)); } /// Instruction not that often - void visitResumeInst(ResumeInst&) /*returns void*/ - { - } - void visitUnreachableInst(UnreachableInst&) /*returns void*/ - { - } - void visitFenceInst(FenceInst &I) /*returns void*/ + void visitResumeInst(ResumeInst&) /*returns void*/ {} + void visitUnreachableInst(UnreachableInst&) /*returns void*/ {} + void visitFenceInst(FenceInst& I) /*returns void*/ { addBlackHoleAddrEdge(getValueNode(&I)); } - void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) + void visitAtomicCmpXchgInst(AtomicCmpXchgInst& I) { addBlackHoleAddrEdge(getValueNode(&I)); } - void visitAtomicRMWInst(AtomicRMWInst &I) + void visitAtomicRMWInst(AtomicRMWInst& I) { addBlackHoleAddrEdge(getValueNode(&I)); } @@ -207,41 +197,41 @@ class SVFIRBuilder: public llvm::InstVisitor /// Handle globals including (global variable and functions) //@{ void visitGlobal(SVFModule* svfModule); - void InitialGlobal(const GlobalVariable *gvar, Constant *C, - u32_t offset); - NodeID getGlobalVarField(const GlobalVariable *gvar, u32_t offset, SVFType* tpy); + void InitialGlobal(const GlobalVariable* gvar, Constant* C, u32_t offset); + NodeID getGlobalVarField(const GlobalVariable* gvar, u32_t offset, SVFType* tpy); //@} /// Process constant expression void processCE(const Value* val); /// Infer field index from byteoffset. - u32_t inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout *dl, AccessPath& ap, APOffset idx); + u32_t inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout* dl, AccessPath& ap, APOffset idx); /// Compute offset of a gep instruction or gep constant expression - bool computeGepOffset(const User *V, AccessPath& ap); + bool computeGepOffset(const User* V, AccessPath& ap); /// Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst, i8* src, int size)) const Value* getBaseValueForExtArg(const Value* V); /// Handle direct call - void handleDirectCall(CallBase* cs, const Function *F); + void handleDirectCall(CallBase* cs, const Function* F); /// Handle indirect call void handleIndCall(CallBase* cs); /// Handle external call //@{ - virtual const Type *getBaseTypeAndFlattenedFields(const Value *V, std::vector &fields, const Value* szValue); - virtual void addComplexConsForExt(Value *D, Value *S, const Value* sz); + virtual const Type* getBaseTypeAndFlattenedFields(const Value* V, std::vector& fields, + const Value* szValue); + virtual void addComplexConsForExt(Value* D, Value* S, const Value* sz); virtual void handleExtCall(const CallBase* cs, const SVFFunction* svfCallee); //@} /// Set current basic block in order to keep track of control flow information inline void setCurrentLocation(const Value* val, const BasicBlock* bb) { - curBB = (bb == nullptr? nullptr : LLVMModuleSet::getLLVMModuleSet()->getSVFBasicBlock(bb)); - curVal = (val == nullptr ? nullptr: LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); + curBB = (bb == nullptr ? nullptr : LLVMModuleSet::getLLVMModuleSet()->getSVFBasicBlock(bb)); + curVal = (val == nullptr ? nullptr : LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); } inline void setCurrentLocation(const SVFValue* val, const SVFBasicBlock* bb) { @@ -258,13 +248,13 @@ class SVFIRBuilder: public llvm::InstVisitor } /// Add global black hole Address edge - void addGlobalBlackHoleAddrEdge(NodeID node, const ConstantExpr *int2Ptrce) + void addGlobalBlackHoleAddrEdge(NodeID node, const ConstantExpr* int2Ptrce) { const SVFValue* cval = getCurrentValue(); const SVFBasicBlock* cbb = getCurrentBB(); - setCurrentLocation(int2Ptrce,nullptr); + setCurrentLocation(int2Ptrce, nullptr); addBlackHoleAddrEdge(node); - setCurrentLocation(cval,cbb); + setCurrentLocation(cval, cbb); } /// Add NullPtr PAGNode @@ -272,7 +262,7 @@ class SVFIRBuilder: public llvm::InstVisitor { LLVMContext& cxt = LLVMModuleSet::getLLVMModuleSet()->getContext(); ConstantPointerNull* constNull = ConstantPointerNull::get(PointerType::getUnqual(cxt)); - NodeID nullPtr = pag->addValNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(constNull),pag->getNullPtr()); + NodeID nullPtr = pag->addValNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(constNull), pag->getNullPtr()); setCurrentLocation(constNull, nullptr); addBlackHoleAddrEdge(pag->getBlkPtr()); return nullPtr; @@ -284,14 +274,13 @@ class SVFIRBuilder: public llvm::InstVisitor inline void addBlackHoleAddrEdge(NodeID node) { - if(PAGEdge *edge = pag->addBlackHoleAddrStmt(node)) - setCurrentBBAndValueForPAGEdge(edge); + if (PAGEdge* edge = pag->addBlackHoleAddrStmt(node)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Address edge inline AddrStmt* addAddrEdge(NodeID src, NodeID dst) { - if(AddrStmt *edge = pag->addAddrStmt(src, dst)) + if (AddrStmt* edge = pag->addAddrStmt(src, dst)) { setCurrentBBAndValueForPAGEdge(edge); return edge; @@ -360,7 +349,7 @@ class SVFIRBuilder: public llvm::InstVisitor inline CopyStmt* addCopyEdge(NodeID src, NodeID dst, CopyStmt::CopyKind kind) { - if(CopyStmt *edge = pag->addCopyStmt(src, dst, kind)) + if (CopyStmt* edge = pag->addCopyStmt(src, dst, kind)) { setCurrentBBAndValueForPAGEdge(edge); return edge; @@ -401,51 +390,44 @@ class SVFIRBuilder: public llvm::InstVisitor return CopyStmt::COPYVAL; } } - assert (false && "Unknown cast inst!"); + assert(false && "Unknown cast inst!"); } /// Add Copy edge inline void addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred) { /// If we already added this phi node, then skip this adding - if(PhiStmt *edge = pag->addPhiStmt(res,opnd,pred)) - setCurrentBBAndValueForPAGEdge(edge); + if (PhiStmt* edge = pag->addPhiStmt(res, opnd, pred)) setCurrentBBAndValueForPAGEdge(edge); } /// Add SelectStmt inline void addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond) { - if(SelectStmt *edge = pag->addSelectStmt(res,op1,op2,cond)) - setCurrentBBAndValueForPAGEdge(edge); + if (SelectStmt* edge = pag->addSelectStmt(res, op1, op2, cond)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Copy edge inline void addCmpEdge(NodeID op1, NodeID op2, NodeID dst, u32_t predict) { - if(CmpStmt *edge = pag->addCmpStmt(op1, op2, dst, predict)) - setCurrentBBAndValueForPAGEdge(edge); + if (CmpStmt* edge = pag->addCmpStmt(op1, op2, dst, predict)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Copy edge inline void addBinaryOPEdge(NodeID op1, NodeID op2, NodeID dst, u32_t opcode) { - if(BinaryOPStmt *edge = pag->addBinaryOPStmt(op1, op2, dst, opcode)) - setCurrentBBAndValueForPAGEdge(edge); + if (BinaryOPStmt* edge = pag->addBinaryOPStmt(op1, op2, dst, opcode)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Unary edge inline void addUnaryOPEdge(NodeID src, NodeID dst, u32_t opcode) { - if(UnaryOPStmt *edge = pag->addUnaryOPStmt(src, dst, opcode)) - setCurrentBBAndValueForPAGEdge(edge); + if (UnaryOPStmt* edge = pag->addUnaryOPStmt(src, dst, opcode)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Branch statement inline void addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec& succs) { - if(BranchStmt *edge = pag->addBranchStmt(br, cond, succs)) - setCurrentBBAndValueForPAGEdge(edge); + if (BranchStmt* edge = pag->addBranchStmt(br, cond, succs)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Load edge inline void addLoadEdge(NodeID src, NodeID dst) { - if(LoadStmt *edge = pag->addLoadStmt(src, dst)) - setCurrentBBAndValueForPAGEdge(edge); + if (LoadStmt* edge = pag->addLoadStmt(src, dst)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Store edge inline void addStoreEdge(NodeID src, NodeID dst) @@ -455,50 +437,42 @@ class SVFIRBuilder: public llvm::InstVisitor node = pag->getICFG()->getIntraICFGNode(inst); else node = nullptr; - if (StoreStmt* edge = pag->addStoreStmt(src, dst, node)) - setCurrentBBAndValueForPAGEdge(edge); + if (StoreStmt* edge = pag->addStoreStmt(src, dst, node)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Call edge inline void addCallEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry) { - if (CallPE* edge = pag->addCallPE(src, dst, cs, entry)) - setCurrentBBAndValueForPAGEdge(edge); + if (CallPE* edge = pag->addCallPE(src, dst, cs, entry)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Return edge inline void addRetEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit) { - if (RetPE* edge = pag->addRetPE(src, dst, cs, exit)) - setCurrentBBAndValueForPAGEdge(edge); + if (RetPE* edge = pag->addRetPE(src, dst, cs, exit)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Gep edge inline void addGepEdge(NodeID src, NodeID dst, const AccessPath& ap, bool constGep) { - if (GepStmt* edge = pag->addGepStmt(src, dst, ap, constGep)) - setCurrentBBAndValueForPAGEdge(edge); + if (GepStmt* edge = pag->addGepStmt(src, dst, ap, constGep)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Offset(Gep) edge inline void addNormalGepEdge(NodeID src, NodeID dst, const AccessPath& ap) { - if (GepStmt* edge = pag->addNormalGepStmt(src, dst, ap)) - setCurrentBBAndValueForPAGEdge(edge); + if (GepStmt* edge = pag->addNormalGepStmt(src, dst, ap)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Variant(Gep) edge inline void addVariantGepEdge(NodeID src, NodeID dst, const AccessPath& ap) { - if (GepStmt* edge = pag->addVariantGepStmt(src, dst, ap)) - setCurrentBBAndValueForPAGEdge(edge); + if (GepStmt* edge = pag->addVariantGepStmt(src, dst, ap)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Thread fork edge for parameter passing inline void addThreadForkEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry) { - if (TDForkPE* edge = pag->addThreadForkPE(src, dst, cs, entry)) - setCurrentBBAndValueForPAGEdge(edge); + if (TDForkPE* edge = pag->addThreadForkPE(src, dst, cs, entry)) setCurrentBBAndValueForPAGEdge(edge); } /// Add Thread join edge for parameter passing inline void addThreadJoinEdge(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit) { - if (TDJoinPE* edge = pag->addThreadJoinPE(src, dst, cs, exit)) - setCurrentBBAndValueForPAGEdge(edge); + if (TDJoinPE* edge = pag->addThreadJoinPE(src, dst, cs, exit)) setCurrentBBAndValueForPAGEdge(edge); } //@} diff --git a/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h b/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h index 6785ef75e..85c6bb2f1 100644 --- a/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h +++ b/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h @@ -34,8 +34,8 @@ #include "SVFIR/SymbolTableInfo.h" /* -* This class is to build SymbolTableInfo, MemObjs and ObjTypeInfo -*/ + * This class is to build SymbolTableInfo, MemObjs and ObjTypeInfo + */ namespace SVF { @@ -44,14 +44,13 @@ class ObjTypeInference; class SymbolTableBuilder { friend class SVFIRBuilder; + private: SymbolTableInfo* symInfo; public: /// Constructor - SymbolTableBuilder(SymbolTableInfo* si): symInfo(si) - { - } + SymbolTableBuilder(SymbolTableInfo* si) : symInfo(si) {} /// Start building memory model void buildMemModel(SVFModule* svfModule); @@ -59,9 +58,7 @@ class SymbolTableBuilder /// Return size of this object based on LLVM value u32_t getNumOfElements(const Type* ety); - protected: - /// collect the syms //@{ void collectSVFTypeInfo(const Value* val); @@ -79,23 +76,21 @@ class SymbolTableBuilder /// Handle constant expression // @{ - void handleGlobalCE(const GlobalVariable *G); - void handleGlobalInitializerCE(const Constant *C); + void handleGlobalCE(const GlobalVariable* G); + void handleGlobalInitializerCE(const Constant* C); void handleCE(const Value* val); // @} - ObjTypeInference* getTypeInference(); /// Forward collect all possible infer sites starting from a value - const Type* inferObjType(const Value *startValue); + const Type* inferObjType(const Value* startValue); /// Get the reference type of heap/static object from an allocation site. //@{ - const Type *inferTypeOfHeapObjOrStaticObj(const Instruction* inst); + const Type* inferTypeOfHeapObjOrStaticObj(const Instruction* inst); //@} - /// Create an objectInfo based on LLVM value ObjTypeInfo* createObjTypeInfo(const Value* val); @@ -111,11 +106,11 @@ class SymbolTableBuilder /// Analyze byte size of heap alloc function (e.g. malloc/calloc/...) u32_t analyzeHeapAllocByteSize(const Value* val); - ///Get a reference to the components of struct_info. - /// Number of flattened elements of an array or struct + /// Get a reference to the components of struct_info. + /// Number of flattened elements of an array or struct u32_t getNumOfFlattenElements(const Type* T); - ///Get a reference to StructInfo. + /// Get a reference to StructInfo. StInfo* getOrAddSVFTypeInfo(const Type* T); MemObj* createBlkObj(SymID symId); diff --git a/svf-llvm/lib/BreakConstantExpr.cpp b/svf-llvm/lib/BreakConstantExpr.cpp index d74a223c5..fdcb588c0 100644 --- a/svf-llvm/lib/BreakConstantExpr.cpp +++ b/svf-llvm/lib/BreakConstantExpr.cpp @@ -24,8 +24,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Author: Yulei Sui */ - - //===- BreakConstantGEPs.cpp - Change constant GEPs into GEP instructions - --// // // The SAFECode Compiler @@ -40,7 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // //===----------------------------------------------------------------------===// - #include "llvm/ADT/Statistic.h" #include "llvm/IR/Constants.h" #include "llvm/IR/InstrTypes.h" @@ -65,8 +62,8 @@ char MergeFunctionRets::ID = 0; #define DEBUG_TYPE "break-constgeps" // Statistics -STATISTIC (GEPChanges, "Number of Converted GEP Constant Expressions"); -STATISTIC (TotalChanges, "Number of Converted Constant Expressions"); +STATISTIC(GEPChanges, "Number of Converted GEP Constant Expressions"); +STATISTIC(TotalChanges, "Number of Converted Constant Expressions"); // // Function: hasConstantGEP() @@ -83,10 +80,9 @@ STATISTIC (TotalChanges, "Number of Converted Constant Expressions"); // GEP within it. // ~nullptr - A pointer to the value casted into a ConstantExpr is returned. // -static ConstantExpr * -hasConstantGEP (Value* V) +static ConstantExpr* hasConstantGEP(Value* V) { - if (ConstantExpr * CE = SVFUtil::dyn_cast(V)) + if (ConstantExpr* CE = SVFUtil::dyn_cast(V)) { if (CE->getOpcode() == Instruction::GetElementPtr) { @@ -96,8 +92,7 @@ hasConstantGEP (Value* V) { for (u32_t index = 0; index < CE->getNumOperands(); ++index) { - if (hasConstantGEP (CE->getOperand(index))) - return CE; + if (hasConstantGEP(CE->getOperand(index))) return CE; } } } @@ -108,10 +103,9 @@ hasConstantGEP (Value* V) // Description: // This function determines whether the given value is a constant expression // that has a constant binary or unary operator expression embedded within it. -static ConstantExpr * -hasConstantBinaryOrUnaryOp (Value* V) +static ConstantExpr* hasConstantBinaryOrUnaryOp(Value* V) { - if (ConstantExpr * CE = SVFUtil::dyn_cast(V)) + if (ConstantExpr* CE = SVFUtil::dyn_cast(V)) { if (Instruction::isBinaryOp(CE->getOpcode()) || Instruction::isUnaryOp(CE->getOpcode())) { @@ -121,8 +115,7 @@ hasConstantBinaryOrUnaryOp (Value* V) { for (u32_t index = 0; index < CE->getNumOperands(); ++index) { - if (hasConstantBinaryOrUnaryOp (CE->getOperand(index))) - return CE; + if (hasConstantBinaryOrUnaryOp(CE->getOperand(index))) return CE; } } } @@ -132,14 +125,13 @@ hasConstantBinaryOrUnaryOp (Value* V) // Description: // Return true if this is a constant Gep or binaryOp or UnaryOp expression -static ConstantExpr * -hasConstantExpr (Value* V) +static ConstantExpr* hasConstantExpr(Value* V) { - if (ConstantExpr * gep = hasConstantGEP(V)) + if (ConstantExpr* gep = hasConstantGEP(V)) { return gep; } - else if (ConstantExpr * buop = hasConstantBinaryOrUnaryOp(V)) + else if (ConstantExpr* buop = hasConstantBinaryOrUnaryOp(V)) { return buop; } @@ -149,7 +141,6 @@ hasConstantExpr (Value* V) } } - // // Function: convertExpression() // @@ -158,14 +149,12 @@ hasConstantExpr (Value* V) // perform any recursion, so the resulting instruction may have constant // expression operands. // -static Instruction* -convertExpression (ConstantExpr * CE, Instruction* InsertPt) +static Instruction* convertExpression(ConstantExpr* CE, Instruction* InsertPt) { // // Convert this constant expression into a regular instruction. // - if (CE->getOpcode() == Instruction::GetElementPtr) - ++GEPChanges; + if (CE->getOpcode() == Instruction::GetElementPtr) ++GEPChanges; ++TotalChanges; Instruction* Result = CE->getAsInstruction(); Result->insertBefore(InsertPt); @@ -182,14 +171,13 @@ convertExpression (ConstantExpr * CE, Instruction* InsertPt) // true - The function was modified. // false - The function was not modified. // -bool -BreakConstantGEPs::runOnModule (Module & module) +bool BreakConstantGEPs::runOnModule(Module& module) { bool modified = false; for (Module::iterator F = module.begin(), E = module.end(); F != E; ++F) { // Worklist of values to check for constant GEP expressions - std::vector Worklist; + std::vector Worklist; // // Initialize the worklist by finding all instructions that have one or more @@ -203,12 +191,12 @@ BreakConstantGEPs::runOnModule (Module & module) // Scan through the operands of this instruction. If it is a constant // expression GEP, insert an instruction GEP before the instruction. // - Instruction* I = &(*i); + Instruction* I = &(*i); for (u32_t index = 0; index < I->getNumOperands(); ++index) { if (hasConstantExpr(I->getOperand(index))) { - Worklist.push_back (I); + Worklist.push_back(I); } } } @@ -226,7 +214,7 @@ BreakConstantGEPs::runOnModule (Module & module) // while (Worklist.size()) { - Instruction* I = Worklist.back(); + Instruction* I = Worklist.back(); Worklist.pop_back(); // @@ -235,7 +223,7 @@ BreakConstantGEPs::runOnModule (Module & module) // instructions because the new instruction must be added to the // appropriate predecessor block. // - if (PHINode * PHI = SVFUtil::dyn_cast(I)) + if (PHINode* PHI = SVFUtil::dyn_cast(I)) { for (u32_t index = 0; index < PHI->getNumIncomingValues(); ++index) { @@ -247,16 +235,16 @@ BreakConstantGEPs::runOnModule (Module & module) // incoming basic block listed multiple times; this seems okay as long // the same value is listed for the incoming block. // - Instruction* InsertPt = PHI->getIncomingBlock(index)->getTerminator(); - if (ConstantExpr * CE = hasConstantExpr(PHI->getIncomingValue(index))) + Instruction* InsertPt = PHI->getIncomingBlock(index)->getTerminator(); + if (ConstantExpr* CE = hasConstantExpr(PHI->getIncomingValue(index))) { - Instruction* NewInst = convertExpression (CE, InsertPt); + Instruction* NewInst = convertExpression(CE, InsertPt); for (u32_t i2 = index; i2 < PHI->getNumIncomingValues(); ++i2) { - if ((PHI->getIncomingBlock (i2)) == PHI->getIncomingBlock (index)) - PHI->setIncomingValue (i2, NewInst); + if ((PHI->getIncomingBlock(i2)) == PHI->getIncomingBlock(index)) + PHI->setIncomingValue(i2, NewInst); } - Worklist.push_back (NewInst); + Worklist.push_back(NewInst); } } } @@ -269,20 +257,15 @@ BreakConstantGEPs::runOnModule (Module & module) // constant expressions immediately before the instruction using the // constant expression. // - if (ConstantExpr * CE = hasConstantExpr(I->getOperand(index))) + if (ConstantExpr* CE = hasConstantExpr(I->getOperand(index))) { - Instruction* NewInst = convertExpression (CE, I); - I->replaceUsesOfWith (CE, NewInst); - Worklist.push_back (NewInst); + Instruction* NewInst = convertExpression(CE, I); + I->replaceUsesOfWith(CE, NewInst); + Worklist.push_back(NewInst); } } } } - } return modified; } - - - - diff --git a/svf-llvm/lib/CHGBuilder.cpp b/svf-llvm/lib/CHGBuilder.cpp index 276856071..69e78ac55 100644 --- a/svf-llvm/lib/CHGBuilder.cpp +++ b/svf-llvm/lib/CHGBuilder.cpp @@ -32,7 +32,7 @@ #include #include #include -#include // setw() for formatting cout +#include // setw() for formatting cout #include #include @@ -57,19 +57,16 @@ const string pureVirtualFunName = "__cxa_pure_virtual"; const string ztiLabel = "_ZTI"; - void CHGBuilder::buildCHG() { double timeStart, timeEnd; timeStart = PTAStat::getClk(true); - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { - DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module " - + M.getName().str() + "...\n")); + DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module " + M.getName().str() + "...\n")); readInheritanceMetadataFromModule(M); - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) - buildCHGNodes(&(*I)); + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) buildCHGNodes(&(*I)); for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) buildCHGNodes(LLVMUtil::getDefFunForMultipleModule(&(*F))); for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) @@ -84,33 +81,30 @@ void CHGBuilder::buildCHG() timeEnd = PTAStat::getClk(true); chg->buildingCHGTime = (timeEnd - timeStart) / TIMEINTERVAL; - if (Options::DumpCHA()) - chg->dump("cha"); + if (Options::DumpCHA()) chg->dump("cha"); } -void CHGBuilder::buildCHGNodes(const GlobalValue *globalvalue) +void CHGBuilder::buildCHGNodes(const GlobalValue* globalvalue) { if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0) { - const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue); + const ConstantStruct* vtblStruct = cppUtil::getVtblStruct(globalvalue); string className = getClassNameFromVtblObj(globalvalue->getName().str()); - if (!chg->getNode(className)) - createNode(className); + if (!chg->getNode(className)) createNode(className); for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei) { - const ConstantArray *vtbl = SVFUtil::dyn_cast(vtblStruct->getOperand(ei)); + const ConstantArray* vtbl = SVFUtil::dyn_cast(vtblStruct->getOperand(ei)); assert(vtbl && "Element of initializer not an array?"); for (u32_t i = 0; i < vtbl->getNumOperands(); ++i) { - if(const ConstantExpr *ce = isCastConstantExpr(vtbl->getOperand(i))) + if (const ConstantExpr* ce = isCastConstantExpr(vtbl->getOperand(i))) { const Value* bitcastValue = ce->getOperand(0); - if (const Function* func = SVFUtil::dyn_cast(bitcastValue)) + if (const Function* func = SVFUtil::dyn_cast(bitcastValue)) { struct DemangledName dname = demangle(func->getName().str()); - if (!chg->getNode(dname.className)) - createNode(dname.className); + if (!chg->getNode(dname.className)) createNode(dname.className); } } } @@ -124,8 +118,7 @@ void CHGBuilder::buildCHGNodes(const Function* F) { struct DemangledName dname = demangle(F->getName().str()); DBOUT(DCHA, outs() << "\t build CHANode for class " + dname.className + "...\n"); - if (!chg->getNode(dname.className)) - createNode(dname.className); + if (!chg->getNode(dname.className)) createNode(dname.className); } } @@ -141,7 +134,7 @@ void CHGBuilder::buildCHGEdges(const Function* F) { connectInheritEdgeViaCall(F, SVFUtil::cast(&(*I))); } - else if (const StoreInst *store = SVFUtil::dyn_cast(&(*I))) + else if (const StoreInst* store = SVFUtil::dyn_cast(&(*I))) { connectInheritEdgeViaStore(F, store); } @@ -150,7 +143,6 @@ void CHGBuilder::buildCHGEdges(const Function* F) } } - void CHGBuilder::buildInternalMaps() { buildClassNameToAncestorsDescendantsMap(); @@ -160,25 +152,22 @@ void CHGBuilder::buildInternalMaps() void CHGBuilder::connectInheritEdgeViaCall(const Function* caller, const CallBase* cs) { - if (getCallee(cs) == nullptr) - return; + if (getCallee(cs) == nullptr) return; const Function* callee = getCallee(cs); struct DemangledName dname = demangle(caller->getName().str()); if ((isConstructor(caller) && isConstructor(callee)) || (isDestructor(caller) && isDestructor(callee))) { - if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet))) - return; + if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet))) return; const Value* csThisPtr = cppUtil::getVCallThisPtr(cs); - //const Argument* consThisPtr = getConstructorThisPtr(caller); - //bool samePtr = isSameThisPtrInConstructor(consThisPtr, csThisPtr); + // const Argument* consThisPtr = getConstructorThisPtr(caller); + // bool samePtr = isSameThisPtrInConstructor(consThisPtr, csThisPtr); bool samePtrTrue = true; if (csThisPtr != nullptr && samePtrTrue) { struct DemangledName basename = demangle(callee->getName().str()); - if (!LLVMUtil::isCallSite(csThisPtr) && - basename.className.size() > 0) + if (!LLVMUtil::isCallSite(csThisPtr) && basename.className.size() > 0) { chg->addEdge(dname.className, basename.className, CHEdge::INHERITANCE); } @@ -189,12 +178,12 @@ void CHGBuilder::connectInheritEdgeViaCall(const Function* caller, const CallBas void CHGBuilder::connectInheritEdgeViaStore(const Function* caller, const StoreInst* storeInst) { struct DemangledName dname = demangle(caller->getName().str()); - if (const ConstantExpr *ce = SVFUtil::dyn_cast(storeInst->getValueOperand())) + if (const ConstantExpr* ce = SVFUtil::dyn_cast(storeInst->getValueOperand())) { if (ce->getOpcode() == Instruction::BitCast) { const Value* bitcastval = ce->getOperand(0); - if (const ConstantExpr *bcce = SVFUtil::dyn_cast(bitcastval)) + if (const ConstantExpr* bcce = SVFUtil::dyn_cast(bitcastval)) { if (bcce->getOpcode() == Instruction::GetElementPtr) { @@ -213,20 +202,18 @@ void CHGBuilder::connectInheritEdgeViaStore(const Function* caller, const StoreI } } -void CHGBuilder::readInheritanceMetadataFromModule(const Module &M) +void CHGBuilder::readInheritanceMetadataFromModule(const Module& M) { - for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(), - mdeit = M.named_metadata_end(); mdit != mdeit; ++mdit) + for (Module::const_named_metadata_iterator mdit = M.named_metadata_begin(), mdeit = M.named_metadata_end(); + mdit != mdeit; ++mdit) { - const NamedMDNode *md = &*mdit; + const NamedMDNode* md = &*mdit; string mdname = md->getName().str(); - if (mdname.compare(0, 15, "__cxx_bases_of_") != 0) - continue; + if (mdname.compare(0, 15, "__cxx_bases_of_") != 0) continue; string className = mdname.substr(15); - for (NamedMDNode::const_op_iterator opit = md->op_begin(), - opeit = md->op_end(); opit != opeit; ++opit) + for (NamedMDNode::const_op_iterator opit = md->op_begin(), opeit = md->op_end(); opit != opeit; ++opit) { - const MDNode *N = *opit; + const MDNode* N = *opit; const MDString* mdstr = SVFUtil::cast(N->getOperand(0).get()); string baseName = mdstr->getString().str(); chg->addEdge(className, baseName, CHEdge::INHERITANCE); @@ -234,10 +221,10 @@ void CHGBuilder::readInheritanceMetadataFromModule(const Module &M) } } -CHNode *CHGBuilder::createNode(const std::string& className) +CHNode* CHGBuilder::createNode(const std::string& className) { assert(!chg->getNode(className) && "this node should never be created before!"); - CHNode * node = new CHNode(className, chg->classNum++); + CHNode* node = new CHNode(className, chg->classNum++); chg->classNameToNodeMap[className] = node; chg->addGNode(node->getId(), node); if (className.size() > 0 && className[className.size() - 1] == '>') @@ -251,7 +238,7 @@ CHNode *CHGBuilder::createNode(const std::string& className) templateNode->setTemplate(); } chg->addEdge(className, templateName, CHEdge::INSTANTCE); - chg->addInstances(templateName,node); + chg->addInstances(templateName, node); } return node; } @@ -264,25 +251,24 @@ CHNode *CHGBuilder::createNode(const std::string& className) void CHGBuilder::buildClassNameToAncestorsDescendantsMap() { - for (CHGraph::const_iterator it = chg->begin(), eit = chg->end(); - it != eit; ++it) + for (CHGraph::const_iterator it = chg->begin(), eit = chg->end(); it != eit; ++it) { - const CHNode *node = it->second; + const CHNode* node = it->second; WorkList worklist; CHNodeSetTy visitedNodes; worklist.push(node); while (!worklist.empty()) { - const CHNode *curnode = worklist.pop(); + const CHNode* curnode = worklist.pop(); if (visitedNodes.find(curnode) == visitedNodes.end()) { - for (CHEdge::CHEdgeSetTy::const_iterator it = - curnode->getOutEdges().begin(), eit = - curnode->getOutEdges().end(); it != eit; ++it) + for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getOutEdges().begin(), + eit = curnode->getOutEdges().end(); + it != eit; ++it) { if ((*it)->getEdgeType() == CHEdge::INHERITANCE) { - CHNode *succnode = (*it)->getDstNode(); + CHNode* succnode = (*it)->getDstNode(); chg->classNameToAncestorsMap[node->getName()].insert(succnode); chg->classNameToDescendantsMap[succnode->getName()].insert(node); worklist.push(succnode); @@ -294,8 +280,7 @@ void CHGBuilder::buildClassNameToAncestorsDescendantsMap() } } -const CHGraph::CHNodeSetTy& CHGBuilder::getInstancesAndDescendants( - const string& className) +const CHGraph::CHNodeSetTy& CHGBuilder::getInstancesAndDescendants(const string& className) { CHGraph::NameToCHNodesMap::const_iterator it = chg->classNameToInstAndDescsMap.find(className); @@ -311,12 +296,11 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getInstancesAndDescendants( const CHNodeSetTy& instances = chg->getInstances(className); for (CHNodeSetTy::const_iterator it = instances.begin(), eit = instances.end(); it != eit; ++it) { - const CHNode *node = *it; + const CHNode* node = *it; chg->classNameToInstAndDescsMap[className].insert(node); const CHNodeSetTy& instance_descendants = chg->getDescendants(node->getName()); - for (CHNodeSetTy::const_iterator dit = - instance_descendants.begin(), deit = - instance_descendants.end(); dit != deit; ++dit) + for (CHNodeSetTy::const_iterator dit = instance_descendants.begin(), deit = instance_descendants.end(); + dit != deit; ++dit) { chg->classNameToInstAndDescsMap[className].insert(*dit); } @@ -326,9 +310,6 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getInstancesAndDescendants( } } - - - /* * do the following things: * 1. initialize virtualFunctions for each class @@ -360,30 +341,26 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getInstancesAndDescendants( * number of "i8 *null" is the same as the number of virtual methods in * "class A" */ -void CHGBuilder::analyzeVTables(const Module &M) +void CHGBuilder::analyzeVTables(const Module& M) { - for (Module::const_global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - const GlobalValue *globalvalue = SVFUtil::dyn_cast(&(*I)); + const GlobalValue* globalvalue = SVFUtil::dyn_cast(&(*I)); if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0) { - const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue); + const ConstantStruct* vtblStruct = cppUtil::getVtblStruct(globalvalue); string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str()); - CHNode *node = chg->getNode(vtblClassName); + CHNode* node = chg->getNode(vtblClassName); assert(node && "node not found?"); - SVFGlobalValue* pValue = - LLVMModuleSet::getLLVMModuleSet()->getSVFGlobalValue( - globalvalue); + SVFGlobalValue* pValue = LLVMModuleSet::getLLVMModuleSet()->getSVFGlobalValue(globalvalue); pValue->setName(vtblClassName); node->setVTable(pValue); for (unsigned int ei = 0; ei < vtblStruct->getNumOperands(); ++ei) { - const ConstantArray *vtbl = - SVFUtil::dyn_cast(vtblStruct->getOperand(ei)); + const ConstantArray* vtbl = SVFUtil::dyn_cast(vtblStruct->getOperand(ei)); assert(vtbl && "Element of initializer not an array?"); /* @@ -404,28 +381,25 @@ void CHGBuilder::analyzeVTables(const Module &M) Constant* operand = vtbl->getOperand(i); if (SVFUtil::isa(operand)) { - if (i > 0 && !SVFUtil::isa(vtbl->getOperand(i-1))) + if (i > 0 && !SVFUtil::isa(vtbl->getOperand(i - 1))) { - auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val) - { + auto foo = [&is_virtual, &null_ptr_num, &vtbl, &i](const Value* val) { if (val->getName().str().compare(0, ztiLabel.size(), ztiLabel) == 0) { is_virtual = true; null_ptr_num = 1; - while (i+null_ptr_num < vtbl->getNumOperands()) + while (i + null_ptr_num < vtbl->getNumOperands()) { - if (SVFUtil::isa(vtbl->getOperand(i+null_ptr_num))) + if (SVFUtil::isa(vtbl->getOperand(i + null_ptr_num))) null_ptr_num++; else break; } } }; - if (const ConstantExpr *ce = - SVFUtil::dyn_cast(vtbl->getOperand(i-1))) + if (const ConstantExpr* ce = SVFUtil::dyn_cast(vtbl->getOperand(i - 1))) { - if(ce->getOpcode() == Instruction::BitCast) - foo(ce->getOperand(0)); + if (ce->getOpcode() == Instruction::BitCast) foo(ce->getOperand(0)); } else { @@ -436,8 +410,7 @@ void CHGBuilder::analyzeVTables(const Module &M) continue; } - auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand) - { + auto foo = [this, &virtualFunctions, &pure_abstract, &vtblClassName](const Value* operand) { if (const Function* f = SVFUtil::dyn_cast(operand)) { addFuncToFuncVector(virtualFunctions, f); @@ -450,25 +423,22 @@ void CHGBuilder::analyzeVTables(const Module &M) pure_abstract &= false; } struct DemangledName dname = demangle(f->getName().str()); - if (dname.className.size() > 0 && - vtblClassName.compare(dname.className) != 0) + if (dname.className.size() > 0 && vtblClassName.compare(dname.className) != 0) { - if(!chg->getNode(dname.className)) createNode(dname.className); + if (!chg->getNode(dname.className)) createNode(dname.className); chg->addEdge(vtblClassName, dname.className, CHEdge::INHERITANCE); } } else { - if (const GlobalAlias *alias = - SVFUtil::dyn_cast(operand)) + if (const GlobalAlias* alias = SVFUtil::dyn_cast(operand)) { - const Constant *aliasValue = alias->getAliasee(); - if (const Function* aliasFunc = - SVFUtil::dyn_cast(aliasValue)) + const Constant* aliasValue = alias->getAliasee(); + if (const Function* aliasFunc = SVFUtil::dyn_cast(aliasValue)) { addFuncToFuncVector(virtualFunctions, aliasFunc); } - else if (const ConstantExpr *aliasconst = + else if (const ConstantExpr* aliasconst = SVFUtil::dyn_cast(aliasValue)) { (void)aliasconst; // Suppress warning of unused variable under release build @@ -476,8 +446,7 @@ void CHGBuilder::analyzeVTables(const Module &M) "aliased constantexpr in vtable not a bitcast"); const Function* aliasbitcastfunc = SVFUtil::dyn_cast(aliasconst->getOperand(0)); - assert(aliasbitcastfunc && - "aliased bitcast in vtable not a function"); + assert(aliasbitcastfunc && "aliased bitcast in vtable not a function"); addFuncToFuncVector(virtualFunctions, aliasbitcastfunc); } else @@ -487,8 +456,7 @@ void CHGBuilder::analyzeVTables(const Module &M) pure_abstract &= false; } - else if (operand->getName().str().compare(0, ztiLabel.size(), - ztiLabel) == 0) + else if (operand->getName().str().compare(0, ztiLabel.size(), ztiLabel) == 0) { } else @@ -502,24 +470,24 @@ void CHGBuilder::analyzeVTables(const Module &M) * vtable in llvm 16 does not have bitcast: * e.g., * @_ZTV1B = linkonce_odr dso_local unnamed_addr constant - * { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI1B, ptr @_ZN1B1fEPi, ptr @_ZN1B1gEPi] }, comdat, align 8 - * compared to its llvm 13 version: + * { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI1B, ptr @_ZN1B1fEPi, ptr @_ZN1B1gEPi] }, + * comdat, align 8 compared to its llvm 13 version: * @_ZTV1B = linkonce_odr dso_local unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, - * i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i8* bitcast (void (%class.B*, i32*)* @_ZN1B1fEPi to i8*), - * i8* bitcast (void (%class.B*, i32*)* @_ZN1B1gEPi to i8*)] }, comdat, align 8 + * i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i8* bitcast (void (%class.B*, i32*)* + * @_ZN1B1fEPi to i8*), i8* bitcast (void (%class.B*, i32*)* @_ZN1B1gEPi to i8*)] }, comdat, + * align 8 * - * For llvm 13, we need to cast the operand into a constant expr and then process the first operand of that constant expr - * For llvm 16, things get simpler. We can directly process each operand + * For llvm 13, we need to cast the operand into a constant expr and then process the first + * operand of that constant expr For llvm 16, things get simpler. We can directly process each + * operand * * for inttoptr in llvm 16, the handling method is the same as before */ - if (const ConstantExpr *ce = - SVFUtil::dyn_cast(operand)) + if (const ConstantExpr* ce = SVFUtil::dyn_cast(operand)) { u32_t opcode = ce->getOpcode(); assert(opcode == Instruction::IntToPtr); - assert(ce->getNumOperands() == 1 && - "inttptr operand num not 1"); + assert(ce->getNumOperands() == 1 && "inttptr operand num not 1"); if (opcode == Instruction::IntToPtr) { node->setMultiInheritance(); @@ -540,8 +508,7 @@ void CHGBuilder::analyzeVTables(const Module &M) virtualFunctions.insert(virtualFunctions.begin(), fun); } } - if (virtualFunctions.size() > 0) - node->addVirtualFunctionVector(virtualFunctions); + if (virtualFunctions.size() > 0) node->addVirtualFunctionVector(virtualFunctions); } if (pure_abstract == true) { @@ -552,7 +519,6 @@ void CHGBuilder::analyzeVTables(const Module &M) } } - void CHGBuilder::buildVirtualFunctionToIDMap() { /* @@ -562,12 +528,10 @@ void CHGBuilder::buildVirtualFunctionToIDMap() * the same name (after demangling) in a group */ CHGraph::CHNodeSetTy visitedNodes; - for (CHGraph::const_iterator nit = chg->begin(), - neit = chg->end(); nit != neit; ++nit) + for (CHGraph::const_iterator nit = chg->begin(), neit = chg->end(); nit != neit; ++nit) { - CHNode *node = nit->second; - if (visitedNodes.find(node) != visitedNodes.end()) - continue; + CHNode* node = nit->second; + if (visitedNodes.find(node) != visitedNodes.end()) continue; string className = node->getName(); @@ -579,22 +543,23 @@ void CHGBuilder::buildVirtualFunctionToIDMap() nodeStack.push(node); while (!nodeStack.empty()) { - const CHNode *curnode = nodeStack.top(); + const CHNode* curnode = nodeStack.top(); nodeStack.pop(); group.insert(curnode); - if (visitedNodes.find(curnode) != visitedNodes.end()) - continue; + if (visitedNodes.find(curnode) != visitedNodes.end()) continue; for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getOutEdges().begin(), - eit = curnode->getOutEdges().end(); it != eit; ++it) + eit = curnode->getOutEdges().end(); + it != eit; ++it) { - CHNode *tmpnode = (*it)->getDstNode(); + CHNode* tmpnode = (*it)->getDstNode(); nodeStack.push(tmpnode); group.insert(tmpnode); } for (CHEdge::CHEdgeSetTy::const_iterator it = curnode->getInEdges().begin(), - eit = curnode->getInEdges().end(); it != eit; ++it) + eit = curnode->getInEdges().end(); + it != eit; ++it) { - CHNode *tmpnode = (*it)->getSrcNode(); + CHNode* tmpnode = (*it)->getSrcNode(); nodeStack.push(tmpnode); group.insert(tmpnode); } @@ -605,15 +570,13 @@ void CHGBuilder::buildVirtualFunctionToIDMap() * get all virtual functions in a specific group */ set virtualFunctions; - for (CHGraph::CHNodeSetTy::iterator it = group.begin(), - eit = group.end(); it != eit; ++it) + for (CHGraph::CHNodeSetTy::iterator it = group.begin(), eit = group.end(); it != eit; ++it) { - const vector &vecs = (*it)->getVirtualFunctionVectors(); - for (vector::const_iterator vit = vecs.begin(), - veit = vecs.end(); vit != veit; ++vit) + const vector& vecs = (*it)->getVirtualFunctionVectors(); + for (vector::const_iterator vit = vecs.begin(), veit = vecs.end(); vit != veit; ++vit) { - for (vector::const_iterator fit = (*vit).begin(), - feit = (*vit).end(); fit != feit; ++fit) + for (vector::const_iterator fit = (*vit).begin(), feit = (*vit).end(); fit != feit; + ++fit) { virtualFunctions.insert(*fit); } @@ -635,43 +598,41 @@ void CHGBuilder::buildVirtualFunctionToIDMap() * <~C, C::~C> * ... */ - set > fNameSet; - for (set::iterator fit = virtualFunctions.begin(), - feit = virtualFunctions.end(); fit != feit; ++fit) + set> fNameSet; + for (set::iterator fit = virtualFunctions.begin(), feit = virtualFunctions.end(); + fit != feit; ++fit) { const SVFFunction* f = *fit; struct DemangledName dname = demangle(f->getName()); fNameSet.insert(pair(dname.funcName, f)); } - for (set>::iterator it = fNameSet.begin(), - eit = fNameSet.end(); it != eit; ++it) + for (set>::iterator it = fNameSet.begin(), eit = fNameSet.end(); it != eit; + ++it) { chg->virtualFunctionToIDMap[it->second] = chg->vfID++; } } } - void CHGBuilder::buildCSToCHAVtblsAndVfnsMap() { - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) { for (const_inst_iterator II = inst_begin(*F), E = inst_end(*F); II != E; ++II) { - if(const CallBase* callInst = SVFUtil::dyn_cast(&*II)) + if (const CallBase* callInst = SVFUtil::dyn_cast(&*II)) { - if (cppUtil::isVirtualCallSite(callInst) == false) - continue; + if (cppUtil::isVirtualCallSite(callInst) == false) continue; VTableSet vtbls; const CHNodeSetTy& chClasses = getCSClasses(callInst); for (CHNodeSetTy::const_iterator it = chClasses.begin(), eit = chClasses.end(); it != eit; ++it) { - const CHNode *child = *it; - const SVFGlobalValue *vtbl = child->getVTable(); + const CHNode* child = *it; + const SVFGlobalValue* vtbl = child->getVTable(); if (vtbl != nullptr) { vtbls.insert(vtbl); @@ -679,12 +640,12 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap() } if (vtbls.size() > 0) { - CallSite cs = SVFUtil::getSVFCallSite(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(callInst)); + CallSite cs = + SVFUtil::getSVFCallSite(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(callInst)); chg->csToCHAVtblsMap[cs] = vtbls; VFunSet virtualFunctions; chg->getVFnsFromVtbls(cs, vtbls, virtualFunctions); - if (virtualFunctions.size() > 0) - chg->csToCHAVFnsMap[cs] = virtualFunctions; + if (virtualFunctions.size() > 0) chg->csToCHAVFnsMap[cs] = virtualFunctions; } } } @@ -692,7 +653,6 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap() } } - const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs) { assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!"); @@ -707,23 +667,24 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs) { Set thisPtrClassNames = getClassNameOfThisPtr(cs); - if(thisPtrClassNames.empty()) + if (thisPtrClassNames.empty()) { // if we cannot infer classname, conservatively push all class nodes - for (const auto &node: *chg) + for (const auto& node : *chg) { chg->csToClassesMap[svfcall].insert(node.second); } return chg->csToClassesMap[svfcall]; } - for (const auto &thisPtrClassName: thisPtrClassNames) + for (const auto& thisPtrClassName : thisPtrClassNames) { if (const CHNode* thisNode = chg->getNode(thisPtrClassName)) { const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName); chg->csToClassesMap[svfcall].insert(thisNode); - for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2) + for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); + it2 != eit; ++it2) chg->csToClassesMap[svfcall].insert(*it2); } } @@ -731,21 +692,19 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs) } } -void CHGBuilder::addFuncToFuncVector(CHNode::FuncVector &v, const Function *lf) +void CHGBuilder::addFuncToFuncVector(CHNode::FuncVector& v, const Function* lf) { if (cppUtil::isCPPThunkFunction(lf)) { if (const auto* tf = cppUtil::getThunkTarget(lf)) { - SVFFunction* pFunction = - LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(tf); + SVFFunction* pFunction = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(tf); v.push_back(pFunction); } } else { - SVFFunction* pFunction = - LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(lf); + SVFFunction* pFunction = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(lf); v.push_back(pFunction); } } diff --git a/svf-llvm/lib/CppUtil.cpp b/svf-llvm/lib/CppUtil.cpp index 1509fcb38..010c94b42 100644 --- a/svf-llvm/lib/CppUtil.cpp +++ b/svf-llvm/lib/CppUtil.cpp @@ -59,28 +59,35 @@ const std::string vtableType = "(...)**"; const std::string znwm = "_Znwm"; const std::string zn1Label = "_ZN1"; // c++ constructor const std::string znstLabel = "_ZNSt"; -const std::string znst5Label = "_ZNSt5"; // _ZNSt5dequeIPK1ASaIS2_EE5frontEv -> std::deque >::front() -const std::string znst12Label = "_ZNSt12"; // _ZNSt12forward_listIPK1ASaIS2_EEC2Ev -> std::forward_list >::forward_list() -const std::string znst6Label = "_ZNSt6"; // _ZNSt6vectorIP1ASaIS1_EEC2Ev -> std::vector >::vector() -const std::string znst7Label = "_ZNSt7"; // _ZNSt7__cxx114listIPK1ASaIS3_EEC2Ev -> std::__cxx11::list >::list() -const std::string znst14Label = "_ZNSt14"; // _ZNSt14_Fwd_list_baseI1ASaIS0_EEC2Ev -> std::_Fwd_list_base >::_Fwd_list_base() - +const std::string znst5Label = + "_ZNSt5"; // _ZNSt5dequeIPK1ASaIS2_EE5frontEv -> std::deque >::front() +const std::string znst12Label = "_ZNSt12"; // _ZNSt12forward_listIPK1ASaIS2_EEC2Ev -> std::forward_list >::forward_list() +const std::string znst6Label = + "_ZNSt6"; // _ZNSt6vectorIP1ASaIS1_EEC2Ev -> std::vector >::vector() +const std::string znst7Label = + "_ZNSt7"; // _ZNSt7__cxx114listIPK1ASaIS3_EEC2Ev -> std::__cxx11::list >::list() +const std::string znst14Label = + "_ZNSt14"; // _ZNSt14_Fwd_list_baseI1ASaIS0_EEC2Ev -> std::_Fwd_list_base >::_Fwd_list_base() const std::string znkstLabel = "_ZNKSt"; -const std::string znkst5Label = "_ZNKSt15_"; // _ZNKSt15_Deque_iteratorIPK1ARS2_PS2_EdeEv -> std::_Deque_iterator::operator*() const -const std::string znkst20Label = "_ZNKSt20_"; // _ZNKSt20_List_const_iteratorIPK1AEdeEv -> std::_List_const_iterator::operator*() const - -const std::string znkst23Label = "_ZNKSt23_"; // _ZNKSt23_Rb_tree_const_iteratorISt4pairIKi1AEEptEv -> std::_List_const_iterator::operator*() const +const std::string znkst5Label = "_ZNKSt15_"; // _ZNKSt15_Deque_iteratorIPK1ARS2_PS2_EdeEv -> std::_Deque_iterator::operator*() const +const std::string znkst20Label = + "_ZNKSt20_"; // _ZNKSt20_List_const_iteratorIPK1AEdeEv -> std::_List_const_iterator::operator*() const +const std::string znkst23Label = "_ZNKSt23_"; // _ZNKSt23_Rb_tree_const_iteratorISt4pairIKi1AEEptEv -> + // std::_List_const_iterator::operator*() const const std::string znkLabel = "_ZNK"; -const std::string znk9Label = "_ZNK9"; // _ZNK9__gnu_cxx17__normal_iteratorIPK1ASt6vectorIS1_SaIS1_EEEdeEv -> __gnu_cxx::__normal_iterator > >::operator*() const +const std::string znk9Label = + "_ZNK9"; // _ZNK9__gnu_cxx17__normal_iteratorIPK1ASt6vectorIS1_SaIS1_EEEdeEv -> __gnu_cxx::__normal_iterator > >::operator*() const const std::string ztilabel = "_ZTI"; const std::string ztiprefix = "typeinfo for "; const std::string dyncast = "__dynamic_cast"; - static bool isOperOverload(const std::string& name) { u32_t leftnum = 0, rightnum = 0; @@ -112,12 +119,9 @@ static std::string getBeforeParenthesis(const std::string& name) s32_t paren_num = 1, pos; for (pos = lastRightParen - 1; pos >= 0; pos--) { - if (name[pos] == ')') - paren_num++; - if (name[pos] == '(') - paren_num--; - if (paren_num == 0) - break; + if (name[pos] == ')') paren_num++; + if (name[pos] == '(') paren_num--; + if (paren_num == 0) break; } return name.substr(0, pos); } @@ -133,12 +137,9 @@ std::string cppUtil::getBeforeBrackets(const std::string& name) s32_t bracket_num = 1, pos; for (pos = name.size() - 2; pos >= 0; pos--) { - if (name[pos] == '>') - bracket_num++; - if (name[pos] == '<') - bracket_num--; - if (bracket_num == 0) - break; + if (name[pos] == '>') bracket_num++; + if (name[pos] == '<') bracket_num--; + if (bracket_num == 0) break; } return name.substr(0, pos); } @@ -155,14 +156,11 @@ static void handleThunkFunction(cppUtil::DemangledName& dname) // these prefixes, we need to remove the prefix // to get the real class name - static std::vector thunkPrefixes = {VThunkFuncLabel, - NVThunkFunLabel - }; + static std::vector thunkPrefixes = {VThunkFuncLabel, NVThunkFunLabel}; for (unsigned i = 0; i < thunkPrefixes.size(); i++) { auto prefix = thunkPrefixes[i]; - if (dname.className.size() > prefix.size() && - dname.className.compare(0, prefix.size(), prefix) == 0) + if (dname.className.size() > prefix.size() && dname.className.compare(0, prefix.size(), prefix) == 0) { dname.className = dname.className.substr(prefix.size()); dname.isThunkFunc = true; @@ -208,8 +206,7 @@ struct cppUtil::DemangledName cppUtil::demangle(const std::string& name) { std::string realnameStr = std::string(realname); std::string beforeParenthesis = getBeforeParenthesis(realnameStr); - if (beforeParenthesis.find("::") == std::string::npos || - isOperOverload(beforeParenthesis)) + if (beforeParenthesis.find("::") == std::string::npos || isOperOverload(beforeParenthesis)) { dname.className = ""; dname.funcName = ""; @@ -243,8 +240,7 @@ Set cppUtil::getClsNamesInBrackets(const std::string& name) { Set res; // Lambda to trim whitespace from both ends of a string - auto trim = [](std::string& s) - { + auto trim = [](std::string& s) { size_t first = s.find_first_not_of(' '); size_t last = s.find_last_not_of(' '); if (first != std::string::npos && last != std::string::npos) @@ -258,8 +254,7 @@ Set cppUtil::getClsNamesInBrackets(const std::string& name) }; // Lambda to remove trailing '*' and '&' characters - auto removePointerAndReference = [](std::string& s) - { + auto removePointerAndReference = [](std::string& s) { while (!s.empty() && (s.back() == '*' || s.back() == '&')) { s.pop_back(); @@ -310,8 +305,7 @@ std::string cppUtil::getClassNameFromVtblObj(const std::string& vtblName) if (realname != nullptr) { std::string realnameStr = std::string(realname); - if (realnameStr.compare(0, vtblLabelAfterDemangle.size(), - vtblLabelAfterDemangle) == 0) + if (realnameStr.compare(0, vtblLabelAfterDemangle.size(), vtblLabelAfterDemangle) == 0) { className = realnameStr.substr(vtblLabelAfterDemangle.size()); } @@ -320,14 +314,13 @@ std::string cppUtil::getClassNameFromVtblObj(const std::string& vtblName) return className; } -const ConstantStruct *cppUtil::getVtblStruct(const GlobalValue *vtbl) +const ConstantStruct* cppUtil::getVtblStruct(const GlobalValue* vtbl) { - const ConstantStruct *vtblStruct = SVFUtil::dyn_cast(vtbl->getOperand(0)); + const ConstantStruct* vtblStruct = SVFUtil::dyn_cast(vtbl->getOperand(0)); assert(vtblStruct && "Initializer of a vtable not a struct?"); - if (vtblStruct->getNumOperands() == 2 && - SVFUtil::isa(vtblStruct->getOperand(0)) && - vtblStruct->getOperand(1)->getType()->isArrayTy()) + if (vtblStruct->getNumOperands() == 2 && SVFUtil::isa(vtblStruct->getOperand(0)) && + vtblStruct->getOperand(1)->getType()->isArrayTy()) return SVFUtil::cast(vtblStruct->getOperand(0)); return vtblStruct; @@ -335,11 +328,9 @@ const ConstantStruct *cppUtil::getVtblStruct(const GlobalValue *vtbl) bool cppUtil::isValVtbl(const Value* val) { - if (!SVFUtil::isa(val)) - return false; + if (!SVFUtil::isa(val)) return false; std::string valName = val->getName().str(); - return valName.compare(0, vtblLabelBeforeDemangle.size(), - vtblLabelBeforeDemangle) == 0; + return valName.compare(0, vtblLabelBeforeDemangle.size(), vtblLabelBeforeDemangle) == 0; } /* @@ -353,23 +344,19 @@ bool cppUtil::isVirtualCallSite(const CallBase* cs) { // the callsite must be an indirect one with at least one argument (this // ptr) - if (cs->getCalledFunction() != nullptr || cs->arg_empty()) - return false; + if (cs->getCalledFunction() != nullptr || cs->arg_empty()) return false; // the first argument (this pointer) must be a pointer type and must be a // class name - if (cs->getArgOperand(0)->getType()->isPointerTy() == false) - return false; + if (cs->getArgOperand(0)->getType()->isPointerTy() == false) return false; const Value* vfunc = cs->getCalledOperand(); if (const LoadInst* vfuncloadinst = SVFUtil::dyn_cast(vfunc)) { const Value* vfuncptr = vfuncloadinst->getPointerOperand(); - if (const GetElementPtrInst* vfuncptrgepinst = - SVFUtil::dyn_cast(vfuncptr)) + if (const GetElementPtrInst* vfuncptrgepinst = SVFUtil::dyn_cast(vfuncptr)) { - if (vfuncptrgepinst->getNumIndices() != 1) - return false; + if (vfuncptrgepinst->getNumIndices() != 1) return false; const Value* vtbl = vfuncptrgepinst->getPointerOperand(); if (SVFUtil::isa(vtbl)) { @@ -434,11 +421,9 @@ const Value* cppUtil::getVCallThisPtr(const CallBase* cs) * %0 = bitcast %class.B1* %this1 to %class.A* * call void @A::A()(%class.A* %0) */ -bool cppUtil::isSameThisPtrInConstructor(const Argument* thisPtr1, - const Value* thisPtr2) +bool cppUtil::isSameThisPtrInConstructor(const Argument* thisPtr1, const Value* thisPtr2) { - if (thisPtr1 == thisPtr2) - return true; + if (thisPtr1 == thisPtr2) return true; for (const Value* thisU : thisPtr1->users()) { if (const StoreInst* store = SVFUtil::dyn_cast(thisU)) @@ -447,10 +432,8 @@ bool cppUtil::isSameThisPtrInConstructor(const Argument* thisPtr1, { if (const LoadInst* load = SVFUtil::dyn_cast(storeU)) { - if (load->getNextNode() && - SVFUtil::isa(load->getNextNode())) - return SVFUtil::cast(load->getNextNode()) == - (thisPtr2->stripPointerCasts()); + if (load->getNextNode() && SVFUtil::isa(load->getNextNode())) + return SVFUtil::cast(load->getNextNode()) == (thisPtr2->stripPointerCasts()); } } } @@ -460,8 +443,7 @@ bool cppUtil::isSameThisPtrInConstructor(const Argument* thisPtr1, const Argument* cppUtil::getConstructorThisPtr(const Function* fun) { - assert((isConstructor(fun) || isDestructor(fun)) && - "not a constructor?"); + assert((isConstructor(fun) || isDestructor(fun)) && "not a constructor?"); assert(fun->arg_size() >= 1 && "argument size >= 1?"); const Argument* thisPtr = &*(fun->arg_begin()); return thisPtr; @@ -481,15 +463,13 @@ void stripBracketsAndNamespace(cppUtil::DemangledName& dname) else { // strip off namespace - dname.className = - cppUtil::getBeforeBrackets(dname.className.substr(colon + 2)); + dname.className = cppUtil::getBeforeBrackets(dname.className.substr(colon + 2)); } } bool cppUtil::isConstructor(const Function* F) { - if (F->isDeclaration()) - return false; + if (F->isDeclaration()) return false; std::string funcName = F->getName().str(); if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0) { @@ -502,14 +482,12 @@ bool cppUtil::isConstructor(const Function* F) } stripBracketsAndNamespace(dname); /// TODO: on mac os function name is an empty string after demangling - return dname.className.size() > 0 && - dname.className.compare(dname.funcName) == 0; + return dname.className.size() > 0 && dname.className.compare(dname.funcName) == 0; } bool cppUtil::isDestructor(const Function* F) { - if (F->isDeclaration()) - return false; + if (F->isDeclaration()) return false; std::string funcName = F->getName().str(); if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0) { @@ -522,8 +500,7 @@ bool cppUtil::isDestructor(const Function* F) } stripBracketsAndNamespace(dname); return (dname.className.size() > 0 && dname.funcName.size() > 0 && - dname.className.size() + 1 == dname.funcName.size() && - dname.funcName.compare(0, 1, "~") == 0 && + dname.className.size() + 1 == dname.funcName.size() && dname.funcName.compare(0, 1, "~") == 0 && dname.className.compare(dname.funcName.substr(1)) == 0); } @@ -536,12 +513,10 @@ bool cppUtil::isDestructor(const Function* F) */ const Value* cppUtil::getVCallVtblPtr(const CallBase* cs) { - const LoadInst* loadInst = - SVFUtil::dyn_cast(cs->getCalledOperand()); + const LoadInst* loadInst = SVFUtil::dyn_cast(cs->getCalledOperand()); assert(loadInst != nullptr); const Value* vfuncptr = loadInst->getPointerOperand(); - const GetElementPtrInst* gepInst = - SVFUtil::dyn_cast(vfuncptr); + const GetElementPtrInst* gepInst = SVFUtil::dyn_cast(vfuncptr); assert(gepInst != nullptr); const Value* vtbl = gepInst->getPointerOperand(); return vtbl; @@ -554,13 +529,12 @@ bool cppUtil::VCallInCtorOrDtor(const CallBase* cs) { Set classNameOfThisPtrs = cppUtil::getClassNameOfThisPtr(cs); const Function* func = cs->getCaller(); - for (const auto &classNameOfThisPtr: classNameOfThisPtrs) + for (const auto& classNameOfThisPtr : classNameOfThisPtrs) { if (cppUtil::isConstructor(func) || cppUtil::isDestructor(func)) { cppUtil::DemangledName dname = cppUtil::demangle(func->getName().str()); - if (classNameOfThisPtr.compare(dname.className) == 0) - return true; + if (classNameOfThisPtr.compare(dname.className) == 0) return true; } } return false; @@ -568,13 +542,12 @@ bool cppUtil::VCallInCtorOrDtor(const CallBase* cs) bool cppUtil::classTyHasVTable(const StructType* ty) { - if(getClassNameFromType(ty).empty()==false) + if (getClassNameFromType(ty).empty() == false) { - for(auto it = ty->element_begin(); it!=ty->element_end(); it++) + for (auto it = ty->element_begin(); it != ty->element_end(); it++) { const std::string& str = LLVMUtil::dumpType(*it); - if (str.find(vtableType) != std::string::npos) - return true; + if (str.find(vtableType) != std::string::npos) return true; } } return false; @@ -616,19 +589,17 @@ Set cppUtil::getClassNameOfThisPtr(const CallBase* inst) Set ans; std::transform(thisPtrNames.begin(), thisPtrNames.end(), std::inserter(ans, ans.begin()), - [](const std::string &thisPtrName) -> std::string - { - size_t found = thisPtrName.find_last_not_of("0123456789"); - if (found != std::string::npos) - { - if (found != thisPtrName.size() - 1 && - thisPtrName[found] == '.') - { - return thisPtrName.substr(0, found); - } - } - return thisPtrName; - }); + [](const std::string& thisPtrName) -> std::string { + size_t found = thisPtrName.find_last_not_of("0123456789"); + if (found != std::string::npos) + { + if (found != thisPtrName.size() - 1 && thisPtrName[found] == '.') + { + return thisPtrName.substr(0, found); + } + } + return thisPtrName; + }); return ans; } @@ -645,12 +616,10 @@ std::string cppUtil::getFunNameOfVCallSite(const CallBase* inst) s32_t cppUtil::getVCallIdx(const CallBase* cs) { - const LoadInst* vfuncloadinst = - SVFUtil::dyn_cast(cs->getCalledOperand()); + const LoadInst* vfuncloadinst = SVFUtil::dyn_cast(cs->getCalledOperand()); assert(vfuncloadinst != nullptr); const Value* vfuncptr = vfuncloadinst->getPointerOperand(); - const GetElementPtrInst* vfuncptrgepinst = - SVFUtil::dyn_cast(vfuncptr); + const GetElementPtrInst* vfuncptrgepinst = SVFUtil::dyn_cast(vfuncptr); User::const_op_iterator oi = vfuncptrgepinst->idx_begin(); const ConstantInt* idx = SVFUtil::dyn_cast(oi->get()); s32_t idx_value; @@ -673,22 +642,21 @@ bool LLVMUtil::isConstantObjSym(const Value* val) { if (const GlobalVariable* v = SVFUtil::dyn_cast(val)) { - if (cppUtil::isValVtbl(v)) - return false; + if (cppUtil::isValVtbl(v)) return false; else if (!v->hasInitializer()) { return !v->isExternalLinkage(v->getLinkage()); } else { - StInfo *stInfo = LLVMModuleSet::getLLVMModuleSet()->getSVFType(v->getInitializer()->getType())->getTypeInfo(); - const std::vector &fields = stInfo->getFlattenFieldTypes(); + StInfo* stInfo = + LLVMModuleSet::getLLVMModuleSet()->getSVFType(v->getInitializer()->getType())->getTypeInfo(); + const std::vector& fields = stInfo->getFlattenFieldTypes(); for (std::vector::const_iterator it = fields.begin(), eit = fields.end(); it != eit; ++it) { const SVFType* elemTy = *it; assert(!SVFUtil::isa(elemTy) && "Initializer of a global is a function?"); - if (SVFUtil::isa(elemTy)) - return false; + if (SVFUtil::isa(elemTy)) return false; } return v->isConstant(); @@ -703,16 +671,15 @@ bool LLVMUtil::isConstantObjSym(const Value* val) * @param foo * @return */ -Set cppUtil::extractClsNamesFromFunc(const Function *foo) +Set cppUtil::extractClsNamesFromFunc(const Function* foo) { assert(foo->hasName() && "foo does not have a name? possible indirect call"); - const std::string &name = foo->getName().str(); + const std::string& name = foo->getName().str(); if (isConstructor(foo) || isDestructor(foo)) { // c++ constructor or destructor DemangledName demangledName = cppUtil::demangle(name); - Set clsNameInBrackets = - cppUtil::getClsNamesInBrackets(name); + Set clsNameInBrackets = cppUtil::getClsNamesInBrackets(name); clsNameInBrackets.insert(demangledName.className); return clsNameInBrackets; } @@ -732,7 +699,7 @@ Set cppUtil::extractClsNamesFromFunc(const Function *foo) * @param input * @return */ -std::vector findInnermostBrackets(const std::string &input) +std::vector findInnermostBrackets(const std::string& input) { typedef std::pair StEdIdxPair; std::stack stack; @@ -771,8 +738,7 @@ std::vector findInnermostBrackets(const std::string &input) } } std::vector ans(innerMostPairs.size()); - std::transform(innerMostPairs.begin(), innerMostPairs.end(), ans.begin(), [&input](StEdIdxPair &p) -> std::string - { + std::transform(innerMostPairs.begin(), innerMostPairs.end(), ans.begin(), [&input](StEdIdxPair& p) -> std::string { return input.substr(p.first + 1, p.second - p.first - 1); }); return ans; @@ -783,21 +749,15 @@ std::vector findInnermostBrackets(const std::string &input) * @param str * @return */ -std::string stripWhitespaces(const std::string &str) +std::string stripWhitespaces(const std::string& str) { - auto start = std::find_if(str.begin(), str.end(), [](unsigned char ch) - { - return !std::isspace(ch); - }); - auto end = std::find_if(str.rbegin(), str.rend(), [](unsigned char ch) - { - return !std::isspace(ch); - }).base(); + auto start = std::find_if(str.begin(), str.end(), [](unsigned char ch) { return !std::isspace(ch); }); + auto end = std::find_if(str.rbegin(), str.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(); return (start < end) ? std::string(start, end) : std::string(); } -std::vector splitAndStrip(const std::string &input, char delimiter) +std::vector splitAndStrip(const std::string& input, char delimiter) { std::vector tokens; size_t start = 0, end = 0; @@ -818,7 +778,7 @@ std::vector splitAndStrip(const std::string &input, char delimiter) * @param oname * @return */ -Set cppUtil::extractClsNamesFromTemplate(const std::string &oname) +Set cppUtil::extractClsNamesFromTemplate(const std::string& oname) { // "std::array" -> A // "std::queue > >" -> A @@ -826,10 +786,10 @@ Set cppUtil::extractClsNamesFromTemplate(const std::string &oname) Set ans; std::string demangleName = llvm::demangle(oname); std::vector innermosts = findInnermostBrackets(demangleName); - for (const auto &innermost: innermosts) + for (const auto& innermost : innermosts) { - const std::vector &allstrs = splitAndStrip(innermost, ','); - for (const auto &str: allstrs) + const std::vector& allstrs = splitAndStrip(innermost, ','); + for (const auto& str : allstrs) { size_t spacePos = str.find(' '); if (spacePos != std::string::npos) @@ -851,23 +811,22 @@ Set cppUtil::extractClsNamesFromTemplate(const std::string &oname) return ans; } - /*! * class sources are functions * where we can extract the class name (constructors/destructors or template functions) * @param val * @return */ -bool cppUtil::isClsNameSource(const Value *val) +bool cppUtil::isClsNameSource(const Value* val) { - if (const auto *callBase = SVFUtil::dyn_cast(val)) + if (const auto* callBase = SVFUtil::dyn_cast(val)) { - const Function *foo = callBase->getCalledFunction(); + const Function* foo = callBase->getCalledFunction(); // indirect call - if(!foo) return false; + if (!foo) return false; return isConstructor(foo) || isDestructor(foo) || isTemplateFunc(foo) || isDynCast(foo); } - else if (const auto *func = SVFUtil::dyn_cast(val)) + else if (const auto* func = SVFUtil::dyn_cast(val)) { return isConstructor(func) || isDestructor(func) || isTemplateFunc(func); } @@ -880,7 +839,7 @@ bool cppUtil::isClsNameSource(const Value *val) * @param label * @return */ -bool cppUtil::matchesLabel(const std::string &foo, const std::string &label) +bool cppUtil::matchesLabel(const std::string& foo, const std::string& label) { return foo.compare(0, label.size(), label) == 0; } @@ -891,14 +850,13 @@ bool cppUtil::matchesLabel(const std::string &foo, const std::string &label) * @param foo * @return */ -bool cppUtil::isTemplateFunc(const Function *foo) +bool cppUtil::isTemplateFunc(const Function* foo) { assert(foo->hasName() && "foo does not have a name? possible indirect call"); - const std::string &name = foo->getName().str(); - bool matchedLabel = matchesLabel(name, znstLabel) || matchesLabel(name, znkstLabel) || - matchesLabel(name, znkLabel); + const std::string& name = foo->getName().str(); + bool matchedLabel = matchesLabel(name, znstLabel) || matchesLabel(name, znkstLabel) || matchesLabel(name, znkLabel); // we exclude "_ZNK6cArray3dupEv" -> cArray::dup() const - const std::string &demangledName = llvm::demangle(name); + const std::string& demangledName = llvm::demangle(name); return matchedLabel && demangledName.find('<') != std::string::npos && demangledName.find('>') != std::string::npos; } @@ -907,7 +865,7 @@ bool cppUtil::isTemplateFunc(const Function *foo) * @param foo * @return */ -bool cppUtil::isDynCast(const Function *foo) +bool cppUtil::isDynCast(const Function* foo) { assert(foo->hasName() && "foo does not have a name? possible indirect call"); return foo->getName().str() == dyncast; @@ -920,23 +878,22 @@ bool cppUtil::isDynCast(const Function *foo) */ std::string cppUtil::extractClsNameFromDynCast(const CallBase* callBase) { - Value *tgtCast = callBase->getArgOperand(2); - const std::string &valueStr = LLVMUtil::dumpValue(tgtCast); + Value* tgtCast = callBase->getArgOperand(2); + const std::string& valueStr = LLVMUtil::dumpValue(tgtCast); u32_t leftPos = valueStr.find(ztilabel); - assert(leftPos != (u32_t) std::string::npos && "does not find ZTI for dyncast?"); + assert(leftPos != (u32_t)std::string::npos && "does not find ZTI for dyncast?"); u32_t rightPos = leftPos; while (rightPos < valueStr.size() && valueStr[rightPos] != ' ') rightPos++; - const std::string &substr = valueStr.substr(leftPos, rightPos - leftPos); + const std::string& substr = valueStr.substr(leftPos, rightPos - leftPos); std::string demangleName = llvm::demangle(substr); - const std::string &realName = demangleName.substr(ztiprefix.size(), - demangleName.size() - ztiprefix.size()); + const std::string& realName = demangleName.substr(ztiprefix.size(), demangleName.size() - ztiprefix.size()); assert(realName != "" && "real name for dyncast empty?"); return realName; } -const Type *cppUtil::cppClsNameToType(const std::string &className) +const Type* cppUtil::cppClsNameToType(const std::string& className) { - StructType *classTy = StructType::getTypeByName(LLVMModuleSet::getLLVMModuleSet()->getContext(), - clsName + className); + StructType* classTy = + StructType::getTypeByName(LLVMModuleSet::getLLVMModuleSet()->getContext(), clsName + className); return classTy ? classTy : LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->ptrType(); } \ No newline at end of file diff --git a/svf-llvm/lib/DCHG.cpp b/svf-llvm/lib/DCHG.cpp index 7390785f7..eb750387e 100644 --- a/svf-llvm/lib/DCHG.cpp +++ b/svf-llvm/lib/DCHG.cpp @@ -18,13 +18,12 @@ using namespace SVF; - -void DCHGraph::handleDIBasicType(const DIBasicType *basicType) +void DCHGraph::handleDIBasicType(const DIBasicType* basicType) { getOrCreateNode(basicType); } -void DCHGraph::handleDICompositeType(const DICompositeType *compositeType) +void DCHGraph::handleDICompositeType(const DICompositeType* compositeType) { switch (compositeType->getTag()) { @@ -42,10 +41,10 @@ void DCHGraph::handleDICompositeType(const DICompositeType *compositeType) if (!fields.empty()) { // We want the first non-static, non-function member; it may not exist. - DIDerivedType *firstMember = nullptr; - for (DINode *n : fields) + DIDerivedType* firstMember = nullptr; + for (DINode* n : fields) { - if (DIDerivedType *fm = SVFUtil::dyn_cast(n)) + if (DIDerivedType* fm = SVFUtil::dyn_cast(n)) { if (fm->getTag() == dwarf::DW_TAG_member && !fm->isStaticMember()) { @@ -73,10 +72,10 @@ void DCHGraph::handleDICompositeType(const DICompositeType *compositeType) if (extended) { DINodeArray fields = compositeType->getElements(); - for (DINode *field : fields) + for (DINode* field : fields) { // fields[0] gives a type which is DW_TAG_member, we want the member's type (getBaseType). - DIDerivedType *firstMember = SVFUtil::dyn_cast(field); + DIDerivedType* firstMember = SVFUtil::dyn_cast(field); assert(firstMember != nullptr && "DCHG: expected member type"); addEdge(compositeType, firstMember->getBaseType(), DCHEdge::FIRST_FIELD); } @@ -94,15 +93,14 @@ void DCHGraph::handleDICompositeType(const DICompositeType *compositeType) } } -void DCHGraph::handleDIDerivedType(const DIDerivedType *derivedType) +void DCHGraph::handleDIDerivedType(const DIDerivedType* derivedType) { switch (derivedType->getTag()) { - case dwarf::DW_TAG_inheritance: - { + case dwarf::DW_TAG_inheritance: { assert(SVFUtil::isa(derivedType->getScope()) && "inheriting from non-type?"); - DCHEdge *edge = addEdge(SVFUtil::dyn_cast(derivedType->getScope()), - derivedType->getBaseType(), DCHEdge::INHERITANCE); + DCHEdge* edge = addEdge(SVFUtil::dyn_cast(derivedType->getScope()), derivedType->getBaseType(), + DCHEdge::INHERITANCE); // If the offset does not exist (for primary base), getConstantFieldIdx should return 0. edge->setOffset(derivedType->getOffsetInBits()); break; @@ -130,22 +128,22 @@ void DCHGraph::handleDIDerivedType(const DIDerivedType *derivedType) } } -void DCHGraph::handleDISubroutineType(const DISubroutineType *subroutineType) +void DCHGraph::handleDISubroutineType(const DISubroutineType* subroutineType) { getOrCreateNode(subroutineType); } -void DCHGraph::handleTypedef(const DIType *typedefType) +void DCHGraph::handleTypedef(const DIType* typedefType) { assert(typedefType && typedefType->getTag() == dwarf::DW_TAG_typedef); // Need to gather them in a set first because we don't know the base type till // we get to the bottom of the (potentially many) typedefs. - std::vector typedefs; + std::vector typedefs; // Check for nullptr because you can typedef void. while (typedefType != nullptr && typedefType->getTag() == dwarf::DW_TAG_typedef) { - const DIDerivedType *typedefDerivedType = SVFUtil::dyn_cast(typedefType); + const DIDerivedType* typedefDerivedType = SVFUtil::dyn_cast(typedefType); // The typedef itself. typedefs.push_back(typedefDerivedType); @@ -153,41 +151,41 @@ void DCHGraph::handleTypedef(const DIType *typedefType) typedefType = typedefDerivedType->getBaseType(); } - const DIType *baseType = typedefType; - DCHNode *baseTypeNode = getOrCreateNode(baseType); + const DIType* baseType = typedefType; + DCHNode* baseTypeNode = getOrCreateNode(baseType); - for (const DIDerivedType *tdef : typedefs) + for (const DIDerivedType* tdef : typedefs) { // Base type needs to hold its typedefs. baseTypeNode->addTypedef(tdef); } } -void DCHGraph::buildVTables(const SVFModule &module) +void DCHGraph::buildVTables(const SVFModule& module) { - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { for (Module::const_global_iterator gvI = M.global_begin(); gvI != M.global_end(); ++gvI) { // Though this will return more than GlobalVariables, we only care about GlobalVariables (for the vtbls). - const GlobalVariable *gv = SVFUtil::dyn_cast(&*gvI); + const GlobalVariable* gv = SVFUtil::dyn_cast(&*gvI); if (gv == nullptr) continue; if (gv->hasMetadata(cppUtil::ctir::vtMDName) && gv->getNumOperands() > 0) { - DIType *type = SVFUtil::dyn_cast(gv->getMetadata(cppUtil::ctir::vtMDName)); + DIType* type = SVFUtil::dyn_cast(gv->getMetadata(cppUtil::ctir::vtMDName)); assert(type && "DCHG::buildVTables: bad metadata for ctir.vt"); - DCHNode *node = getOrCreateNode(type); + DCHNode* node = getOrCreateNode(type); const SVFGlobalValue* svfgv = LLVMModuleSet::getLLVMModuleSet()->getSVFGlobalValue(gv); node->setVTable(svfgv); vtblToTypeMap[svfgv] = getCanonicalType(type); - const ConstantStruct *vtbls = cppUtil::getVtblStruct(gv); + const ConstantStruct* vtbls = cppUtil::getVtblStruct(gv); for (unsigned nthVtbl = 0; nthVtbl < vtbls->getNumOperands(); ++nthVtbl) { - const ConstantArray *vtbl = SVFUtil::dyn_cast(vtbls->getOperand(nthVtbl)); + const ConstantArray* vtbl = SVFUtil::dyn_cast(vtbls->getOperand(nthVtbl)); assert(vtbl && "Element of vtbl struct not an array"); - std::vector &vfns = node->getVfnVector(nthVtbl); + std::vector& vfns = node->getVfnVector(nthVtbl); // Iterating over the vtbl, we will run into: // 1. i8* null (don't care for now). @@ -195,14 +193,14 @@ void DCHGraph::buildVTables(const SVFModule &module) // 3. i8* bitcast ... (we only care when a function pointer is being bitcasted). for (unsigned cN = 0; cN < vtbl->getNumOperands(); ++cN) { - Constant *c = vtbl->getOperand(cN); + Constant* c = vtbl->getOperand(cN); if (SVFUtil::isa(c)) { // Don't care for now. continue; } - ConstantExpr *ce = SVFUtil::dyn_cast(c); + ConstantExpr* ce = SVFUtil::dyn_cast(c); assert(ce && "non-ConstantExpr, non-ConstantPointerNull in vtable?"); if (ce->getOpcode() == Instruction::BitCast) { @@ -220,10 +218,10 @@ void DCHGraph::buildVTables(const SVFModule &module) } } -const NodeBS &DCHGraph::cha(const DIType *type, bool firstField) +const NodeBS& DCHGraph::cha(const DIType* type, bool firstField) { type = getCanonicalType(type); - Map &cacheMap = firstField ? chaFFMap : chaMap; + Map& cacheMap = firstField ? chaFFMap : chaMap; // Check if we've already computed. if (cacheMap.find(type) != cacheMap.end()) @@ -232,15 +230,14 @@ const NodeBS &DCHGraph::cha(const DIType *type, bool firstField) } NodeBS children; - const DCHNode *node = getOrCreateNode(type); + const DCHNode* node = getOrCreateNode(type); // Consider oneself a child, otherwise the recursion will just come up with nothing. children.set(node->getId()); - for (const DCHEdge *edge : node->getInEdges()) + for (const DCHEdge* edge : node->getInEdges()) { // Don't care about anything but inheritance, first-field, and standard def. edges. - if ( edge->getEdgeKind() != DCHEdge::INHERITANCE - && edge->getEdgeKind() != DCHEdge::FIRST_FIELD - && edge->getEdgeKind() != DCHEdge::STD_DEF) + if (edge->getEdgeKind() != DCHEdge::INHERITANCE && edge->getEdgeKind() != DCHEdge::FIRST_FIELD && + edge->getEdgeKind() != DCHEdge::STD_DEF) { continue; } @@ -251,7 +248,7 @@ const NodeBS &DCHGraph::cha(const DIType *type, bool firstField) continue; } - const NodeBS &cchildren = cha(edge->getSrcNode()->getType(), firstField); + const NodeBS& cchildren = cha(edge->getSrcNode()->getType(), firstField); // Children's children are my children. for (NodeID cchild : cchildren) { @@ -265,7 +262,7 @@ const NodeBS &DCHGraph::cha(const DIType *type, bool firstField) return cacheMap[type]; } -void DCHGraph::flatten(const DICompositeType *type) +void DCHGraph::flatten(const DICompositeType* type) { type = SVFUtil::dyn_cast(getCanonicalType(type)); assert(type && "DCHG::flatten: canon type of struct/class is not struct/class"); @@ -278,17 +275,16 @@ void DCHGraph::flatten(const DICompositeType *type) // Create empty vector. fieldTypes[type]; - assert(type != nullptr - && (type->getTag() == dwarf::DW_TAG_class_type - || type->getTag() == dwarf::DW_TAG_structure_type) - && "DCHG::flatten: expected a class/struct"); + assert(type != nullptr && + (type->getTag() == dwarf::DW_TAG_class_type || type->getTag() == dwarf::DW_TAG_structure_type) && + "DCHG::flatten: expected a class/struct"); // Sort the fields from getElements. Especially a problem for classes; it's all jumbled up. - std::vector fields; + std::vector fields; DINodeArray fieldsDINA = type->getElements(); for (unsigned i = 0; i < fieldsDINA.size(); ++i) { - if (const DIDerivedType *dt = SVFUtil::dyn_cast(fieldsDINA[i])) + if (const DIDerivedType* dt = SVFUtil::dyn_cast(fieldsDINA[i])) { // Don't care about subprograms, only member/inheritance. fields.push_back(dt); @@ -296,21 +292,20 @@ void DCHGraph::flatten(const DICompositeType *type) } // TODO: virtual inheritance is not handled at all! - std::sort(fields.begin(), fields.end(), - [](const DIDerivedType *&a, const DIDerivedType *&b) -> bool - { return a->getOffsetInBits() < b->getOffsetInBits(); }); + std::sort(fields.begin(), fields.end(), [](const DIDerivedType*& a, const DIDerivedType*& b) -> bool { + return a->getOffsetInBits() < b->getOffsetInBits(); + }); - for (const DIDerivedType *mt : fields) + for (const DIDerivedType* mt : fields) { - assert((mt->getTag() == dwarf::DW_TAG_member || mt->getTag() == dwarf::DW_TAG_inheritance) - && "DCHG: expected member/inheritance"); + assert((mt->getTag() == dwarf::DW_TAG_member || mt->getTag() == dwarf::DW_TAG_inheritance) && + "DCHG: expected member/inheritance"); // Either we have a class, struct, array, or something not in need of flattening. - const DIType *fieldType = mt->getBaseType(); - if (fieldType->getTag() == dwarf::DW_TAG_structure_type - || fieldType->getTag() == dwarf::DW_TAG_class_type) + const DIType* fieldType = mt->getBaseType(); + if (fieldType->getTag() == dwarf::DW_TAG_structure_type || fieldType->getTag() == dwarf::DW_TAG_class_type) { flatten(SVFUtil::dyn_cast(fieldType)); - for (const DIType *ft : fieldTypes[fieldType]) + for (const DIType* ft : fieldTypes[fieldType]) { // ft is already a canonical type because the "root" additions insert // canonical types. @@ -319,12 +314,12 @@ void DCHGraph::flatten(const DICompositeType *type) } else if (fieldType->getTag() == dwarf::DW_TAG_array_type) { - const DICompositeType *arrayType = SVFUtil::dyn_cast(fieldType); - const DIType *baseType = arrayType->getBaseType(); - if (const DICompositeType *cbt = SVFUtil::dyn_cast(baseType)) + const DICompositeType* arrayType = SVFUtil::dyn_cast(fieldType); + const DIType* baseType = arrayType->getBaseType(); + if (const DICompositeType* cbt = SVFUtil::dyn_cast(baseType)) { flatten(cbt); - for (const DIType *ft : fieldTypes[cbt]) + for (const DIType* ft : fieldTypes[cbt]) { // ft is already a canonical type like above. fieldTypes[type].push_back(ft); @@ -342,15 +337,14 @@ void DCHGraph::flatten(const DICompositeType *type) } } -bool DCHGraph::isAgg(const DIType *t) +bool DCHGraph::isAgg(const DIType* t) { if (t == nullptr) return false; - return t->getTag() == dwarf::DW_TAG_array_type - || t->getTag() == dwarf::DW_TAG_structure_type - || t->getTag() == dwarf::DW_TAG_class_type; + return t->getTag() == dwarf::DW_TAG_array_type || t->getTag() == dwarf::DW_TAG_structure_type || + t->getTag() == dwarf::DW_TAG_class_type; } -void DCHGraph::gatherAggs(const DICompositeType *type) +void DCHGraph::gatherAggs(const DICompositeType* type) { if (containingAggs.find(getCanonicalType(type)) != containingAggs.end()) { @@ -363,18 +357,17 @@ void DCHGraph::gatherAggs(const DICompositeType *type) if (type->getTag() == dwarf::DW_TAG_array_type) { - const DIType *bt = type->getBaseType(); + const DIType* bt = type->getBaseType(); bt = stripQualifiers(bt); if (isAgg(bt)) { - const DICompositeType *cbt = SVFUtil::dyn_cast(bt); + const DICompositeType* cbt = SVFUtil::dyn_cast(bt); containingAggs[getCanonicalType(type)].insert(getCanonicalType(cbt)); gatherAggs(cbt); // These must be canonical already because of aggs.insert above/below. - containingAggs[getCanonicalType(type)].insert( - containingAggs[getCanonicalType(cbt)].begin(), - containingAggs[getCanonicalType(cbt)].end()); + containingAggs[getCanonicalType(type)].insert(containingAggs[getCanonicalType(cbt)].begin(), + containingAggs[getCanonicalType(cbt)].end()); } } else @@ -383,27 +376,26 @@ void DCHGraph::gatherAggs(const DICompositeType *type) for (unsigned i = 0; i < fields.size(); ++i) { // Unwrap the member (could be a subprogram, not type, so guard needed). - if (const DIDerivedType *mt = SVFUtil::dyn_cast(fields[i])) + if (const DIDerivedType* mt = SVFUtil::dyn_cast(fields[i])) { - const DIType *ft = mt->getBaseType(); + const DIType* ft = mt->getBaseType(); ft = stripQualifiers(ft); if (isAgg(ft)) { - const DICompositeType *cft = SVFUtil::dyn_cast(ft); + const DICompositeType* cft = SVFUtil::dyn_cast(ft); containingAggs[getCanonicalType(type)].insert(getCanonicalType(cft)); gatherAggs(cft); // These must be canonical already because of aggs.insert above. - containingAggs[getCanonicalType(type)].insert( - containingAggs[getCanonicalType(cft)].begin(), - containingAggs[getCanonicalType(cft)].end()); + containingAggs[getCanonicalType(type)].insert(containingAggs[getCanonicalType(cft)].begin(), + containingAggs[getCanonicalType(cft)].end()); } } } } } -DCHNode *DCHGraph::getOrCreateNode(const DIType *type) +DCHNode* DCHGraph::getOrCreateNode(const DIType* type) { type = getCanonicalType(type); @@ -413,7 +405,7 @@ DCHNode *DCHGraph::getOrCreateNode(const DIType *type) return diTypeToNodeMap[type]; } - DCHNode *node = new DCHNode(type, numTypes++); + DCHNode* node = new DCHNode(type, numTypes++); addGNode(node->getId(), node); diTypeToNodeMap[type] = node; // TODO: handle templates. @@ -423,19 +415,19 @@ DCHNode *DCHGraph::getOrCreateNode(const DIType *type) const DIType* DCHGraph::getCSStaticType(CallBase* cs) const { - MDNode *md = cs->getMetadata(cppUtil::ctir::derefMDName); + MDNode* md = cs->getMetadata(cppUtil::ctir::derefMDName); assert(md != nullptr && "Missing type metadata at virtual callsite"); - DIType *diType = SVFUtil::dyn_cast(md); + DIType* diType = SVFUtil::dyn_cast(md); assert(diType != nullptr && "Incorrect metadata type at virtual callsite"); return diType; } -DCHEdge *DCHGraph::addEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKind et) +DCHEdge* DCHGraph::addEdge(const DIType* t1, const DIType* t2, DCHEdge::GEdgeKind et) { - DCHNode *src = getOrCreateNode(t1); - DCHNode *dst = getOrCreateNode(t2); + DCHNode* src = getOrCreateNode(t1); + DCHNode* dst = getOrCreateNode(t2); - DCHEdge *edge = hasEdge(t1, t2, et); + DCHEdge* edge = hasEdge(t1, t2, et); if (edge == nullptr) { // Create a new edge. @@ -447,14 +439,14 @@ DCHEdge *DCHGraph::addEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKin return edge; } -DCHEdge *DCHGraph::hasEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKind et) +DCHEdge* DCHGraph::hasEdge(const DIType* t1, const DIType* t2, DCHEdge::GEdgeKind et) { - DCHNode *src = getOrCreateNode(t1); - DCHNode *dst = getOrCreateNode(t2); + DCHNode* src = getOrCreateNode(t1); + DCHNode* dst = getOrCreateNode(t2); - for (DCHEdge *edge : src->getOutEdges()) + for (DCHEdge* edge : src->getOutEdges()) { - DCHNode *node = edge->getDstNode(); + DCHNode* node = edge->getDstNode(); DCHEdge::GEdgeKind edgeType = edge->getEdgeKind(); if (node == dst && edgeType == et) { @@ -470,7 +462,7 @@ void DCHGraph::buildCHG(bool extend) { extended = extend; DebugInfoFinder finder; - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { finder.processModule(M); } @@ -478,7 +470,7 @@ void DCHGraph::buildCHG(bool extend) // Create the void node regardless of whether it appears. getOrCreateNode(nullptr); // Find any char type. - const DIType *charType = nullptr; + const DIType* charType = nullptr; /* * We want void at the top, char as a child, and everything is a child of char: * void @@ -488,28 +480,27 @@ void DCHGraph::buildCHG(bool extend) * x y z */ - - for (const DIType *type : finder.types()) + for (const DIType* type : finder.types()) { - if (const DIBasicType *basicType = SVFUtil::dyn_cast(type)) + if (const DIBasicType* basicType = SVFUtil::dyn_cast(type)) { - if (basicType->getEncoding() == dwarf::DW_ATE_unsigned_char - || basicType->getEncoding() == dwarf::DW_ATE_signed_char) + if (basicType->getEncoding() == dwarf::DW_ATE_unsigned_char || + basicType->getEncoding() == dwarf::DW_ATE_signed_char) { charType = type; } handleDIBasicType(basicType); } - else if (const DICompositeType *compositeType = SVFUtil::dyn_cast(type)) + else if (const DICompositeType* compositeType = SVFUtil::dyn_cast(type)) { handleDICompositeType(compositeType); } - else if (const DIDerivedType *derivedType = SVFUtil::dyn_cast(type)) + else if (const DIDerivedType* derivedType = SVFUtil::dyn_cast(type)) { handleDIDerivedType(derivedType); } - else if (const DISubroutineType *subroutineType = SVFUtil::dyn_cast(type)) + else if (const DISubroutineType* subroutineType = SVFUtil::dyn_cast(type)) { handleDISubroutineType(subroutineType); } @@ -530,8 +521,7 @@ void DCHGraph::buildCHG(bool extend) for (iterator nodeI = begin(); nodeI != end(); ++nodeI) { // Everything without a parent gets char as a parent. - if (nodeI->second->getType() != nullptr - && nodeI->second->getOutEdges().size() == 0) + if (nodeI->second->getType() != nullptr && nodeI->second->getOutEdges().size() == 0) { addEdge(nodeI->second->getType(), charType, DCHEdge::STD_DEF); } @@ -544,7 +534,7 @@ void DCHGraph::buildCHG(bool extend) } } -const VFunSet &DCHGraph::getCSVFsBasedonCHA(CallSite cs) +const VFunSet& DCHGraph::getCSVFsBasedonCHA(CallSite cs) { if (csCHAMap.find(cs) != csCHAMap.end()) { @@ -552,7 +542,7 @@ const VFunSet &DCHGraph::getCSVFsBasedonCHA(CallSite cs) } VFunSet vfns; - const VTableSet &vtbls = getCSVtblsBasedonCHA(cs); + const VTableSet& vtbls = getCSVtblsBasedonCHA(cs); getVFnsFromVtbls(cs, vtbls, vfns); // Cache. @@ -561,9 +551,9 @@ const VFunSet &DCHGraph::getCSVFsBasedonCHA(CallSite cs) return csCHAMap[cs]; } -const VTableSet &DCHGraph::getCSVtblsBasedonCHA(CallSite cs) +const VTableSet& DCHGraph::getCSVtblsBasedonCHA(CallSite cs) { - const DIType *type = getCanonicalType(getCSStaticType(cs)); + const DIType* type = getCanonicalType(getCSStaticType(cs)); // Check if we've already computed. if (vtblCHAMap.find(type) != vtblCHAMap.end()) { @@ -571,11 +561,11 @@ const VTableSet &DCHGraph::getCSVtblsBasedonCHA(CallSite cs) } VTableSet vtblSet; - const NodeBS &children = cha(type, false); + const NodeBS& children = cha(type, false); for (NodeID childId : children) { - DCHNode *child = getGNode(childId); - const SVFGlobalValue *vtbl = child->getVTable(); + DCHNode* child = getGNode(childId); + const SVFGlobalValue* vtbl = child->getVTable(); // TODO: what if it is null? if (vtbl != nullptr) { @@ -589,18 +579,18 @@ const VTableSet &DCHGraph::getCSVtblsBasedonCHA(CallSite cs) return vtblCHAMap[type]; } -void DCHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) +void DCHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet& vtbls, VFunSet& virtualFunctions) { size_t idx = cs.getFunIdxInVtable(); std::string funName = cs.getFunNameOfVirtualCall(); - for (const SVFGlobalValue *vtbl : vtbls) + for (const SVFGlobalValue* vtbl : vtbls) { assert(vtblToTypeMap.find(vtbl) != vtblToTypeMap.end() && "floating vtbl"); - const DIType *type = vtblToTypeMap[vtbl]; + const DIType* type = vtblToTypeMap[vtbl]; assert(hasNode(type) && "trying to get vtbl for type not in graph"); - const DCHNode *node = getNode(type); - std::vector> allVfns = node->getVfnVectors(); - for (std::vector vfnV : allVfns) + const DCHNode* node = getNode(type); + std::vector> allVfns = node->getVfnVectors(); + for (std::vector vfnV : allVfns) { // We only care about any virtual function corresponding to idx. if (idx >= vfnV.size()) @@ -672,18 +662,18 @@ void DCHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &vi } } -bool DCHGraph::isBase(const DIType *a, const DIType *b, bool firstField) +bool DCHGraph::isBase(const DIType* a, const DIType* b, bool firstField) { a = getCanonicalType(a); b = getCanonicalType(b); assert(hasNode(a) && hasNode(b) && "DCHG: isBase query for non-existent node!"); - const DCHNode *bNode = getNode(b); + const DCHNode* bNode = getNode(b); - const NodeBS &aChildren = cha(a, firstField); + const NodeBS& aChildren = cha(a, firstField); return aChildren.test(bNode->getId()); } -bool DCHGraph::isFieldOf(const DIType *f, const DIType *b) +bool DCHGraph::isFieldOf(const DIType* f, const DIType* b) { assert(f && b && "DCHG::isFieldOf: given nullptr!"); @@ -693,12 +683,12 @@ bool DCHGraph::isFieldOf(const DIType *f, const DIType *b) if (b->getTag() == dwarf::DW_TAG_array_type || b->getTag() == dwarf::DW_TAG_pointer_type) { - const DIType *baseType = nullptr; - if (const DICompositeType *arrayType = SVFUtil::dyn_cast(b)) + const DIType* baseType = nullptr; + if (const DICompositeType* arrayType = SVFUtil::dyn_cast(b)) { baseType = arrayType->getBaseType(); } - else if (const DIDerivedType *ptrType = SVFUtil::dyn_cast(b)) + else if (const DIDerivedType* ptrType = SVFUtil::dyn_cast(b)) { baseType = ptrType->getBaseType(); } @@ -707,10 +697,9 @@ bool DCHGraph::isFieldOf(const DIType *f, const DIType *b) baseType = getCanonicalType(baseType); return f == baseType || (baseType != nullptr && isFieldOf(f, baseType)); } - else if (b->getTag() == dwarf::DW_TAG_class_type - || b->getTag() == dwarf::DW_TAG_structure_type) + else if (b->getTag() == dwarf::DW_TAG_class_type || b->getTag() == dwarf::DW_TAG_structure_type) { - const std::vector &fields = getFieldTypes(b); + const std::vector& fields = getFieldTypes(b); return std::find(fields.begin(), fields.end(), f) != fields.end(); } else @@ -719,10 +708,10 @@ bool DCHGraph::isFieldOf(const DIType *f, const DIType *b) } } -const DIType *DCHGraph::getCanonicalType(const DIType *t) +const DIType* DCHGraph::getCanonicalType(const DIType* t) { // We want stripped types to be canonical. - const DIType *unstrippedT = t; + const DIType* unstrippedT = t; t = stripQualifiers(t); // Is there a mapping for the unstripped type? Yes - return it. @@ -743,7 +732,7 @@ const DIType *DCHGraph::getCanonicalType(const DIType *t) } // Canonical type for t is not cached, find one for it. - for (const DIType *canonType : canonicalTypes) + for (const DIType* canonType : canonicalTypes) { if (teq(t, canonType)) { @@ -760,47 +749,36 @@ const DIType *DCHGraph::getCanonicalType(const DIType *t) return canonicalTypeMap[t]; } -const DIType *DCHGraph::stripQualifiers(const DIType *t) +const DIType* DCHGraph::stripQualifiers(const DIType* t) { while (true) { // nullptr means void. - if (t == nullptr - || SVFUtil::isa(t) - || SVFUtil::isa(t)) + if (t == nullptr || SVFUtil::isa(t) || SVFUtil::isa(t)) { break; } unsigned tag = t->getTag(); // Verbose for clarity. - if ( tag == dwarf::DW_TAG_const_type - || tag == dwarf::DW_TAG_atomic_type - || tag == dwarf::DW_TAG_volatile_type - || tag == dwarf::DW_TAG_restrict_type - || tag == dwarf::DW_TAG_typedef) + if (tag == dwarf::DW_TAG_const_type || tag == dwarf::DW_TAG_atomic_type || tag == dwarf::DW_TAG_volatile_type || + tag == dwarf::DW_TAG_restrict_type || tag == dwarf::DW_TAG_typedef) { // Qualifier - get underlying type. - const DIDerivedType *dt = SVFUtil::dyn_cast(t); + const DIDerivedType* dt = SVFUtil::dyn_cast(t); assert(t && "DCHG: expected DerivedType"); t = dt->getBaseType(); } - else if ( tag == dwarf::DW_TAG_array_type - || tag == dwarf::DW_TAG_class_type - || tag == dwarf::DW_TAG_structure_type - || tag == dwarf::DW_TAG_union_type - || tag == dwarf::DW_TAG_enumeration_type - || tag == dwarf::DW_TAG_member - || tag == dwarf::DW_TAG_pointer_type - || tag == dwarf::DW_TAG_ptr_to_member_type - || tag == dwarf::DW_TAG_reference_type - || tag == dwarf::DW_TAG_rvalue_reference_type) + else if (tag == dwarf::DW_TAG_array_type || tag == dwarf::DW_TAG_class_type || + tag == dwarf::DW_TAG_structure_type || tag == dwarf::DW_TAG_union_type || + tag == dwarf::DW_TAG_enumeration_type || tag == dwarf::DW_TAG_member || + tag == dwarf::DW_TAG_pointer_type || tag == dwarf::DW_TAG_ptr_to_member_type || + tag == dwarf::DW_TAG_reference_type || tag == dwarf::DW_TAG_rvalue_reference_type) { // Hit a non-qualifier. break; } - else if ( tag == dwarf::DW_TAG_inheritance - || tag == dwarf::DW_TAG_friend) + else if (tag == dwarf::DW_TAG_inheritance || tag == dwarf::DW_TAG_friend) { assert(false && "DCHG: unexpected tag when stripping qualifiers"); } @@ -813,19 +791,19 @@ const DIType *DCHGraph::stripQualifiers(const DIType *t) return t; } -const DIType *DCHGraph::stripArray(const DIType *t) +const DIType* DCHGraph::stripArray(const DIType* t) { t = stripQualifiers(t); if (t->getTag() == dwarf::DW_TAG_array_type) { - const DICompositeType *at = SVFUtil::dyn_cast(t); + const DICompositeType* at = SVFUtil::dyn_cast(t); return stripArray(at->getBaseType()); } return t; } -bool DCHGraph::teq(const DIType *t1, const DIType *t2) +bool DCHGraph::teq(const DIType* t1, const DIType* t2) { t1 = stripQualifiers(t1); t2 = stripQualifiers(t2); @@ -846,55 +824,52 @@ bool DCHGraph::teq(const DIType *t1, const DIType *t2) // Check if we need base type comparisons. if (SVFUtil::isa(t1) && SVFUtil::isa(t2)) { - const DIBasicType *b1 = SVFUtil::dyn_cast(t1); - const DIBasicType *b2 = SVFUtil::dyn_cast(t2); + const DIBasicType* b1 = SVFUtil::dyn_cast(t1); + const DIBasicType* b2 = SVFUtil::dyn_cast(t2); unsigned enc1 = b1->getEncoding(); unsigned enc2 = b2->getEncoding(); - bool okayEnc = ((enc1 == dwarf::DW_ATE_signed || enc1 == dwarf::DW_ATE_unsigned || enc1 == dwarf::DW_ATE_boolean) - && (enc2 == dwarf::DW_ATE_signed || enc2 == dwarf::DW_ATE_unsigned || enc2 == dwarf::DW_ATE_boolean)) - || - (enc1 == dwarf::DW_ATE_float && enc2 == dwarf::DW_ATE_float) - || - ((enc1 == dwarf::DW_ATE_signed_char || enc1 == dwarf::DW_ATE_unsigned_char) - && - (enc2 == dwarf::DW_ATE_signed_char || enc2 == dwarf::DW_ATE_unsigned_char)); + bool okayEnc = + ((enc1 == dwarf::DW_ATE_signed || enc1 == dwarf::DW_ATE_unsigned || enc1 == dwarf::DW_ATE_boolean) && + (enc2 == dwarf::DW_ATE_signed || enc2 == dwarf::DW_ATE_unsigned || enc2 == dwarf::DW_ATE_boolean)) || + (enc1 == dwarf::DW_ATE_float && enc2 == dwarf::DW_ATE_float) || + ((enc1 == dwarf::DW_ATE_signed_char || enc1 == dwarf::DW_ATE_unsigned_char) && + (enc2 == dwarf::DW_ATE_signed_char || enc2 == dwarf::DW_ATE_unsigned_char)); if (!okayEnc) return false; // Now we have split integers, floats, and chars, ignoring signedness. - return t1->getSizeInBits() == t2->getSizeInBits() - && t1->getAlignInBits() == t2->getAlignInBits(); + return t1->getSizeInBits() == t2->getSizeInBits() && t1->getAlignInBits() == t2->getAlignInBits(); } // Check, do we need to compare base types? // This makes pointers, references, and arrays equivalent. // Will handle member types. - if ((SVFUtil::isa(t1) || t1->getTag() == dwarf::DW_TAG_array_type) - && (SVFUtil::isa(t2) || t2->getTag() == dwarf::DW_TAG_array_type)) + if ((SVFUtil::isa(t1) || t1->getTag() == dwarf::DW_TAG_array_type) && + (SVFUtil::isa(t2) || t2->getTag() == dwarf::DW_TAG_array_type)) { const DIType *base1, *base2; // Set base1. - if (const DIDerivedType *d1 = SVFUtil::dyn_cast(t1)) + if (const DIDerivedType* d1 = SVFUtil::dyn_cast(t1)) { base1 = d1->getBaseType(); } else { - const DICompositeType *c1 = SVFUtil::dyn_cast(t1); + const DICompositeType* c1 = SVFUtil::dyn_cast(t1); assert(c1 && "teq: bad cast for array type"); base1 = c1->getBaseType(); } // Set base2. - if (const DIDerivedType *d2 = SVFUtil::dyn_cast(t2)) + if (const DIDerivedType* d2 = SVFUtil::dyn_cast(t2)) { base2 = d2->getBaseType(); } else { - const DICompositeType *c2 = SVFUtil::dyn_cast(t2); + const DICompositeType* c2 = SVFUtil::dyn_cast(t2); assert(c2 && "teq: bad cast for array type"); base2 = c2->getBaseType(); } @@ -906,8 +881,8 @@ bool DCHGraph::teq(const DIType *t1, const DIType *t2) if (SVFUtil::isa(t1) && SVFUtil::isa(t2)) { - const DICompositeType *ct1 = SVFUtil::dyn_cast(t1); - const DICompositeType *ct2 = SVFUtil::dyn_cast(t2); + const DICompositeType* ct1 = SVFUtil::dyn_cast(t1); + const DICompositeType* ct2 = SVFUtil::dyn_cast(t2); if (ct1->getTag() != ct2->getTag()) return false; @@ -926,9 +901,7 @@ bool DCHGraph::teq(const DIType *t1, const DIType *t2) // Either union or struct, simply test all fields are equal. // Seems like it is enough to check it was defined in the same place. // The elements sometimes differ but are referring to the same fields. - return ct1->getName() == ct2->getName() - && ct1->getFile() == ct2->getFile() - && ct1->getLine() == ct2->getLine(); + return ct1->getName() == ct2->getName() && ct1->getFile() == ct2->getFile() && ct1->getLine() == ct2->getLine(); } // They were not equal base types (discounting signedness), nor were they @@ -937,7 +910,7 @@ bool DCHGraph::teq(const DIType *t1, const DIType *t2) return false; } -bool DCHGraph::isFirstField(const DIType *f, const DIType *b) +bool DCHGraph::isFirstField(const DIType* f, const DIType* b) { // TODO: some improvements. // - cha should be changed to accept which edge types to use, @@ -948,10 +921,10 @@ bool DCHGraph::isFirstField(const DIType *f, const DIType *b) if (f == b) return true; - const DCHNode *node = getNode(f); + const DCHNode* node = getNode(f); assert(node && "DCHG::isFirstField: node not found"); // Consider oneself a child, otherwise the recursion will just come up with nothing. - for (const DCHEdge *edge : node->getInEdges()) + for (const DCHEdge* edge : node->getInEdges()) { // Only care about first-field edges. if (edge->getEdgeKind() == DCHEdge::FIRST_FIELD) @@ -964,7 +937,7 @@ bool DCHGraph::isFirstField(const DIType *f, const DIType *b) return false; } -std::string DCHGraph::diTypeToStr(const DIType *t) +std::string DCHGraph::diTypeToStr(const DIType* t) { std::stringstream ss; @@ -973,11 +946,11 @@ std::string DCHGraph::diTypeToStr(const DIType *t) return "void"; } - if (const DIBasicType *bt = SVFUtil::dyn_cast(t)) + if (const DIBasicType* bt = SVFUtil::dyn_cast(t)) { ss << bt->getName().str(); } - else if (const DIDerivedType *dt = SVFUtil::dyn_cast(t)) + else if (const DIDerivedType* dt = SVFUtil::dyn_cast(t)) { if (dt->getName() == "__vtbl_ptr_type") { @@ -1005,8 +978,8 @@ std::string DCHGraph::diTypeToStr(const DIType *t) } else if (dt->getTag() == dwarf::DW_TAG_ptr_to_member_type) { - ss << diTypeToStr(dt->getBaseType()) - << " " << diTypeToStr(SVFUtil::dyn_cast(dt->getExtraData())) << "::*"; + ss << diTypeToStr(dt->getBaseType()) << " " << diTypeToStr(SVFUtil::dyn_cast(dt->getExtraData())) + << "::*"; } else if (dt->getTag() == dwarf::DW_TAG_reference_type) { @@ -1021,11 +994,10 @@ std::string DCHGraph::diTypeToStr(const DIType *t) ss << dt->getName().str() << "->" << diTypeToStr(dt->getBaseType()); } } - else if (const DICompositeType *ct = SVFUtil::dyn_cast(t)) + else if (const DICompositeType* ct = SVFUtil::dyn_cast(t)) { - if (ct->getTag() == dwarf::DW_TAG_class_type - || ct->getTag() == dwarf::DW_TAG_structure_type - || ct->getTag() == dwarf::DW_TAG_union_type) + if (ct->getTag() == dwarf::DW_TAG_class_type || ct->getTag() == dwarf::DW_TAG_structure_type || + ct->getTag() == dwarf::DW_TAG_union_type) { if (ct->getTag() == dwarf::DW_TAG_class_type) @@ -1057,11 +1029,11 @@ std::string DCHGraph::diTypeToStr(const DIType *t) { // fields[i] gives a type which is DW_TAG_member, we want the member's type (getBaseType). // It can also give a Subprogram type if the class just had non-virtual functions. - if (const DISubprogram *sp = SVFUtil::dyn_cast(fields[i])) + if (const DISubprogram* sp = SVFUtil::dyn_cast(fields[i])) { ss << sp->getName().str(); } - else if (const DIDerivedType *mt = SVFUtil::dyn_cast(fields[i])) + else if (const DIDerivedType* mt = SVFUtil::dyn_cast(fields[i])) { assert(mt->getTag() == dwarf::DW_TAG_member && "DCHG: expected member"); ss << diTypeToStr(mt->getBaseType()); @@ -1082,10 +1054,10 @@ std::string DCHGraph::diTypeToStr(const DIType *t) DINodeArray sizes = ct->getElements(); for (unsigned i = 0; i < sizes.size(); ++i) { - DISubrange *sr = SVFUtil::dyn_cast(sizes[0]); + DISubrange* sr = SVFUtil::dyn_cast(sizes[0]); assert(sr != nullptr && "DCHG: non-subrange as array element?"); int64_t count = -1; - if (const ConstantInt* ci = sr->getCount().dyn_cast()) + if (const ConstantInt* ci = sr->getCount().dyn_cast()) { count = ci->getSExtValue(); } @@ -1099,10 +1071,9 @@ std::string DCHGraph::diTypeToStr(const DIType *t) } else if (ct->getTag() == dwarf::DW_TAG_union_type) { - } } - else if (const DISubroutineType *st = SVFUtil::dyn_cast(t)) + else if (const DISubroutineType* st = SVFUtil::dyn_cast(t)) { DITypeRefArray types = st->getTypeArray(); // Must have one element at least (the first type). @@ -1160,12 +1131,13 @@ void DCHGraph::print(void) SVFUtil::outs() << line; } - const DCHNode *node = getGNode(id); + const DCHNode* node = getGNode(id); - SVFUtil::outs() << indent(currIndent) << id << ": " << diTypeToStr(node->getType()) << " [" << node->getType() << "]" << "\n"; - if (node->getType() != nullptr - && (node->getType()->getTag() == dwarf::DW_TAG_class_type - || node->getType()->getTag() == dwarf::DW_TAG_structure_type)) + SVFUtil::outs() << indent(currIndent) << id << ": " << diTypeToStr(node->getType()) << " [" << node->getType() + << "]" + << "\n"; + if (node->getType() != nullptr && (node->getType()->getTag() == dwarf::DW_TAG_class_type || + node->getType()->getTag() == dwarf::DW_TAG_structure_type)) { ++numStructs; unsigned numFields = getFieldTypes(node->getType()).size(); @@ -1175,7 +1147,7 @@ void DCHGraph::print(void) currIndent += singleIndent; SVFUtil::outs() << indent(currIndent) << "Virtual functions\n"; currIndent += singleIndent; - const std::vector> &vfnVectors = node->getVfnVectors(); + const std::vector>& vfnVectors = node->getVfnVectors(); for (unsigned i = 0; i < vfnVectors.size(); ++i) { SVFUtil::outs() << indent(currIndent) << "[ vtable #" << i << " ]\n"; @@ -1183,8 +1155,8 @@ void DCHGraph::print(void) for (unsigned j = 0; j < vfnVectors[i].size(); ++j) { struct cppUtil::DemangledName dname = cppUtil::demangle(vfnVectors[i][j]->getName().str()); - SVFUtil::outs() << indent(currIndent) << "[" << j << "] " - << dname.className << "::" << dname.funcName << "\n"; + SVFUtil::outs() << indent(currIndent) << "[" << j << "] " << dname.className << "::" << dname.funcName + << "\n"; } currIndent -= singleIndent; @@ -1200,7 +1172,7 @@ void DCHGraph::print(void) SVFUtil::outs() << indent(currIndent) << "Bases\n"; currIndent += singleIndent; - for (const DCHEdge *edge : node->getOutEdges()) + for (const DCHEdge* edge : node->getOutEdges()) { std::string arrow; if (edge->getEdgeKind() == DCHEdge::INHERITANCE) @@ -1224,8 +1196,8 @@ void DCHGraph::print(void) arrow = "----unknown---->"; } - SVFUtil::outs() << indent(currIndent) << "[ " << diTypeToStr(node->getType()) << " ] " - << arrow << " [ " << diTypeToStr(edge->getDstNode()->getType()) << " ]\n"; + SVFUtil::outs() << indent(currIndent) << "[ " << diTypeToStr(node->getType()) << " ] " << arrow << " [ " + << diTypeToStr(edge->getDstNode()->getType()) << " ]\n"; } if (node->getOutEdges().size() == 0) @@ -1239,8 +1211,8 @@ void DCHGraph::print(void) currIndent += singleIndent; - const Set &typedefs = node->getTypedefs(); - for (const DIDerivedType *tdef : typedefs) + const Set& typedefs = node->getTypedefs(); + for (const DIDerivedType* tdef : typedefs) { std::string typedefName = "void"; if (tdef != nullptr) diff --git a/svf-llvm/lib/ICFGBuilder.cpp b/svf-llvm/lib/ICFGBuilder.cpp index a210e429a..3d296f9d4 100644 --- a/svf-llvm/lib/ICFGBuilder.cpp +++ b/svf-llvm/lib/ICFGBuilder.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * ICFGBuilder.cpp * @@ -44,16 +43,15 @@ void ICFGBuilder::build(SVFModule* svfModule) // Add the unique global ICFGNode at the entry of a program (before the main method). icfg->addGlobalICFGNode(); - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) { - const Function *fun = &*F; + const Function* fun = &*F; const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun); - if (SVFUtil::isExtCall(svffun)) - continue; + if (SVFUtil::isExtCall(svffun)) continue; WorkList worklist; - processFunEntry(fun,worklist); + processFunEntry(fun, worklist); processFunBody(worklist); processFunExit(fun); } @@ -64,21 +62,21 @@ void ICFGBuilder::build(SVFModule* svfModule) /*! * function entry */ -void ICFGBuilder::processFunEntry(const Function* fun, WorkList& worklist) +void ICFGBuilder::processFunEntry(const Function* fun, WorkList& worklist) { - FunEntryICFGNode* FunEntryICFGNode = icfg->getFunEntryICFGNode(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)); + FunEntryICFGNode* FunEntryICFGNode = + icfg->getFunEntryICFGNode(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)); const Instruction* entryInst = &((fun->getEntryBlock()).front()); const SVFInstruction* svfentryInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(entryInst); InstVec insts; - if (isIntrinsicInst(svfentryInst)) - LLVMUtil::getNextInsts(entryInst, insts); + if (isIntrinsicInst(svfentryInst)) LLVMUtil::getNextInsts(entryInst, insts); else insts.push_back(entryInst); - for (InstVec::const_iterator nit = insts.begin(), enit = insts.end(); - nit != enit; ++nit) + for (InstVec::const_iterator nit = insts.begin(), enit = insts.end(); nit != enit; ++nit) { - ICFGNode* instNode = getOrAddBlockICFGNode(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(*nit)); //add interprocedural edge + ICFGNode* instNode = getOrAddBlockICFGNode( + LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(*nit)); // add interprocedural edge icfg->addIntraEdge(FunEntryICFGNode, instNode); worklist.push(*nit); } @@ -108,8 +106,7 @@ void ICFGBuilder::processFunBody(WorkList& worklist) InstVec nextInsts; LLVMUtil::getNextInsts(inst, nextInsts); u32_t branchID = 0; - for (InstVec::const_iterator nit = nextInsts.begin(), enit = - nextInsts.end(); nit != enit; ++nit) + for (InstVec::const_iterator nit = nextInsts.begin(), enit = nextInsts.end(); nit != enit; ++nit) { const Instruction* succ = *nit; const SVFInstruction* svfsucc = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(succ); @@ -123,20 +120,23 @@ void ICFGBuilder::processFunBody(WorkList& worklist) if (const BranchInst* br = SVFUtil::dyn_cast(inst)) { assert(branchID <= 1 && "if/else has more than two branches?"); - if(br->isConditional()) - icfg->addConditionalIntraEdge(srcNode, dstNode, LLVMModuleSet::getLLVMModuleSet()->getSVFValue(br->getCondition()), 1 - branchID); + if (br->isConditional()) + icfg->addConditionalIntraEdge( + srcNode, dstNode, LLVMModuleSet::getLLVMModuleSet()->getSVFValue(br->getCondition()), + 1 - branchID); else icfg->addIntraEdge(srcNode, dstNode); } else if (const SwitchInst* si = SVFUtil::dyn_cast(inst)) { /// branch condition value - const ConstantInt* condVal = const_cast(si)->findCaseDest(const_cast(succ->getParent())); + const ConstantInt* condVal = + const_cast(si)->findCaseDest(const_cast(succ->getParent())); /// default case is set to -1; s64_t val = -1; - if (condVal && condVal->getBitWidth() <= 64) - val = condVal->getSExtValue(); - icfg->addConditionalIntraEdge(srcNode, dstNode, LLVMModuleSet::getLLVMModuleSet()->getSVFValue(si->getCondition()),val); + if (condVal && condVal->getBitWidth() <= 64) val = condVal->getSExtValue(); + icfg->addConditionalIntraEdge( + srcNode, dstNode, LLVMModuleSet::getLLVMModuleSet()->getSVFValue(si->getCondition()), val); } else icfg->addIntraEdge(srcNode, dstNode); @@ -153,7 +153,7 @@ void ICFGBuilder::processFunBody(WorkList& worklist) * If a function has multiple exit(0), we will only have one "unreachle" instruction * after the UnifyFunctionExitNodes pass. */ -void ICFGBuilder::processFunExit(const Function* f) +void ICFGBuilder::processFunExit(const Function* f) { const SVFFunction* fun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(f); FunExitICFGNode* FunExitICFGNode = icfg->getFunExitICFGNode(fun); @@ -162,7 +162,7 @@ void ICFGBuilder::processFunExit(const Function* f) { for (const SVFInstruction* inst : svfbb->getInstructionList()) { - if(inst->isRetInst()) + if (inst->isRetInst()) { ICFGNode* instNode = getOrAddBlockICFGNode(inst); icfg->addIntraEdge(instNode, FunExitICFGNode); @@ -171,9 +171,6 @@ void ICFGBuilder::processFunExit(const Function* f) } } - - - /*! * (1) Add and get CallBlockICFGNode * (2) Handle call instruction by creating interprocedural edges @@ -183,7 +180,7 @@ InterICFGNode* ICFGBuilder::getOrAddInterBlockICFGNode(const SVFInstruction* ins assert(SVFUtil::isCallSite(inst) && "not a call instruction?"); assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!"); CallICFGNode* callICFGNode = getCallICFGNode(inst); - addICFGInterEdges(inst, getCallee(inst)); //creating interprocedural edges + addICFGInterEdges(inst, getCallee(inst)); // creating interprocedural edges return callICFGNode; } @@ -196,7 +193,7 @@ void ICFGBuilder::addICFGInterEdges(const SVFInstruction* cs, const SVFFunction* RetICFGNode* retBlockNode = getRetICFGNode(cs); /// direct call - if(callee) + if (callee) { /// if this is an external function (no function body) if (isExtCall(callee)) @@ -219,19 +216,17 @@ void ICFGBuilder::addICFGInterEdges(const SVFInstruction* cs, const SVFFunction* } } /* -* Add the global initialization statements immediately after the function entry of main -*/ + * Add the global initialization statements immediately after the function entry of main + */ void ICFGBuilder::connectGlobalToProgEntry(SVFModule* svfModule) { const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction(svfModule); /// Return back if the main function is not found, the bc file might be a library only - if(mainFunc == nullptr) - return; + if (mainFunc == nullptr) return; FunEntryICFGNode* entryNode = icfg->getFunEntryICFGNode(mainFunc); GlobalICFGNode* globalNode = icfg->getGlobalICFGNode(); IntraCFGEdge* intraEdge = new IntraCFGEdge(globalNode, entryNode); icfg->addICFGEdge(intraEdge); } - diff --git a/svf-llvm/lib/LLVMLoopAnalysis.cpp b/svf-llvm/lib/LLVMLoopAnalysis.cpp index 8b762bfd0..ff9e454da 100644 --- a/svf-llvm/lib/LLVMLoopAnalysis.cpp +++ b/svf-llvm/lib/LLVMLoopAnalysis.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * LLVMLoopAnalysis.cpp * @@ -46,10 +45,10 @@ using namespace SVFUtil; * @param mod SVF module * @param llvmLoops output llvm loops */ -void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg) +void LLVMLoopAnalysis::buildLLVMLoops(SVFModule* mod, ICFG* icfg) { llvm::DominatorTree DT = llvm::DominatorTree(); - std::vector loop_stack; + std::vector loop_stack; for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) @@ -63,17 +62,17 @@ void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg) llvm::LoopInfoBase loopInfo; std::vector llvmLoops; loopInfo.analyze(DT); - for (const auto &loop: loopInfo) + for (const auto& loop : loopInfo) { loop_stack.push_back(loop); } // pre-order traversal on loop-subloop tree while (!loop_stack.empty()) { - const Loop *loop = loop_stack.back(); + const Loop* loop = loop_stack.back(); loop_stack.pop_back(); llvmLoops.push_back(loop); - for (const auto &subloop: loop->getSubLoops()) + for (const auto& subloop : loop->getSubLoops()) { loop_stack.push_back(subloop); } @@ -87,9 +86,9 @@ void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg) * We start from here * @param icfg ICFG */ -void LLVMLoopAnalysis::build(ICFG *icfg) +void LLVMLoopAnalysis::build(ICFG* icfg) { - std::vector llvmLoops; + std::vector llvmLoops; buildLLVMLoops(PAG::getPAG()->getModule(), icfg); } @@ -98,34 +97,34 @@ void LLVMLoopAnalysis::build(ICFG *icfg) * @param icfg ICFG * @param llvmLoops input llvm loops */ -void LLVMLoopAnalysis::buildSVFLoops(ICFG *icfg, std::vector &llvmLoops) +void LLVMLoopAnalysis::buildSVFLoops(ICFG* icfg, std::vector& llvmLoops) { - for (const auto &llvmLoop: llvmLoops) + for (const auto& llvmLoop : llvmLoops) { DBOUT(DPAGBuild, outs() << "loop name: " << llvmLoop->getName().data() << "\n"); // count all node id in loop - Set loop_ids; - Set nodes; - for (const auto &BB: llvmLoop->getBlocks()) + Set loop_ids; + Set nodes; + for (const auto& BB : llvmLoop->getBlocks()) { - for (const auto &ins: *BB) + for (const auto& ins : *BB) { const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(&ins); loop_ids.insert(icfg->getICFGNode(svfInst)); nodes.insert(icfg->getICFGNode(svfInst)); } } - SVFLoop *svf_loop = new SVFLoop(nodes, Options::LoopBound()); - for (const auto &node: nodes) + SVFLoop* svf_loop = new SVFLoop(nodes, Options::LoopBound()); + for (const auto& node : nodes) { icfg->addNodeToSVFLoop(node, svf_loop); } // mark loop header's first inst BasicBlock* header_blk = llvmLoop->getHeader(); - Instruction &in_ins = *header_blk->begin(); + Instruction& in_ins = *header_blk->begin(); const SVFInstruction* svfInInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(&in_ins); - ICFGNode *in_node = icfg->getICFGNode(svfInInst); - for (const auto &edge: in_node->getInEdges()) + ICFGNode* in_node = icfg->getICFGNode(svfInInst); + for (const auto& edge : in_node->getInEdges()) { if (loop_ids.find(edge->getSrcNode()) == loop_ids.end()) { @@ -141,10 +140,10 @@ void LLVMLoopAnalysis::buildSVFLoops(ICFG *icfg, std::vector &llvm } } // handle in edge - llvm::Instruction &br_ins = header_blk->back(); + llvm::Instruction& br_ins = header_blk->back(); const SVFInstruction* svfBrInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(&br_ins); - ICFGNode *br_node = icfg->getICFGNode(svfBrInst); - for (const auto &edge: br_node->getOutEdges()) + ICFGNode* br_node = icfg->getICFGNode(svfBrInst); + for (const auto& edge : br_node->getOutEdges()) { if (loop_ids.find(edge->getDstNode()) != loop_ids.end()) { @@ -159,13 +158,13 @@ void LLVMLoopAnalysis::buildSVFLoops(ICFG *icfg, std::vector &llvm // mark loop end's first inst llvm::SmallVector ExitBlocks; llvmLoop->getExitBlocks(ExitBlocks); - for (const auto& exit_blk: ExitBlocks) + for (const auto& exit_blk : ExitBlocks) { assert(!exit_blk->empty() && "exit block is empty?"); - llvm::Instruction &out_ins = *exit_blk->begin(); + llvm::Instruction& out_ins = *exit_blk->begin(); const SVFInstruction* svfOutInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(&out_ins); - ICFGNode *out_node = icfg->getICFGNode(svfOutInst); - for (const auto &edge: out_node->getInEdges()) + ICFGNode* out_node = icfg->getICFGNode(svfOutInst); + for (const auto& edge : out_node->getInEdges()) { svf_loop->addOutICFGEdge(edge); DBOUT(DPAGBuild, outs() << " out edge: " << edge->toString() << "\n"); diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 675825023..c71ab2f62 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -66,16 +66,16 @@ using namespace SVF; } */ -#define SVF_MAIN_FUNC_NAME "svf.main" -#define SVF_GLOBAL_CTORS "llvm.global_ctors" -#define SVF_GLOBAL_DTORS "llvm.global_dtors" +#define SVF_MAIN_FUNC_NAME "svf.main" +#define SVF_GLOBAL_CTORS "llvm.global_ctors" +#define SVF_GLOBAL_DTORS "llvm.global_dtors" LLVMModuleSet* LLVMModuleSet::llvmModuleSet = nullptr; bool LLVMModuleSet::preProcessed = false; LLVMModuleSet::LLVMModuleSet() - : symInfo(SymbolTableInfo::SymbolInfo()), - svfModule(SVFModule::getSVFModule()), typeInference(new ObjTypeInference()) + : symInfo(SymbolTableInfo::SymbolInfo()), svfModule(SVFModule::getSVFModule()), + typeInference(new ObjTypeInference()) { } @@ -90,31 +90,31 @@ ObjTypeInference* LLVMModuleSet::getTypeInference() return typeInference; } -SVFModule* LLVMModuleSet::buildSVFModule(Module &mod) +SVFModule* LLVMModuleSet::buildSVFModule(Module& mod) { LLVMModuleSet* mset = getLLVMModuleSet(); double startSVFModuleTime = SVFStat::getClk(true); SVFModule::getSVFModule()->setModuleIdentifier(mod.getModuleIdentifier()); - mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()` - mset->loadExtAPIModules(); // Uses context from module through `this->getContext()` + mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()` + mset->loadExtAPIModules(); // Uses context from module through `this->getContext()` mset->build(); double endSVFModuleTime = SVFStat::getClk(true); - SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime)/TIMEINTERVAL; + SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime) / TIMEINTERVAL; mset->buildSymbolTable(); // Don't releaseLLVMModuleSet() here, as IRBuilder might still need LLVMMoudleSet return SVFModule::getSVFModule(); } -SVFModule* LLVMModuleSet::buildSVFModule(const std::vector &moduleNameVec) +SVFModule* LLVMModuleSet::buildSVFModule(const std::vector& moduleNameVec) { double startSVFModuleTime = SVFStat::getClk(true); LLVMModuleSet* mset = getLLVMModuleSet(); - mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()` - mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()` + mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()` + mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()` if (!moduleNameVec.empty()) { @@ -124,8 +124,7 @@ SVFModule* LLVMModuleSet::buildSVFModule(const std::vector &moduleN mset->build(); double endSVFModuleTime = SVFStat::getClk(true); - SVFStat::timeOfBuildingLLVMModule = - (endSVFModuleTime - startSVFModuleTime) / TIMEINTERVAL; + SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime) / TIMEINTERVAL; mset->buildSymbolTable(); // Don't releaseLLVMModuleSet() here, as IRBuilder might still need LLVMMoudleSet @@ -143,21 +142,18 @@ void LLVMModuleSet::buildSymbolTable() const builder.buildMemModel(svfModule); } double endSymInfoTime = SVFStat::getClk(true); - SVFStat::timeOfBuildingSymbolTable = - (endSymInfoTime - startSymInfoTime) / TIMEINTERVAL; + SVFStat::timeOfBuildingSymbolTable = (endSymInfoTime - startSymInfoTime) / TIMEINTERVAL; } void LLVMModuleSet::build() { - if(preProcessed==false) - prePassSchedule(); + if (preProcessed == false) prePassSchedule(); buildFunToFunMap(); buildGlobalDefToRepMap(); removeUnusedExtAPIs(); - if (Options::SVFMain()) - addSVFMain(); + if (Options::SVFMain()) addSVFMain(); createSVFDataStructure(); initSVFFunction(); @@ -188,11 +184,11 @@ void LLVMModuleSet::createSVFDataStructure() } } - for (const Function* func: candidateDefs) + for (const Function* func : candidateDefs) { createSVFFunction(func); } - for (const Function* func: candidateDecls) + for (const Function* func : candidateDecls) { createSVFFunction(func); } @@ -201,10 +197,9 @@ void LLVMModuleSet::createSVFDataStructure() for (const Module& mod : modules) { /// GlobalVariable - for (const GlobalVariable& global : mod.globals()) + for (const GlobalVariable& global : mod.globals()) { - SVFGlobalValue* svfglobal = new SVFGlobalValue( - global.getName().str(), getSVFType(global.getType())); + SVFGlobalValue* svfglobal = new SVFGlobalValue(global.getName().str(), getSVFType(global.getType())); svfModule->addGlobalSet(svfglobal); addGlobalValueMap(&global, svfglobal); } @@ -212,8 +207,7 @@ void LLVMModuleSet::createSVFDataStructure() /// GlobalAlias for (const GlobalAlias& alias : mod.aliases()) { - SVFGlobalValue* svfalias = new SVFGlobalValue( - alias.getName().str(), getSVFType(alias.getType())); + SVFGlobalValue* svfalias = new SVFGlobalValue(alias.getName().str(), getSVFType(alias.getType())); svfModule->addAliasSet(svfalias); addGlobalValueMap(&alias, svfalias); } @@ -221,8 +215,7 @@ void LLVMModuleSet::createSVFDataStructure() /// GlobalIFunc for (const GlobalIFunc& ifunc : mod.ifuncs()) { - SVFGlobalValue* svfifunc = new SVFGlobalValue( - ifunc.getName().str(), getSVFType(ifunc.getType())); + SVFGlobalValue* svfifunc = new SVFGlobalValue(ifunc.getName().str(), getSVFType(ifunc.getType())); svfModule->addAliasSet(svfifunc); addGlobalValueMap(&ifunc, svfifunc); } @@ -231,25 +224,20 @@ void LLVMModuleSet::createSVFDataStructure() void LLVMModuleSet::createSVFFunction(const Function* func) { - SVFFunction* svfFunc = new SVFFunction( - getSVFType(func->getType()), - SVFUtil::cast( - getSVFType(func->getFunctionType())), - func->isDeclaration(), LLVMUtil::isIntrinsicFun(func), - func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo); + SVFFunction* svfFunc = new SVFFunction(getSVFType(func->getType()), + SVFUtil::cast(getSVFType(func->getFunctionType())), + func->isDeclaration(), LLVMUtil::isIntrinsicFun(func), + func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo); svfModule->addFunctionSet(svfFunc); - if (ExtFun2Annotations.find(func) != ExtFun2Annotations.end()) - svfFunc->setAnnotations(ExtFun2Annotations[func]); + if (ExtFun2Annotations.find(func) != ExtFun2Annotations.end()) svfFunc->setAnnotations(ExtFun2Annotations[func]); addFunctionMap(func, svfFunc); for (const Argument& arg : func->args()) { - SVFArgument* svfarg = new SVFArgument( - getSVFType(arg.getType()), svfFunc, arg.getArgNo(), - LLVMUtil::isArgOfUncalledFunction(&arg)); + SVFArgument* svfarg = new SVFArgument(getSVFType(arg.getType()), svfFunc, arg.getArgNo(), + LLVMUtil::isArgOfUncalledFunction(&arg)); // Setting up arg name - if (!arg.hasName()) - svfarg->setName(std::to_string(arg.getArgNo())); + if (!arg.hasName()) svfarg->setName(std::to_string(arg.getArgNo())); svfFunc->addArgument(svfarg); addArgumentMap(&arg, svfarg); @@ -257,8 +245,7 @@ void LLVMModuleSet::createSVFFunction(const Function* func) for (const BasicBlock& bb : *func) { - SVFBasicBlock* svfBB = - new SVFBasicBlock(getSVFType(bb.getType()), svfFunc); + SVFBasicBlock* svfBB = new SVFBasicBlock(getSVFType(bb.getType()), svfFunc); svfFunc->addBasicBlock(svfBB); addBasicBlockMap(&bb, svfBB); for (const Instruction& inst : bb) @@ -267,22 +254,16 @@ void LLVMModuleSet::createSVFFunction(const Function* func) if (const CallBase* call = SVFUtil::dyn_cast(&inst)) { if (cppUtil::isVirtualCallSite(call)) - svfInst = new SVFVirtualCallInst( - getSVFType(call->getType()), svfBB, - call->getFunctionType()->isVarArg(), - inst.isTerminator()); + svfInst = new SVFVirtualCallInst(getSVFType(call->getType()), svfBB, + call->getFunctionType()->isVarArg(), inst.isTerminator()); else - svfInst = new SVFCallInst( - getSVFType(call->getType()), svfBB, - call->getFunctionType()->isVarArg(), - inst.isTerminator()); + svfInst = new SVFCallInst(getSVFType(call->getType()), svfBB, call->getFunctionType()->isVarArg(), + inst.isTerminator()); } else { - svfInst = - new SVFInstruction(getSVFType(inst.getType()), - svfBB, inst.isTerminator(), - SVFUtil::isa(inst)); + svfInst = new SVFInstruction(getSVFType(inst.getType()), svfBB, inst.isTerminator(), + SVFUtil::isa(inst)); } svfBB->addInstruction(svfInst); @@ -311,7 +292,7 @@ void LLVMModuleSet::initSVFFunction() void LLVMModuleSet::initSVFBasicBlock(const Function* func) { - SVFFunction *svfFun = getSVFFunction(func); + SVFFunction* svfFun = getSVFFunction(func); for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit) { const BasicBlock* bb = &*bit; @@ -339,7 +320,7 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func) for (BasicBlock::const_iterator iit = bb->begin(), eiit = bb->end(); iit != eiit; ++iit) { const Instruction* inst = &*iit; - if(const CallBase* call = SVFUtil::dyn_cast(inst)) + if (const CallBase* call = SVFUtil::dyn_cast(inst)) { SVFInstruction* svfinst = getSVFInstruction(call); SVFCallInst* svfcall = SVFUtil::cast(svfinst); @@ -354,13 +335,13 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func) { svfcall->setCalledOperand(getSVFValue(called_llvmval)); } - if(SVFVirtualCallInst* virtualCall = SVFUtil::dyn_cast(svfcall)) + if (SVFVirtualCallInst* virtualCall = SVFUtil::dyn_cast(svfcall)) { virtualCall->setVtablePtr(getSVFValue(cppUtil::getVCallVtblPtr(call))); virtualCall->setFunIdxInVtable(cppUtil::getVCallIdx(call)); virtualCall->setFunNameOfVirtualCall(cppUtil::getFunNameOfVCallSite(call)); } - for(u32_t i = 0; i < call->arg_size(); i++) + for (u32_t i = 0; i < call->arg_size(); i++) { SVFValue* svfval = getSVFValue(call->getArgOperand(i)); svfcall->addArgument(svfval); @@ -372,16 +353,14 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func) } // For no return functions, we set the last block as exit BB // This ensures that each function that has definition must have an exit BB - if(svfFun->exitBlock == nullptr && svfFun->hasBasicBlock()) svfFun->setExitBlock( - const_cast(svfFun->back())); + if (svfFun->exitBlock == nullptr && svfFun->hasBasicBlock()) + svfFun->setExitBlock(const_cast(svfFun->back())); } - void LLVMModuleSet::initDomTree(SVFFunction* svffun, const Function* fun) { - if (fun->isDeclaration()) - return; - //process and stored dt & df + if (fun->isDeclaration()) return; + // process and stored dt & df DominatorTree dt; DominanceFrontier df; dt.recalculate(const_cast(*fun)); @@ -390,13 +369,13 @@ void LLVMModuleSet::initDomTree(SVFFunction* svffun, const Function* fun) PostDominatorTree pdt = PostDominatorTree(const_cast(*fun)); SVFLoopAndDomInfo* ld = svffun->getLoopAndDomInfo(); - Map> & dfBBsMap = ld->getDomFrontierMap(); + Map>& dfBBsMap = ld->getDomFrontierMap(); for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++) { const BasicBlock* keyBB = dfIter->first; - const std::set& domSet = dfIter->second; + const std::set& domSet = dfIter->second; Set& valueBasicBlocks = dfBBsMap[getSVFBasicBlock(keyBB)]; - for (const BasicBlock* bbValue:domSet) + for (const BasicBlock* bbValue : domSet) { valueBasicBlocks.insert(getSVFBasicBlock(bbValue)); } @@ -405,9 +384,9 @@ void LLVMModuleSet::initDomTree(SVFFunction* svffun, const Function* fun) LLVMUtil::getFunReachableBBs(fun, reachableBBs); ld->setReachableBBs(reachableBBs); - for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit) + for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit != beit; ++bit) { - const BasicBlock &bb = *bit; + const BasicBlock& bb = *bit; SVFBasicBlock* svfBB = getSVFBasicBlock(&bb); if (DomTreeNode* dtNode = dt.getNode(&bb)) { @@ -424,7 +403,7 @@ void LLVMModuleSet::initDomTree(SVFFunction* svffun, const Function* fun) u32_t level = pdtNode->getLevel(); ld->getBBPDomLevel()[svfBB] = level; BasicBlock* idomBB = pdtNode->getIDom()->getBlock(); - const SVFBasicBlock* idom = idomBB == NULL ? NULL: getSVFBasicBlock(idomBB); + const SVFBasicBlock* idom = idomBB == NULL ? NULL : getSVFBasicBlock(idomBB); ld->getBB2PIdom()[svfBB] = idom; SVFLoopAndDomInfo::BBSet& bbSet = ld->getPostDomTreeMap()[svfBB]; @@ -446,7 +425,6 @@ void LLVMModuleSet::initDomTree(SVFFunction* svffun, const Function* fun) } } - /*! * Invoke llvm passes to modify module */ @@ -454,27 +432,25 @@ void LLVMModuleSet::prePassSchedule() { /// BreakConstantGEPs Pass std::unique_ptr p1 = std::make_unique(); - for (Module &M : getLLVMModules()) + for (Module& M : getLLVMModules()) { p1->runOnModule(M); } /// MergeFunctionRets Pass - std::unique_ptr p2 = - std::make_unique(); - for (Module &M : getLLVMModules()) + std::unique_ptr p2 = std::make_unique(); + for (Module& M : getLLVMModules()) { for (auto F = M.begin(), E = M.end(); F != E; ++F) { - Function &fun = *F; - if (fun.isDeclaration()) - continue; + Function& fun = *F; + if (fun.isDeclaration()) continue; p2->runOnFunction(fun); } } } -void LLVMModuleSet::preProcessBCs(std::vector &moduleNameVec) +void LLVMModuleSet::preProcessBCs(std::vector& moduleNameVec) { LLVMModuleSet* mset = getLLVMModuleSet(); mset->loadModules(moduleNameVec); @@ -495,18 +471,18 @@ void LLVMModuleSet::preProcessBCs(std::vector &moduleNameVec) releaseLLVMModuleSet(); } -void LLVMModuleSet::loadModules(const std::vector &moduleNameVec) +void LLVMModuleSet::loadModules(const std::vector& moduleNameVec) { // We read SVFIR from LLVM IR - if(Options::Graphtxt().empty()) + if (Options::Graphtxt().empty()) { - if(moduleNameVec.empty()) + if (moduleNameVec.empty()) { SVFUtil::outs() << "no LLVM bc file is found!\n"; exit(0); } - //assert(!moduleNameVec.empty() && "no LLVM bc file is found!"); + // assert(!moduleNameVec.empty() && "no LLVM bc file is found!"); } // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR else @@ -592,14 +568,16 @@ void LLVMModuleSet::loadExtAPIModules() Err.print("SVFModuleLoader", llvm::errs()); abort(); } - // The module of extapi.bc needs to be inserted before applications modules, like std::vector> modules{extapi_module, app_module}. - // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found. + // The module of extapi.bc needs to be inserted before applications modules, like + // std::vector> modules{extapi_module, app_module}. Otherwise, when overwriting + // the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be + // found. modules.insert(modules.begin(), *mod); - owned_modules.insert(owned_modules.begin(),std::move(mod)); + owned_modules.insert(owned_modules.begin(), std::move(mod)); } } -std::vector LLVMModuleSet::getLLVMGlobalFunctions(const GlobalVariable *global) +std::vector LLVMModuleSet::getLLVMGlobalFunctions(const GlobalVariable* global) { // This function is used to extract constructor and destructor functions // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors. @@ -618,7 +596,6 @@ std::vector LLVMModuleSet::getLLVMGlobalFunctions(const Global // function will only run if the associated data from the current module is // not discarded. However the associated data is currently ignored. - // This class is used for the priority queue that sorts the functions by // their priority. Each object of this class stands for an item in the // function array. @@ -627,10 +604,9 @@ std::vector LLVMModuleSet::getLLVMGlobalFunctions(const Global public: u32_t priority; const Function* func; - LLVMGlobalFunction() {}; - LLVMGlobalFunction(u32_t _priority, const Function* _func) - : priority(_priority), func(_func) {}; - bool operator>(const LLVMGlobalFunction &other) const + LLVMGlobalFunction(){}; + LLVMGlobalFunction(u32_t _priority, const Function* _func) : priority(_priority), func(_func){}; + bool operator>(const LLVMGlobalFunction& other) const { if (priority != other.priority) { @@ -643,37 +619,28 @@ std::vector LLVMModuleSet::getLLVMGlobalFunctions(const Global } }; - std::priority_queue, - greater> - queue; - std::vector result; + std::priority_queue, greater> queue; + std::vector result; // The @llvm.global_ctors/dtors global variable is an array of struct. Each // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}. // First get the array here. - if(const ConstantArray *globalFuncArray = - SVFUtil::dyn_cast(global->getInitializer())) + if (const ConstantArray* globalFuncArray = SVFUtil::dyn_cast(global->getInitializer())) { // Get each struct in the array. for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i) { - if ( - const ConstantStruct *globalFuncItem = - SVFUtil::dyn_cast( - globalFuncArray->getOperand(i))) + if (const ConstantStruct* globalFuncItem = + SVFUtil::dyn_cast(globalFuncArray->getOperand(i))) { // Extract priority and function from the struct - const ConstantInt* priority = SVFUtil::dyn_cast( - globalFuncItem->getOperand(0)); - const Function* func = SVFUtil::dyn_cast( - globalFuncItem->getOperand(1)); + const ConstantInt* priority = SVFUtil::dyn_cast(globalFuncItem->getOperand(0)); + const Function* func = SVFUtil::dyn_cast(globalFuncItem->getOperand(1)); if (priority && func) { - queue.push(LLVMGlobalFunction(priority - ->getZExtValue(), - func)); + queue.push(LLVMGlobalFunction(priority->getZExtValue(), func)); } } } @@ -695,7 +662,7 @@ void LLVMModuleSet::addSVFMain() Function* orgMain = 0; Module* mainMod = nullptr; - for (Module &mod : modules) + for (Module& mod : modules) { // Collect ctor and dtor functions for (const GlobalVariable& global : mod.globals()) @@ -711,7 +678,7 @@ void LLVMModuleSet::addSVFMain() } // Find main function - for (auto &func : mod) + for (auto& func : mod) { auto funName = func.getName(); @@ -727,8 +694,7 @@ void LLVMModuleSet::addSVFMain() // Only create svf.main when the original main function is found, and also // there are global constructor or destructor functions. - if (orgMain && getModuleNum() > 0 && - (ctor_funcs.size() > 0 || dtor_funcs.size() > 0)) + if (orgMain && getModuleNum() > 0 && (ctor_funcs.size() > 0 || dtor_funcs.size() > 0)) { assert(mainMod && "Module with main function not found."); Module& M = *mainMod; @@ -737,18 +703,12 @@ void LLVMModuleSet::addSVFMain() Type* i32 = IntegerType::getInt32Ty(M.getContext()); // define void @svf.main(i32, i8**, i8**) #if (LLVM_VERSION_MAJOR >= 9) - FunctionCallee svfmainFn = M.getOrInsertFunction( - SVF_MAIN_FUNC_NAME, - Type::getVoidTy(M.getContext()), - i32,ptr,ptr - ); + FunctionCallee svfmainFn = + M.getOrInsertFunction(SVF_MAIN_FUNC_NAME, Type::getVoidTy(M.getContext()), i32, ptr, ptr); Function* svfmain = SVFUtil::dyn_cast(svfmainFn.getCallee()); #else - Function* svfmain = SVFUtil::dyn_cast(M.getOrInsertFunction( - SVF_MAIN_FUNC_NAME, - Type::getVoidTy(M.getContext()), - i32,i8ptr2,i8ptr2 - )); + Function* svfmain = SVFUtil::dyn_cast( + M.getOrInsertFunction(SVF_MAIN_FUNC_NAME, Type::getVoidTy(M.getContext()), i32, i8ptr2, i8ptr2)); #endif svfmain->setCallingConv(llvm::CallingConv::C); BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain); @@ -757,10 +717,7 @@ void LLVMModuleSet::addSVFMain() // emitted in the order of priority for (auto& ctor : ctor_funcs) { - auto target = M.getOrInsertFunction( - ctor->getName(), - Type::getVoidTy(M.getContext()) - ); + auto target = M.getOrInsertFunction(ctor->getName(), Type::getVoidTy(M.getContext())); Builder.CreateCall(target); } // main() should be called after all ctor functions and before dtor @@ -784,32 +741,28 @@ void LLVMModuleSet::addSVFMain() void LLVMModuleSet::collectExtFunAnnotations(const Module* mod) { - GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations"); - if (glob == nullptr || !glob->hasInitializer()) - return; + GlobalVariable* glob = mod->getGlobalVariable("llvm.global.annotations"); + if (glob == nullptr || !glob->hasInitializer()) return; - ConstantArray *ca = SVFUtil::dyn_cast(glob->getInitializer()); - if (ca == nullptr) - return; + ConstantArray* ca = SVFUtil::dyn_cast(glob->getInitializer()); + if (ca == nullptr) return; for (unsigned i = 0; i < ca->getNumOperands(); ++i) { - ConstantStruct *structAn = SVFUtil::dyn_cast(ca->getOperand(i)); - if (structAn == nullptr || structAn->getNumOperands() == 0) - continue; + ConstantStruct* structAn = SVFUtil::dyn_cast(ca->getOperand(i)); + if (structAn == nullptr || structAn->getNumOperands() == 0) continue; // Check if the annotation is for a function Function* fun = nullptr; - GlobalVariable *annotateStr = nullptr; + GlobalVariable* annotateStr = nullptr; /// Non-opaque pointer - if (ConstantExpr *expr = SVFUtil::dyn_cast(structAn->getOperand(0))) + if (ConstantExpr* expr = SVFUtil::dyn_cast(structAn->getOperand(0))) { if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa(expr->getOperand(0))) fun = SVFUtil::cast(expr->getOperand(0)); - ConstantExpr *note = SVFUtil::cast(structAn->getOperand(1)); - if (note->getOpcode() != Instruction::GetElementPtr) - continue; + ConstantExpr* note = SVFUtil::cast(structAn->getOperand(1)); + if (note->getOpcode() != Instruction::GetElementPtr) continue; annotateStr = SVFUtil::dyn_cast(note->getOperand(0)); } @@ -820,22 +773,22 @@ void LLVMModuleSet::collectExtFunAnnotations(const Module* mod) annotateStr = SVFUtil::dyn_cast(structAn->getOperand(1)); } - if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer()) - continue;; + if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer()) continue; + ; - ConstantDataSequential *data = SVFUtil::dyn_cast(annotateStr->getInitializer()); + ConstantDataSequential* data = SVFUtil::dyn_cast(annotateStr->getInitializer()); if (data && data->isString()) { std::string annotation = data->getAsString().str(); - if (!annotation.empty()) - ExtFun2Annotations[fun].push_back(annotation); + if (!annotation.empty()) ExtFun2Annotations[fun].push_back(annotation); } } } /* - For a more detailed explanation of the Function declaration and definition mapping relationships and how External APIs are handled, - please refer to the SVF Wiki: https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c + For a more detailed explanation of the Function declaration and definition mapping relationships and how External + APIs are handled, please refer to the SVF Wiki: + https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c Table 1 | ------- | ----------------- | --------------- | ----------------- | ----------- | @@ -850,10 +803,11 @@ void LLVMModuleSet::collectExtFunAnnotations(const Module* mod) | ExtDecl | FunDeclToDefMap | X | X | ExtFuncsVec | | ------- | ----------------- | --------------- | ----------------- | ----------- | - When a user wants to use functions in extapi.c to overwrite the functions defined in the app code, two relationships, "AppDef -> ExtDef" and "ExtDef -> AppDef," are used. - Use Ext function definition to override the App function definition (Ext function with "__attribute__((annotate("OVERWRITE")))" in extapi.c). - The app function definition will be changed to an app function declaration. - Then, put the app function declaration and its corresponding Ext function definition into FunDeclToDefMap/FunDefToDeclsMap. + When a user wants to use functions in extapi.c to overwrite the functions defined in the app code, two + relationships, "AppDef -> ExtDef" and "ExtDef -> AppDef," are used. Use Ext function definition to override the App + function definition (Ext function with "__attribute__((annotate("OVERWRITE")))" in extapi.c). The app function + definition will be changed to an app function declaration. Then, put the app function declaration and its + corresponding Ext function definition into FunDeclToDefMap/FunDefToDeclsMap. ------------------------------------------------------ AppDef -> ExtDef (overwrite): For example, @@ -883,7 +837,8 @@ void LLVMModuleSet::collectExtFunAnnotations(const Module* mod) are put into FunDefToDeclsMap; ------------------------------------------------------ In principle, all functions in extapi.c have bodies (definitions), but some functions (those starting with "sse_") - have only function declarations without definitions. ExtFuncsVec is used to record function declarations starting with "sse_" that are used. + have only function declarations without definitions. ExtFuncsVec is used to record function declarations starting + with "sse_" that are used. ExtDecl -> ExtDecl: For example, @@ -933,12 +888,9 @@ void LLVMModuleSet::buildFunToFunMap() { std::vector annotations = ExtFun2Annotations[&fun]; auto it = - std::find_if(annotations.begin(), annotations.end(), - [&](const std::string& annotation) - { - return annotation.find("OVERWRITE") != - std::string::npos; - }); + std::find_if(annotations.begin(), annotations.end(), [&](const std::string& annotation) { + return annotation.find("OVERWRITE") != std::string::npos; + }); if (it != annotations.end()) { overwriteExtFuncs.insert(&fun); @@ -966,9 +918,8 @@ void LLVMModuleSet::buildFunToFunMap() } } // Find the intersectNames - std::set_intersection( - declNames.begin(), declNames.end(), defNames.begin(), defNames.end(), - std::inserter(intersectNames, intersectNames.end())); + std::set_intersection(declNames.begin(), declNames.end(), defNames.begin(), defNames.end(), + std::inserter(intersectNames, intersectNames.end())); ///// name to def map NameToFunDefMapTy nameToFunDefMap; @@ -1000,7 +951,7 @@ void LLVMModuleSet::buildFunToFunMap() string funName = fdecl->getName().str(); NameToFunDefMapTy::iterator mit; if (intersectNames.find(funName) != intersectNames.end() && - (mit = nameToFunDefMap.find(funName)) != nameToFunDefMap.end()) + (mit = nameToFunDefMap.find(funName)) != nameToFunDefMap.end()) { FunDeclToDefMap[fdecl] = mit->second; } @@ -1010,11 +961,9 @@ void LLVMModuleSet::buildFunToFunMap() for (const Function* fdef : funDefs) { string funName = fdef->getName().str(); - if (intersectNames.find(funName) == intersectNames.end()) - continue; + if (intersectNames.find(funName) == intersectNames.end()) continue; NameToFunDeclsMapTy::iterator mit = nameToFunDeclsMap.find(funName); - if (mit == nameToFunDeclsMap.end()) - continue; + if (mit == nameToFunDeclsMap.end()) continue; std::vector& decls = FunDefToDeclsMap[fdef]; const auto& declsSet = mit->second; @@ -1065,14 +1014,14 @@ void LLVMModuleSet::buildFunToFunMap() // (1) The types are exactly the same, // (2) Both are pointer types, and at least one of them is a void*. // Note that getPointerElementType() will be deprecated in the future versions of LLVM. - // Considering compatibility, avoid using getPointerElementType()->isIntegerTy(8) to determine if it is a void * type. + // Considering compatibility, avoid using getPointerElementType()->isIntegerTy(8) to determine if it is + // a void * type. if (!(returnType1 == returnType2 || (returnType1->isPointerTy() && returnType2->isPointerTy()))) { continue; } - if (appfunc->arg_size() != owfunc->arg_size()) - continue; + if (appfunc->arg_size() != owfunc->arg_size()) continue; bool argMismatch = false; Function::const_arg_iterator argIter1 = appfunc->arg_begin(); @@ -1082,7 +1031,8 @@ void LLVMModuleSet::buildFunToFunMap() Type* argType1 = argIter1->getType(); Type* argType2 = argIter2->getType(); - // Check if the parameters types are compatible: (1) The types are exactly the same, (2) Both are pointer types, and at least one of them is a void*. + // Check if the parameters types are compatible: (1) The types are exactly the same, (2) Both are + // pointer types, and at least one of them is a void*. if (!(argType1 == argType2 || (argType1->isPointerTy() && argType2->isPointerTy()))) { argMismatch = true; @@ -1091,8 +1041,7 @@ void LLVMModuleSet::buildFunToFunMap() argIter1++; argIter2++; } - if (argMismatch) - continue; + if (argMismatch) continue; Function* fun = const_cast(appfunc); Module* mod = fun->getParent(); @@ -1122,36 +1071,28 @@ void LLVMModuleSet::buildGlobalDefToRepMap() { typedef Map> NameToGlobalsMapTy; NameToGlobalsMapTy nameToGlobalsMap; - for (Module &mod : modules) + for (Module& mod : modules) { // Collect ctor and dtor functions for (GlobalVariable& global : mod.globals()) { - if (global.hasPrivateLinkage()) - continue; + if (global.hasPrivateLinkage()) continue; string name = global.getName().str(); - if (name.empty()) - continue; + if (name.empty()) continue; nameToGlobalsMap[std::move(name)].insert(&global); } } for (const auto& pair : nameToGlobalsMap) { - const Set &globals = pair.second; + const Set& globals = pair.second; const auto repIt = - std::find_if(globals.begin(), globals.end(), - [](GlobalVariable* g) - { - return g->hasInitializer(); - }); - GlobalVariable* rep = - repIt != globals.end() - ? *repIt - // When there is no initializer, just pick the first one. - : (assert(!globals.empty() && "Empty global set"), - *globals.begin()); + std::find_if(globals.begin(), globals.end(), [](GlobalVariable* g) { return g->hasInitializer(); }); + GlobalVariable* rep = repIt != globals.end() + ? *repIt + // When there is no initializer, just pick the first one. + : (assert(!globals.empty() && "Empty global set"), *globals.begin()); for (const GlobalVariable* cur : globals) { @@ -1165,8 +1106,7 @@ void LLVMModuleSet::removeUnusedExtAPIs() Set removedFuncList; for (Module& mod : modules) { - if (mod.getName().str() != ExtAPI::getExtAPI()->getExtBcPath()) - continue; + if (mod.getName().str() != ExtAPI::getExtAPI()->getExtBcPath()) continue; for (Function& func : mod.functions()) { if (isCalledExtFunction(&func)) @@ -1187,8 +1127,7 @@ void LLVMModuleSet::dumpModulesToFile(const std::string& suffix) std::string moduleName = mod.getName().str(); std::string OutputFilename; std::size_t pos = moduleName.rfind('.'); - if (pos != std::string::npos) - OutputFilename = moduleName.substr(0, pos) + suffix; + if (pos != std::string::npos) OutputFilename = moduleName.substr(0, pos) + suffix; else OutputFilename = moduleName + suffix; @@ -1209,12 +1148,9 @@ void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue) { SVFValue2LLVMValue[svfvalue] = val; - if(val->hasName()) - svfvalue->setName(val->getName().str()); - if (LLVMUtil::isPtrInUncalledFunction(val)) - svfvalue->setPtrInUncalledFunction(); - if (LLVMUtil::isConstDataOrAggData(val)) - svfvalue->setConstDataOrAggData(); + if (val->hasName()) svfvalue->setName(val->getName().str()); + if (LLVMUtil::isPtrInUncalledFunction(val)) svfvalue->setPtrInUncalledFunction(); + if (LLVMUtil::isConstDataOrAggData(val)) svfvalue->setConstDataOrAggData(); if (SVFGlobalValue* glob = SVFUtil::dyn_cast(svfvalue)) { @@ -1236,7 +1172,7 @@ void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue) SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd) { LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(cd); - if(it!=LLVMConst2SVFConst.end()) + if (it != LLVMConst2SVFConst.end()) { assert(SVFUtil::isa(it->second) && "not a SVFConstantData type!"); return SVFUtil::cast(it->second); @@ -1244,36 +1180,34 @@ SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd) else { SVFConstantData* svfcd = nullptr; - if(const ConstantInt* cint = SVFUtil::dyn_cast(cd)) + if (const ConstantInt* cint = SVFUtil::dyn_cast(cd)) { - /// bitwidth == 1 : cint has value from getZExtValue() because `bool true` will be translated to -1 using sign extension (i.e., getSExtValue). - /// bitwidth <=64 1 : cint has value from getSExtValue() - /// bitwidth >64 1 : cint has value 0 because it represents an invalid int - if(cint->getBitWidth() == 1) + /// bitwidth == 1 : cint has value from getZExtValue() because `bool true` will be translated to -1 using + /// sign extension (i.e., getSExtValue). bitwidth <=64 1 : cint has value from getSExtValue() bitwidth >64 1 + /// : cint has value 0 because it represents an invalid int + if (cint->getBitWidth() == 1) svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getZExtValue()); - else if(cint->getBitWidth() <= 64 && cint->getBitWidth() > 1) + else if (cint->getBitWidth() <= 64 && cint->getBitWidth() > 1) svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getSExtValue()); else svfcd = new SVFConstantInt(getSVFType(cint->getType()), 0, 0); } - else if(const ConstantFP* cfp = SVFUtil::dyn_cast(cd)) + else if (const ConstantFP* cfp = SVFUtil::dyn_cast(cd)) { double dval = 0; // TODO: Why only double is considered? What about float? if (cfp->isNormalFP()) { const llvm::fltSemantics& semantics = cfp->getValueAPF().getSemantics(); - if (&semantics == &llvm::APFloat::IEEEhalf() || - &semantics == &llvm::APFloat::IEEEsingle() || - &semantics == &llvm::APFloat::IEEEdouble() || - &semantics == &llvm::APFloat::IEEEquad() || - &semantics == &llvm::APFloat::x87DoubleExtended()) + if (&semantics == &llvm::APFloat::IEEEhalf() || &semantics == &llvm::APFloat::IEEEsingle() || + &semantics == &llvm::APFloat::IEEEdouble() || &semantics == &llvm::APFloat::IEEEquad() || + &semantics == &llvm::APFloat::x87DoubleExtended()) { dval = cfp->getValueAPF().convertToDouble(); } else { - assert (false && "Unsupported floating point type"); + assert(false && "Unsupported floating point type"); abort(); } } @@ -1284,16 +1218,15 @@ SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd) } svfcd = new SVFConstantFP(getSVFType(cd->getType()), dval); } - else if(SVFUtil::isa(cd)) + else if (SVFUtil::isa(cd)) svfcd = new SVFConstantNullPtr(getSVFType(cd->getType())); else if (SVFUtil::isa(cd)) svfcd = new SVFBlackHoleValue(getSVFType(cd->getType())); else svfcd = new SVFConstantData(getSVFType(cd->getType())); - svfModule->addConstant(svfcd); - addConstantDataMap(cd,svfcd); + addConstantDataMap(cd, svfcd); return svfcd; } } @@ -1301,7 +1234,7 @@ SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd) SVFConstant* LLVMModuleSet::getOtherSVFConstant(const Constant* oc) { LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(oc); - if(it!=LLVMConst2SVFConst.end()) + if (it != LLVMConst2SVFConst.end()) { return it->second; } @@ -1309,7 +1242,7 @@ SVFConstant* LLVMModuleSet::getOtherSVFConstant(const Constant* oc) { SVFConstant* svfoc = new SVFConstant(getSVFType(oc->getType())); svfModule->addConstant(svfoc); - addOtherConstantMap(oc,svfoc); + addOtherConstantMap(oc, svfoc); return svfoc; } } @@ -1317,36 +1250,32 @@ SVFConstant* LLVMModuleSet::getOtherSVFConstant(const Constant* oc) SVFOtherValue* LLVMModuleSet::getSVFOtherValue(const Value* ov) { LLVMValue2SVFOtherValueMap::const_iterator it = LLVMValue2SVFOtherValue.find(ov); - if(it!=LLVMValue2SVFOtherValue.end()) + if (it != LLVMValue2SVFOtherValue.end()) { return it->second; } else { - SVFOtherValue* svfov = - SVFUtil::isa(ov) - ? new SVFMetadataAsValue(getSVFType(ov->getType())) - : new SVFOtherValue(getSVFType(ov->getType())); + SVFOtherValue* svfov = SVFUtil::isa(ov) ? new SVFMetadataAsValue(getSVFType(ov->getType())) + : new SVFOtherValue(getSVFType(ov->getType())); svfModule->addOtherValue(svfov); - addOtherValueMap(ov,svfov); + addOtherValueMap(ov, svfov); return svfov; } } SVFValue* LLVMModuleSet::getSVFValue(const Value* value) { - if (const Function* fun = SVFUtil::dyn_cast(value)) - return getSVFFunction(fun); + if (const Function* fun = SVFUtil::dyn_cast(value)) return getSVFFunction(fun); else if (const BasicBlock* bb = SVFUtil::dyn_cast(value)) return getSVFBasicBlock(bb); - else if(const Instruction* inst = SVFUtil::dyn_cast(value)) + else if (const Instruction* inst = SVFUtil::dyn_cast(value)) return getSVFInstruction(inst); else if (const Argument* arg = SVFUtil::dyn_cast(value)) return getSVFArgument(arg); else if (const Constant* cons = SVFUtil::dyn_cast(value)) { - if (const ConstantData* cd = SVFUtil::dyn_cast(cons)) - return getSVFConstantData(cd); + if (const ConstantData* cd = SVFUtil::dyn_cast(cons)) return getSVFConstantData(cd); else if (const GlobalValue* glob = SVFUtil::dyn_cast(cons)) return getSVFGlobalValue(glob); else @@ -1358,10 +1287,10 @@ SVFValue* LLVMModuleSet::getSVFValue(const Value* value) const Type* LLVMModuleSet::getLLVMType(const SVFType* T) const { - for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it) + for (LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it != eit; + ++it) { - if (it->second == T) - return it->first; + if (it->second == T) return it->first; } assert(false && "can't find the corresponding LLVM Type"); abort(); @@ -1374,8 +1303,7 @@ SVFType* LLVMModuleSet::getSVFType(const Type* T) { assert(T && "SVFType should not be null"); LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T); - if (it != LLVMType2SVFType.end()) - return it->second; + if (it != LLVMType2SVFType.end()) return it->second; SVFType* svfType = addSVFTypeInfo(T); StInfo* stinfo = collectTypeInfo(T); @@ -1417,16 +1345,14 @@ StInfo* LLVMModuleSet::collectTypeInfo(const Type* T) SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T) { - assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() && - "SVFType has been added before"); + assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() && "SVFType has been added before"); // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value) u32_t byteSize = 1; if (T->isSized()) { - const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()-> - getMainLLVMModule()->getDataLayout(); - Type *mut_T = const_cast(T); + const llvm::DataLayout& DL = LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule()->getDataLayout(); + Type* mut_T = const_cast(T); byteSize = DL.getTypeAllocSize(mut_T); } @@ -1448,8 +1374,7 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T) else if (const StructType* st = SVFUtil::dyn_cast(T)) { auto svfst = new SVFStructType(byteSize); - if (st->hasName()) - svfst->setName(st->getName().str()); + if (st->hasName()) svfst->setName(st->getName().str()); svftype = svfst; } else if (const auto at = SVFUtil::dyn_cast(T)) @@ -1529,8 +1454,7 @@ StInfo* LLVMModuleSet::collectArrayInfo(const ArrayType* ty) } } - assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum && - "typeForArray size incorrect!!!"); + assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum && "typeForArray size incorrect!!!"); stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum); return stInfo; @@ -1540,8 +1464,7 @@ StInfo* LLVMModuleSet::collectArrayInfo(const ArrayType* ty) * Fill in struct_info for T. * Given a Struct type, we recursively extend and record its fields and types. */ -StInfo* LLVMModuleSet::collectStructInfo(const StructType* structTy, - u32_t& numFields) +StInfo* LLVMModuleSet::collectStructInfo(const StructType* structTy, u32_t& numFields) { /// The struct info should not be processed before StInfo* stInfo = new StInfo(1); @@ -1574,7 +1497,6 @@ StInfo* LLVMModuleSet::collectStructInfo(const StructType* structTy, const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj]; stInfo->getFlattenElementTypes().push_back(ty); } - } else { @@ -1586,14 +1508,12 @@ StInfo* LLVMModuleSet::collectStructInfo(const StructType* structTy, } } - assert(stInfo->getFlattenElementTypes().size() == strideOffset && - "typeForStruct size incorrect!"); - stInfo->setNumOfFieldsAndElems(numFields,strideOffset); + assert(stInfo->getFlattenElementTypes().size() == strideOffset && "typeForStruct size incorrect!"); + stInfo->setNumOfFieldsAndElems(numFields, strideOffset); return stInfo; } - /*! * Collect simple type (non-aggregate) info */ @@ -1606,7 +1526,7 @@ StInfo* LLVMModuleSet::collectSimpleTypeInfo(const Type* ty) stInfo->getFlattenFieldTypes().push_back(svfType); stInfo->getFlattenElementTypes().push_back(svfType); - stInfo->setNumOfFieldsAndElems(1,1); + stInfo->setNumOfFieldsAndElems(1, 1); return stInfo; } diff --git a/svf-llvm/lib/LLVMUtil.cpp b/svf-llvm/lib/LLVMUtil.cpp index e2b6b5dd5..17cc79098 100644 --- a/svf-llvm/lib/LLVMUtil.cpp +++ b/svf-llvm/lib/LLVMUtil.cpp @@ -33,13 +33,11 @@ #include #include "SVF-LLVM/LLVMModule.h" - using namespace SVF; const Function* LLVMUtil::getDefFunForMultipleModule(const Function* fun) { - if (fun == nullptr) - return nullptr; + if (fun == nullptr) return nullptr; LLVMModuleSet* llvmModuleset = LLVMModuleSet::getLLVMModuleSet(); if (fun->isDeclaration() && llvmModuleset->hasDefinition(fun)) fun = LLVMModuleSet::getLLVMModuleSet()->getDefinition(fun); @@ -52,8 +50,7 @@ const Function* LLVMUtil::getProgFunction(const std::string& funName) { for (const Function& fun : M) { - if (fun.getName() == funName) - return &fun; + if (fun.getName() == funName) return &fun; } } return nullptr; @@ -66,14 +63,14 @@ const Function* LLVMUtil::getProgFunction(const std::string& funName) * 3) stack * 4) heap */ -bool LLVMUtil::isObject(const Value* ref) +bool LLVMUtil::isObject(const Value* ref) { - if (SVFUtil::isa(ref) && SVFUtil::isHeapAllocExtCallViaRet(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast(ref)))) - return true; - if (SVFUtil::isa(ref)) - return true; - if (SVFUtil::isa(ref)) + if (SVFUtil::isa(ref) && + SVFUtil::isHeapAllocExtCallViaRet( + LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast(ref)))) return true; + if (SVFUtil::isa(ref)) return true; + if (SVFUtil::isa(ref)) return true; return false; } @@ -81,30 +78,29 @@ bool LLVMUtil::isObject(const Value* ref) /*! * Return reachable bbs from function entry */ -void LLVMUtil::getFunReachableBBs (const Function* fun, std::vector &reachableBBs) +void LLVMUtil::getFunReachableBBs(const Function* fun, std::vector& reachableBBs) { - assert(!SVFUtil::isExtCall(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)) && "The calling function cannot be an external function."); - //initial DominatorTree + assert(!SVFUtil::isExtCall(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)) && + "The calling function cannot be an external function."); + // initial DominatorTree DominatorTree dt; dt.recalculate(const_cast(*fun)); Set visited; std::vector bbVec; bbVec.push_back(&fun->getEntryBlock()); - while(!bbVec.empty()) + while (!bbVec.empty()) { const BasicBlock* bb = bbVec.back(); bbVec.pop_back(); const SVFBasicBlock* svfbb = LLVMModuleSet::getLLVMModuleSet()->getSVFBasicBlock(bb); reachableBBs.push_back(svfbb); - if(DomTreeNode *dtNode = dt.getNode(const_cast(bb))) + if (DomTreeNode* dtNode = dt.getNode(const_cast(bb))) { - for (DomTreeNode::iterator DI = dtNode->begin(), DE = dtNode->end(); - DI != DE; ++DI) + for (DomTreeNode::iterator DI = dtNode->begin(), DE = dtNode->end(); DI != DE; ++DI) { const BasicBlock* succbb = (*DI)->getBlock(); - if(visited.find(succbb)==visited.end()) - visited.insert(succbb); + if (visited.find(succbb) == visited.end()) visited.insert(succbb); else continue; bbVec.push_back(succbb); @@ -118,11 +114,9 @@ void LLVMUtil::getFunReachableBBs (const Function* fun, std::vectorbegin(), eit = bb->end(); - it != eit; ++it) + for (BasicBlock::const_iterator it = bb->begin(), eit = bb->end(); it != eit; ++it) { - if(SVFUtil::isa(*it)) - return true; + if (SVFUtil::isa(*it)) return true; } return false; } @@ -130,7 +124,7 @@ bool LLVMUtil::basicBlockHasRetInst(const BasicBlock* bb) /*! * Return true if the function has a return instruction reachable from function entry */ -bool LLVMUtil::functionDoesNotRet(const Function* fun) +bool LLVMUtil::functionDoesNotRet(const Function* fun) { const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun); if (SVFUtil::isExtCall(svffun)) @@ -140,7 +134,7 @@ bool LLVMUtil::functionDoesNotRet(const Function* fun) std::vector bbVec; Set visited; bbVec.push_back(&fun->getEntryBlock()); - while(!bbVec.empty()) + while (!bbVec.empty()) { const BasicBlock* bb = bbVec.back(); bbVec.pop_back(); @@ -149,12 +143,10 @@ bool LLVMUtil::functionDoesNotRet(const Function* fun) return false; } - for (succ_const_iterator sit = succ_begin(bb), esit = succ_end(bb); - sit != esit; ++sit) + for (succ_const_iterator sit = succ_begin(bb), esit = succ_end(bb); sit != esit; ++sit) { const BasicBlock* succbb = (*sit); - if(visited.find(succbb)==visited.end()) - visited.insert(succbb); + if (visited.find(succbb) == visited.end()) visited.insert(succbb); else continue; bbVec.push_back(succbb); @@ -166,30 +158,24 @@ bool LLVMUtil::functionDoesNotRet(const Function* fun) /*! * Return true if this is a function without any possible caller */ -bool LLVMUtil::isUncalledFunction (const Function* fun) +bool LLVMUtil::isUncalledFunction(const Function* fun) { - if(fun->hasAddressTaken()) - return false; - if (LLVMUtil::isProgEntryFunction(fun)) - return false; + if (fun->hasAddressTaken()) return false; + if (LLVMUtil::isProgEntryFunction(fun)) return false; for (Value::const_user_iterator i = fun->user_begin(), e = fun->user_end(); i != e; ++i) { - if (LLVMUtil::isCallSite(*i)) - return false; + if (LLVMUtil::isCallSite(*i)) return false; } if (LLVMModuleSet::getLLVMModuleSet()->hasDeclaration(fun)) { - const LLVMModuleSet::FunctionSetType &decls = LLVMModuleSet::getLLVMModuleSet()->getDeclaration(fun); - for (LLVMModuleSet::FunctionSetType::const_iterator it = decls.begin(), - eit = decls.end(); it != eit; ++it) + const LLVMModuleSet::FunctionSetType& decls = LLVMModuleSet::getLLVMModuleSet()->getDeclaration(fun); + for (LLVMModuleSet::FunctionSetType::const_iterator it = decls.begin(), eit = decls.end(); it != eit; ++it) { const Function* decl = *it; - if(decl->hasAddressTaken()) - return false; + if (decl->hasAddressTaken()) return false; for (Value::const_user_iterator i = decl->user_begin(), e = decl->user_end(); i != e; ++i) { - if (LLVMUtil::isCallSite(*i)) - return false; + if (LLVMUtil::isCallSite(*i)) return false; } } } @@ -199,27 +185,25 @@ bool LLVMUtil::isUncalledFunction (const Function* fun) /*! * Return true if this is a value in a dead function (function without any caller) */ -bool LLVMUtil::isPtrInUncalledFunction (const Value* value) +bool LLVMUtil::isPtrInUncalledFunction(const Value* value) { - if(const Instruction* inst = SVFUtil::dyn_cast(value)) + if (const Instruction* inst = SVFUtil::dyn_cast(value)) { - if(isUncalledFunction(inst->getParent()->getParent())) - return true; + if (isUncalledFunction(inst->getParent()->getParent())) return true; } - else if(const Argument* arg = SVFUtil::dyn_cast(value)) + else if (const Argument* arg = SVFUtil::dyn_cast(value)) { - if(isUncalledFunction(arg->getParent())) - return true; + if (isUncalledFunction(arg->getParent())) return true; } return false; } bool LLVMUtil::isIntrinsicFun(const Function* func) { - if (func && (func->getIntrinsicID() == llvm::Intrinsic::donothing || - func->getIntrinsicID() == llvm::Intrinsic::dbg_declare || - func->getIntrinsicID() == llvm::Intrinsic::dbg_label || - func->getIntrinsicID() == llvm::Intrinsic::dbg_value)) + if (func && + (func->getIntrinsicID() == llvm::Intrinsic::donothing || + func->getIntrinsicID() == llvm::Intrinsic::dbg_declare || + func->getIntrinsicID() == llvm::Intrinsic::dbg_label || func->getIntrinsicID() == llvm::Intrinsic::dbg_value)) { return true; } @@ -245,12 +229,10 @@ bool LLVMUtil::isIntrinsicInst(const Instruction* inst) */ const Value* LLVMUtil::stripConstantCasts(const Value* val) { - if (SVFUtil::isa(val) || isInt2PtrConstantExpr(val)) - return val; - else if (const ConstantExpr *CE = SVFUtil::dyn_cast(val)) + if (SVFUtil::isa(val) || isInt2PtrConstantExpr(val)) return val; + else if (const ConstantExpr* CE = SVFUtil::dyn_cast(val)) { - if (Instruction::isCast(CE->getOpcode())) - return stripConstantCasts(CE->getOperand(0)); + if (Instruction::isCast(CE->getOpcode())) return stripConstantCasts(CE->getOperand(0)); } return val; } @@ -274,18 +256,17 @@ void LLVMUtil::viewCFGOnly(const Function* fun) /*! * Strip all casts */ -const Value* LLVMUtil::stripAllCasts(const Value* val) +const Value* LLVMUtil::stripAllCasts(const Value* val) { while (true) { - if (const CastInst *ci = SVFUtil::dyn_cast(val)) + if (const CastInst* ci = SVFUtil::dyn_cast(val)) { val = ci->getOperand(0); } - else if (const ConstantExpr *ce = SVFUtil::dyn_cast(val)) + else if (const ConstantExpr* ce = SVFUtil::dyn_cast(val)) { - if(ce->isCast()) - val = ce->getOperand(0); + if (ce->isCast()) val = ce->getOperand(0); else return val; } @@ -304,8 +285,7 @@ void LLVMUtil::getNextInsts(const Instruction* curInst, std::vectorgetNextNode(); const SVFInstruction* svfNextInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(nextInst); - if (LLVMUtil::isIntrinsicInst(nextInst)) - getNextInsts(nextInst, instList); + if (LLVMUtil::isIntrinsicInst(nextInst)) getNextInsts(nextInst, instList); else instList.push_back(svfNextInst); } @@ -317,15 +297,13 @@ void LLVMUtil::getNextInsts(const Instruction* curInst, std::vectorfront()); const SVFInstruction* svfNextInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(nextInst); - if (LLVMUtil::isIntrinsicInst(nextInst)) - getNextInsts(nextInst, instList); + if (LLVMUtil::isIntrinsicInst(nextInst)) getNextInsts(nextInst, instList); else instList.push_back(svfNextInst); } } } - /// Get the previous instructions following control flow void LLVMUtil::getPrevInsts(const Instruction* curInst, std::vector& instList) { @@ -334,8 +312,7 @@ void LLVMUtil::getPrevInsts(const Instruction* curInst, std::vectorgetPrevNode(); const SVFInstruction* svfPrevInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(prevInst); - if (LLVMUtil::isIntrinsicInst(prevInst)) - getPrevInsts(prevInst, instList); + if (LLVMUtil::isIntrinsicInst(prevInst)) getPrevInsts(prevInst, instList); else instList.push_back(svfPrevInst); } @@ -347,8 +324,7 @@ void LLVMUtil::getPrevInsts(const Instruction* curInst, std::vectorback()); const SVFInstruction* svfPrevInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(prevInst); - if (LLVMUtil::isIntrinsicInst(prevInst)) - getPrevInsts(prevInst, instList); + if (LLVMUtil::isIntrinsicInst(prevInst)) getPrevInsts(prevInst, instList); else instList.push_back(svfPrevInst); } @@ -364,11 +340,10 @@ const Value* LLVMUtil::getFirstUseViaCastInst(const Value* val) { assert(SVFUtil::isa(val->getType()) && "this value should be a pointer type!"); /// If type is void* (i8*) and val is immediately used at a bitcast instruction - const Value *latestUse = nullptr; - for (const auto &it : val->uses()) + const Value* latestUse = nullptr; + for (const auto& it : val->uses()) { - if (SVFUtil::isa(it.getUser())) - latestUse = it.getUser(); + if (SVFUtil::isa(it.getUser())) latestUse = it.getUser(); else latestUse = nullptr; } @@ -384,7 +359,7 @@ u32_t LLVMUtil::getNumOfElements(const Type* ety) u32_t numOfFields = 1; if (SVFUtil::isa(ety)) { - if(Options::ModelArrays()) + if (Options::ModelArrays()) return LLVMModuleSet::getLLVMModuleSet()->getSVFType(ety)->getTypeInfo()->getNumOfFlattenElements(); else return LLVMModuleSet::getLLVMModuleSet()->getSVFType(ety)->getTypeInfo()->getNumOfFlattenFields(); @@ -398,8 +373,7 @@ u32_t LLVMUtil::getNumOfElements(const Type* ety) u32_t LLVMUtil::getBBPredecessorNum(const BasicBlock* BB) { u32_t num = 0; - for (const_pred_iterator it = pred_begin(BB), et = pred_end(BB); it != et; ++it) - num++; + for (const_pred_iterator it = pred_begin(BB), et = pred_end(BB); it != et; ++it) num++; return num; } @@ -408,7 +382,7 @@ u32_t LLVMUtil::getBBPredecessorNum(const BasicBlock* BB) * llvm::parseIRFile (lib/IRReader/IRReader.cpp) * llvm::parseIR (lib/IRReader/IRReader.cpp) */ -bool LLVMUtil::isIRFile(const std::string &filename) +bool LLVMUtil::isIRFile(const std::string& filename) { llvm::LLVMContext context; llvm::SMDiagnostic err; @@ -426,11 +400,10 @@ bool LLVMUtil::isIRFile(const std::string &filename) return true; // It is an LLVM IR file } - /// Get the names of all modules into a vector /// And process arguments -void LLVMUtil::processArguments(int argc, char **argv, int &arg_num, char **arg_value, - std::vector &moduleNameVec) +void LLVMUtil::processArguments(int argc, char** argv, int& arg_num, char** arg_value, + std::vector& moduleNameVec) { bool first_ir_file = true; for (int i = 0; i < argc; ++i) @@ -438,8 +411,7 @@ void LLVMUtil::processArguments(int argc, char **argv, int &arg_num, char **arg_ std::string argument(argv[i]); if (LLVMUtil::isIRFile(argument)) { - if (find(moduleNameVec.begin(), moduleNameVec.end(), argument) - == moduleNameVec.end()) + if (find(moduleNameVec.begin(), moduleNameVec.end(), argument) == moduleNameVec.end()) moduleNameVec.push_back(argument); if (first_ir_file) { @@ -458,24 +430,20 @@ void LLVMUtil::processArguments(int argc, char **argv, int &arg_num, char **arg_ void LLVMUtil::removeFunAnnotations(Set& removedFuncList) { - if (removedFuncList.empty()) - return; // No functions to remove annotations in extapi.bc module + if (removedFuncList.empty()) return; // No functions to remove annotations in extapi.bc module Module* module = (*removedFuncList.begin())->getParent(); GlobalVariable* glob = module->getGlobalVariable("llvm.global.annotations"); - if (glob == nullptr || !glob->hasInitializer()) - return; + if (glob == nullptr || !glob->hasInitializer()) return; ConstantArray* ca = SVFUtil::dyn_cast(glob->getInitializer()); - if (ca == nullptr) - return; + if (ca == nullptr) return; std::vector newAnnotations; for (unsigned i = 0; i < ca->getNumOperands(); ++i) { ConstantStruct* structAn = SVFUtil::dyn_cast(ca->getOperand(i)); - if (structAn == nullptr) - continue; + if (structAn == nullptr) continue; Function* annotatedFunc = nullptr; @@ -495,20 +463,21 @@ void LLVMUtil::removeFunAnnotations(Set& removedFuncList) } // Process the annotated function if it's not in the removed list - if (annotatedFunc && std::find(removedFuncList.begin(), removedFuncList.end(), annotatedFunc) == removedFuncList.end()) + if (annotatedFunc && + std::find(removedFuncList.begin(), removedFuncList.end(), annotatedFunc) == removedFuncList.end()) { newAnnotations.push_back(structAn); } } - if (newAnnotations.size() == ca->getNumOperands()) - return; // No annotations to remove + if (newAnnotations.size() == ca->getNumOperands()) return; // No annotations to remove ArrayType* annotationsType = ArrayType::get(ca->getType()->getElementType(), newAnnotations.size()); Constant* newCA = ConstantArray::get(annotationsType, newAnnotations); glob->setName("llvm.global.annotations.old"); - GlobalVariable *GV = new GlobalVariable(newCA->getType(), glob->isConstant(), glob->getLinkage(), newCA, "llvm.global.annotations"); + GlobalVariable* GV = + new GlobalVariable(newCA->getType(), glob->isConstant(), glob->getLinkage(), newCA, "llvm.global.annotations"); GV->setSection(glob->getSection()); #if (LLVM_VERSION_MAJOR < 17) @@ -524,19 +493,20 @@ void LLVMUtil::removeFunAnnotations(Set& removedFuncList) } /// Get all called funcions in a parent function -std::vector LLVMUtil::getCalledFunctions(const Function *F) +std::vector LLVMUtil::getCalledFunctions(const Function* F) { - std::vector calledFunctions; - for (const Instruction &I : instructions(F)) + std::vector calledFunctions; + for (const Instruction& I : instructions(F)) { - if (const CallBase *callInst = SVFUtil::dyn_cast(&I)) + if (const CallBase* callInst = SVFUtil::dyn_cast(&I)) { - Function *calledFunction = callInst->getCalledFunction(); + Function* calledFunction = callInst->getCalledFunction(); if (calledFunction) { calledFunctions.push_back(calledFunction); - std::vector nestedCalledFunctions = getCalledFunctions(calledFunction); - calledFunctions.insert(calledFunctions.end(), nestedCalledFunctions.begin(), nestedCalledFunctions.end()); + std::vector nestedCalledFunctions = getCalledFunctions(calledFunction); + calledFunctions.insert(calledFunctions.end(), nestedCalledFunctions.begin(), + nestedCalledFunctions.end()); } } } @@ -552,8 +522,7 @@ bool LLVMUtil::isUnusedGlobalVariable(const GlobalVariable& global) { // Check if any global strings has at least one effective user for (auto& use : global.uses()) - if (use.getUser()->getNumUses() != 0) - return false; + if (use.getUser()->getNumUses() != 0) return false; } return true; } @@ -568,19 +537,16 @@ void LLVMUtil::removeUnusedGlobalVariables(Module* module) unusedGlobals.push_back(&global); // Delete unused global variables - for (GlobalVariable* global : unusedGlobals) - global->eraseFromParent(); + for (GlobalVariable* global : unusedGlobals) global->eraseFromParent(); } /// Delete unused functions, annotations and global variables in extapi.bc void LLVMUtil::removeUnusedFuncsAndAnnotationsAndGlobalVariables(Set removedFuncList) { - if (removedFuncList.empty()) - return; + if (removedFuncList.empty()) return; Module* mod = (*removedFuncList.begin())->getParent(); - if (mod->getName().str() != ExtAPI::getExtAPI()->getExtBcPath()) - return; + if (mod->getName().str() != ExtAPI::getExtAPI()->getExtBcPath()) return; /// Delete unused function annotations LLVMUtil::removeFunAnnotations(removedFuncList); @@ -593,14 +559,12 @@ void LLVMUtil::removeUnusedFuncsAndAnnotationsAndGlobalVariables(Set /// Otherwise, errors may occur when calling eraseFromParent(). std::vector funcsToKeep; /// Check whether a function is called by other functions - auto isCalledFunction = [](llvm::Function* F) - { + auto isCalledFunction = [](llvm::Function* F) { assert(F && "Null function pointer!"); for (auto& use : F->uses()) { llvm::User* user = use.getUser(); - if (llvm::isa(user)) - return true; + if (llvm::isa(user)) return true; } return false; }; @@ -615,8 +579,7 @@ void LLVMUtil::removeUnusedFuncsAndAnnotationsAndGlobalVariables(Set func->eraseFromParent(); } // Delete first kind functions - for (Function* func : funcsToKeep) - func->eraseFromParent(); + for (Function* func : funcsToKeep) func->eraseFromParent(); // Delete unused global variables removeUnusedGlobalVariables(mod); } @@ -625,26 +588,24 @@ std::string LLVMUtil::restoreFuncName(std::string funcName) { assert(!funcName.empty() && "Empty function name"); // Some function names change due to mangling, such as "fopen" to "\01_fopen" on macOS. - // Since C function names cannot include '.', change the function name from llvm.memcpy.p0i8.p0i8.i64 to llvm_memcpy_p0i8_p0i8_i64." + // Since C function names cannot include '.', change the function name from llvm.memcpy.p0i8.p0i8.i64 to + // llvm_memcpy_p0i8_p0i8_i64." bool hasSpecialPrefix = funcName[0] == '\01'; bool hasDot = funcName.find('.') != std::string::npos; - if (!hasDot && !hasSpecialPrefix) - return funcName; + if (!hasDot && !hasSpecialPrefix) return funcName; // Remove prefix "\01_" or "\01" if (hasSpecialPrefix) { const std::string prefix1 = "\01_"; const std::string prefix2 = "\01"; - if (funcName.substr(0, prefix1.length()) == prefix1) - funcName = funcName.substr(prefix1.length()); + if (funcName.substr(0, prefix1.length()) == prefix1) funcName = funcName.substr(prefix1.length()); else if (funcName.substr(0, prefix2.length()) == prefix2) funcName = funcName.substr(prefix2.length()); } // Replace '.' with '_' - if (hasDot) - std::replace(funcName.begin(), funcName.end(), '.', '_'); + if (hasDot) std::replace(funcName.begin(), funcName.end(), '.', '_'); return funcName; } @@ -667,19 +628,20 @@ const Value* LLVMUtil::getGlobalRep(const Value* val) u32_t LLVMUtil::getTypeSizeInBytes(const Type* type) { // if the type has size then simply return it, otherwise just return 0 - if(type->isSized()) - return getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule())->getTypeStoreSize(const_cast(type)); + if (type->isSized()) + return getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule()) + ->getTypeStoreSize(const_cast(type)); else return 0; } -u32_t LLVMUtil::getTypeSizeInBytes(const StructType *sty, u32_t field_idx) +u32_t LLVMUtil::getTypeSizeInBytes(const StructType* sty, u32_t field_idx) { - const StructLayout *stTySL = getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule())->getStructLayout( const_cast(sty) ); + const StructLayout* stTySL = getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule()) + ->getStructLayout(const_cast(sty)); /// if this struct type does not have any element, i.e., opaque - if(sty->isOpaque()) - return 0; + if (sty->isOpaque()) return 0; else return stTySL->getElementOffset(field_idx); } @@ -687,9 +649,9 @@ u32_t LLVMUtil::getTypeSizeInBytes(const StructType *sty, u32_t field_idx) /*! * Get the meta data (line number and file name) info of a LLVM value */ -const std::string LLVMUtil::getSourceLoc(const Value* val ) +const std::string LLVMUtil::getSourceLoc(const Value* val) { - if(val==nullptr) return "{ empty val }"; + if (val == nullptr) return "{ empty val }"; std::string str; std::stringstream rawstr(str); @@ -699,27 +661,27 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) { if (SVFUtil::isa(inst)) { - for (llvm::DbgInfoIntrinsic *DII : FindDbgDeclareUses(const_cast(inst))) + for (llvm::DbgInfoIntrinsic* DII : FindDbgDeclareUses(const_cast(inst))) { - if (llvm::DbgDeclareInst *DDI = SVFUtil::dyn_cast(DII)) + if (llvm::DbgDeclareInst* DDI = SVFUtil::dyn_cast(DII)) { - llvm::DIVariable *DIVar = SVFUtil::cast(DDI->getVariable()); + llvm::DIVariable* DIVar = SVFUtil::cast(DDI->getVariable()); rawstr << "\"ln\": " << DIVar->getLine() << ", \"fl\": \"" << DIVar->getFilename().str() << "\""; break; } } } - else if (MDNode *N = inst->getMetadata("dbg")) // Here I is an LLVM instruction + else if (MDNode* N = inst->getMetadata("dbg")) // Here I is an LLVM instruction { - llvm::DILocation* Loc = SVFUtil::cast(N); // DILocation is in DebugInfo.h + llvm::DILocation* Loc = SVFUtil::cast(N); // DILocation is in DebugInfo.h unsigned Line = Loc->getLine(); unsigned Column = Loc->getColumn(); std::string File = Loc->getFilename().str(); - //StringRef Dir = Loc.getDirectory(); - if(File.empty() || Line == 0) + // StringRef Dir = Loc.getDirectory(); + if (File.empty() || Line == 0) { auto inlineLoc = Loc->getInlinedAt(); - if(inlineLoc) + if (inlineLoc) { Line = inlineLoc->getLine(); Column = inlineLoc->getColumn(); @@ -731,11 +693,10 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) } else if (const Argument* argument = SVFUtil::dyn_cast(val)) { - if (argument->getArgNo()%10 == 1) - rawstr << argument->getArgNo() << "st"; - else if (argument->getArgNo()%10 == 2) + if (argument->getArgNo() % 10 == 1) rawstr << argument->getArgNo() << "st"; + else if (argument->getArgNo() % 10 == 2) rawstr << argument->getArgNo() << "nd"; - else if (argument->getArgNo()%10 == 3) + else if (argument->getArgNo() % 10 == 3) rawstr << argument->getArgNo() << "rd"; else rawstr << argument->getArgNo() << "th"; @@ -746,20 +707,19 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) { rawstr << "Glob "; NamedMDNode* CU_Nodes = gvar->getParent()->getNamedMetadata("llvm.dbg.cu"); - if(CU_Nodes) + if (CU_Nodes) { for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { - llvm::DICompileUnit *CUNode = SVFUtil::cast(CU_Nodes->getOperand(i)); - for (llvm::DIGlobalVariableExpression *GV : CUNode->getGlobalVariables()) + llvm::DICompileUnit* CUNode = SVFUtil::cast(CU_Nodes->getOperand(i)); + for (llvm::DIGlobalVariableExpression* GV : CUNode->getGlobalVariables()) { - llvm::DIGlobalVariable * DGV = GV->getVariable(); + llvm::DIGlobalVariable* DGV = GV->getVariable(); - if(DGV->getName() == gvar->getName()) + if (DGV->getName() == gvar->getName()) { rawstr << "\"ln\": " << DGV->getLine() << ", \"fl\": \"" << DGV->getFilename().str() << "\""; } - } } } @@ -770,9 +730,10 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) } else if (const BasicBlock* bb = SVFUtil::dyn_cast(val)) { - rawstr << "\"basic block\": " << bb->getName().str() << ", \"location\": " << getSourceLoc(bb->getFirstNonPHI()); + rawstr << "\"basic block\": " << bb->getName().str() + << ", \"location\": " << getSourceLoc(bb->getFirstNonPHI()); } - else if(LLVMUtil::isConstDataOrAggData(val)) + else if (LLVMUtil::isConstDataOrAggData(val)) { rawstr << "constant data"; } @@ -782,12 +743,10 @@ const std::string LLVMUtil::getSourceLoc(const Value* val ) } rawstr << " }"; - if(rawstr.str()=="{ }") - return ""; + if (rawstr.str() == "{ }") return ""; return rawstr.str(); } - /*! * Get source code line number of a function according to debug info */ @@ -799,7 +758,7 @@ const std::string LLVMUtil::getSourceLocOfFunction(const Function* F) * https://reviews.llvm.org/D18074?id=50385 * looks like the relevant */ - if (llvm::DISubprogram *SP = F->getSubprogram()) + if (llvm::DISubprogram* SP = F->getSubprogram()) { if (SP->describes(F)) rawstr << "\"ln\": " << SP->getLine() << ", \"file\": \"" << SP->getFilename().str() << "\""; @@ -813,47 +772,42 @@ void LLVMUtil::getNextInsts(const Instruction* curInst, std::vectorisTerminator()) { const Instruction* nextInst = curInst->getNextNode(); - if (LLVMUtil::isIntrinsicInst(nextInst)) - getNextInsts(nextInst, instList); + if (LLVMUtil::isIntrinsicInst(nextInst)) getNextInsts(nextInst, instList); else instList.push_back(nextInst); } else { - const BasicBlock *BB = curInst->getParent(); + const BasicBlock* BB = curInst->getParent(); // Visit all successors of BB in the CFG for (succ_const_iterator it = succ_begin(BB), ie = succ_end(BB); it != ie; ++it) { const Instruction* nextInst = &((*it)->front()); - if (LLVMUtil::isIntrinsicInst(nextInst)) - getNextInsts(nextInst, instList); + if (LLVMUtil::isIntrinsicInst(nextInst)) getNextInsts(nextInst, instList); else instList.push_back(nextInst); } } } - /// Get the previous instructions following control flow void LLVMUtil::getPrevInsts(const Instruction* curInst, std::vector& instList) { if (curInst != &(curInst->getParent()->front())) { const Instruction* prevInst = curInst->getPrevNode(); - if (LLVMUtil::isIntrinsicInst(prevInst)) - getPrevInsts(prevInst, instList); + if (LLVMUtil::isIntrinsicInst(prevInst)) getPrevInsts(prevInst, instList); else instList.push_back(prevInst); } else { - const BasicBlock *BB = curInst->getParent(); + const BasicBlock* BB = curInst->getParent(); // Visit all successors of BB in the CFG for (const_pred_iterator it = pred_begin(BB), ie = pred_end(BB); it != ie; ++it) { const Instruction* prevInst = &((*it)->back()); - if (LLVMUtil::isIntrinsicInst(prevInst)) - getPrevInsts(prevInst, instList); + if (LLVMUtil::isIntrinsicInst(prevInst)) getPrevInsts(prevInst, instList); else instList.push_back(prevInst); } @@ -866,13 +820,11 @@ bool LLVMUtil::isConstantObjSym(const SVFValue* val) return isConstantObjSym(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(val)); } - std::string LLVMUtil::dumpValue(const Value* val) { std::string str; llvm::raw_string_ostream rawstr(str); - if (val) - rawstr << " " << *val << " "; + if (val) rawstr << " " << *val << " "; else rawstr << " llvm Value is null"; return rawstr.str(); @@ -882,19 +834,17 @@ std::string LLVMUtil::dumpType(const Type* type) { std::string str; llvm::raw_string_ostream rawstr(str); - if (type) - rawstr << " " << *type << " "; + if (type) rawstr << " " << *type << " "; else rawstr << " llvm type is null"; return rawstr.str(); } -std::string LLVMUtil::dumpValueAndDbgInfo(const Value *val) +std::string LLVMUtil::dumpValueAndDbgInfo(const Value* val) { std::string str; llvm::raw_string_ostream rawstr(str); - if (val) - rawstr << dumpValue(val) << getSourceLoc(val); + if (val) rawstr << dumpValue(val) << getSourceLoc(val); else rawstr << " llvm Value is null"; return rawstr.str(); @@ -918,8 +868,7 @@ std::string SVFValue::toString() const else { auto llvmVal = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(this); - if (llvmVal) - rawstr << " " << *llvmVal << " "; + if (llvmVal) rawstr << " " << *llvmVal << " "; else rawstr << " No llvmVal found"; } diff --git a/svf-llvm/lib/ObjTypeInference.cpp b/svf-llvm/lib/ObjTypeInference.cpp index 4611bef58..93603794e 100644 --- a/svf-llvm/lib/ObjTypeInference.cpp +++ b/svf-llvm/lib/ObjTypeInference.cpp @@ -35,41 +35,37 @@ #include "Util/Casting.h" #define TYPE_DEBUG 0 /* Turn this on if you're debugging type inference */ -#define ERR_MSG(msg) \ - do \ - { \ - SVFUtil::errs() << SVFUtil::errMsg("Error ") << __FILE__ << ':' \ - << __LINE__ << ": " << (msg) << '\n'; \ +#define ERR_MSG(msg) \ + do \ + { \ + SVFUtil::errs() << SVFUtil::errMsg("Error ") << __FILE__ << ':' << __LINE__ << ": " << (msg) << '\n'; \ } while (0) -#define ABORT_MSG(msg) \ - do \ - { \ - ERR_MSG(msg); \ - abort(); \ +#define ABORT_MSG(msg) \ + do \ + { \ + ERR_MSG(msg); \ + abort(); \ } while (0) -#define ABORT_IFNOT(condition, msg) \ - do \ - { \ - if (!(condition)) \ - ABORT_MSG(msg); \ +#define ABORT_IFNOT(condition, msg) \ + do \ + { \ + if (!(condition)) ABORT_MSG(msg); \ } while (0) #if TYPE_DEBUG -#define WARN_MSG(msg) \ - do \ - { \ - SVFUtil::outs() << SVFUtil::wrnMsg("Warning ") << __FILE__ << ':' \ - << __LINE__ << ": " << msg << '\n'; \ - } while (0) -#define WARN_IFNOT(condition, msg) \ - do \ - { \ - if (!(condition)) \ - WARN_MSG(msg); \ - } while (0) +# define WARN_MSG(msg) \ + do \ + { \ + SVFUtil::outs() << SVFUtil::wrnMsg("Warning ") << __FILE__ << ':' << __LINE__ << ": " << msg << '\n'; \ + } while (0) +# define WARN_IFNOT(condition, msg) \ + do \ + { \ + if (!(condition)) WARN_MSG(msg); \ + } while (0) #else -#define WARN_MSG(msg) -#define WARN_IFNOT(condition, msg) +# define WARN_MSG(msg) +# define WARN_IFNOT(condition, msg) #endif using namespace SVF; @@ -77,31 +73,30 @@ using namespace SVFUtil; using namespace LLVMUtil; using namespace cppUtil; - const std::string TYPEMALLOC = "TYPE_MALLOC"; /// Determine type based on infer site /// https://llvm.org/docs/OpaquePointers.html#migration-instructions -const Type *infersiteToType(const Value *val) +const Type* infersiteToType(const Value* val) { assert(val && "value cannot be empty"); if (SVFUtil::isa(val)) { - return llvm::getLoadStoreType(const_cast(val)); + return llvm::getLoadStoreType(const_cast(val)); } - else if (const auto *gepInst = SVFUtil::dyn_cast(val)) + else if (const auto* gepInst = SVFUtil::dyn_cast(val)) { return gepInst->getSourceElementType(); } - else if (const auto *call = SVFUtil::dyn_cast(val)) + else if (const auto* call = SVFUtil::dyn_cast(val)) { return call->getFunctionType(); } - else if (const auto *allocaInst = SVFUtil::dyn_cast(val)) + else if (const auto* allocaInst = SVFUtil::dyn_cast(val)) { return allocaInst->getAllocatedType(); } - else if (const auto *globalValue = SVFUtil::dyn_cast(val)) + else if (const auto* globalValue = SVFUtil::dyn_cast(val)) { return globalValue->getValueType(); } @@ -111,18 +106,19 @@ const Type *infersiteToType(const Value *val) } } -const Type *ObjTypeInference::defaultType(const Value *val) +const Type* ObjTypeInference::defaultType(const Value* val) { ABORT_IFNOT(val, "val cannot be null"); // heap has a default type of 8-bit integer type - if (SVFUtil::isa(val) && SVFUtil::isHeapAllocExtCallViaRet( - LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast(val)))) + if (SVFUtil::isa(val) && + SVFUtil::isHeapAllocExtCallViaRet( + LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast(val)))) return int8Type(); // otherwise we return a pointer type in the default address space return ptrType(); } -LLVMContext &ObjTypeInference::getLLVMCtx() +LLVMContext& ObjTypeInference::getLLVMCtx() { return LLVMModuleSet::getLLVMModuleSet()->getContext(); } @@ -133,11 +129,11 @@ LLVMContext &ObjTypeInference::getLLVMCtx() * if not, find allocations and then forward get or infer types * @param val */ -const Type *ObjTypeInference::inferObjType(const Value *var) +const Type* ObjTypeInference::inferObjType(const Value* var) { if (isAlloc(var)) return fwInferObjType(var); - Set &sources = bwfindAllocOfVar(var); - Set types; + Set& sources = bwfindAllocOfVar(var); + Set types; if (sources.empty()) { // cannot find allocation, try to fw infer starting from var @@ -145,12 +141,12 @@ const Type *ObjTypeInference::inferObjType(const Value *var) } else { - for (const auto &source: sources) + for (const auto& source : sources) { types.insert(fwInferObjType(source)); } } - const Type *largestTy = selectLargestSizedType(types); + const Type* largestTy = selectLargestSizedType(types); ABORT_IFNOT(largestTy, "return type cannot be null"); return largestTy; } @@ -159,14 +155,14 @@ const Type *ObjTypeInference::inferObjType(const Value *var) * forward infer the type of the object pointed by var * @param var */ -const Type *ObjTypeInference::fwInferObjType(const Value *var) +const Type* ObjTypeInference::fwInferObjType(const Value* var) { - if (const AllocaInst *allocaInst = SVFUtil::dyn_cast(var)) + if (const AllocaInst* allocaInst = SVFUtil::dyn_cast(var)) { // stack object return infersiteToType(allocaInst); } - else if (const GlobalValue *global = SVFUtil::dyn_cast(var)) + else if (const GlobalValue* global = SVFUtil::dyn_cast(var)) { // global object return infersiteToType(global); @@ -190,44 +186,34 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) while (!workList.empty()) { auto curPair = workList.pop(); - if (visited.count(curPair)) - continue; + if (visited.count(curPair)) continue; visited.insert(curPair); const Value* curValue = curPair.first; bool canUpdate = curPair.second; Set infersites; - auto insertInferSite = [&infersites, - &canUpdate](const Value* infersite) - { - if (canUpdate) - infersites.insert(infersite); + auto insertInferSite = [&infersites, &canUpdate](const Value* infersite) { + if (canUpdate) infersites.insert(infersite); }; - auto insertInferSitesOrPushWorklist = - [this, &infersites, &workList, &canUpdate](const auto& pUser) - { + auto insertInferSitesOrPushWorklist = [this, &infersites, &workList, &canUpdate](const auto& pUser) { auto vIt = _valueToInferSites.find(pUser); if (canUpdate) { if (vIt != _valueToInferSites.end()) { - infersites.insert(vIt->second.begin(), - vIt->second.end()); + infersites.insert(vIt->second.begin(), vIt->second.end()); } } else { - if (vIt == _valueToInferSites.end()) - workList.push({pUser, false}); + if (vIt == _valueToInferSites.end()) workList.push({pUser, false}); } }; if (!canUpdate && !_valueToInferSites.count(curValue)) { workList.push({curValue, true}); } - if (const auto* gepInst = - SVFUtil::dyn_cast(curValue)) - insertInferSite(gepInst); + if (const auto* gepInst = SVFUtil::dyn_cast(curValue)) insertInferSite(gepInst); for (const auto it : curValue->users()) { if (const auto* loadInst = SVFUtil::dyn_cast(it)) @@ -240,8 +226,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) */ insertInferSite(loadInst); } - else if (const auto* storeInst = - SVFUtil::dyn_cast(it)) + else if (const auto* storeInst = SVFUtil::dyn_cast(it)) { if (storeInst->getPointerOperand() == curValue) { @@ -255,8 +240,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) } else { - for (const auto nit : - storeInst->getPointerOperand()->users()) + for (const auto nit : storeInst->getPointerOperand()->users()) { /* * propagate across store (value operand) and load @@ -265,15 +249,12 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) %q = load i8*, i8** %p ..infer based on %q.. */ - if (SVFUtil::isa(nit)) - insertInferSitesOrPushWorklist(nit); + if (SVFUtil::isa(nit)) insertInferSitesOrPushWorklist(nit); } /* - * infer based on store (value operand) <- gep (result element) + * infer based on store (value operand) <- gep (result element) */ - if (const auto* gepInst = - SVFUtil::dyn_cast( - storeInst->getPointerOperand())) + if (const auto* gepInst = SVFUtil::dyn_cast(storeInst->getPointerOperand())) { /* %call1 = call i8* @TYPE_MALLOC(i32 noundef 16, i32 @@ -294,35 +275,25 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) 0, !dbg !50 */ const Value* gepBase = gepInst->getPointerOperand(); - if (const auto* load = - SVFUtil::dyn_cast(gepBase)) + if (const auto* load = SVFUtil::dyn_cast(gepBase)) { - for (const auto loadUse : - load->getPointerOperand()->users()) + for (const auto loadUse : load->getPointerOperand()->users()) { - if (loadUse == load || - !SVFUtil::isa(loadUse)) - continue; + if (loadUse == load || !SVFUtil::isa(loadUse)) continue; for (const auto gepUse : loadUse->users()) { - if (!SVFUtil::isa( - gepUse)) - continue; - for (const auto loadUse2 : - gepUse->users()) + if (!SVFUtil::isa(gepUse)) continue; + for (const auto loadUse2 : gepUse->users()) { - if (SVFUtil::isa( - loadUse2)) + if (SVFUtil::isa(loadUse2)) { - insertInferSitesOrPushWorklist( - loadUse2); + insertInferSitesOrPushWorklist(loadUse2); } } } } } - else if (const auto* alloc = - SVFUtil::dyn_cast(gepBase)) + else if (const auto* alloc = SVFUtil::dyn_cast(gepBase)) { /* %2 = alloca %struct.ll, align 8 @@ -338,15 +309,12 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) */ for (const auto gepUse : alloc->users()) { - if (!SVFUtil::isa( - gepUse)) - continue; + if (!SVFUtil::isa(gepUse)) continue; for (const auto loadUse2 : gepUse->users()) { if (SVFUtil::isa(loadUse2)) { - insertInferSitesOrPushWorklist( - loadUse2); + insertInferSitesOrPushWorklist(loadUse2); } } } @@ -354,8 +322,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) } } } - else if (const auto* gepInst = - SVFUtil::dyn_cast(it)) + else if (const auto* gepInst = SVFUtil::dyn_cast(it)) { /* * infer based on gep (pointer operand) @@ -364,11 +331,9 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) %next = getelementptr inbounds %struct.MyStruct, %struct.MyStruct* %1, i32 0.. */ - if (gepInst->getPointerOperand() == curValue) - insertInferSite(gepInst); + if (gepInst->getPointerOperand() == curValue) insertInferSite(gepInst); } - else if (const auto* bitcast = - SVFUtil::dyn_cast(it)) + else if (const auto* bitcast = SVFUtil::dyn_cast(it)) { // continue on bitcast insertInferSitesOrPushWorklist(bitcast); @@ -378,8 +343,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) // continue on bitcast insertInferSitesOrPushWorklist(phiNode); } - else if (const auto* retInst = - SVFUtil::dyn_cast(it)) + else if (const auto* retInst = SVFUtil::dyn_cast(it)) { /* * propagate from return to caller @@ -394,14 +358,11 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) */ for (const auto callsite : retInst->getFunction()->users()) { - if (const auto* callBase = - SVFUtil::dyn_cast(callsite)) + if (const auto* callBase = SVFUtil::dyn_cast(callsite)) { // skip function as parameter // e.g., call void @foo(%struct.ssl_ctx_st* %9, i32 (i8*, i32, i32, i8*)* @passwd_callback) - if (callBase->getCalledFunction() != - retInst->getFunction()) - continue; + if (callBase->getCalledFunction() != retInst->getFunction()) continue; insertInferSitesOrPushWorklist(callBase); } } @@ -421,31 +382,29 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) // skip global function value -> callsite // e.g., def @foo() -> call @foo() // we don't skip function as parameter, e.g., def @foo() -> call @bar(..., @foo) - if (SVFUtil::isa(curValue) && - curValue == callBase->getCalledFunction()) - continue; + if (SVFUtil::isa(curValue) && curValue == callBase->getCalledFunction()) continue; // skip indirect call // e.g., %0 = ... -> call %0(...) - if (!callBase->hasArgument(curValue)) - continue; + if (!callBase->hasArgument(curValue)) continue; if (Function* calleeFunc = callBase->getCalledFunction()) { u32_t pos = getArgPosInCall(callBase, curValue); - // for varargs function, we cannot directly get the value-flow between actual and formal args e.g., consider the following vararg function @callee 1: call void @callee(%arg) 2: define dso_local i32 @callee(...) #0 !dbg !17 { 3: ....... 4: %5 = load i32, ptr %vaarg.addr, align 4, !dbg !55 5: ....... - // 6: } - // it is challenging to precisely identify the forward value-flow of %arg (Line 2) because the function definition of callee (Line 2) does not have any formal args related to the actual arg %arg therefore we track all possible instructions like ``load i32, ptr %vaarg.addr'' + // for varargs function, we cannot directly get the value-flow between actual and formal args + // e.g., consider the following vararg function @callee 1: call void @callee(%arg) 2: define + // dso_local i32 @callee(...) #0 !dbg !17 { 3: ....... 4: %5 = load i32, ptr %vaarg.addr, + // align 4, !dbg !55 5: ....... 6: } it is challenging to precisely identify the forward + // value-flow of %arg (Line 2) because the function definition of callee (Line 2) does not have + // any formal args related to the actual arg %arg therefore we track all possible instructions + // like ``load i32, ptr %vaarg.addr'' if (calleeFunc->isVarArg()) { // conservatively track all var args for (auto& I : instructions(calleeFunc)) { - if (auto* load = - llvm::dyn_cast(&I)) + if (auto* load = llvm::dyn_cast(&I)) { - llvm::Value* loadPointer = - load->getPointerOperand(); - if (loadPointer->getName().compare( - "vaarg.addr") == 0) + llvm::Value* loadPointer = load->getPointerOperand(); + if (loadPointer->getName().compare("vaarg.addr") == 0) { insertInferSitesOrPushWorklist(load); } @@ -454,8 +413,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) } else if (!calleeFunc->isDeclaration()) { - insertInferSitesOrPushWorklist( - calleeFunc->getArg(pos)); + insertInferSitesOrPushWorklist(calleeFunc->getArg(pos)); } } } @@ -463,8 +421,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) if (canUpdate) { Set types; - std::transform(infersites.begin(), infersites.end(), - std::inserter(types, types.begin()), + std::transform(infersites.begin(), infersites.end(), std::inserter(types, types.begin()), infersiteToType); _valueToInferSites[curValue] = SVFUtil::move(infersites); _valueToType[curValue] = selectLargestSizedType(types); @@ -474,8 +431,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) if (type == nullptr) { type = defaultType(var); - WARN_MSG("Using default type, trace ID is " + - std::to_string(traceId) + ":" + dumpValueAndDbgInfo(var)); + WARN_MSG("Using default type, trace ID is " + std::to_string(traceId) + ":" + dumpValueAndDbgInfo(var)); } ABORT_IFNOT(type, "type cannot be a null ptr"); return type; @@ -487,7 +443,7 @@ const Type *ObjTypeInference::fwInferObjType(const Value *var) * @param var * @return */ -Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) +Set& ObjTypeInference::bwfindAllocOfVar(const Value* var) { // consult cache @@ -506,16 +462,14 @@ Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) auto curPair = workList.pop(); if (visited.count(curPair)) continue; visited.insert(curPair); - const Value *curValue = curPair.first; + const Value* curValue = curPair.first; bool canUpdate = curPair.second; - Set sources; - auto insertAllocs = [&sources, &canUpdate](const Value *source) - { + Set sources; + auto insertAllocs = [&sources, &canUpdate](const Value* source) { if (canUpdate) sources.insert(source); }; - auto insertAllocsOrPushWorklist = [this, &sources, &workList, &canUpdate](const auto &pUser) - { + auto insertAllocsOrPushWorklist = [this, &sources, &workList, &canUpdate](const auto& pUser) { auto vIt = _valueToAllocs.find(pUser); if (canUpdate) { @@ -539,23 +493,23 @@ Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) { insertAllocs(curValue); } - else if (const auto *bitCastInst = SVFUtil::dyn_cast(curValue)) + else if (const auto* bitCastInst = SVFUtil::dyn_cast(curValue)) { - Value *prevVal = bitCastInst->getOperand(0); + Value* prevVal = bitCastInst->getOperand(0); insertAllocsOrPushWorklist(prevVal); } - else if (const auto *phiNode = SVFUtil::dyn_cast(curValue)) + else if (const auto* phiNode = SVFUtil::dyn_cast(curValue)) { for (u32_t i = 0; i < phiNode->getNumOperands(); ++i) { insertAllocsOrPushWorklist(phiNode->getOperand(i)); } } - else if (const auto *loadInst = SVFUtil::dyn_cast(curValue)) + else if (const auto* loadInst = SVFUtil::dyn_cast(curValue)) { - for (const auto use: loadInst->getPointerOperand()->users()) + for (const auto use : loadInst->getPointerOperand()->users()) { - if (const StoreInst *storeInst = SVFUtil::dyn_cast(use)) + if (const StoreInst* storeInst = SVFUtil::dyn_cast(use)) { if (storeInst->getPointerOperand() == loadInst->getPointerOperand()) { @@ -564,11 +518,11 @@ Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) } } } - else if (const auto *argument = SVFUtil::dyn_cast(curValue)) + else if (const auto* argument = SVFUtil::dyn_cast(curValue)) { - for (const auto use: argument->getParent()->users()) + for (const auto use : argument->getParent()->users()) { - if (const CallBase *callBase = SVFUtil::dyn_cast(use)) + if (const CallBase* callBase = SVFUtil::dyn_cast(use)) { // skip function as parameter // e.g., call void @foo(%struct.ssl_ctx_st* %9, i32 (i8*, i32, i32, i8*)* @passwd_callback) @@ -578,16 +532,16 @@ Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) } } } - else if (const auto *callBase = SVFUtil::dyn_cast(curValue)) + else if (const auto* callBase = SVFUtil::dyn_cast(curValue)) { ABORT_IFNOT(!callBase->doesNotReturn(), "callbase does not return:" + dumpValueAndDbgInfo(callBase)); - if (Function *callee = callBase->getCalledFunction()) + if (Function* callee = callBase->getCalledFunction()) { if (!callee->isDeclaration()) { - const SVFFunction *svfFunc = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee); - const Value *pValue = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfFunc->getExitBB()->back()); - const auto *retInst = SVFUtil::dyn_cast(pValue); + const SVFFunction* svfFunc = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee); + const Value* pValue = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfFunc->getExitBB()->back()); + const auto* retInst = SVFUtil::dyn_cast(pValue); ABORT_IFNOT(retInst && retInst->getReturnValue(), "not return inst?"); insertAllocsOrPushWorklist(retInst->getReturnValue()); } @@ -598,7 +552,7 @@ Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) _valueToAllocs[curValue] = SVFUtil::move(sources); } } - Set &srcs = _valueToAllocs[var]; + Set& srcs = _valueToAllocs[var]; if (srcs.empty()) { WARN_MSG("Cannot find allocation: " + dumpValueAndDbgInfo(var)); @@ -606,7 +560,7 @@ Set &ObjTypeInference::bwfindAllocOfVar(const Value *var) return srcs; } -bool ObjTypeInference::isAlloc(const SVF::Value *val) +bool ObjTypeInference::isAlloc(const SVF::Value* val) { return LLVMUtil::isObject(val); } @@ -615,35 +569,33 @@ bool ObjTypeInference::isAlloc(const SVF::Value *val) * validate type inference * @param cs : stub malloc function with element number label */ -void ObjTypeInference::validateTypeCheck(const CallBase *cs) +void ObjTypeInference::validateTypeCheck(const CallBase* cs) { - if (const Function *func = cs->getCalledFunction()) + if (const Function* func = cs->getCalledFunction()) { if (func->getName().find(TYPEMALLOC) != std::string::npos) { - const Type *objType = fwInferObjType(cs); - const auto *pInt = - SVFUtil::dyn_cast(cs->getOperand(1)); + const Type* objType = fwInferObjType(cs); + const auto* pInt = SVFUtil::dyn_cast(cs->getOperand(1)); assert(pInt && "the second argument is a integer"); u32_t iTyNum = objTyToNumFields(objType); if (iTyNum >= pInt->getZExtValue()) SVFUtil::outs() << SVFUtil::sucMsg("\t SUCCESS :") << dumpValueAndDbgInfo(cs) - << SVFUtil::pasMsg(" TYPE: ") - << dumpType(objType) << "\n"; + << SVFUtil::pasMsg(" TYPE: ") << dumpType(objType) << "\n"; else { - SVFUtil::errs() << SVFUtil::errMsg("\t FAILURE :") << ":" << dumpValueAndDbgInfo(cs) << " TYPE: " - << dumpType(objType) << "\n"; + SVFUtil::errs() << SVFUtil::errMsg("\t FAILURE :") << ":" << dumpValueAndDbgInfo(cs) + << " TYPE: " << dumpType(objType) << "\n"; abort(); } } } } -void ObjTypeInference::typeSizeDiffTest(const PointerType *oPTy, const Type *iTy, const Value *val) +void ObjTypeInference::typeSizeDiffTest(const PointerType* oPTy, const Type* iTy, const Value* val) { #if TYPE_DEBUG - Type *oTy = getPtrElementType(oPTy); + Type* oTy = getPtrElementType(oPTy); u32_t iTyNum = objTyToNumFields(iTy); if (getNumOfElements(oTy) > iTyNum) { @@ -654,7 +606,7 @@ void ObjTypeInference::typeSizeDiffTest(const PointerType *oPTy, const Type *iTy #endif } -u32_t ObjTypeInference::getArgPosInCall(const CallBase *callBase, const Value *arg) +u32_t ObjTypeInference::getArgPosInCall(const CallBase* callBase, const Value* arg) { assert(callBase->hasArgument(arg) && "callInst does not have argument arg?"); auto it = std::find(callBase->arg_begin(), callBase->arg_end(), arg); @@ -662,39 +614,35 @@ u32_t ObjTypeInference::getArgPosInCall(const CallBase *callBase, const Value *a return std::distance(callBase->arg_begin(), it); } - -const Type *ObjTypeInference::selectLargestSizedType(Set &objTys) +const Type* ObjTypeInference::selectLargestSizedType(Set& objTys) { if (objTys.empty()) return nullptr; // map type size to types from with key in descending order - OrderedMap, std::greater> typeSzToTypes; - for (const Type *ty: objTys) + OrderedMap, std::greater> typeSzToTypes; + for (const Type* ty : objTys) { typeSzToTypes[objTyToNumFields(ty)].insert(ty); } assert(!typeSzToTypes.empty() && "typeSzToTypes cannot be empty"); - OrderedSet largestTypes; + OrderedSet largestTypes; std::tie(std::ignore, largestTypes) = *typeSzToTypes.begin(); assert(!largestTypes.empty() && "largest element cannot be empty"); return *largestTypes.begin(); } -u32_t ObjTypeInference::objTyToNumFields(const Type *objTy) +u32_t ObjTypeInference::objTyToNumFields(const Type* objTy) { u32_t num = Options::MaxFieldLimit(); - if (SVFUtil::isa(objTy)) - num = getNumOfElements(objTy); - else if (const auto *st = SVFUtil::dyn_cast(objTy)) + if (SVFUtil::isa(objTy)) num = getNumOfElements(objTy); + else if (const auto* st = SVFUtil::dyn_cast(objTy)) { /// For an C++ class, it can have variant elements depending on the vtable size, /// Hence we only handle non-cpp-class object, the type of the cpp class is treated as default PointerType - if (!classTyHasVTable(st)) - num = getNumOfElements(st); + if (!classTyHasVTable(st)) num = getNumOfElements(st); } return num; } - /*! * get or infer the class names of thisptr; starting from :param:`thisPtr`, will walk backwards to find * all potential sources for the class name. Valid sources include global or stack variables, heap allocations, @@ -704,7 +652,7 @@ u32_t ObjTypeInference::objTyToNumFields(const Type *objTy) * @param thisPtr * @return a set of all possible type names that :param:`thisPtr` could point to */ -Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) +Set& ObjTypeInference::inferThisPtrClsName(const Value* thisPtr) { auto it = _thisPtrClassNames.find(thisPtr); if (it != _thisPtrClassNames.end()) return it->second; @@ -712,24 +660,23 @@ Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) Set names; // Lambda for checking a function is a valid name source & extracting a class name from it - auto addNamesFromFunc = [&names](const Function *func) -> void - { + auto addNamesFromFunc = [&names](const Function* func) -> void { ABORT_IFNOT(isClsNameSource(func), "Func is invalid class name source: " + dumpValueAndDbgInfo(func)); - for (const auto &name : extractClsNamesFromFunc(func)) names.insert(name); + for (const auto& name : extractClsNamesFromFunc(func)) names.insert(name); }; // Lambda for getting callee & extracting class name for calls to constructors/destructors/template funcs - auto addNamesFromCall = [&names, &addNamesFromFunc](const CallBase *call) -> void - { + auto addNamesFromCall = [&names, &addNamesFromFunc](const CallBase* call) -> void { ABORT_IFNOT(isClsNameSource(call), "Call is invalid class name source: " + dumpValueAndDbgInfo(call)); - const auto *func = call->getCalledFunction(); + const auto* func = call->getCalledFunction(); if (isDynCast(func)) names.insert(extractClsNameFromDynCast(call)); - else addNamesFromFunc(func); + else + addNamesFromFunc(func); }; // Walk backwards to find all valid source sites for the pointer (e.g. stack/global/heap variables) - for (const auto &val: bwFindAllocOrClsNameSources(thisPtr)) + for (const auto& val : bwFindAllocOrClsNameSources(thisPtr)) { // A source site is either a constructor/destructor/template function from which the class name can be // extracted; a call to a C++ constructor/destructor/template function from which the class name can be @@ -738,7 +685,7 @@ Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) // which the class' name can then be extracted; skip starting pointer if (val == thisPtr) continue; - if (const auto *func = SVFUtil::dyn_cast(val)) + if (const auto* func = SVFUtil::dyn_cast(val)) { // Constructor/destructor/template func; extract name from func directly addNamesFromFunc(func); @@ -754,11 +701,13 @@ Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) // Stack/global/heap allocation site; walk forward; find constructor/destructor/template calls ABORT_IFNOT((SVFUtil::isa(val)), "Alloc site source is not a stack/heap/global variable: " + dumpValueAndDbgInfo(val)); - for (const auto *src : fwFindClsNameSources(val)) + for (const auto* src : fwFindClsNameSources(val)) { - if (const auto *func = SVFUtil::dyn_cast(src)) addNamesFromFunc(func); - else if (const auto *call = SVFUtil::dyn_cast(src)) addNamesFromCall(call); - else ABORT_MSG("Source site from forward walk is invalid: " + dumpValueAndDbgInfo(src)); + if (const auto* func = SVFUtil::dyn_cast(src)) addNamesFromFunc(func); + else if (const auto* call = SVFUtil::dyn_cast(src)) + addNamesFromCall(call); + else + ABORT_MSG("Source site from forward walk is invalid: " + dumpValueAndDbgInfo(src)); } } else @@ -777,7 +726,7 @@ Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) * @param startValue * @return */ -Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *startValue) +Set& ObjTypeInference::bwFindAllocOrClsNameSources(const Value* startValue) { // consult cache @@ -796,16 +745,14 @@ Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s auto curPair = workList.pop(); if (visited.count(curPair)) continue; visited.insert(curPair); - const Value *curValue = curPair.first; + const Value* curValue = curPair.first; bool canUpdate = curPair.second; - Set sources; - auto insertSource = [&sources, &canUpdate](const Value *source) - { + Set sources; + auto insertSource = [&sources, &canUpdate](const Value* source) { if (canUpdate) sources.insert(source); }; - auto insertSourcesOrPushWorklist = [this, &sources, &workList, &canUpdate](const auto &pUser) - { + auto insertSourcesOrPushWorklist = [this, &sources, &workList, &canUpdate](const auto& pUser) { auto vIt = _valueToAllocOrClsNameSources.find(pUser); if (canUpdate) { @@ -826,9 +773,9 @@ Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s } // If current value is an instruction inside a constructor/destructor/template, use it as a source - if (const auto *inst = SVFUtil::dyn_cast(curValue)) + if (const auto* inst = SVFUtil::dyn_cast(curValue)) { - if (const auto *parent = inst->getFunction()) + if (const auto* parent = inst->getFunction()) { if (isClsNameSource(parent)) insertSource(parent); } @@ -842,26 +789,26 @@ Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s } // Explore the current value further depending on the type of the value; use cached values if possible - if (const auto *getElementPtrInst = SVFUtil::dyn_cast(curValue)) + if (const auto* getElementPtrInst = SVFUtil::dyn_cast(curValue)) { insertSourcesOrPushWorklist(getElementPtrInst->getPointerOperand()); } - else if (const auto *bitCastInst = SVFUtil::dyn_cast(curValue)) + else if (const auto* bitCastInst = SVFUtil::dyn_cast(curValue)) { insertSourcesOrPushWorklist(bitCastInst->getOperand(0)); } - else if (const auto *phiNode = SVFUtil::dyn_cast(curValue)) + else if (const auto* phiNode = SVFUtil::dyn_cast(curValue)) { - for (const auto *op : phiNode->operand_values()) + for (const auto* op : phiNode->operand_values()) { insertSourcesOrPushWorklist(op); } } - else if (const auto *loadInst = SVFUtil::dyn_cast(curValue)) + else if (const auto* loadInst = SVFUtil::dyn_cast(curValue)) { - for (const auto *user : loadInst->getPointerOperand()->users()) + for (const auto* user : loadInst->getPointerOperand()->users()) { - if (const auto *storeInst = SVFUtil::dyn_cast(user)) + if (const auto* storeInst = SVFUtil::dyn_cast(user)) { if (storeInst->getPointerOperand() == loadInst->getPointerOperand()) { @@ -870,11 +817,11 @@ Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s } } } - else if (const auto *argument = SVFUtil::dyn_cast(curValue)) + else if (const auto* argument = SVFUtil::dyn_cast(curValue)) { - for (const auto *user: argument->getParent()->users()) + for (const auto* user : argument->getParent()->users()) { - if (const auto *callBase = SVFUtil::dyn_cast(user)) + if (const auto* callBase = SVFUtil::dyn_cast(user)) { // skip function as parameter // e.g., call void @foo(%struct.ssl_ctx_st* %9, i32 (i8*, i32, i32, i8*)* @passwd_callback) @@ -884,16 +831,16 @@ Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s } } } - else if (const auto *callBase = SVFUtil::dyn_cast(curValue)) + else if (const auto* callBase = SVFUtil::dyn_cast(curValue)) { ABORT_IFNOT(!callBase->doesNotReturn(), "callbase does not return:" + dumpValueAndDbgInfo(callBase)); - if (const auto *callee = callBase->getCalledFunction()) + if (const auto* callee = callBase->getCalledFunction()) { if (!callee->isDeclaration()) { - const SVFFunction *svfFunc = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee); - const Value *pValue = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfFunc->getExitBB()->back()); - const auto *retInst = SVFUtil::dyn_cast(pValue); + const SVFFunction* svfFunc = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee); + const Value* pValue = LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfFunc->getExitBB()->back()); + const auto* retInst = SVFUtil::dyn_cast(pValue); ABORT_IFNOT(retInst && retInst->getReturnValue(), "not return inst?"); insertSourcesOrPushWorklist(retInst->getReturnValue()); } @@ -910,7 +857,7 @@ Set &ObjTypeInference::bwFindAllocOrClsNameSources(const Value *s return _valueToAllocOrClsNameSources[startValue]; } -Set &ObjTypeInference::fwFindClsNameSources(const Value *startValue) +Set& ObjTypeInference::fwFindClsNameSources(const Value* startValue) { assert(startValue && "startValue was null?"); @@ -921,27 +868,26 @@ Set &ObjTypeInference::fwFindClsNameSources(const Value *start return tIt->second; } - Set sources; + Set sources; // Lambda for adding a callee to the sources iff it is a constructor/destructor/template/dyncast - auto inferViaCppCall = [&sources](const CallBase *caller) - { + auto inferViaCppCall = [&sources](const CallBase* caller) { if (!caller) return; if (isClsNameSource(caller)) sources.insert(caller); }; // Find all calls of starting val (or through cast); add as potential source iff applicable - for (const auto *user : startValue->users()) + for (const auto* user : startValue->users()) { - if (const auto *caller = SVFUtil::dyn_cast(user)) + if (const auto* caller = SVFUtil::dyn_cast(user)) { inferViaCppCall(caller); } - else if (const auto *bitcast = SVFUtil::dyn_cast(user)) + else if (const auto* bitcast = SVFUtil::dyn_cast(user)) { - for (const auto *cast_user : bitcast->users()) + for (const auto* cast_user : bitcast->users()) { - if (const auto *caller = SVFUtil::dyn_cast(cast_user)) + if (const auto* caller = SVFUtil::dyn_cast(cast_user)) { inferViaCppCall(caller); } diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 4b6b80e42..20ca1286c 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -46,7 +46,6 @@ using namespace SVF; using namespace SVFUtil; using namespace LLVMUtil; - /*! * Start building SVFIR here */ @@ -78,8 +77,7 @@ SVFIR* SVFIRBuilder::build() } // If the SVFIR has been built before, then we return the unique SVFIR of the program - if(pag->getNodeNumAfterPAGBuild() > 1) - return pag; + if (pag->getNodeNumAfterPAGBuild() > 1) return pag; /// initial external library information /// initial SVFIR nodes @@ -97,22 +95,21 @@ SVFIR* SVFIRBuilder::build() const Function& fun = *F; const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(&fun); /// collect return node of function fun - if(!fun.isDeclaration()) + if (!fun.isDeclaration()) { /// Return SVFIR node will not be created for function which can not /// reach the return instruction due to call to abort(), exit(), /// etc. In 176.gcc of SPEC 2000, function build_objc_string() from /// c-lang.c shows an example when fun.doesNotReturn() evaluates /// to TRUE because of abort(). - if(fun.doesNotReturn() == false && fun.getReturnType()->isVoidTy() == false) - pag->addFunRet(svffun,pag->getGNode(pag->getReturnNode(svffun))); + if (fun.doesNotReturn() == false && fun.getReturnType()->isVoidTy() == false) + pag->addFunRet(svffun, pag->getGNode(pag->getReturnNode(svffun))); /// To be noted, we do not record arguments which are in declared function without body /// TODO: what about external functions with SVFIR imported by commandline? - for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end(); - I != E; ++I) + for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end(); I != E; ++I) { - setCurrentLocation(&*I,&fun.getEntryBlock()); + setCurrentLocation(&*I, &fun.getEntryBlock()); NodeID argValNodeId = pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&*I)); // if this is the function does not have caller (e.g. main) // or a dead function, shall we create a black hole address edge for it? @@ -121,18 +118,16 @@ SVFIR* SVFIRBuilder::build() // if(I->getType()->isPointerTy()) // addBlackHoleAddrEdge(argValNodeId); //} - pag->addFunArgs(svffun,pag->getGNode(argValNodeId)); + pag->addFunArgs(svffun, pag->getGNode(argValNodeId)); } } - for (Function::const_iterator bit = fun.begin(), ebit = fun.end(); - bit != ebit; ++bit) + for (Function::const_iterator bit = fun.begin(), ebit = fun.end(); bit != ebit; ++bit) { const BasicBlock& bb = *bit; - for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end(); - it != eit; ++it) + for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end(); it != eit; ++it) { const Instruction& inst = *it; - setCurrentLocation(&inst,&bb); + setCurrentLocation(&inst, &bb); visit(const_cast(inst)); } } @@ -146,16 +141,13 @@ SVFIR* SVFIRBuilder::build() pag->setNodeNumAfterPAGBuild(pag->getTotalNodeNum()); // dump SVFIR - if (Options::PAGDotGraph()) - pag->dump("svfir_initial"); + if (Options::PAGDotGraph()) pag->dump("svfir_initial"); // print to command line of the SVFIR graph - if (Options::PAGPrint()) - pag->print(); + if (Options::PAGPrint()) pag->print(); // dump ICFG - if (Options::DumpICFG()) - pag->getICFG()->dump("icfg_initial"); + if (Options::DumpICFG()) pag->getICFG()->dump("icfg_initial"); if (Options::LoopAnalysis()) { @@ -189,52 +181,46 @@ void SVFIRBuilder::initialiseNodes() pag->addBlackholePtrNode(); addNullPtrNode(); - for (SymbolTableInfo::ValueToIDMapTy::iterator iter = - symTable->valSyms().begin(); iter != symTable->valSyms().end(); - ++iter) + for (SymbolTableInfo::ValueToIDMapTy::iterator iter = symTable->valSyms().begin(); + iter != symTable->valSyms().end(); ++iter) { DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n"); - if(iter->second == symTable->blkPtrSymID() || iter->second == symTable->nullPtrSymID()) - continue; + if (iter->second == symTable->blkPtrSymID() || iter->second == symTable->nullPtrSymID()) continue; pag->addValNode(iter->first, iter->second); } - for (SymbolTableInfo::ValueToIDMapTy::iterator iter = - symTable->objSyms().begin(); iter != symTable->objSyms().end(); - ++iter) + for (SymbolTableInfo::ValueToIDMapTy::iterator iter = symTable->objSyms().begin(); + iter != symTable->objSyms().end(); ++iter) { DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n"); - if(iter->second == symTable->blackholeSymID() || iter->second == symTable->constantSymID()) - continue; + if (iter->second == symTable->blackholeSymID() || iter->second == symTable->constantSymID()) continue; pag->addObjNode(iter->first, iter->second); } - for (SymbolTableInfo::FunToIDMapTy::iterator iter = - symTable->retSyms().begin(); iter != symTable->retSyms().end(); - ++iter) + for (SymbolTableInfo::FunToIDMapTy::iterator iter = symTable->retSyms().begin(); iter != symTable->retSyms().end(); + ++iter) { DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n"); pag->addRetNode(iter->first, iter->second); } - for (SymbolTableInfo::FunToIDMapTy::iterator iter = - symTable->varargSyms().begin(); - iter != symTable->varargSyms().end(); ++iter) + for (SymbolTableInfo::FunToIDMapTy::iterator iter = symTable->varargSyms().begin(); + iter != symTable->varargSyms().end(); ++iter) { DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n"); pag->addVarargNode(iter->first, iter->second); } /// add address edges for constant nodes. - for (SymbolTableInfo::ValueToIDMapTy::iterator iter = - symTable->objSyms().begin(); iter != symTable->objSyms().end(); ++iter) + for (SymbolTableInfo::ValueToIDMapTy::iterator iter = symTable->objSyms().begin(); + iter != symTable->objSyms().end(); ++iter) { DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n"); const SVFValue* val = iter->first; if (isConstantObjSym(val)) { NodeID ptr = pag->getValueNode(val); - if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr()) + if (ptr != pag->getBlkPtr() && ptr != pag->getNullPtr()) { setCurrentLocation(val, nullptr); addAddrEdge(iter->second, ptr); @@ -242,9 +228,7 @@ void SVFIRBuilder::initialiseNodes() } } - assert(pag->getTotalNodeNum() >= symTable->getTotalSymNum() - && "not all node have been initialized!!!"); - + assert(pag->getTotalNodeNum() >= symTable->getTotalSymNum() && "not all node have been initialized!!!"); } /* @@ -256,7 +240,8 @@ void SVFIRBuilder::initialiseNodes() e.g. field_idx = getelementptr i8, %struct_type %p, i64 1 */ -u32_t SVFIRBuilder::inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout *dl, AccessPath& ap, APOffset idx) +u32_t SVFIRBuilder::inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, DataLayout* dl, AccessPath& ap, + APOffset idx) { return 0; } @@ -267,68 +252,69 @@ u32_t SVFIRBuilder::inferFieldIdxFromByteOffset(const llvm::GEPOperator* gepOp, * otherwise if "i" is a variable determined by runtime, then it is a variant offset * Return TRUE if the offset of this GEP insn is a constant. */ -bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap) +bool SVFIRBuilder::computeGepOffset(const User* V, AccessPath& ap) { assert(V); - const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast(V); - DataLayout * dataLayout = getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule()); - llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true); - if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset)) + const llvm::GEPOperator* gepOp = SVFUtil::dyn_cast(V); + DataLayout* dataLayout = getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule()); + llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()), 0, true); + if (gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout, byteOffset)) { - //s32_t bo = byteOffset.getSExtValue(); + // s32_t bo = byteOffset.getSExtValue(); } bool isConst = true; bool prevPtrOperand = false; - for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V); - gi != ge; ++gi) + for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V); gi != ge; ++gi) { const Type* gepTy = *gi; const SVFType* svfGepTy = LLVMModuleSet::getLLVMModuleSet()->getSVFType(gepTy); assert((prevPtrOperand && svfGepTy->isPointerTy()) == false && "Expect no more than one gep operand to be of a pointer type"); - if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true; + if (!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true; const Value* offsetVal = gi.getOperand(); const SVFValue* offsetSvfVal = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(offsetVal); assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?"); ap.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(offsetSvfVal)), svfGepTy); - //The int value of the current index operand + // The int value of the current index operand const ConstantInt* op = SVFUtil::dyn_cast(offsetVal); // if Options::ModelConsts() is disabled. We will treat whole array as one, // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2 - if(const ArrayType* arrTy = SVFUtil::dyn_cast(gepTy)) + if (const ArrayType* arrTy = SVFUtil::dyn_cast(gepTy)) { - if(!op || (arrTy->getArrayNumElements() <= (u32_t)op->getSExtValue())) - continue; + if (!op || (arrTy->getArrayNumElements() <= (u32_t)op->getSExtValue())) continue; APOffset idx = op->getSExtValue(); - u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(arrTy), idx); + u32_t offset = + pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(arrTy), idx); ap.setFldIdx(ap.getConstantStructFldIdx() + offset); } - else if (const StructType *ST = SVFUtil::dyn_cast(gepTy)) + else if (const StructType* ST = SVFUtil::dyn_cast(gepTy)) { assert(op && "non-const offset accessing a struct"); - //The actual index + // The actual index APOffset idx = op->getSExtValue(); - u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(ST), idx); + u32_t offset = + pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(ST), idx); ap.setFldIdx(ap.getConstantStructFldIdx() + offset); } else if (gepTy->isSingleValueType()) { // If it's a non-constant offset access - // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index) - // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index) - if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType()) + // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, + // i32 %non-const-index) If its point-to target is single value (pointer arithmetic), then it's a variant + // gep (%result = gep i8* %p, i32 %non-const-index) + if (!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType()) { isConst = false; } // The actual index - //s32_t idx = op->getSExtValue(); + // s32_t idx = op->getSExtValue(); // For pointer arithmetic we ignore the byte offset // consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)? @@ -347,12 +333,13 @@ void SVFIRBuilder::processCE(const Value* val) { if (const ConstantExpr* gepce = isGepConstantExpr(ref)) { - DBOUT(DPAGBuild, outs() << "handle gep constant expression " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); + DBOUT(DPAGBuild, outs() << "handle gep constant expression " + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); const Constant* opnd = gepce->getOperand(0); // handle recursive constant express case (gep (bitcast (gep X 1)) 1) processCE(opnd); - auto &GEPOp = llvm::cast(*gepce); - Type *pType = GEPOp.getSourceElementType(); + auto& GEPOp = llvm::cast(*gepce); + Type* pType = GEPOp.getSourceElementType(); AccessPath ap(0, LLVMModuleSet::getLLVMModuleSet()->getSVFType(pType)); bool constGep = computeGepOffset(gepce, ap); // must invoke pag methods here, otherwise it will be a dead recursion cycle @@ -363,23 +350,27 @@ void SVFIRBuilder::processCE(const Value* val) * The gep edge created are like constexpr (same edge may appear at multiple callsites) * so bb/inst of this edge may be rewritten several times, we treat it as global here. */ - addGepEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gepce)), ap, constGep); + addGepEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), + pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gepce)), ap, constGep); setCurrentLocation(cval, cbb); } else if (const ConstantExpr* castce = isCastConstantExpr(ref)) { - DBOUT(DPAGBuild, outs() << "handle cast constant expression " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); + DBOUT(DPAGBuild, outs() << "handle cast constant expression " + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); const Constant* opnd = castce->getOperand(0); processCE(opnd); const SVFValue* cval = getCurrentValue(); const SVFBasicBlock* cbb = getCurrentBB(); setCurrentLocation(castce, nullptr); - addCopyEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(castce)), CopyStmt::BITCAST); + addCopyEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), + pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(castce)), CopyStmt::BITCAST); setCurrentLocation(cval, cbb); } else if (const ConstantExpr* selectce = isSelectConstantExpr(ref)) { - DBOUT(DPAGBuild, outs() << "handle select constant expression " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); + DBOUT(DPAGBuild, outs() << "handle select constant expression " + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); const Constant* src1 = selectce->getOperand(1); const Constant* src2 = selectce->getOperand(2); processCE(src1); @@ -391,7 +382,7 @@ void SVFIRBuilder::processCE(const Value* val) NodeID nsrc1 = pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(src1)); NodeID nsrc2 = pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(src2)); NodeID nres = pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(selectce)); - addSelectStmt(nres,nsrc1, nsrc2, cond); + addSelectStmt(nres, nsrc1, nsrc2, cond); setCurrentLocation(cval, cbb); } // if we meet a int2ptr, then it points-to black hole @@ -402,7 +393,9 @@ void SVFIRBuilder::processCE(const Value* val) const SVFBasicBlock* cbb = getCurrentBB(); const SVFValue* cval = getCurrentValue(); setCurrentLocation(int2Ptrce, nullptr); - addCopyEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(int2Ptrce)), CopyStmt::INTTOPTR); + addCopyEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), + pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(int2Ptrce)), + CopyStmt::INTTOPTR); setCurrentLocation(cval, cbb); } else if (const ConstantExpr* ptr2Intce = isPtr2IntConstantExpr(ref)) @@ -412,10 +405,12 @@ void SVFIRBuilder::processCE(const Value* val) const SVFBasicBlock* cbb = getCurrentBB(); const SVFValue* cval = getCurrentValue(); setCurrentLocation(ptr2Intce, nullptr); - addCopyEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ptr2Intce)), CopyStmt::PTRTOINT); + addCopyEdge(pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(opnd)), + pag->getValueNode(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ptr2Intce)), + CopyStmt::PTRTOINT); setCurrentLocation(cval, cbb); } - else if(isTruncConstantExpr(ref) || isCmpConstantExpr(ref)) + else if (isTruncConstantExpr(ref) || isCmpConstantExpr(ref)) { // we don't handle trunc and cmp instruction for now const SVFValue* cval = getCurrentValue(); @@ -452,7 +447,8 @@ void SVFIRBuilder::processCE(const Value* val) else if (SVFUtil::isa(ref)) { // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182)) - // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194 + // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and + // SVFIRBuilder.cpp:183-194 const SVFValue* cval = getCurrentValue(); const SVFBasicBlock* cbb = getCurrentBB(); setCurrentLocation(ref, nullptr); @@ -462,7 +458,7 @@ void SVFIRBuilder::processCE(const Value* val) } else { - if(SVFUtil::isa(val)) + if (SVFUtil::isa(val)) assert(false && "we don't handle all other constant expression for now!"); } } @@ -472,7 +468,7 @@ void SVFIRBuilder::processCE(const Value* val) * FIXME:Here we only get the field that actually used in the program * We ignore the initialization of global variable field that not used in the program */ -NodeID SVFIRBuilder::getGlobalVarField(const GlobalVariable *gvar, u32_t offset, SVFType* tpy) +NodeID SVFIRBuilder::getGlobalVarField(const GlobalVariable* gvar, u32_t offset, SVFType* tpy) { // if the global variable do not have any field needs to be initialized @@ -499,10 +495,11 @@ NodeID SVFIRBuilder::getGlobalVarField(const GlobalVariable *gvar, u32_t offset, * struct Z *m = &z; // store z m (pointer type) * struct Z n = {10,&z.s}; // store z.s n , &z.s constant expression (constant expression) */ -void SVFIRBuilder::InitialGlobal(const GlobalVariable *gvar, Constant *C, - u32_t offset) +void SVFIRBuilder::InitialGlobal(const GlobalVariable* gvar, Constant* C, u32_t offset) { - DBOUT(DPAGBuild, outs() << "global " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gvar)->toString() << " constant initializer: " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(C)->toString() << "\n"); + DBOUT(DPAGBuild, + outs() << "global " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gvar)->toString() + << " constant initializer: " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(C)->toString() << "\n"); if (C->getType()->isSingleValueType()) { NodeID src = getValueNode(C); @@ -525,7 +522,8 @@ void SVFIRBuilder::InitialGlobal(const GlobalVariable *gvar, Constant *C, else if (SVFUtil::isa(C)) { // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182)) - // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194 + // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and + // SVFIRBuilder.cpp:183-194 processCE(C); setCurrentLocation(C, nullptr); addAddrEdge(pag->getConstantNode(), src); @@ -541,36 +539,38 @@ void SVFIRBuilder::InitialGlobal(const GlobalVariable *gvar, Constant *C, } else if (SVFUtil::isa(C)) { - if(cppUtil::isValVtbl(gvar) && !Options::VtableInSVFIR()) - return; + if (cppUtil::isValVtbl(gvar) && !Options::VtableInSVFIR()) return; for (u32_t i = 0, e = C->getNumOperands(); i != e; i++) { - u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(C->getType()), i); + u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx( + LLVMModuleSet::getLLVMModuleSet()->getSVFType(C->getType()), i); InitialGlobal(gvar, SVFUtil::cast(C->getOperand(i)), offset + off); } } - else if(ConstantData* data = SVFUtil::dyn_cast(C)) + else if (ConstantData* data = SVFUtil::dyn_cast(C)) { - if(Options::ModelConsts()) + if (Options::ModelConsts()) { - if(ConstantDataSequential* seq = SVFUtil::dyn_cast(data)) + if (ConstantDataSequential* seq = SVFUtil::dyn_cast(data)) { - for(u32_t i = 0; i < seq->getNumElements(); i++) + for (u32_t i = 0; i < seq->getNumElements(); i++) { - u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx(LLVMModuleSet::getLLVMModuleSet()->getSVFType(C->getType()), i); + u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx( + LLVMModuleSet::getLLVMModuleSet()->getSVFType(C->getType()), i); Constant* ct = seq->getElementAsConstant(i); InitialGlobal(gvar, ct, offset + off); } } else { - assert((SVFUtil::isa(data)) && "Single value type data should have been handled!"); + assert((SVFUtil::isa(data)) && + "Single value type data should have been handled!"); } } } else { - //TODO:assert(SVFUtil::isa(C),"what else do we have"); + // TODO:assert(SVFUtil::isa(C),"what else do we have"); } } @@ -581,11 +581,11 @@ void SVFIRBuilder::visitGlobal(SVFModule* svfModule) { /// initialize global variable - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - GlobalVariable *gvar = &*I; + GlobalVariable* gvar = &*I; NodeID idx = getValueNode(gvar); NodeID obj = getObjectNode(gvar); @@ -594,13 +594,13 @@ void SVFIRBuilder::visitGlobal(SVFModule* svfModule) if (gvar->hasInitializer()) { - Constant *C = gvar->getInitializer(); - DBOUT(DPAGBuild, outs() << "add global var node " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gvar)->toString() << "\n"); + Constant* C = gvar->getInitializer(); + DBOUT(DPAGBuild, outs() << "add global var node " + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gvar)->toString() << "\n"); InitialGlobal(gvar, C, 0); } } - /// initialize global functions for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { @@ -613,7 +613,8 @@ void SVFIRBuilder::visitGlobal(SVFModule* svfModule) addAddrEdge(obj, idx); } - // Handle global aliases (due to linkage of multiple bc files), e.g., @x = internal alias @y. We need to add a copy from y to x. + // Handle global aliases (due to linkage of multiple bc files), e.g., @x = internal alias @y. We need to add a + // copy from y to x. for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++) { const GlobalAlias* alias = &*I; @@ -630,28 +631,29 @@ void SVFIRBuilder::visitGlobal(SVFModule* svfModule) * Visit alloca instructions * Add edge V (dst) <-- O (src), V here is a value node on SVFIR, O is object node on SVFIR */ -void SVFIRBuilder::visitAllocaInst(AllocaInst &inst) +void SVFIRBuilder::visitAllocaInst(AllocaInst& inst) { // AllocaInst should always be a pointer type assert(SVFUtil::isa(inst.getType())); - DBOUT(DPAGBuild, outs() << "process alloca " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process alloca " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID dst = getValueNode(&inst); NodeID src = getObjectNode(&inst); addAddrWithStackArraySz(src, dst, inst); - } /*! * Visit phi instructions */ -void SVFIRBuilder::visitPHINode(PHINode &inst) +void SVFIRBuilder::visitPHINode(PHINode& inst) { - DBOUT(DPAGBuild, outs() << "process phi " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process phi " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID dst = getValueNode(&inst); @@ -659,24 +661,24 @@ void SVFIRBuilder::visitPHINode(PHINode &inst) { const Value* val = inst.getIncomingValue(i); const Instruction* incomingInst = SVFUtil::dyn_cast(val); - bool matched = (incomingInst == nullptr || - incomingInst->getFunction() == inst.getFunction()); - (void) matched; // Suppress warning of unused variable under release build + bool matched = (incomingInst == nullptr || incomingInst->getFunction() == inst.getFunction()); + (void)matched; // Suppress warning of unused variable under release build assert(matched && "incomingInst's Function incorrect"); const Instruction* predInst = &inst.getIncomingBlock(i)->back(); const SVFInstruction* svfPrevInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(predInst); const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(svfPrevInst); NodeID src = getValueNode(val); - addPhiStmt(dst,src,icfgNode); + addPhiStmt(dst, src, icfgNode); } } /* * Visit load instructions */ -void SVFIRBuilder::visitLoadInst(LoadInst &inst) +void SVFIRBuilder::visitLoadInst(LoadInst& inst) { - DBOUT(DPAGBuild, outs() << "process load " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process load " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID dst = getValueNode(&inst); @@ -688,31 +690,31 @@ void SVFIRBuilder::visitLoadInst(LoadInst &inst) /*! * Visit store instructions */ -void SVFIRBuilder::visitStoreInst(StoreInst &inst) +void SVFIRBuilder::visitStoreInst(StoreInst& inst) { // StoreInst itself should always not be a pointer type assert(!SVFUtil::isa(inst.getType())); - DBOUT(DPAGBuild, outs() << "process store " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process store " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID dst = getValueNode(inst.getPointerOperand()); NodeID src = getValueNode(inst.getValueOperand()); addStoreEdge(src, dst); - } /*! * Visit getelementptr instructions */ -void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst) +void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst& inst) { NodeID dst = getValueNode(&inst); // GetElementPtrInst should always be a pointer or a vector contains pointers // for now we don't handle vector type here - if(SVFUtil::isa(inst.getType())) + if (SVFUtil::isa(inst.getType())) { addBlackHoleAddrEdge(dst); return; @@ -720,7 +722,8 @@ void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst) assert(SVFUtil::isa(inst.getType())); - DBOUT(DPAGBuild, outs() << "process gep " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process gep " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID src = getValueNode(inst.getPointerOperand()); @@ -732,10 +735,11 @@ void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst) /* * Visit cast instructions */ -void SVFIRBuilder::visitCastInst(CastInst &inst) +void SVFIRBuilder::visitCastInst(CastInst& inst) { - DBOUT(DPAGBuild, outs() << "process cast " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process cast " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID dst = getValueNode(&inst); const Value* opnd = inst.getOperand(0); @@ -746,7 +750,7 @@ void SVFIRBuilder::visitCastInst(CastInst &inst) /*! * Visit Binary Operator */ -void SVFIRBuilder::visitBinaryOperator(BinaryOperator &inst) +void SVFIRBuilder::visitBinaryOperator(BinaryOperator& inst) { NodeID dst = getValueNode(&inst); assert(inst.getNumOperands() == 2 && "not two operands for BinaryOperator?"); @@ -761,7 +765,7 @@ void SVFIRBuilder::visitBinaryOperator(BinaryOperator &inst) /*! * Visit Unary Operator */ -void SVFIRBuilder::visitUnaryOperator(UnaryOperator &inst) +void SVFIRBuilder::visitUnaryOperator(UnaryOperator& inst) { NodeID dst = getValueNode(&inst); assert(inst.getNumOperands() == 1 && "not one operand for Unary instruction?"); @@ -774,7 +778,7 @@ void SVFIRBuilder::visitUnaryOperator(UnaryOperator &inst) /*! * Visit compare instruction */ -void SVFIRBuilder::visitCmpInst(CmpInst &inst) +void SVFIRBuilder::visitCmpInst(CmpInst& inst) { NodeID dst = getValueNode(&inst); assert(inst.getNumOperands() == 2 && "not two operands for compare instruction?"); @@ -786,34 +790,34 @@ void SVFIRBuilder::visitCmpInst(CmpInst &inst) addCmpEdge(op1Node, op2Node, dst, predicate); } - /*! * Visit select instructions */ -void SVFIRBuilder::visitSelectInst(SelectInst &inst) +void SVFIRBuilder::visitSelectInst(SelectInst& inst) { - DBOUT(DPAGBuild, outs() << "process select " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process select " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); NodeID dst = getValueNode(&inst); NodeID src1 = getValueNode(inst.getTrueValue()); NodeID src2 = getValueNode(inst.getFalseValue()); NodeID cond = getValueNode(inst.getCondition()); /// Two operands have same incoming basic block, both are the current BB - addSelectStmt(dst,src1,src2, cond); + addSelectStmt(dst, src1, src2, cond); } -void SVFIRBuilder::visitCallInst(CallInst &i) +void SVFIRBuilder::visitCallInst(CallInst& i) { visitCallSite(&i); } -void SVFIRBuilder::visitInvokeInst(InvokeInst &i) +void SVFIRBuilder::visitInvokeInst(InvokeInst& i) { visitCallSite(&i); } -void SVFIRBuilder::visitCallBrInst(CallBrInst &i) +void SVFIRBuilder::visitCallBrInst(CallBrInst& i) { visitCallSite(&i); } @@ -825,13 +829,11 @@ void SVFIRBuilder::visitCallSite(CallBase* cs) { // skip llvm intrinsics - if(isIntrinsicInst(cs)) - return; + if (isIntrinsicInst(cs)) return; const SVFInstruction* svfcall = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs); - DBOUT(DPAGBuild, - outs() << "process callsite " << svfcall->toString() << "\n"); + DBOUT(DPAGBuild, outs() << "process callsite " << svfcall->toString() << "\n"); CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(svfcall); RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(svfcall); @@ -840,12 +842,11 @@ void SVFIRBuilder::visitCallSite(CallBase* cs) /// Collect callsite arguments and returns for (u32_t i = 0; i < cs->arg_size(); i++) - pag->addCallSiteArgs(callBlockNode,pag->getGNode(getValueNode(cs->getArgOperand(i)))); + pag->addCallSiteArgs(callBlockNode, pag->getGNode(getValueNode(cs->getArgOperand(i)))); - if(!cs->getType()->isVoidTy()) - pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs))); + if (!cs->getType()->isVoidTy()) pag->addCallSiteRets(retBlockNode, pag->getGNode(getValueNode(cs))); - if (const Function *callee = LLVMUtil::getCallee(cs)) + if (const Function* callee = LLVMUtil::getCallee(cs)) { callee = LLVMUtil::getDefFunForMultipleModule(callee); const SVFFunction* svfcallee = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee); @@ -860,7 +861,7 @@ void SVFIRBuilder::visitCallSite(CallBase* cs) } else { - //If the callee was not identified as a function (null F), this is indirect. + // If the callee was not identified as a function (null F), this is indirect. handleIndCall(cs); } } @@ -868,28 +869,28 @@ void SVFIRBuilder::visitCallSite(CallBase* cs) /*! * Visit return instructions of a function */ -void SVFIRBuilder::visitReturnInst(ReturnInst &inst) +void SVFIRBuilder::visitReturnInst(ReturnInst& inst) { // ReturnInst itself should always not be a pointer type assert(!SVFUtil::isa(inst.getType())); - DBOUT(DPAGBuild, outs() << "process return " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); + DBOUT(DPAGBuild, + outs() << "process return " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(&inst)->toString() << " \n"); - if(Value* src = inst.getReturnValue()) + if (Value* src = inst.getReturnValue()) { - const SVFFunction *F = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(inst.getParent()->getParent()); + const SVFFunction* F = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(inst.getParent()->getParent()); NodeID rnF = getReturnNode(F); NodeID vnS = getValueNode(src); const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(&inst); const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(svfInst); - //vnS may be null if src is a null ptr - addPhiStmt(rnF,vnS,icfgNode); + // vnS may be null if src is a null ptr + addPhiStmt(rnF, vnS, icfgNode); } } - /*! * visit extract value instructions for structures in registers * TODO: for now we just assume the pointer after extraction points to blackhole @@ -898,7 +899,7 @@ void SVFIRBuilder::visitReturnInst(ReturnInst &inst) * however we can not create %call34 as an memory object, as it is register value. * Is that necessary treat extract value as getelementptr instruction later to get more precise results? */ -void SVFIRBuilder::visitExtractValueInst(ExtractValueInst &inst) +void SVFIRBuilder::visitExtractValueInst(ExtractValueInst& inst) { NodeID dst = getValueNode(&inst); addBlackHoleAddrEdge(dst); @@ -912,7 +913,7 @@ void SVFIRBuilder::visitExtractValueInst(ExtractValueInst &inst) * * = extractelement <4 x i32> %vec, i32 0 ; yields i32 */ -void SVFIRBuilder::visitExtractElementInst(ExtractElementInst &inst) +void SVFIRBuilder::visitExtractElementInst(ExtractElementInst& inst) { NodeID dst = getValueNode(&inst); addBlackHoleAddrEdge(dst); @@ -922,12 +923,11 @@ void SVFIRBuilder::visitExtractElementInst(ExtractElementInst &inst) * Branch and switch instructions are treated as UnaryOP * br %cmp label %if.then, label %if.else */ -void SVFIRBuilder::visitBranchInst(BranchInst &inst) +void SVFIRBuilder::visitBranchInst(BranchInst& inst) { NodeID brinst = getValueNode(&inst); NodeID cond; - if (inst.isConditional()) - cond = getValueNode(inst.getCondition()); + if (inst.isConditional()) cond = getValueNode(inst.getCondition()); else cond = pag->getNullPtr(); @@ -942,13 +942,12 @@ void SVFIRBuilder::visitBranchInst(BranchInst &inst) assert(branchID <= 1 && "if/else has more than two branches?"); const SVFInstruction* svfSuccInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(succInst); const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(svfSuccInst); - successors.push_back(std::make_pair(icfgNode, 1-branchID)); + successors.push_back(std::make_pair(icfgNode, 1 - branchID)); branchID++; } addBranchStmt(brinst, cond, successors); } - /** * See more: https://github.com/SVF-tools/SVF/pull/1191 * @@ -994,7 +993,7 @@ void SVFIRBuilder::visitBranchInst(BranchInst &inst) /// see more: https://github.com/SVF-tools/SVF/pull/992 /// The following implementation follows ICFGBuilder::processFunBody -void SVFIRBuilder::visitSwitchInst(SwitchInst &inst) +void SVFIRBuilder::visitSwitchInst(SwitchInst& inst) { NodeID brinst = getValueNode(&inst); NodeID cond = getValueNode(inst.getCondition()); @@ -1008,8 +1007,7 @@ void SVFIRBuilder::visitSwitchInst(SwitchInst &inst) const ConstantInt* condVal = inst.findCaseDest(const_cast(succInst->getParent())); /// default case is set to -1; s64_t val = -1; - if (condVal && condVal->getBitWidth() <= 64) - val = condVal->getSExtValue(); + if (condVal && condVal->getBitWidth() <= 64) val = condVal->getSExtValue(); const SVFInstruction* svfSuccInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(succInst); const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(svfSuccInst); successors.push_back(std::make_pair(icfgNode, val)); @@ -1017,13 +1015,13 @@ void SVFIRBuilder::visitSwitchInst(SwitchInst &inst) addBranchStmt(brinst, cond, successors); } - /// %ap = alloca %struct.va_list /// %ap2 = bitcast %struct.va_list* %ap to i8* /// ; Read a single integer argument from %ap2 /// %tmp = va_arg i8* %ap2, i32 (VAArgInst) -/// TODO: for now, create a copy edge from %ap2 to %tmp, we assume here %tmp should point to the n-th argument of the var_args -void SVFIRBuilder::visitVAArgInst(VAArgInst &inst) +/// TODO: for now, create a copy edge from %ap2 to %tmp, we assume here %tmp should point to the n-th argument of the +/// var_args +void SVFIRBuilder::visitVAArgInst(VAArgInst& inst) { NodeID dst = getValueNode(&inst); Value* opnd = inst.getPointerOperand(); @@ -1035,7 +1033,7 @@ void SVFIRBuilder::visitVAArgInst(VAArgInst &inst) /// If is undef or poison, ‘freeze’ returns an arbitrary, but fixed value of type `ty` /// Otherwise, this instruction is a no-op and returns the input /// For now, we assume is never a poison or undef. -void SVFIRBuilder::visitFreezeInst(FreezeInst &inst) +void SVFIRBuilder::visitFreezeInst(FreezeInst& inst) { NodeID dst = getValueNode(&inst); for (u32_t i = 0; i < inst.getNumOperands(); i++) @@ -1046,11 +1044,10 @@ void SVFIRBuilder::visitFreezeInst(FreezeInst &inst) } } - /*! * Add the constraints for a direct, non-external call. */ -void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) +void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function* F) { assert(F); @@ -1059,32 +1056,33 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) DBOUT(DPAGBuild, outs() << "handle direct call " << svfcall->toString() << " callee " << F->getName().str() << "\n"); - //Only handle the ret.val. if it's used as a ptr. + // Only handle the ret.val. if it's used as a ptr. NodeID dstrec = getValueNode(cs); - //Does it actually return a ptr? + // Does it actually return a ptr? if (!cs->getType()->isVoidTy()) { NodeID srcret = getReturnNode(svffun); CallICFGNode* callICFGNode = pag->getICFG()->getCallICFGNode(svfcall); FunExitICFGNode* exitICFGNode = pag->getICFG()->getFunExitICFGNode(svffun); - addRetEdge(srcret, dstrec,callICFGNode, exitICFGNode); + addRetEdge(srcret, dstrec, callICFGNode, exitICFGNode); } - //Iterators for the actual and formal parameters + // Iterators for the actual and formal parameters u32_t itA = 0, ieA = cs->arg_size(); Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end(); - //Go through the fixed parameters. + // Go through the fixed parameters. DBOUT(DPAGBuild, outs() << " args:"); for (; itF != ieF; ++itA, ++itF) { - //Some programs (e.g. Linux kernel) leave unneeded parameters empty. + // Some programs (e.g. Linux kernel) leave unneeded parameters empty. if (itA == ieA) { DBOUT(DPAGBuild, outs() << " !! not enough args\n"); break; } - const Value* AA = cs->getArgOperand(itA), *FA = &*itF; //current actual/formal arg + const Value *AA = cs->getArgOperand(itA), *FA = &*itF; // current actual/formal arg - DBOUT(DPAGBuild, outs() << "process actual parm " << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(AA)->toString() << " \n"); + DBOUT(DPAGBuild, outs() << "process actual parm " + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(AA)->toString() << " \n"); NodeID dstFA = getValueNode(FA); NodeID srcAA = getValueNode(AA); @@ -1092,7 +1090,7 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(svffun); addCallEdge(srcAA, dstFA, icfgNode, entry); } - //Any remaining actual args must be varargs. + // Any remaining actual args must be varargs. if (F->isVarArg()) { NodeID vaF = getVarargNode(svffun); @@ -1103,33 +1101,30 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) NodeID vnAA = getValueNode(AA); CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(svfcall); FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(svffun); - addCallEdge(vnAA,vaF, icfgNode,entry); + addCallEdge(vnAA, vaF, icfgNode, entry); } } - if(itA != ieA) + if (itA != ieA) { /// FIXME: this assertion should be placed for correct checking except /// bug program like 188.ammp, 300.twolf writeWrnMsg("too many args to non-vararg func."); writeWrnMsg("(" + svfcall->getSourceLoc() + ")"); - } } const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V) { - const Value* value = stripAllCasts(V); + const Value* value = stripAllCasts(V); assert(value && "null ptr?"); - if(const GetElementPtrInst* gep = SVFUtil::dyn_cast(value)) + if (const GetElementPtrInst* gep = SVFUtil::dyn_cast(value)) { APOffset totalidx = 0; for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi) { - if(const ConstantInt* op = SVFUtil::dyn_cast(gi.getOperand())) - totalidx += op->getSExtValue(); + if (const ConstantInt* op = SVFUtil::dyn_cast(gi.getOperand())) totalidx += op->getSExtValue(); } - if(totalidx == 0 && !SVFUtil::isa(value->getType())) - value = gep->getPointerOperand(); + if (totalidx == 0 && !SVFUtil::isa(value->getType())) value = gep->getPointerOperand(); } return value; } @@ -1143,7 +1138,7 @@ void SVFIRBuilder::handleIndCall(CallBase* cs) const SVFValue* svfcalledval = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(cs->getCalledOperand()); const CallICFGNode* cbn = pag->getICFG()->getCallICFGNode(svfcall); - pag->addIndirectCallsites(cbn,pag->getValueNode(svfcalledval)); + pag->addIndirectCallsites(cbn, pag->getValueNode(svfcalledval)); } void SVFIRBuilder::updateCallGraph(CallGraph* callgraph) @@ -1153,12 +1148,15 @@ void SVFIRBuilder::updateCallGraph(CallGraph* callgraph) for (; iter != eiter; iter++) { const CallICFGNode* callBlock = iter->first; - const CallBase* callbase = SVFUtil::cast(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(callBlock->getCallSite())); + const CallBase* callbase = + SVFUtil::cast(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(callBlock->getCallSite())); assert(callBlock->isIndirectCall() && "this is not an indirect call?"); const CallGraph::FunctionSet& functions = iter->second; - for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) + for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); + func_iter++) { - const Function* callee = SVFUtil::cast(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(*func_iter)); + const Function* callee = + SVFUtil::cast(LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(*func_iter)); if (isExtCall(*func_iter)) { @@ -1175,8 +1173,7 @@ void SVFIRBuilder::updateCallGraph(CallGraph* callgraph) } // dump SVFIR - if (Options::PAGDotGraph()) - pag->dump("svfir_final"); + if (Options::PAGDotGraph()) pag->dump("svfir_final"); } /* @@ -1186,24 +1183,23 @@ void SVFIRBuilder::sanityCheck() { for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter) { - (void) pag->getGNode(nIter->first); - //TODO:: - // (1) every source(root) node of a pag tree should be object node - // if a node has no incoming edge, but has outgoing edges - // then it has to be an object node. - // (2) make sure every variable should be initialized - // otherwise it causes the a null pointer, the aliasing relation may not be captured - // when loading a pointer value should make sure - // some value has been store into this pointer before - // q = load p, some value should stored into p first like store w p; - // (3) make sure PAGNode should not have a const expr value (pointer should have unique def) - // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb) - // are set correctly for dummy gepval node - // (5) reduce unnecessary copy edge (const casts) and ensure correctness. + (void)pag->getGNode(nIter->first); + // TODO:: + // (1) every source(root) node of a pag tree should be object node + // if a node has no incoming edge, but has outgoing edges + // then it has to be an object node. + // (2) make sure every variable should be initialized + // otherwise it causes the a null pointer, the aliasing relation may not be captured + // when loading a pointer value should make sure + // some value has been store into this pointer before + // q = load p, some value should stored into p first like store w p; + // (3) make sure PAGNode should not have a const expr value (pointer should have unique def) + // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb) + // are set correctly for dummy gepval node + // (5) reduce unnecessary copy edge (const casts) and ensure correctness. } } - /*! * Add a temp field value node according to base value and offset * this node is after the initial node method, it is out of scope of symInfo table @@ -1212,9 +1208,9 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const { NodeID base = getValueNode(val); NodeID gepval = pag->getGepValVar(curVal, base, ap); - if (gepval==UINT_MAX) + if (gepval == UINT_MAX) { - assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?"); + assert(((int)UINT_MAX) == -1 && "maximum limit of unsigned int is not -1?"); /* * getGepValVar can only be called from two places: * 1. SVFIRBuilder::addComplexConsForExt to handle external calls @@ -1223,7 +1219,8 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const * 1. Instruction * 2. GlobalVariable */ - assert((SVFUtil::isa(curVal)) && "curVal not an instruction or a globalvariable?"); + assert((SVFUtil::isa(curVal)) && + "curVal not an instruction or a globalvariable?"); // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program // We preserve the current BB information to restore it after creating the gepNode @@ -1231,9 +1228,9 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const const SVFBasicBlock* cbb = getCurrentBB(); setCurrentLocation(curVal, nullptr); LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet(); - NodeID gepNode = pag->addGepValNode(curVal, llvmmodule->getSVFValue(val), ap, - NodeIDAllocator::get()->allocateValueId(), - llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext()))); + NodeID gepNode = + pag->addGepValNode(curVal, llvmmodule->getSVFValue(val), ap, NodeIDAllocator::get()->allocateValueId(), + llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext()))); addGepEdge(base, gepNode, ap, true); setCurrentLocation(cval, cbb); return gepNode; @@ -1242,7 +1239,6 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const return gepval; } - /* * curVal <--------> PAGEdge * Instruction Any Edge @@ -1258,11 +1254,10 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const */ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) { - if (SVFModule::pagReadFromTXT()) - return; + if (SVFModule::pagReadFromTXT()) return; assert(curVal && "current Val is nullptr?"); - edge->setBB(curBB!=nullptr ? curBB : nullptr); + edge->setBB(curBB != nullptr ? curBB : nullptr); edge->setValue(curVal); // backmap in valuToEdgeMap pag->mapValueToEdge(curVal, edge); @@ -1271,13 +1266,15 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) { const SVFFunction* srcFun = edge->getSrcNode()->getFunction(); const SVFFunction* dstFun = edge->getDstNode()->getFunction(); - if(srcFun!=nullptr && !SVFUtil::isa(edge) && !SVFUtil::isa(edge->getSrcNode()->getValue())) + if (srcFun != nullptr && !SVFUtil::isa(edge) && + !SVFUtil::isa(edge->getSrcNode()->getValue())) { - assert(srcFun==curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?"); + assert(srcFun == curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?"); } - if(dstFun!=nullptr && !SVFUtil::isa(edge) && !SVFUtil::isa(edge->getDstNode()->getValue())) + if (dstFun != nullptr && !SVFUtil::isa(edge) && + !SVFUtil::isa(edge->getDstNode()->getValue())) { - assert(dstFun==curInst->getFunction() && "DstNode of the PAGEdge not in the same function?"); + assert(dstFun == curInst->getFunction() && "DstNode of the PAGEdge not in the same function?"); } /// We assume every GepValVar and its GepStmt are unique across whole program @@ -1285,14 +1282,13 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) assert(curBB && "instruction does not have a basic block??"); /// We will have one unique function exit ICFGNode for all returns - if(curInst->isRetInst()) + if (curInst->isRetInst()) { icfgNode = pag->getICFG()->getFunExitICFGNode(curInst->getFunction()); } else { - if(SVFUtil::isa(edge)) - icfgNode = pag->getICFG()->getRetICFGNode(curInst); + if (SVFUtil::isa(edge)) icfgNode = pag->getICFG()->getRetICFGNode(curInst); else icfgNode = pag->getICFG()->getICFGNode(curInst); } @@ -1302,12 +1298,10 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) assert(curBB && (curBB->getParent()->getEntryBlock() == curBB)); icfgNode = pag->getICFG()->getFunEntryICFGNode(arg->getParent()); } - else if (SVFUtil::isa(curVal) || - SVFUtil::isa(curVal) || + else if (SVFUtil::isa(curVal) || SVFUtil::isa(curVal) || SVFUtil::isa(curVal)) { - if (!curBB) - pag->addGlobalPAGEdge(edge); + if (!curBB) pag->addGlobalPAGEdge(edge); else { icfgNode = pag->getICFG()->getICFGNode(curBB->front()); @@ -1318,25 +1312,24 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) assert(false && "what else value can we have?"); } - pag->addToSVFStmtList(icfgNode,edge); + pag->addToSVFStmtList(icfgNode, edge); icfgNode->addSVFStmt(edge); - if(const CallPE* callPE = SVFUtil::dyn_cast(edge)) + if (const CallPE* callPE = SVFUtil::dyn_cast(edge)) { CallICFGNode* callNode = const_cast(callPE->getCallSite()); FunEntryICFGNode* entryNode = const_cast(callPE->getFunEntryICFGNode()); - if(ICFGEdge* edge = pag->getICFG()->hasInterICFGEdge(callNode,entryNode, ICFGEdge::CallCF)) + if (ICFGEdge* edge = pag->getICFG()->hasInterICFGEdge(callNode, entryNode, ICFGEdge::CallCF)) SVFUtil::cast(edge)->addCallPE(callPE); } - else if(const RetPE* retPE = SVFUtil::dyn_cast(edge)) + else if (const RetPE* retPE = SVFUtil::dyn_cast(edge)) { RetICFGNode* retNode = const_cast(retPE->getCallSite()->getRetICFGNode()); FunExitICFGNode* exitNode = const_cast(retPE->getFunExitICFGNode()); - if(ICFGEdge* edge = pag->getICFG()->hasInterICFGEdge(exitNode, retNode, ICFGEdge::RetCF)) + if (ICFGEdge* edge = pag->getICFG()->hasInterICFGEdge(exitNode, retNode, ICFGEdge::RetCF)) SVFUtil::cast(edge)->addRetPE(retPE); } } - /*! * Get a base SVFVar given a pointer * Return the source node of its connected normal gep edge @@ -1345,17 +1338,15 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) */ AccessPath SVFIRBuilder::getAccessPathFromBaseNode(NodeID nodeId) { - SVFVar* node = pag->getGNode(nodeId); + SVFVar* node = pag->getGNode(nodeId); SVFStmt::SVFStmtSetTy& geps = node->getIncomingEdges(SVFStmt::Gep); /// if this node is already a base node - if(geps.empty()) - return AccessPath(0); + if (geps.empty()) return AccessPath(0); - assert(geps.size()==1 && "one node can only be connected by at most one gep edge!"); + assert(geps.size() == 1 && "one node can only be connected by at most one gep edge!"); SVFVar::iterator it = geps.begin(); const GepStmt* gepEdge = SVFUtil::cast(*it); - if(gepEdge->isVariantFieldGep()) - return AccessPath(0); + if (gepEdge->isVariantFieldGep()) return AccessPath(0); else return gepEdge->getAccessPath(); } diff --git a/svf-llvm/lib/SVFIRExtAPI.cpp b/svf-llvm/lib/SVFIRExtAPI.cpp index fb19d7f16..c192137b2 100644 --- a/svf-llvm/lib/SVFIRExtAPI.cpp +++ b/svf-llvm/lib/SVFIRExtAPI.cpp @@ -40,20 +40,24 @@ using namespace LLVMUtil; /*! * Find the base type and the max possible offset of an object pointed to by (V). */ -const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(const Value* V, std::vector &fields, const Value* szValue) +const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(const Value* V, std::vector& fields, + const Value* szValue) { assert(V); const Value* value = getBaseValueForExtArg(V); - const Type *objType = LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(value); - u32_t numOfElems = pag->getSymbolInfo()->getNumOfFlattenElements(LLVMModuleSet::getLLVMModuleSet()->getSVFType(objType)); + const Type* objType = LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(value); + u32_t numOfElems = + pag->getSymbolInfo()->getNumOfFlattenElements(LLVMModuleSet::getLLVMModuleSet()->getSVFType(objType)); /// use user-specified size for this copy operation if the size is a constaint int - if(szValue && SVFUtil::isa(szValue)) + if (szValue && SVFUtil::isa(szValue)) { - numOfElems = (numOfElems > SVFUtil::cast(szValue)->getSExtValue()) ? SVFUtil::cast(szValue)->getSExtValue() : numOfElems; + numOfElems = (numOfElems > SVFUtil::cast(szValue)->getSExtValue()) + ? SVFUtil::cast(szValue)->getSExtValue() + : numOfElems; } LLVMContext& context = LLVMModuleSet::getLLVMModuleSet()->getContext(); - for(u32_t ei = 0; ei < numOfElems; ei++) + for (u32_t ei = 0; ei < numOfElems; ei++) { AccessPath ls(ei); // make a ConstantInt and create char for the content type due to byte-wise copy @@ -75,22 +79,20 @@ const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(const Value* V, std::vec * Add the load/store constraints and temp. nodes for the complex constraint * *D = *S (where D/S may point to structs). */ -void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue) +void SVFIRBuilder::addComplexConsForExt(Value* D, Value* S, const Value* szValue) { assert(D && S); - NodeID vnD= getValueNode(D), vnS= getValueNode(S); - if(!vnD || !vnS) - return; + NodeID vnD = getValueNode(D), vnS = getValueNode(S); + if (!vnD || !vnS) return; std::vector fields; - //Get the max possible size of the copy, unless it was provided. + // Get the max possible size of the copy, unless it was provided. std::vector srcFields; std::vector dstFields; const Type* stype = getBaseTypeAndFlattenedFields(S, srcFields, szValue); const Type* dtype = getBaseTypeAndFlattenedFields(D, dstFields, szValue); - if(srcFields.size() > dstFields.size()) - fields = dstFields; + if (srcFields.size() > dstFields.size()) fields = dstFields; else fields = srcFields; @@ -100,24 +102,24 @@ void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue if (fields.size() == 1 && (LLVMUtil::isConstDataOrAggData(D) || LLVMUtil::isConstDataOrAggData(S))) { NodeID dummy = pag->addDummyValNode(); - addLoadEdge(vnD,dummy); - addStoreEdge(dummy,vnS); + addLoadEdge(vnD, dummy); + addStoreEdge(dummy, vnS); return; } - //For each field (i), add (Ti = *S + i) and (*D + i = Ti). + // For each field (i), add (Ti = *S + i) and (*D + i = Ti). for (u32_t index = 0; index < sz; index++) { LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet(); - const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype), - fields[index].getConstantStructFldIdx()); - const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(stype), - fields[index].getConstantStructFldIdx()); - NodeID dField = getGepValVar(D,fields[index],dElementType); - NodeID sField = getGepValVar(S,fields[index],sElementType); + const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType( + llvmmodule->getSVFType(dtype), fields[index].getConstantStructFldIdx()); + const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType( + llvmmodule->getSVFType(stype), fields[index].getConstantStructFldIdx()); + NodeID dField = getGepValVar(D, fields[index], dElementType); + NodeID sField = getGepValVar(S, fields[index], sElementType); NodeID dummy = pag->addDummyValNode(); - addLoadEdge(sField,dummy); - addStoreEdge(dummy,dField); + addLoadEdge(sField, dummy); + addStoreEdge(dummy, dField); } } @@ -156,37 +158,38 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle { // Side-effects similar to void *memcpy(void *dest, const void * src, size_t n) // which copies n characters from memory area 'src' to memory area 'dest'. - if(svfCallee->getName().find("iconv") != std::string::npos) + if (svfCallee->getName().find("iconv") != std::string::npos) addComplexConsForExt(cs->getArgOperand(3), cs->getArgOperand(1), nullptr); - else if(svfCallee->getName().find("bcopy") != std::string::npos) + else if (svfCallee->getName().find("bcopy") != std::string::npos) addComplexConsForExt(cs->getArgOperand(1), cs->getArgOperand(0), cs->getArgOperand(2)); - if(svfCall->arg_size() == 3) + if (svfCall->arg_size() == 3) addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), cs->getArgOperand(2)); else addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), nullptr); - if(SVFUtil::isa(cs->getType())) + if (SVFUtil::isa(cs->getType())) addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL); } - else if(isMemsetExtFun(svfCallee)) + else if (isMemsetExtFun(svfCallee)) { // Side-effects similar to memset(void *str, int c, size_t n) - // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str + // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the + // argument str std::vector dstFields; - const Type *dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(0), dstFields, cs->getArgOperand(2)); + const Type* dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(0), dstFields, cs->getArgOperand(2)); u32_t sz = dstFields.size(); - //For each field (i), add store edge *(arg0 + i) = arg1 + // For each field (i), add store edge *(arg0 + i) = arg1 for (u32_t index = 0; index < sz; index++) { LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet(); - const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype), - dstFields[index].getConstantStructFldIdx()); + const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType( + llvmmodule->getSVFType(dtype), dstFields[index].getConstantStructFldIdx()); NodeID dField = getGepValVar(cs->getArgOperand(0), dstFields[index], dElementType); - addStoreEdge(getValueNode(cs->getArgOperand(1)),dField); + addStoreEdge(getValueNode(cs->getArgOperand(1)), dField); } - if(SVFUtil::isa(cs->getType())) + if (SVFUtil::isa(cs->getType())) addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL); } - else if(svfCallee->getName().compare("dlsym") == 0) + else if (svfCallee->getName().compare("dlsym") == 0) { /* Side-effects of void* dlsym( void* handle, const char* funName), @@ -202,54 +205,50 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle } */ const Value* src = cs->getArgOperand(1); - if(const GetElementPtrInst* gep = SVFUtil::dyn_cast(src)) + if (const GetElementPtrInst* gep = SVFUtil::dyn_cast(src)) src = stripConstantCasts(gep->getPointerOperand()); - auto getHookFn = [](const Value* src)->const Function* - { - if (!SVFUtil::isa(src)) - return nullptr; + auto getHookFn = [](const Value* src) -> const Function* { + if (!SVFUtil::isa(src)) return nullptr; - auto *glob = SVFUtil::cast(src); - if (!glob->hasInitializer() || !SVFUtil::isa(glob->getInitializer())) - return nullptr; + auto* glob = SVFUtil::cast(src); + if (!glob->hasInitializer() || !SVFUtil::isa(glob->getInitializer())) return nullptr; - auto *constarray = SVFUtil::cast(glob->getInitializer()); + auto* constarray = SVFUtil::cast(glob->getInitializer()); return LLVMUtil::getProgFunction(constarray->getAsCString().str()); }; - if (const Function *fn = getHookFn(src)) + if (const Function* fn = getHookFn(src)) { NodeID srcNode = getValueNode(fn); - addCopyEdge(srcNode, getValueNode(cs), CopyStmt::COPYVAL); + addCopyEdge(srcNode, getValueNode(cs), CopyStmt::COPYVAL); } } - else if(svfCallee->getName().find("_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_") != std::string::npos) + else if (svfCallee->getName().find("_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_") != + std::string::npos) { - // The purpose of this function is to insert a new node into the red-black tree and then rebalance the tree to ensure that the red-black tree properties are maintained. + // The purpose of this function is to insert a new node into the red-black tree and then rebalance the tree to + // ensure that the red-black tree properties are maintained. assert(svfCall->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n"); // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }. // Now we calculate the offset from base to vArg3 NodeID vnArg3 = pag->getValueNode(svfCall->getArgOperand(3)); - APOffset offset = - getAccessPathFromBaseNode(vnArg3).getConstantStructFldIdx(); + APOffset offset = getAccessPathFromBaseNode(vnArg3).getConstantStructFldIdx(); // We get all flattened fields of base - vector fields = pag->getTypeLocSetsMap(vnArg3).second; + vector fields = pag->getTypeLocSetsMap(vnArg3).second; // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1 // Note that arg0 is aligned with "offset". for (APOffset i = offset + 1; i <= offset + 3; ++i) { - if((u32_t)i >= fields.size()) - break; - const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first, - fields[i].getConstantStructFldIdx()); + if ((u32_t)i >= fields.size()) break; + const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType( + pag->getTypeLocSetsMap(vnArg3).first, fields[i].getConstantStructFldIdx()); NodeID vnD = getGepValVar(cs->getArgOperand(3), fields[i], elementType); NodeID vnS = pag->getValueNode(svfCall->getArgOperand(1)); - if(vnD && vnS) - addStoreEdge(vnS,vnD); + if (vnD && vnS) addStoreEdge(vnS, vnD); } } @@ -268,8 +267,8 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle /// Connect actual parameter to formal parameter of the start routine if (actualParm->getType()->isPointerTy() && formalParm->getType()->isPointerTy()) { - CallICFGNode *icfgNode = pag->getICFG()->getCallICFGNode(svfInst); - FunEntryICFGNode *entry = pag->getICFG()->getFunEntryICFGNode(forkedFun); + CallICFGNode* icfgNode = pag->getICFG()->getCallICFGNode(svfInst); + FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(forkedFun); addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm), icfgNode, entry); } } @@ -283,7 +282,8 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle } /// If forkedFun does not pass to spawnee as function type but as void pointer /// remember to update inter-procedural callgraph/SVFIR/SVFG etc. when indirect call targets are resolved - /// We don't connect the callgraph here, further investigation is need to handle mod-ref during SVFG construction. + /// We don't connect the callgraph here, further investigation is need to handle mod-ref during SVFG + /// construction. } /// TODO: inter-procedural SVFIR edges for thread joins diff --git a/svf-llvm/lib/SymbolTableBuilder.cpp b/svf-llvm/lib/SymbolTableBuilder.cpp index ba82e122c..80e3f3d96 100644 --- a/svf-llvm/lib/SymbolTableBuilder.cpp +++ b/svf-llvm/lib/SymbolTableBuilder.cpp @@ -47,11 +47,10 @@ using namespace LLVMUtil; MemObj* SymbolTableBuilder::createBlkObj(SymID symId) { assert(symInfo->isBlkObj(symId)); - assert(symInfo->objMap.find(symId)==symInfo->objMap.end()); + assert(symInfo->objMap.find(symId) == symInfo->objMap.end()); LLVMModuleSet* llvmset = LLVMModuleSet::getLLVMModuleSet(); MemObj* obj = - new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType( - IntegerType::get(llvmset->getContext(), 32)))); + new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(IntegerType::get(llvmset->getContext(), 32)))); symInfo->objMap[symId] = obj; return obj; } @@ -59,16 +58,14 @@ MemObj* SymbolTableBuilder::createBlkObj(SymID symId) MemObj* SymbolTableBuilder::createConstantObj(SymID symId) { assert(symInfo->isConstantObj(symId)); - assert(symInfo->objMap.find(symId)==symInfo->objMap.end()); + assert(symInfo->objMap.find(symId) == symInfo->objMap.end()); LLVMModuleSet* llvmset = LLVMModuleSet::getLLVMModuleSet(); MemObj* obj = - new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType( - IntegerType::get(llvmset->getContext(), 32)))); + new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(IntegerType::get(llvmset->getContext(), 32)))); symInfo->objMap[symId] = obj; return obj; } - /*! * This method identify which is value sym and which is object sym */ @@ -88,11 +85,12 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) assert(symInfo->totalSymNum++ == SymbolTableInfo::BlackHole && "Something changed!"); createBlkObj(SymbolTableInfo::BlackHole); - // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is disabled) + // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is + // disabled) assert(symInfo->totalSymNum++ == SymbolTableInfo::ConstantObj && "Something changed!"); createConstantObj(SymbolTableInfo::ConstantObj); - for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) + for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { // Add symbols for all the globals . for (const GlobalVariable& gv : M.globals()) @@ -112,8 +110,7 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) { collectSym(&fun); collectRet(&fun); - if (fun.getFunctionType()->isVarArg()) - collectVararg(&fun); + if (fun.getFunctionType()->isVarArg()) collectVararg(&fun); // Add symbols for all formal parameters. for (const Argument& arg : fun.args()) @@ -133,13 +130,11 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) collectSym(st->getPointerOperand()); collectSym(st->getValueOperand()); } - else if (const LoadInst* ld = - SVFUtil::dyn_cast(&inst)) + else if (const LoadInst* ld = SVFUtil::dyn_cast(&inst)) { collectSym(ld->getPointerOperand()); } - else if (const AllocaInst* alloc = - SVFUtil::dyn_cast(&inst)) + else if (const AllocaInst* alloc = SVFUtil::dyn_cast(&inst)) { collectSym(alloc->getArraySize()); } @@ -150,8 +145,7 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) collectSym(phi->getIncomingValue(i)); } } - else if (const GetElementPtrInst* gep = - SVFUtil::dyn_cast(&inst)) + else if (const GetElementPtrInst* gep = SVFUtil::dyn_cast(&inst)) { collectSym(gep->getPointerOperand()); for (u32_t i = 0; i < gep->getNumOperands(); ++i) @@ -159,49 +153,38 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) collectSym(gep->getOperand(i)); } } - else if (const SelectInst* sel = - SVFUtil::dyn_cast(&inst)) + else if (const SelectInst* sel = SVFUtil::dyn_cast(&inst)) { collectSym(sel->getTrueValue()); collectSym(sel->getFalseValue()); collectSym(sel->getCondition()); } - else if (const BinaryOperator* binary = - SVFUtil::dyn_cast(&inst)) + else if (const BinaryOperator* binary = SVFUtil::dyn_cast(&inst)) { - for (u32_t i = 0; i < binary->getNumOperands(); i++) - collectSym(binary->getOperand(i)); + for (u32_t i = 0; i < binary->getNumOperands(); i++) collectSym(binary->getOperand(i)); } - else if (const UnaryOperator* unary = - SVFUtil::dyn_cast(&inst)) + else if (const UnaryOperator* unary = SVFUtil::dyn_cast(&inst)) { - for (u32_t i = 0; i < unary->getNumOperands(); i++) - collectSym(unary->getOperand(i)); + for (u32_t i = 0; i < unary->getNumOperands(); i++) collectSym(unary->getOperand(i)); } else if (const CmpInst* cmp = SVFUtil::dyn_cast(&inst)) { - for (u32_t i = 0; i < cmp->getNumOperands(); i++) - collectSym(cmp->getOperand(i)); + for (u32_t i = 0; i < cmp->getNumOperands(); i++) collectSym(cmp->getOperand(i)); } - else if (const CastInst* cast = - SVFUtil::dyn_cast(&inst)) + else if (const CastInst* cast = SVFUtil::dyn_cast(&inst)) { collectSym(cast->getOperand(0)); } - else if (const ReturnInst* ret = - SVFUtil::dyn_cast(&inst)) + else if (const ReturnInst* ret = SVFUtil::dyn_cast(&inst)) { - if (ret->getReturnValue()) - collectSym(ret->getReturnValue()); + if (ret->getReturnValue()) collectSym(ret->getReturnValue()); } - else if (const BranchInst* br = - SVFUtil::dyn_cast(&inst)) + else if (const BranchInst* br = SVFUtil::dyn_cast(&inst)) { Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0); collectSym(opnd); } - else if (const SwitchInst* sw = - SVFUtil::dyn_cast(&inst)) + else if (const SwitchInst* sw = SVFUtil::dyn_cast(&inst)) { collectSym(sw->getCondition()); } @@ -239,14 +222,13 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) void SymbolTableBuilder::collectSVFTypeInfo(const Value* val) { - Type *valType = val->getType(); + Type* valType = val->getType(); (void)getOrAddSVFTypeInfo(valType); - if(isGepConstantExpr(val) || SVFUtil::isa(val)) + if (isGepConstantExpr(val) || SVFUtil::isa(val)) { - for (bridge_gep_iterator - gi = bridge_gep_begin(SVFUtil::cast(val)), - ge = bridge_gep_end(SVFUtil::cast(val)); - gi != ge; ++gi) + for (bridge_gep_iterator gi = bridge_gep_begin(SVFUtil::cast(val)), + ge = bridge_gep_end(SVFUtil::cast(val)); + gi != ge; ++gi) { const Type* gepTy = *gi; (void)getOrAddSVFTypeInfo(gepTy); @@ -260,14 +242,11 @@ void SymbolTableBuilder::collectSVFTypeInfo(const Value* val) void SymbolTableBuilder::collectSym(const Value* val) { - //TODO: filter the non-pointer type // if (!SVFUtil::isa(val->getType())) return; + // TODO: filter the non-pointer type // if (!SVFUtil::isa(val->getType())) return; DBOUT(DMemModel, - outs() - << "collect sym from ##" - << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->toString() - << " \n"); - //TODO handle constant expression value here?? + outs() << "collect sym from ##" << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->toString() << " \n"); + // TODO handle constant expression value here?? handleCE(val); // create a value sym @@ -293,23 +272,20 @@ void SymbolTableBuilder::collectVal(const Value* val) { return; } - SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->valSymMap.find( - LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); + SymbolTableInfo::ValueToIDMapTy::iterator iter = + symInfo->valSymMap.find(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); if (iter == symInfo->valSymMap.end()) { // create val sym and sym type SVFValue* svfVal = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val); SymID id = NodeIDAllocator::get()->allocateValueId(); symInfo->valSymMap.insert(std::make_pair(svfVal, id)); - DBOUT(DMemModel, - outs() << "create a new value sym " << id << "\n"); + DBOUT(DMemModel, outs() << "create a new value sym " << id << "\n"); /// handle global constant expression here - if (const GlobalVariable* globalVar = SVFUtil::dyn_cast(val)) - handleGlobalCE(globalVar); + if (const GlobalVariable* globalVar = SVFUtil::dyn_cast(val)) handleGlobalCE(globalVar); } - if (isConstantObjSym(val)) - collectObj(val); + if (isConstantObjSym(val)) collectObj(val); } /*! @@ -318,13 +294,13 @@ void SymbolTableBuilder::collectVal(const Value* val) void SymbolTableBuilder::collectObj(const Value* val) { val = LLVMUtil::getGlobalRep(val); - SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->objSymMap.find( - LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); + SymbolTableInfo::ValueToIDMapTy::iterator iter = + symInfo->objSymMap.find(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); if (iter == symInfo->objSymMap.end()) { SVFValue* svfVal = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val); - // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string) - // then we treat them as one ConstantObj + // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. + // string) then we treat them as one ConstantObj if (isConstantObjSym(val) && !symInfo->getModelConstants()) { symInfo->objSymMap.insert(std::make_pair(svfVal, symInfo->constantSymID())); @@ -335,13 +311,10 @@ void SymbolTableBuilder::collectObj(const Value* val) // create obj sym and sym type SymID id = NodeIDAllocator::get()->allocateObjectId(); symInfo->objSymMap.insert(std::make_pair(svfVal, id)); - DBOUT(DMemModel, - outs() << "create a new obj sym " << id << "\n"); + DBOUT(DMemModel, outs() << "create a new obj sym " << id << "\n"); // create a memory object - MemObj* mem = - new MemObj(id, createObjTypeInfo(val), - LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); + MemObj* mem = new MemObj(id, createObjTypeInfo(val), LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)); assert(symInfo->objMap.find(id) == symInfo->objMap.end()); symInfo->objMap[id] = mem; } @@ -353,10 +326,8 @@ void SymbolTableBuilder::collectObj(const Value* val) */ void SymbolTableBuilder::collectRet(const Function* val) { - const SVFFunction* svffun = - LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(val); - SymbolTableInfo::FunToIDMapTy::iterator iter = - symInfo->returnSymMap.find(svffun); + const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(val); + SymbolTableInfo::FunToIDMapTy::iterator iter = symInfo->returnSymMap.find(svffun); if (iter == symInfo->returnSymMap.end()) { SymID id = NodeIDAllocator::get()->allocateValueId(); @@ -370,10 +341,8 @@ void SymbolTableBuilder::collectRet(const Function* val) */ void SymbolTableBuilder::collectVararg(const Function* val) { - const SVFFunction* svffun = - LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(val); - SymbolTableInfo::FunToIDMapTy::iterator iter = - symInfo->varargSymMap.find(svffun); + const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(val); + SymbolTableInfo::FunToIDMapTy::iterator iter = symInfo->varargSymMap.find(svffun); if (iter == symInfo->varargSymMap.end()) { SymID id = NodeIDAllocator::get()->allocateValueId(); @@ -392,10 +361,7 @@ void SymbolTableBuilder::handleCE(const Value* val) if (const ConstantExpr* ce = isGepConstantExpr(ref)) { DBOUT(DMemModelCE, outs() << "handle constant expression " - << LLVMModuleSet::getLLVMModuleSet() - ->getSVFValue(ref) - ->toString() - << "\n"); + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); collectVal(ce); // handle the recursive constant express case @@ -409,10 +375,7 @@ void SymbolTableBuilder::handleCE(const Value* val) else if (const ConstantExpr* ce = isCastConstantExpr(ref)) { DBOUT(DMemModelCE, outs() << "handle constant expression " - << LLVMModuleSet::getLLVMModuleSet() - ->getSVFValue(ref) - ->toString() - << "\n"); + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); collectVal(ce); collectVal(ce->getOperand(0)); // handle the recursive constant express case @@ -422,10 +385,7 @@ void SymbolTableBuilder::handleCE(const Value* val) else if (const ConstantExpr* ce = isSelectConstantExpr(ref)) { DBOUT(DMemModelCE, outs() << "handle constant expression " - << LLVMModuleSet::getLLVMModuleSet() - ->getSVFValue(ref) - ->toString() - << "\n"); + << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(ref)->toString() << "\n"); collectVal(ce); collectVal(ce->getOperand(0)); collectVal(ce->getOperand(1)); @@ -469,8 +429,7 @@ void SymbolTableBuilder::handleCE(const Value* val) } else { - assert(!SVFUtil::isa(val) && - "we don't handle all other constant expression for now!"); + assert(!SVFUtil::isa(val) && "we don't handle all other constant expression for now!"); collectVal(ref); } } @@ -483,10 +442,10 @@ void SymbolTableBuilder::handleGlobalCE(const GlobalVariable* G) { assert(G); - //The type this global points to + // The type this global points to const Type* T = G->getValueType(); bool is_array = 0; - //An array is considered a single variable of its type. + // An array is considered a single variable of its type. while (const ArrayType* AT = SVFUtil::dyn_cast(T)) { T = AT->getElementType(); @@ -495,7 +454,7 @@ void SymbolTableBuilder::handleGlobalCE(const GlobalVariable* G) if (SVFUtil::isa(T)) { - //A struct may be used in constant GEP expr. + // A struct may be used in constant GEP expr. for (const User* user : G->users()) { handleCE(user); @@ -546,14 +505,13 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant* C) handleGlobalInitializerCE(SVFUtil::cast(C->getOperand(i))); } } - else if(const ConstantData* data = SVFUtil::dyn_cast(C)) + else if (const ConstantData* data = SVFUtil::dyn_cast(C)) { if (Options::ModelConsts()) { - if (const ConstantDataSequential* seq = - SVFUtil::dyn_cast(data)) + if (const ConstantDataSequential* seq = SVFUtil::dyn_cast(data)) { - for(u32_t i = 0; i < seq->getNumElements(); i++) + for (u32_t i = 0; i < seq->getNumElements(); i++) { const Constant* ct = seq->getElementAsConstant(i); handleGlobalInitializerCE(ct); @@ -561,25 +519,23 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant* C) } else { - assert( - (SVFUtil::isa(data)) && - "Single value type data should have been handled!"); + assert((SVFUtil::isa(data)) && + "Single value type data should have been handled!"); } } } else { - //TODO:assert(SVFUtil::isa(C),"what else do we have"); + // TODO:assert(SVFUtil::isa(C),"what else do we have"); } } -ObjTypeInference *SymbolTableBuilder::getTypeInference() +ObjTypeInference* SymbolTableBuilder::getTypeInference() { return LLVMModuleSet::getLLVMModuleSet()->getTypeInference(); } - -const Type* SymbolTableBuilder::inferObjType(const Value *startValue) +const Type* SymbolTableBuilder::inferObjType(const Value* startValue) { return getTypeInference()->inferObjType(startValue); } @@ -587,25 +543,25 @@ const Type* SymbolTableBuilder::inferObjType(const Value *startValue) /*! * Return the type of the object from a heap allocation */ -const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction *inst) +const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction* inst) { const Value* startValue = inst; - const PointerType *originalPType = SVFUtil::dyn_cast(inst->getType()); + const PointerType* originalPType = SVFUtil::dyn_cast(inst->getType()); const Type* inferedType = nullptr; assert(originalPType && "empty type?"); const SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(inst); - if(SVFUtil::isHeapAllocExtCallViaRet(svfinst)) + if (SVFUtil::isHeapAllocExtCallViaRet(svfinst)) { - if(const Value* v = getFirstUseViaCastInst(inst)) + if (const Value* v = getFirstUseViaCastInst(inst)) { - if (const PointerType *newTy = SVFUtil::dyn_cast(v->getType())) + if (const PointerType* newTy = SVFUtil::dyn_cast(v->getType())) { originalPType = newTy; } } inferedType = inferObjType(startValue); } - else if(SVFUtil::isHeapAllocExtCallViaArg(svfinst)) + else if (SVFUtil::isHeapAllocExtCallViaArg(svfinst)) { const CallBase* cs = LLVMUtil::getLLVMCallSite(inst); int arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::getSVFCallSite(svfinst)); @@ -615,7 +571,7 @@ const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction } else { - assert( false && "not a heap allocation instruction?"); + assert(false && "not a heap allocation instruction?"); } getTypeInference()->typeSizeDiffTest(originalPType, inferedType, startValue); @@ -643,13 +599,13 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val) { if (SVFUtil::isa(val->getType())) { - if (const AllocaInst *allocaInst = SVFUtil::dyn_cast(val)) + if (const AllocaInst* allocaInst = SVFUtil::dyn_cast(val)) { // get the type of the allocated memory // e.g., for `%retval = alloca i64, align 4`, we return i64 objTy = allocaInst->getAllocatedType(); } - else if (const GlobalValue *global = SVFUtil::dyn_cast(val)) + else if (const GlobalValue* global = SVFUtil::dyn_cast(val)) { // get the pointee type of the global pointer (begins with @ symbol in llvm) objTy = global->getValueType(); @@ -664,11 +620,10 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val) if (objTy) { - (void) getOrAddSVFTypeInfo(objTy); - ObjTypeInfo* typeInfo = new ObjTypeInfo( - LLVMModuleSet::getLLVMModuleSet()->getSVFType(objTy), - Options::MaxFieldLimit()); - initTypeInfo(typeInfo,val, objTy); + (void)getOrAddSVFTypeInfo(objTy); + ObjTypeInfo* typeInfo = + new ObjTypeInfo(LLVMModuleSet::getLLVMModuleSet()->getSVFType(objTy), Options::MaxFieldLimit()); + initTypeInfo(typeInfo, val, objTy); return typeInfo; } else @@ -678,15 +633,14 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val) writeWrnMsg("(" + LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->getSourceLoc() + ")"); if (isConstantObjSym(val)) { - ObjTypeInfo* typeInfo = new ObjTypeInfo( - LLVMModuleSet::getLLVMModuleSet()->getSVFType(val->getType()), - 0); - initTypeInfo(typeInfo,val, val->getType()); + ObjTypeInfo* typeInfo = new ObjTypeInfo(LLVMModuleSet::getLLVMModuleSet()->getSVFType(val->getType()), 0); + initTypeInfo(typeInfo, val, val->getType()); return typeInfo; } else { - assert(false && "Memory object must be either (1) held by a pointer-typed ref value or (2) a constant value (e.g., 10)."); + assert(false && "Memory object must be either (1) held by a pointer-typed ref value or (2) a constant " + "value (e.g., 10)."); abort(); } } @@ -697,25 +651,21 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val) */ void SymbolTableBuilder::analyzeObjType(ObjTypeInfo* typeinfo, const Value* val) { - const Type *elemTy = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(typeinfo->getType()); + const Type* elemTy = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(typeinfo->getType()); // Find the inter nested array element while (const ArrayType* AT = SVFUtil::dyn_cast(elemTy)) { elemTy = AT->getElementType(); - if (SVFUtil::isa(val) && - SVFUtil::cast(val)->hasInitializer() && - SVFUtil::isa( - SVFUtil::cast(val)->getInitializer())) + if (SVFUtil::isa(val) && SVFUtil::cast(val)->hasInitializer() && + SVFUtil::isa(SVFUtil::cast(val)->getInitializer())) typeinfo->setFlag(ObjTypeInfo::CONST_ARRAY_OBJ); else typeinfo->setFlag(ObjTypeInfo::VAR_ARRAY_OBJ); } if (SVFUtil::isa(elemTy)) { - if (SVFUtil::isa(val) && - SVFUtil::cast(val)->hasInitializer() && - SVFUtil::isa( - SVFUtil::cast(val)->getInitializer())) + if (SVFUtil::isa(val) && SVFUtil::cast(val)->hasInitializer() && + SVFUtil::isa(SVFUtil::cast(val)->getInitializer())) typeinfo->setFlag(ObjTypeInfo::CONST_STRUCT_OBJ); else typeinfo->setFlag(ObjTypeInfo::VAR_STRUCT_OBJ); @@ -738,14 +688,11 @@ void SymbolTableBuilder::analyzeObjType(ObjTypeInfo* typeinfo, const Value* val) */ u32_t SymbolTableBuilder::analyzeHeapAllocByteSize(const Value* val) { - if(const llvm::CallInst* callInst = llvm::dyn_cast(val)) + if (const llvm::CallInst* callInst = llvm::dyn_cast(val)) { - if (const llvm::Function* calledFunction = - callInst->getCalledFunction()) + if (const llvm::Function* calledFunction = callInst->getCalledFunction()) { - const SVFFunction* svfFunction = - LLVMModuleSet::getLLVMModuleSet()->getSVFFunction( - calledFunction); + const SVFFunction* svfFunction = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(calledFunction); std::vector args; // Heap alloc functions have annoation like "AllocSize:Arg1" for (std::string annotation : svfFunction->getAnnotations()) @@ -764,8 +711,7 @@ u32_t SymbolTableBuilder::analyzeHeapAllocByteSize(const Value* val) std::istringstream(token.substr(3)) >> argIndex; if (argIndex < callInst->getNumOperands() - 1) { - args.push_back( - callInst->getArgOperand(argIndex)); + args.push_back(callInst->getArgOperand(argIndex)); } } } @@ -777,8 +723,7 @@ u32_t SymbolTableBuilder::analyzeHeapAllocByteSize(const Value* val) // for annotations like "AllocSize:Arg0*Arg1" for (const llvm::Value* arg : args) { - if (const llvm::ConstantInt* constIntArg = - llvm::dyn_cast(arg)) + if (const llvm::ConstantInt* constIntArg = llvm::dyn_cast(arg)) { // Multiply the constant Value if all Args are const product *= constIntArg->getZExtValue(); @@ -811,15 +756,14 @@ u32_t SymbolTableBuilder::analyzeHeapObjType(ObjTypeInfo* typeinfo, const Value* typeinfo->setFlag(ObjTypeInfo::HEAP_OBJ); analyzeObjType(typeinfo, val); const Type* objTy = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(typeinfo->getType()); - if(SVFUtil::isa(objTy)) - return getNumOfElements(objTy); - else if(const StructType* st = SVFUtil::dyn_cast(objTy)) + if (SVFUtil::isa(objTy)) return getNumOfElements(objTy); + else if (const StructType* st = SVFUtil::dyn_cast(objTy)) { /// For an C++ class, it can have variant elements depending on the vtable size, /// Hence we only handle non-cpp-class object, the type of the cpp class is treated as default PointerType - if(cppUtil::classTyHasVTable(st)) + if (cppUtil::classTyHasVTable(st)) typeinfo->resetTypeForHeapStaticObj(LLVMModuleSet::getLLVMModuleSet()->getSVFType( - LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->ptrType())); + LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->ptrType())); else return getNumOfElements(objTy); } @@ -831,10 +775,10 @@ u32_t SymbolTableBuilder::analyzeHeapObjType(ObjTypeInfo* typeinfo, const Value* */ void SymbolTableBuilder::analyzeStaticObjType(ObjTypeInfo* typeinfo, const Value* val) { - if(const Value* castUse = getFirstUseViaCastInst(val)) + if (const Value* castUse = getFirstUseViaCastInst(val)) { typeinfo->setFlag(ObjTypeInfo::STATIC_OBJ); - analyzeObjType(typeinfo,castUse); + analyzeObjType(typeinfo, castUse); } else { @@ -845,8 +789,7 @@ void SymbolTableBuilder::analyzeStaticObjType(ObjTypeInfo* typeinfo, const Value /*! * Initialize the type info of an object */ -void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, - const Type* objTy) +void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, const Type* objTy) { u32_t elemNum = 1; @@ -858,18 +801,19 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, if (SVFUtil::isa(val)) { typeinfo->setFlag(ObjTypeInfo::FUNCTION_OBJ); - analyzeObjType(typeinfo,val); + analyzeObjType(typeinfo, val); elemNum = getNumOfElements(objTy); } /// if val is AllocaInst, byteSize is Type's LLVM ByteSize * ArraySize /// e.g. alloc i32, 10. byteSize is 4 (i32's size) * 10 (ArraySize) = 40 - else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast(val)) + else if (const AllocaInst* allocaInst = SVFUtil::dyn_cast(val)) { typeinfo->setFlag(ObjTypeInfo::STACK_OBJ); - analyzeObjType(typeinfo,val); - /// This is for `alloca `. For example, `alloca i64 3` allocates 3 i64 on the stack (objSize=3) - /// In most cases, `NumElements` is not specified in the instruction, which means there is only one element (objSize=1). - if(const ConstantInt* sz = SVFUtil::dyn_cast(allocaInst->getArraySize())) + analyzeObjType(typeinfo, val); + /// This is for `alloca `. For example, `alloca i64 3` allocates 3 i64 on the stack + /// (objSize=3) In most cases, `NumElements` is not specified in the instruction, which means there is only one + /// element (objSize=1). + if (const ConstantInt* sz = SVFUtil::dyn_cast(allocaInst->getArraySize())) { elemNum = sz->getZExtValue() * getNumOfElements(objTy); byteSize = sz->getZExtValue() * typeinfo->getType()->getByteSize(); @@ -883,36 +827,33 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, } /// if val is GlobalVar, byteSize is Type's LLVM ByteSize /// All GlobalVariable must have constant size - else if(SVFUtil::isa(val)) + else if (SVFUtil::isa(val)) { typeinfo->setFlag(ObjTypeInfo::GLOBVAR_OBJ); - if(isConstantObjSym(val)) - typeinfo->setFlag(ObjTypeInfo::CONST_GLOBAL_OBJ); - analyzeObjType(typeinfo,val); + if (isConstantObjSym(val)) typeinfo->setFlag(ObjTypeInfo::CONST_GLOBAL_OBJ); + analyzeObjType(typeinfo, val); elemNum = getNumOfElements(objTy); byteSize = typeinfo->getType()->getByteSize(); } /// if val is heap alloc else if (SVFUtil::isa(val) && - isHeapAllocExtCall( - LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction( - SVFUtil::cast(val)))) + isHeapAllocExtCall(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast(val)))) { - elemNum = analyzeHeapObjType(typeinfo,val); + elemNum = analyzeHeapObjType(typeinfo, val); // analyze heap alloc like (malloc/calloc/...), the alloc functions have // annotation like "AllocSize:Arg1". Please refer to extapi.c. // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1", // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40 byteSize = analyzeHeapAllocByteSize(val); } - else if(ArgInProgEntryFunction(val)) + else if (ArgInProgEntryFunction(val)) { - analyzeStaticObjType(typeinfo,val); + analyzeStaticObjType(typeinfo, val); // user input data, label its field as infinite here elemNum = typeinfo->getMaxFieldOffsetLimit(); byteSize = typeinfo->getType()->getByteSize(); } - else if(LLVMUtil::isConstDataOrAggData(val)) + else if (LLVMUtil::isConstDataOrAggData(val)) { typeinfo->setFlag(ObjTypeInfo::CONST_DATA); elemNum = getNumOfFlattenElements(val->getType()); @@ -925,13 +866,12 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val, } // Reset maxOffsetLimit if it is over the total fieldNum of this object - if(typeinfo->getMaxFieldOffsetLimit() > elemNum) - typeinfo->setNumOfElements(elemNum); + if (typeinfo->getMaxFieldOffsetLimit() > elemNum) typeinfo->setNumOfElements(elemNum); // set ByteSize. If ByteSize > 0, this typeinfo has constant type. // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize; - byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit(); + byteSize = Options::MaxFieldLimit() > byteSize ? byteSize : Options::MaxFieldLimit(); typeinfo->setByteSizeOfObj(byteSize); } @@ -952,8 +892,7 @@ u32_t SymbolTableBuilder::getNumOfElements(const Type* ety) /// Number of flattened elements of an array or struct u32_t SymbolTableBuilder::getNumOfFlattenElements(const Type* T) { - if(Options::ModelArrays()) - return getOrAddSVFTypeInfo(T)->getNumOfFlattenElements(); + if (Options::ModelArrays()) return getOrAddSVFTypeInfo(T)->getNumOfFlattenElements(); else return getOrAddSVFTypeInfo(T)->getNumOfFlattenFields(); } diff --git a/svf-llvm/lib/extapi.c b/svf-llvm/lib/extapi.c index eb8577a96..c7c8e2d5a 100644 --- a/svf-llvm/lib/extapi.c +++ b/svf-llvm/lib/extapi.c @@ -1,471 +1,413 @@ #include -#define NULL ((void *)0) +#define NULL ((void*)0) #define STATIC_OBJECT malloc(10) /* Functions with __attribute__((annotate("XXX"))) will be handle by SVF specifcially. - Their logical behaviours can't be described by C/C++ language. For example, "malloc()" functionality is to alloc an object to it's return value. + Their logical behaviours can't be described by C/C++ language. For example, "malloc()" functionality is to alloc an + object to it's return value. The description of methodProperties is as follows: ALLOC_RET, // returns a ptr to a newly allocated object ALLOC_ARGi // stores a pointer to an allocated object in *argi - REALLOC_RET, + REALLOC_RET, MEMSET, // memcpy() operations MEMCPY, // memset() operations OVERWRITE, // svf function overwrite app function */ -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *malloc(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* malloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *fopen(const char *voidname, const char *mode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* fopen(const char* voidname, + const char* mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *fopen64(const char *voidname, const char *mode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* fopen64(const char* voidname, + const char* mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *fdopen(int fd, const char *mode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* fdopen(int fd, const char* mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -struct dirent64 *readdir64(void *dirp) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) struct dirent64* readdir64(void* dirp) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *tmpvoid64(void) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* tmpvoid64(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) -void *calloc(unsigned long nitems, unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) void* calloc(unsigned long nitems, + unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *zmalloc(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* zmalloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *gzdopen(int fd, const char *mode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* gzdopen(int fd, const char* mode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *iconv_open(const char *tocode, const char *fromcode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* iconv_open(const char* tocode, + const char* fromcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *lalloc(unsigned long size, int a) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* lalloc(unsigned long size, int a) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *lalloc_clear(unsigned long size, int a) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* lalloc_clear(unsigned long size, int a) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -long *nhalloc(unsigned int a, const char *b, int c) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) long* nhalloc(unsigned int a, const char* b, + int c) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *oballoc(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* oballoc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *popen(const char *command, const char *type) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* popen(const char* command, const char* type) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *pthread_getspecific(const char *a, const char *b) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* pthread_getspecific(const char* a, + const char* b) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -struct dirent *readdir(void *dirp) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) struct dirent* readdir(void* dirp) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) -void* safe_calloc(unsigned nelem, unsigned elsize) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) void* safe_calloc(unsigned nelem, + unsigned elsize) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void* safe_malloc(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* safe_malloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) -char* safecalloc(int a, int b) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) char* safecalloc(int a, int b) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -char* safemalloc(int a, int b) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) char* safemalloc(int a, int b) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *setmntent(const char *voidname, const char *type) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* setmntent(const char* voidname, + const char* type) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *shmat(int shmid, const void *shmaddr, int shmflg) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* shmat(int shmid, const void* shmaddr, + int shmflg) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void* __sysv_signal(int a, void *b) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* __sysv_signal(int a, void* b) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void (*signal(int sig, void (*func)(int)))(int) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void (*signal(int sig, void (*func)(int)))(int) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *tempnam(const char *dir, const char *pfx) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* tempnam(const char* dir, const char* pfx) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *tmpvoid(void) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* tmpvoid(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void* xcalloc(unsigned long size1, unsigned long size2) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* xcalloc(unsigned long size1, + unsigned long size2) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void* xmalloc(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* xmalloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *_Znam(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* _Znam(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *_Znaj(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* _Znaj(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *_Znwj(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* _Znwj(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *__cxa_allocate_exception(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* __cxa_allocate_exception(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) -void* aligned_alloc(unsigned long size1, unsigned long size2) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) void* aligned_alloc(unsigned long size1, + unsigned long size2) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) -void* memalign(unsigned long size1, unsigned long size2) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) void* memalign(unsigned long size1, + unsigned long size2) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *valloc(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* valloc(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) -void *mmap64(void *addr, unsigned long len, int prot, int flags, int fildes, long off) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) void* mmap64(void* addr, unsigned long len, int prot, + int flags, int fildes, long off) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *XSetLocaleModifiers(char *a) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* XSetLocaleModifiers(char* a) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char * __strdup(const char * string) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* __strdup(const char* string) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *crypt(const char *key, const char *salt) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* crypt(const char* key, const char* salt) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *ctime(const void *timer) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* ctime(const void* timer) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *dlerror(void) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* dlerror(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *dlopen(const char *voidname, int flags) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* dlopen(const char* voidname, int flags) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -const char *gai_strerror(int errcode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) const char* gai_strerror(int errcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -const char *gcry_cipher_algo_name(int errcode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) const char* gcry_cipher_algo_name(int errcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -const char *svfgcry_md_algo_name_(int errcode) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) const char* svfgcry_md_algo_name_(int errcode) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *getenv(const char *name) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* getenv(const char* name) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *getlogin(void) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* getlogin(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *getpass(const char *prompt) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* getpass(const char* prompt) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -const char * gnutls_strerror(int error) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) const char* gnutls_strerror(int error) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -const char *gpg_strerror(unsigned int a) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) const char* gpg_strerror(unsigned int a) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -const char * gzerror(void* file, int * errnum) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) const char* gzerror(void* file, int* errnum) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *inet_ntoa(unsigned int in) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* inet_ntoa(unsigned int in) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *initscr(void) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* initscr(void) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void* llvm_stacksave() +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* llvm_stacksave() { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) -void *mmap(void *addr, unsigned long len, int prot, int flags, int fildes, long off) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg1"))) void* mmap(void* addr, unsigned long len, int prot, + int flags, int fildes, long off) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *newwin(int nlines, int ncols, int begin_y, int begin_x) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* newwin(int nlines, int ncols, int begin_y, + int begin_x) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *nl_langinfo(int item) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* nl_langinfo(int item) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *opendir(const char *name) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* opendir(const char* name) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void *sbrk(long increment) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* sbrk(long increment) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *strdup(const char *s) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* strdup(const char* s) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *strerror(int errnum) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* strerror(int errnum) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *strsignal(int errnum) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* strsignal(int errnum) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *textdomain(const char * domainname) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* textdomain(const char* domainname) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *tgetstr(char *id, char **area) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* tgetstr(char* id, char** area) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *tigetstr(char *capname) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* tigetstr(char* capname) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *tmpnam(char *s) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* tmpnam(char* s) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *ttyname(int fd) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* ttyname(int fd) { return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -char *getcwd(char *buf, unsigned long size) +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:UNKNOWN"))) char* getcwd(char* buf, unsigned long size) { return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) -char *mem_realloc(void *ptr, unsigned long size) +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) char* mem_realloc(void* ptr, unsigned long size) { return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) -char *realloc(void *ptr, unsigned long size) +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) char* realloc(void* ptr, unsigned long size) { return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) -void* safe_realloc(void *p, unsigned long n) +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) void* safe_realloc(void* p, unsigned long n) { return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1*Arg2"))) -void* saferealloc(void *p, unsigned long n1, unsigned long n2) +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1*Arg2"))) void* saferealloc(void* p, unsigned long n1, + unsigned long n2) { return NULL; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:UNKNOWN"))) -void* safexrealloc() +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:UNKNOWN"))) void* safexrealloc() { return NULL; } - -char *strtok(char *str, const char *delim) +char* strtok(char* str, const char* delim) { return str; } -char *strtok_r(char *str, const char *delim, char **saveptr) +char* strtok_r(char* str, const char* delim, char** saveptr) { return str; } @@ -475,356 +417,316 @@ char* strsep(char** stringp, const char* delim) return *stringp; } -__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) -void *xrealloc(void *ptr, unsigned long bytes) +__attribute__((annotate("REALLOC_RET"), annotate("AllocSize:Arg1"))) void* xrealloc(void* ptr, unsigned long bytes) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *_Znwm(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* _Znwm(unsigned long size) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *_ZnwmRKSt9nothrow_t(unsigned long size, void *) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* _ZnwmRKSt9nothrow_t(unsigned long size, void*) { return NULL; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -void *_ZnamRKSt9nothrow_t(unsigned long size, void *) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) void* _ZnamRKSt9nothrow_t(unsigned long size, void*) { return NULL; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int asprintf(char **restrict strp, const char *restrict fmt, ...) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int asprintf(char** restrict strp, + const char* restrict fmt, ...) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int vasprintf(char **strp, const char *fmt, void* ap) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int vasprintf(char** strp, const char* fmt, + void* ap) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int db_create(void **dbp, void *dbenv, unsigned int flags) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int db_create(void** dbp, void* dbenv, + unsigned int flags) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int gnutls_pkcs12_bag_init(void *a) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int gnutls_pkcs12_bag_init(void* a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int gnutls_pkcs12_init(void *a) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int gnutls_pkcs12_init(void* a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int gnutls_x509_crt_init(void *a) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int gnutls_x509_crt_init(void* a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) -int gnutls_x509_privkey_init(void *a) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:UNKNOWN"))) int gnutls_x509_privkey_init(void* a) { return 0; } -__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:Arg2"))) -int posix_memalign(void **a, unsigned long b, unsigned long c) +__attribute__((annotate("ALLOC_ARG0"), annotate("AllocSize:Arg2"))) int posix_memalign(void** a, unsigned long b, + unsigned long c) { return 0; } -__attribute__((annotate("ALLOC_ARG1"), annotate("AllocSize:UNKNOWN"))) -int scandir(const char *restrict dirp, struct dirent ***restrict namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) +__attribute__((annotate("ALLOC_ARG1"), annotate("AllocSize:UNKNOWN"))) int scandir( + const char* restrict dirp, struct dirent*** restrict namelist, int (*filter)(const struct dirent*), + int (*compar)(const struct dirent**, const struct dirent**)) { return 0; } -__attribute__((annotate("ALLOC_ARG2"), annotate("AllocSize:UNKNOWN"))) -int XmbTextPropertyToTextList(void *a, void *b, char ***c, int *d) +__attribute__((annotate("ALLOC_ARG2"), annotate("AllocSize:UNKNOWN"))) int XmbTextPropertyToTextList(void* a, void* b, + char*** c, int* d) { return 0; } -__attribute__((annotate("MEMCPY"))) -void llvm_memcpy_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memcpy_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memcpy_p0_p0_i64(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memcpy_p0_p0_i64(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memcpy_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memcpy_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memcpy_p0_p0_i32(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memcpy_p0_p0_i32(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memcpy(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memcpy(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memmove(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memmove(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memmove_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memmove_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memmove_p0_p0_i64(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memmove_p0_p0_i64(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memmove_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memmove_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void llvm_memmove_p0_p0_i32(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void llvm_memmove_p0_p0_i32(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void __memcpy_chk(char* dst, char* src, int sz, int flag){} +__attribute__((annotate("MEMCPY"))) void __memcpy_chk(char* dst, char* src, int sz, int flag) {} -__attribute__((annotate("MEMCPY"))) -void *memmove(void *str1, const void *str2, unsigned long n) +__attribute__((annotate("MEMCPY"))) void* memmove(void* str1, const void* str2, unsigned long n) { return NULL; } -__attribute__((annotate("MEMCPY"))) -void bcopy(const void *s1, void *s2, unsigned long n){} +__attribute__((annotate("MEMCPY"))) void bcopy(const void* s1, void* s2, unsigned long n) {} -__attribute__((annotate("MEMCPY"))) -void *memccpy( void * restrict dest, const void * restrict src, int c, unsigned long count) +__attribute__((annotate("MEMCPY"))) void* memccpy(void* restrict dest, const void* restrict src, int c, + unsigned long count) { return NULL; } -__attribute__((annotate("MEMCPY"))) -void __memmove_chk(char* dst, char* src, int sz){} +__attribute__((annotate("MEMCPY"))) void __memmove_chk(char* dst, char* src, int sz) {} -__attribute__((annotate("MEMSET"))) -void llvm_memset(char* dst, char elem, int sz, int flag){} +__attribute__((annotate("MEMSET"))) void llvm_memset(char* dst, char elem, int sz, int flag) {} -__attribute__((annotate("MEMSET"))) -void llvm_memset_p0i8_i32(char* dst, char elem, int sz, int flag){} +__attribute__((annotate("MEMSET"))) void llvm_memset_p0i8_i32(char* dst, char elem, int sz, int flag) {} -__attribute__((annotate("MEMSET"))) -void llvm_memset_p0_i32(char* dst, char elem, int sz, int flag){} +__attribute__((annotate("MEMSET"))) void llvm_memset_p0_i32(char* dst, char elem, int sz, int flag) {} -__attribute__((annotate("MEMSET"))) -void llvm_memset_p0i8_i64(char* dst, char elem, int sz, int flag){} +__attribute__((annotate("MEMSET"))) void llvm_memset_p0i8_i64(char* dst, char elem, int sz, int flag) {} -__attribute__((annotate("MEMSET"))) -void llvm_memset_p0_i64(char* dst, char elem, int sz, int flag){} +__attribute__((annotate("MEMSET"))) void llvm_memset_p0_i64(char* dst, char elem, int sz, int flag) {} -__attribute__((annotate("MEMSET"))) -char *__memset_chk(char * dest, int c, unsigned long destlen, int flag) +__attribute__((annotate("MEMSET"))) char* __memset_chk(char* dest, int c, unsigned long destlen, int flag) { return NULL; } -__attribute__((annotate("MEMSET"))) -char *wmemset(wchar_t * dst, wchar_t elem, int sz, int flag) { +__attribute__((annotate("MEMSET"))) char* wmemset(wchar_t* dst, wchar_t elem, int sz, int flag) +{ return NULL; } - -__attribute__((annotate("STRCPY"))) -char * __strcpy_chk(char * dest, const char * src, unsigned long destlen) +__attribute__((annotate("STRCPY"))) char* __strcpy_chk(char* dest, const char* src, unsigned long destlen) { return NULL; } -__attribute__((annotate("STRCAT"))) -char *__strcat_chk(char * dest, const char * src, unsigned long destlen) +__attribute__((annotate("STRCAT"))) char* __strcat_chk(char* dest, const char* src, unsigned long destlen) { return NULL; } -__attribute__((annotate("STRCAT"))) -wchar_t* __wcscat_chk(wchar_t * dest, const wchar_t * src) +__attribute__((annotate("STRCAT"))) wchar_t* __wcscat_chk(wchar_t* dest, const wchar_t* src) { return NULL; } -__attribute__((annotate("STRCPY"))) -char *stpcpy(char *restrict dst, const char *restrict src) +__attribute__((annotate("STRCPY"))) char* stpcpy(char* restrict dst, const char* restrict src) { return NULL; } -__attribute__((annotate("STRCAT"))) -char *strcat(char *dest, const char *src) +__attribute__((annotate("STRCAT"))) char* strcat(char* dest, const char* src) { return NULL; } -__attribute__((annotate("STRCAT"))) -char *wcscat(char *dest, const char *src) +__attribute__((annotate("STRCAT"))) char* wcscat(char* dest, const char* src) { return NULL; } - -__attribute__((annotate("STRCPY"))) -char *strcpy(char *dest, const char *src) +__attribute__((annotate("STRCPY"))) char* strcpy(char* dest, const char* src) { return NULL; } -__attribute__((annotate("STRCAT"))) -char *strncat(char *dest, const char *src, unsigned long n) +__attribute__((annotate("STRCAT"))) char* strncat(char* dest, const char* src, unsigned long n) { return NULL; } -__attribute__((annotate("STRCAT"))) -wchar_t* wcsncat(wchar_t * dest, const wchar_t * src, int n) { +__attribute__((annotate("STRCAT"))) wchar_t* wcsncat(wchar_t* dest, const wchar_t* src, int n) +{ return NULL; } -__attribute__((annotate("STRCAT"))) -char *__strncat_chk(char *dest, const char *src, unsigned long n) +__attribute__((annotate("STRCAT"))) char* __strncat_chk(char* dest, const char* src, unsigned long n) { return NULL; } -__attribute__((annotate("STRCAT"))) -wchar_t* __wcsncat_chk(wchar_t * dest, const wchar_t * src, int n) { +__attribute__((annotate("STRCAT"))) wchar_t* __wcsncat_chk(wchar_t* dest, const wchar_t* src, int n) +{ return NULL; } -__attribute__((annotate("MEMCPY"))) -char *strncpy(char *dest, const char *src, unsigned long n) +__attribute__((annotate("MEMCPY"))) char* strncpy(char* dest, const char* src, unsigned long n) { return NULL; } -__attribute__((annotate("STRCPY"))) -char *wcscpy(wchar_t* dest, const wchar_t* src) { +__attribute__((annotate("STRCPY"))) char* wcscpy(wchar_t* dest, const wchar_t* src) +{ return NULL; } -__attribute__((annotate("MEMCPY"))) -unsigned long iconv(void* cd, char **restrict inbuf, unsigned long *restrict inbytesleft, char **restrict outbuf, unsigned long *restrict outbytesleft) +__attribute__((annotate("MEMCPY"))) unsigned long iconv(void* cd, char** restrict inbuf, + unsigned long* restrict inbytesleft, char** restrict outbuf, + unsigned long* restrict outbytesleft) { return 0; } -__attribute__((annotate("OVERWRITE"))) -void* _ZNSt5arrayIPK1ALm2EE4backEv(void *arg) +__attribute__((annotate("OVERWRITE"))) void* _ZNSt5arrayIPK1ALm2EE4backEv(void* arg) { void* ptr1 = (char*)arg + 0; void* ptr2 = (char*)ptr1 + 0; return ptr2; } -__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) -__attribute__((annotate("OVERWRITE"))) -void *SyGetmem(unsigned long size) +__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0"))) __attribute__((annotate("OVERWRITE"))) void* +SyGetmem(unsigned long size) { return NULL; } -void * __rawmemchr(const void * s, int c) +void* __rawmemchr(const void* s, int c) { - return (void *)s; + return (void*)s; } -struct jpeg_error_mgr *jpeg_std_error(struct jpeg_error_mgr * a) +struct jpeg_error_mgr* jpeg_std_error(struct jpeg_error_mgr* a) { return a; } -char *fgets(char *str, int n, void *stream) +char* fgets(char* str, int n, void* stream) { return str; } -char *fgets_unlocked(char *str, int n, void *stream) +char* fgets_unlocked(char* str, int n, void* stream) { return str; } -char* gets(char *str) +char* gets(char* str) { return str; } -void *memchr(const void *str, int c, unsigned long n) +void* memchr(const void* str, int c, unsigned long n) { - return (void *)str; + return (void*)str; } -void *memrchr(const void *str, int c, unsigned long n) +void* memrchr(const void* str, int c, unsigned long n) { - return (void *)str; + return (void*)str; } -void * mremap(void * old_address, unsigned long old_size, unsigned long new_size, int flags) +void* mremap(void* old_address, unsigned long old_size, unsigned long new_size, int flags) { return old_address; } -char *strchr(const char *str, int c) +char* strchr(const char* str, int c) { - return (char *)str; + return (char*)str; } -char *__strchrnull(const char *s, int c) +char* __strchrnull(const char* s, int c) { - return (char *)s; + return (char*)s; } -char *strcasestr(const char *haystack, const char *needle) +char* strcasestr(const char* haystack, const char* needle) { - return (char *)haystack; + return (char*)haystack; } -char* index(const char *s, int c) +char* index(const char* s, int c) { - return (char *)s; + return (char*)s; } -char* rindex(const char *s, int c) +char* rindex(const char* s, int c) { - return (char *)s; + return (char*)s; } -char *strerror_r(int errnum, char *buf, unsigned long buflen) +char* strerror_r(int errnum, char* buf, unsigned long buflen) { return buf; } -char *strpbrk(const char *str1, const char *str2) +char* strpbrk(const char* str1, const char* str2) { - return (char *)str1; + return (char*)str1; } -char *strptime(const void* s, const void* format, void* tm) +char* strptime(const void* s, const void* format, void* tm) { - return (char *)s; + return (char*)s; } -char *strrchr(const char *str, int c) +char* strrchr(const char* str, int c) { - return (char *)str; + return (char*)str; } -char *strstr(const char *haystack, const char *needle) +char* strstr(const char* haystack, const char* needle) { - return (char *)haystack; + return (char*)haystack; } -char *tmpnam_r(char *s) +char* tmpnam_r(char* s) { return s; } @@ -859,7 +761,7 @@ int isgraph(int c) return c; } -int islower( int arg ) +int islower(int arg) { return arg; } @@ -889,42 +791,43 @@ int isxdigit(int c) return c; } -char *asctime_r(const void *tm, char *buf) +char* asctime_r(const void* tm, char* buf) { return buf; } -void *bsearch(const void *key, const void *base, unsigned long nitems, unsigned long size, int (*compar)(const void *, const void *)) +void* bsearch(const void* key, const void* base, unsigned long nitems, unsigned long size, + int (*compar)(const void*, const void*)) { - return (void *)base; + return (void*)base; } -struct mntent *getmntent_r(void *fp, struct mntent *mntbuf, char *buf, int buflen) +struct mntent* getmntent_r(void* fp, struct mntent* mntbuf, char* buf, int buflen) { return mntbuf; } -struct tm *gmtime_r(const void *timer, struct tm *buf) +struct tm* gmtime_r(const void* timer, struct tm* buf) { return buf; } -char * gzgets(void* file, char * buf, int len) +char* gzgets(void* file, char* buf, int len) { return buf; } -struct tm *localtime_r(const void *timep, struct tm *result) +struct tm* localtime_r(const void* timep, struct tm* result) { return result; } -char *realpath(const char *restrict path, char *restrict resolved_path) +char* realpath(const char* restrict path, char* restrict resolved_path) { return resolved_path; } -void* freopen64( const char* voidname, const char* mode, void* fp ) +void* freopen64(const char* voidname, const char* mode, void* fp) { return fp; } @@ -934,99 +837,99 @@ void* freopen(const char* voidname, const char* mode, void* fp) return fp; } -const char *inet_ntop(int af, const void *restrict src, char *restrict dst, unsigned int size) +const char* inet_ntop(int af, const void* restrict src, char* restrict dst, unsigned int size) { return dst; } -double strtod(const char *str, char **endptr) +double strtod(const char* str, char** endptr) { - *endptr = (char *)str; + *endptr = (char*)str; return 0.0; } -double strtod_l(const char *str, char **endptr, void *loc) +double strtod_l(const char* str, char** endptr, void* loc) { - *endptr = (char *)str; + *endptr = (char*)str; return 0.0; } -float strtof(const char *nptr, char **endptr) +float strtof(const char* nptr, char** endptr) { - *endptr = (char *)nptr; + *endptr = (char*)nptr; return 0.0; } -float strtof_l(const char *nptr, char **endptr, void *loc) +float strtof_l(const char* nptr, char** endptr, void* loc) { - *endptr = (char *)nptr; + *endptr = (char*)nptr; return 0.0; } -long int strtol(const char *str, char **endptr, int base) +long int strtol(const char* str, char** endptr, int base) { - *endptr = (char *)str; + *endptr = (char*)str; return 0; } -long long strtoll(const char *str, char **endptr, int base) +long long strtoll(const char* str, char** endptr, int base) { - *endptr = (char *)str; + *endptr = (char*)str; return 0; } long double strtold(const char* str, char** endptr) { - *endptr = (char *)str; + *endptr = (char*)str; return 0.0; } -unsigned long int strtoul(const char *str, char **endptr, int base) +unsigned long int strtoul(const char* str, char** endptr, int base) { - *endptr = (char *)str; + *endptr = (char*)str; return 0; } -unsigned long long strtoull(const char *str, char **endptr, int base) +unsigned long long strtoull(const char* str, char** endptr, int base) { - *endptr = (char *)str; + *endptr = (char*)str; return 0; } -char *gcvt(double x, int ndigit, char *buf) +char* gcvt(double x, int ndigit, char* buf) { return buf; } -void *memmem(const void *haystack, unsigned long haystacklen, const void *needle, unsigned long needlelen) +void* memmem(const void* haystack, unsigned long haystacklen, const void* needle, unsigned long needlelen) { - return (void *)haystack; + return (void*)haystack; } -char* ctime_r(const char *timer, char *buf) +char* ctime_r(const char* timer, char* buf) { return buf; } -int readdir_r(void *__restrict__dir, void *__restrict__entry, void **__restrict__result) +int readdir_r(void* __restrict__dir, void* __restrict__entry, void** __restrict__result) { - __restrict__entry = *__restrict__result; + __restrict__entry = *__restrict__result; return 0; } -int getpwnam_r(const char *name, void *pwd, char *buf, unsigned long buflen, void **result) +int getpwnam_r(const char* name, void* pwd, char* buf, unsigned long buflen, void** result) { *result = pwd; return 0; } -int getpwuid_r(unsigned int uid, void *pwd, char *buf, unsigned long buflen, void **result) +int getpwuid_r(unsigned int uid, void* pwd, char* buf, unsigned long buflen, void** result) { *result = pwd; return 0; } -void _ZNSt8__detail15_List_node_base7_M_hookEPS0_(void *arg0, void **arg1) +void _ZNSt8__detail15_List_node_base7_M_hookEPS0_(void* arg0, void** arg1) { *arg1 = arg0; } @@ -1036,37 +939,37 @@ void* __dynamic_cast(void* source, const void* sourceTypeInfo, const void* targe return source; } -void _ZNSsC1EPKcRKSaIcE(void **arg0, void *arg1) +void _ZNSsC1EPKcRKSaIcE(void** arg0, void* arg1) { *arg0 = arg1; } -void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_(void **arg0, void *arg1) +void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_(void** arg0, void* arg1) { *arg0 = arg1; } -const unsigned short **__ctype_b_loc(void) +const unsigned short** __ctype_b_loc(void) { return STATIC_OBJECT; } -int **__ctype_tolower_loc(void) +int** __ctype_tolower_loc(void) { return STATIC_OBJECT; } -int **__ctype_toupper_loc(void) +int** __ctype_toupper_loc(void) { return STATIC_OBJECT; } -int *__errno_location(void) +int* __errno_location(void) { return STATIC_OBJECT; } -int * __h_errno_location(void) +int* __h_errno_location(void) { return STATIC_OBJECT; } @@ -1076,172 +979,172 @@ void* __res_state(void) return STATIC_OBJECT; } -char *asctime(const void *timeptr) +char* asctime(const void* timeptr) { return STATIC_OBJECT; } -char * bindtextdomain(const char * domainname, const char * dirname) +char* bindtextdomain(const char* domainname, const char* dirname) { return STATIC_OBJECT; } -char * bind_textdomain_codeset(const char * domainname, const char * codeset) +char* bind_textdomain_codeset(const char* domainname, const char* codeset) { return STATIC_OBJECT; } -char *ctermid(char *s) +char* ctermid(char* s) { return s; } -char * dcgettext(const char * domainname, const char * msgid, int category) +char* dcgettext(const char* domainname, const char* msgid, int category) { return STATIC_OBJECT; } -char * dgettext(const char * domainname, const char * msgid) +char* dgettext(const char* domainname, const char* msgid) { return STATIC_OBJECT; } -char * dngettext(const char * domainname, const char * msgid, const char * msgid_plural, unsigned long int n) +char* dngettext(const char* domainname, const char* msgid, const char* msgid_plural, unsigned long int n) { return STATIC_OBJECT; } -struct group *getgrgid(unsigned int gid) +struct group* getgrgid(unsigned int gid) { return STATIC_OBJECT; } -struct group *getgrnam(const char *name) +struct group* getgrnam(const char* name) { return STATIC_OBJECT; } -struct hostent *gethostbyaddr(const void *addr, unsigned int len, int type) +struct hostent* gethostbyaddr(const void* addr, unsigned int len, int type) { return STATIC_OBJECT; } -struct hostent *gethostbyname(const char *name) +struct hostent* gethostbyname(const char* name) { return STATIC_OBJECT; } -struct hostent *gethostbyname2(const char *name, int af) +struct hostent* gethostbyname2(const char* name, int af) { return STATIC_OBJECT; } -struct mntent *getmntent(void *stream) +struct mntent* getmntent(void* stream) { return STATIC_OBJECT; } -struct protoent *getprotobyname(const char *name) +struct protoent* getprotobyname(const char* name) { return STATIC_OBJECT; } -struct protoent *getprotobynumber(int proto) +struct protoent* getprotobynumber(int proto) { return STATIC_OBJECT; } -struct passwd *getpwent(void) +struct passwd* getpwent(void) { return STATIC_OBJECT; } -struct passwd *getpwnam(const char *name) +struct passwd* getpwnam(const char* name) { return STATIC_OBJECT; } -struct passwd *getpwuid(unsigned int uid) +struct passwd* getpwuid(unsigned int uid) { return STATIC_OBJECT; } -struct servent *getservbyname(const char *name, const char *proto) +struct servent* getservbyname(const char* name, const char* proto) { return STATIC_OBJECT; } -struct servent *getservbyport(int port, const char *proto) +struct servent* getservbyport(int port, const char* proto) { return STATIC_OBJECT; } -struct spwd *getspnam(const char *name) +struct spwd* getspnam(const char* name) { return STATIC_OBJECT; } -char * gettext(const char * msgid) +char* gettext(const char* msgid) { return STATIC_OBJECT; } -struct tm *gmtime(const void *timer) +struct tm* gmtime(const void* timer) { return STATIC_OBJECT; } -const char *gnu_get_libc_version(void) +const char* gnu_get_libc_version(void) { return STATIC_OBJECT; } -const char * gnutls_check_version(const char * req_version) +const char* gnutls_check_version(const char* req_version) { return STATIC_OBJECT; } -struct lconv *localeconv(void) +struct lconv* localeconv(void) { return STATIC_OBJECT; } -struct tm *localtime(const void *timer) +struct tm* localtime(const void* timer) { return STATIC_OBJECT; } -char * ngettext(const char * msgid, const char * msgid_plural, unsigned long int n) +char* ngettext(const char* msgid, const char* msgid_plural, unsigned long int n) { return STATIC_OBJECT; } -void *pango_cairo_font_map_get_default(void) +void* pango_cairo_font_map_get_default(void) { return STATIC_OBJECT; } -char *re_comp(const char *regex) +char* re_comp(const char* regex) { return STATIC_OBJECT; } -char *setlocale(int category, const char *locale) +char* setlocale(int category, const char* locale) { return STATIC_OBJECT; } -char *tgoto(const char *cap, int col, int row) +char* tgoto(const char* cap, int col, int row) { return STATIC_OBJECT; } -char *tparm(char *str, ...) +char* tparm(char* str, ...) { return STATIC_OBJECT; } -const char *zError(int a) +const char* zError(int a) { return STATIC_OBJECT; } diff --git a/svf-llvm/tools/AE/ae.cpp b/svf-llvm/tools/AE/ae.cpp index 047009a70..3d745ef45 100644 --- a/svf-llvm/tools/AE/ae.cpp +++ b/svf-llvm/tools/AE/ae.cpp @@ -39,18 +39,9 @@ using namespace SVF; using namespace SVFUtil; +static Option SYMABS("symabs", "symbolic abstraction test", false); -static Option SYMABS( - "symabs", - "symbolic abstraction test", - false -); - -static Option AETEST( - "aetest", - "abstract execution basic function test", - false -); +static Option AETEST("aetest", "abstract execution basic function test", false); class SymblicAbstractionTest { @@ -69,40 +60,31 @@ class SymblicAbstractionTest outs() << "hello print\n"; } - AbstractState RSY_time(AbstractState& inv, const Z3Expr& phi, - RelationSolver& rs) + AbstractState RSY_time(AbstractState& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); AbstractState resRSY = rs.RSY(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast( - end_time - start_time); - outs() << "running time of RSY : " << duration.count() - << " microseconds\n"; + auto duration = std::chrono::duration_cast(end_time - start_time); + outs() << "running time of RSY : " << duration.count() << " microseconds\n"; return resRSY; } - AbstractState Bilateral_time(AbstractState& inv, const Z3Expr& phi, - RelationSolver& rs) + AbstractState Bilateral_time(AbstractState& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); AbstractState resBilateral = rs.bilateral(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast( - end_time - start_time); - outs() << "running time of Bilateral: " << duration.count() - << " microseconds\n"; + auto duration = std::chrono::duration_cast(end_time - start_time); + outs() << "running time of Bilateral: " << duration.count() << " microseconds\n"; return resBilateral; } - AbstractState BS_time(AbstractState& inv, const Z3Expr& phi, - RelationSolver& rs) + AbstractState BS_time(AbstractState& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); AbstractState resBS = rs.BS(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast( - end_time - start_time); - outs() << "running time of BS : " << duration.count() - << " microseconds\n"; + auto duration = std::chrono::duration_cast(end_time - start_time); + outs() << "running time of BS : " << duration.count() << " microseconds\n"; return resBS; } @@ -115,8 +97,7 @@ class SymblicAbstractionTest itv[0] = IntervalValue(0, 1); relation[0] = getContext().int_const("0"); // var1 := var0 + 1; - relation[1] = - getContext().int_const("1") == getContext().int_const("0") + 1; + relation[1] = getContext().int_const("1") == getContext().int_const("0") + 1; itv[1] = itv[0].getInterval() + IntervalValue(1); // Test extract sub vars Set res; @@ -149,8 +130,7 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 1); // var1 := var0 + 1; - relation[1] = - getContext().int_const("1") == getContext().int_const("0") * 2; + relation[1] = getContext().int_const("1") == getContext().int_const("0") * 2; itv[1] = itv[0].getInterval() * IntervalValue(2); // Test extract sub vars @@ -184,12 +164,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 10); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 - var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") - getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") - getContext().int_const("0"); itv[2] = itv[1].getInterval() - itv[0].getInterval(); // Test extract sub vars Set res; @@ -210,10 +188,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, - {1, IntervalValue(0, 10)}, - {2, IntervalValue(0, 0)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(0, 0)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -226,12 +202,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 100); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 - var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") - getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") - getContext().int_const("0"); itv[2] = itv[1].getInterval() - itv[0].getInterval(); // Test extract sub vars @@ -253,10 +227,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100)}, - {1, IntervalValue(0, 100)}, - {2, IntervalValue(0, 0)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(0, 100)}, {1, IntervalValue(0, 100)}, {2, IntervalValue(0, 0)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -269,12 +241,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 1000); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 - var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") - getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") - getContext().int_const("0"); itv[2] = itv[1].getInterval() - itv[0].getInterval(); // Test extract sub vars @@ -296,10 +266,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1000)}, - {1, IntervalValue(0, 1000)}, - {2, IntervalValue(0, 0)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(0, 1000)}, {1, IntervalValue(0, 1000)}, {2, IntervalValue(0, 0)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -312,12 +280,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 10000); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 - var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") - getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") - getContext().int_const("0"); itv[2] = itv[1].getInterval() - itv[0].getInterval(); // Test extract sub vars @@ -339,10 +305,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10000)}, - {1, IntervalValue(0, 10000)}, - {2, IntervalValue(0, 0)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(0, 10000)}, {1, IntervalValue(0, 10000)}, {2, IntervalValue(0, 0)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -355,12 +319,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 100000); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 - var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") - getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") - getContext().int_const("0"); itv[2] = itv[1].getInterval() - itv[0].getInterval(); // Test extract sub vars @@ -382,10 +344,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100000)}, - {1, IntervalValue(0, 100000)}, - {2, IntervalValue(0, 0)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(0, 100000)}, {1, IntervalValue(0, 100000)}, {2, IntervalValue(0, 0)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -398,12 +358,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(1, 10); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 / var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") / getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") / getContext().int_const("0"); itv[2] = itv[1].getInterval() / itv[0].getInterval(); // Test extract sub vars Set res; @@ -424,10 +382,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10)}, - {1, IntervalValue(1, 10)}, - {2, IntervalValue(1, 1)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(1, 10)}, {1, IntervalValue(1, 10)}, {2, IntervalValue(1, 1)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -440,12 +396,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(1, 1000); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 / var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") / getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") / getContext().int_const("0"); itv[2] = itv[1].getInterval() / itv[0].getInterval(); // Test extract sub vars Set res; @@ -466,10 +420,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 1000)}, - {1, IntervalValue(1, 1000)}, - {2, IntervalValue(1, 1)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(1, 1000)}, {1, IntervalValue(1, 1000)}, {2, IntervalValue(1, 1)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -482,12 +434,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(1, 10000); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 / var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") / getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") / getContext().int_const("0"); itv[2] = itv[1].getInterval() / itv[0].getInterval(); // Test extract sub vars Set res; @@ -508,10 +458,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10000)}, - {1, IntervalValue(1, 10000)}, - {2, IntervalValue(1, 1)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(1, 10000)}, {1, IntervalValue(1, 10000)}, {2, IntervalValue(1, 1)}}; } void testRelExeState3_4() @@ -523,12 +471,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(1, 100000); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 / var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") / getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") / getContext().int_const("0"); itv[2] = itv[1].getInterval() / itv[0].getInterval(); // Test extract sub vars Set res; @@ -549,10 +495,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 100000)}, - {1, IntervalValue(1, 100000)}, - {2, IntervalValue(1, 1)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(1, 100000)}, {1, IntervalValue(1, 100000)}, {2, IntervalValue(1, 1)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -565,12 +509,10 @@ class SymblicAbstractionTest relation[0] = getContext().int_const("0"); itv[0] = IntervalValue(0, 10); // var1 := var0; - relation[1] = - getContext().int_const("1") == getContext().int_const("0"); + relation[1] = getContext().int_const("1") == getContext().int_const("0"); itv[1] = itv[0]; // var2 := var1 / var0; - relation[2] = getContext().int_const("2") == - getContext().int_const("1") / getContext().int_const("0"); + relation[2] = getContext().int_const("2") == getContext().int_const("1") / getContext().int_const("0"); itv[2] = itv[1].getInterval() / itv[0].getInterval(); // Test extract sub vars Set res; @@ -594,10 +536,8 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, - {1, IntervalValue(0, 10)}, - {2, IntervalValue(0, 10)} - }; + AbstractState::VarToAbsValMap intendedRes = { + {0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(0, 10)}}; assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -637,16 +577,18 @@ class AETest assert((IntervalValue::bottom() / IntervalValue(2)).equals(IntervalValue::bottom())); assert((IntervalValue::top() / IntervalValue(0)).equals(IntervalValue::bottom())); assert((IntervalValue(4) / IntervalValue(2)).equals(IntervalValue(2))); - assert((IntervalValue(3) / IntervalValue(2)).equals(IntervalValue(1))); // - assert((IntervalValue(-3) / IntervalValue(2)).equals(IntervalValue(-1))); // + assert((IntervalValue(3) / IntervalValue(2)).equals(IntervalValue(1))); // + assert((IntervalValue(-3) / IntervalValue(2)).equals(IntervalValue(-1))); // assert((IntervalValue(1, 3) / IntervalValue(2)).equals(IntervalValue(0, 1))); // assert((IntervalValue(2, 7) / IntervalValue(2)).equals(IntervalValue(1, 3))); // assert((IntervalValue(-3, 3) / IntervalValue(2)).equals(IntervalValue(-1, 1))); - assert((IntervalValue(-3, IntervalValue::plus_infinity()) / IntervalValue(2)).equals(IntervalValue(-1, IntervalValue::plus_infinity()))); - assert((IntervalValue(IntervalValue::minus_infinity(), 3) / IntervalValue(2)).equals(IntervalValue(IntervalValue::minus_infinity(), 1))); - assert((IntervalValue(1, 3) / IntervalValue(1, 2)).equals(IntervalValue(0, 3)));// + assert((IntervalValue(-3, IntervalValue::plus_infinity()) / IntervalValue(2)) + .equals(IntervalValue(-1, IntervalValue::plus_infinity()))); + assert((IntervalValue(IntervalValue::minus_infinity(), 3) / IntervalValue(2)) + .equals(IntervalValue(IntervalValue::minus_infinity(), 1))); + assert((IntervalValue(1, 3) / IntervalValue(1, 2)).equals(IntervalValue(0, 3))); // assert((IntervalValue(-3, 3) / IntervalValue(1, 2)).equals(IntervalValue(-3, 3))); - assert((IntervalValue(2, 7) / IntervalValue(-2, 3)).equals(IntervalValue(-7, 7))); // + assert((IntervalValue(2, 7) / IntervalValue(-2, 3)).equals(IntervalValue(-7, 7))); // assert((IntervalValue(-2, 7) / IntervalValue(-2, 3)).equals(IntervalValue(-7, 7))); // assert((IntervalValue(IntervalValue::minus_infinity(), 7) / IntervalValue(-2, 3)).equals(IntervalValue::top())); assert((IntervalValue(-2, IntervalValue::plus_infinity()) / IntervalValue(-2, 3)).equals(IntervalValue::top())); @@ -670,7 +612,7 @@ class AETest assert((IntervalValue(IntervalValue::minus_infinity(), 3) % IntervalValue(2)).equals(IntervalValue(-1, 1))); assert((IntervalValue(1, 3) % IntervalValue(1, 2)).equals(IntervalValue(0, 1))); assert((IntervalValue(-3, 3) % IntervalValue(1, 2)).equals(IntervalValue(-1, 1))); - assert((IntervalValue(2, 7) % IntervalValue(-2, 3)).equals(IntervalValue::top())); // + assert((IntervalValue(2, 7) % IntervalValue(-2, 3)).equals(IntervalValue::top())); // assert((IntervalValue(-2, 7) % IntervalValue(-2, 3)).equals(IntervalValue::top())); // assert((IntervalValue(IntervalValue::minus_infinity(), 7) % IntervalValue(-2, 3)).equals(IntervalValue::top())); assert((IntervalValue(-2, IntervalValue::plus_infinity()) % IntervalValue(-2, 3)).equals(IntervalValue::top())); @@ -680,13 +622,19 @@ class AETest assert((IntervalValue(-6, 6) % IntervalValue(3, 9)).equals(IntervalValue(-6, 6))); // shl << - assert((IntervalValue(IntervalValue::plus_infinity()) << IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(IntervalValue::top()))); - assert((IntervalValue(IntervalValue::plus_infinity()) << IntervalValue(2, 2)).equals(IntervalValue(IntervalValue::plus_infinity()))); - assert((IntervalValue(IntervalValue::minus_infinity()) << IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(IntervalValue::top()))); - assert((IntervalValue(IntervalValue::minus_infinity()) << IntervalValue(2, 2)).equals(IntervalValue(IntervalValue::minus_infinity()))); - assert((IntervalValue(2, 2) << IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(IntervalValue::top()))); + assert((IntervalValue(IntervalValue::plus_infinity()) << IntervalValue(IntervalValue::plus_infinity())) + .equals(IntervalValue(IntervalValue::top()))); + assert((IntervalValue(IntervalValue::plus_infinity()) << IntervalValue(2, 2)) + .equals(IntervalValue(IntervalValue::plus_infinity()))); + assert((IntervalValue(IntervalValue::minus_infinity()) << IntervalValue(IntervalValue::plus_infinity())) + .equals(IntervalValue(IntervalValue::top()))); + assert((IntervalValue(IntervalValue::minus_infinity()) << IntervalValue(2, 2)) + .equals(IntervalValue(IntervalValue::minus_infinity()))); + assert((IntervalValue(2, 2) << IntervalValue(IntervalValue::plus_infinity())) + .equals(IntervalValue(IntervalValue::top()))); assert((IntervalValue(0, 0) << IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(0, 0))); - assert((IntervalValue(-2, -2) << IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(IntervalValue::top()))); + assert((IntervalValue(-2, -2) << IntervalValue(IntervalValue::plus_infinity())) + .equals(IntervalValue(IntervalValue::top()))); assert((IntervalValue(0, 0) << IntervalValue(2, 2)).equals(IntervalValue(0, 0))); assert((IntervalValue(2, 2) << IntervalValue(3, 3)).equals(IntervalValue(16, 16))); assert((IntervalValue(-2, -2) << IntervalValue(3, 3)).equals(IntervalValue(-16, -16))); @@ -701,27 +649,37 @@ class AETest assert((IntervalValue(1, 3) << IntervalValue(2)).equals(IntervalValue(4, 12))); assert((IntervalValue(2, 7) << IntervalValue(2)).equals(IntervalValue(8, 28))); assert((IntervalValue(-3, 3) << IntervalValue(2)).equals(IntervalValue(-12, 12))); - assert((IntervalValue(-3, IntervalValue::plus_infinity()) << IntervalValue(2)).equals(IntervalValue(-12, IntervalValue::plus_infinity()))); - assert((IntervalValue(IntervalValue::minus_infinity(), 3) << IntervalValue(2)).equals(IntervalValue(IntervalValue::minus_infinity(), 12))); + assert((IntervalValue(-3, IntervalValue::plus_infinity()) << IntervalValue(2)) + .equals(IntervalValue(-12, IntervalValue::plus_infinity()))); + assert((IntervalValue(IntervalValue::minus_infinity(), 3) << IntervalValue(2)) + .equals(IntervalValue(IntervalValue::minus_infinity(), 12))); assert((IntervalValue(1, 3) << IntervalValue(1, 2)).equals(IntervalValue(2, 12))); assert((IntervalValue(-3, 3) << IntervalValue(1, 2)).equals(IntervalValue(-12, 12))); assert((IntervalValue(2, 7) << IntervalValue(-2, 3)).equals(IntervalValue(2, 56))); assert((IntervalValue(-2, 7) << IntervalValue(-2, 3)).equals(IntervalValue(-16, 56))); - assert((IntervalValue(IntervalValue::minus_infinity(), 7) << IntervalValue(-2, 3)).equals(IntervalValue(IntervalValue::minus_infinity(), 56))); - assert((IntervalValue(-2, IntervalValue::plus_infinity()) << IntervalValue(-2, 3)).equals(IntervalValue(-16, IntervalValue::plus_infinity()))); - assert((IntervalValue(-2, 7) << IntervalValue(IntervalValue::minus_infinity(), 3)).equals(IntervalValue(-16, 56))); - assert((IntervalValue(-2, 7) << IntervalValue(-2, IntervalValue::plus_infinity())).equals(IntervalValue::top())); + assert((IntervalValue(IntervalValue::minus_infinity(), 7) << IntervalValue(-2, 3)) + .equals(IntervalValue(IntervalValue::minus_infinity(), 56))); + assert((IntervalValue(-2, IntervalValue::plus_infinity()) << IntervalValue(-2, 3)) + .equals(IntervalValue(-16, IntervalValue::plus_infinity()))); + assert( + (IntervalValue(-2, 7) << IntervalValue(IntervalValue::minus_infinity(), 3)).equals(IntervalValue(-16, 56))); + assert( + (IntervalValue(-2, 7) << IntervalValue(-2, IntervalValue::plus_infinity())).equals(IntervalValue::top())); assert((IntervalValue(-6, -3) << IntervalValue(3, 9)).equals(IntervalValue(-3072, -24))); assert((IntervalValue(-6, 6) << IntervalValue(3, 9)).equals(IntervalValue(-3072, 3072))); - assert((IntervalValue(-2, 7) << IntervalValue(IntervalValue::minus_infinity(), -1)).equals(IntervalValue::bottom())); + assert((IntervalValue(-2, 7) << IntervalValue(IntervalValue::minus_infinity(), -1)) + .equals(IntervalValue::bottom())); assert((IntervalValue(0) << IntervalValue::top()).equals(IntervalValue(0))); - // shr >> - assert((IntervalValue(IntervalValue::plus_infinity()) >> IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(IntervalValue::plus_infinity()))); - assert((IntervalValue(IntervalValue::plus_infinity()) >> IntervalValue(2)).equals(IntervalValue(IntervalValue::plus_infinity()))); - assert((IntervalValue(IntervalValue::minus_infinity()) >> IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(IntervalValue::minus_infinity()))); - assert((IntervalValue(IntervalValue::minus_infinity()) >> IntervalValue(2)).equals(IntervalValue(IntervalValue::minus_infinity()))); + assert((IntervalValue(IntervalValue::plus_infinity()) >> IntervalValue(IntervalValue::plus_infinity())) + .equals(IntervalValue(IntervalValue::plus_infinity()))); + assert((IntervalValue(IntervalValue::plus_infinity()) >> IntervalValue(2)) + .equals(IntervalValue(IntervalValue::plus_infinity()))); + assert((IntervalValue(IntervalValue::minus_infinity()) >> IntervalValue(IntervalValue::plus_infinity())) + .equals(IntervalValue(IntervalValue::minus_infinity()))); + assert((IntervalValue(IntervalValue::minus_infinity()) >> IntervalValue(2)) + .equals(IntervalValue(IntervalValue::minus_infinity()))); assert((IntervalValue(2) >> IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(0))); assert((IntervalValue(0) >> IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(0))); assert((IntervalValue(-2) >> IntervalValue(IntervalValue::plus_infinity())).equals(IntervalValue(-1))); @@ -739,19 +697,26 @@ class AETest assert((IntervalValue(1, 3) >> IntervalValue(2)).equals(IntervalValue(0))); assert((IntervalValue(2, 7) >> IntervalValue(2)).equals(IntervalValue(0, 1))); assert((IntervalValue(-15, 15) >> IntervalValue(2)).equals(IntervalValue(-4, 3))); - assert((IntervalValue(-15, IntervalValue::plus_infinity()) >> IntervalValue(2)).equals(IntervalValue(-4, IntervalValue::plus_infinity()))); - assert((IntervalValue(IntervalValue::minus_infinity(), 15) >> IntervalValue(2)).equals(IntervalValue(IntervalValue::minus_infinity(), 3))); + assert((IntervalValue(-15, IntervalValue::plus_infinity()) >> IntervalValue(2)) + .equals(IntervalValue(-4, IntervalValue::plus_infinity()))); + assert((IntervalValue(IntervalValue::minus_infinity(), 15) >> IntervalValue(2)) + .equals(IntervalValue(IntervalValue::minus_infinity(), 3))); assert((IntervalValue(0, 15) >> IntervalValue(1, 2)).equals(IntervalValue(0, 7))); assert((IntervalValue(-17, 15) >> IntervalValue(1, 2)).equals(IntervalValue(-9, 7))); assert((IntervalValue(2, 7) >> IntervalValue(-2, 3)).equals(IntervalValue(0, 7))); assert((IntervalValue(-2, 7) >> IntervalValue(-2, 3)).equals(IntervalValue(-2, 7))); - assert((IntervalValue(IntervalValue::minus_infinity(), 7) >> IntervalValue(-2, 3)).equals(IntervalValue(IntervalValue::minus_infinity(), 7))); - assert((IntervalValue(-2, IntervalValue::plus_infinity()) >> IntervalValue(-2, 3)).equals(IntervalValue(-2, IntervalValue::plus_infinity()))); - assert((IntervalValue(-2, 7) >> IntervalValue(IntervalValue::minus_infinity(), 3)).equals(IntervalValue(-2, 7))); - assert((IntervalValue(-2, 7) >> IntervalValue(-2, IntervalValue::plus_infinity())).equals(IntervalValue(-2, 7))); + assert((IntervalValue(IntervalValue::minus_infinity(), 7) >> IntervalValue(-2, 3)) + .equals(IntervalValue(IntervalValue::minus_infinity(), 7))); + assert((IntervalValue(-2, IntervalValue::plus_infinity()) >> IntervalValue(-2, 3)) + .equals(IntervalValue(-2, IntervalValue::plus_infinity()))); + assert( + (IntervalValue(-2, 7) >> IntervalValue(IntervalValue::minus_infinity(), 3)).equals(IntervalValue(-2, 7))); + assert( + (IntervalValue(-2, 7) >> IntervalValue(-2, IntervalValue::plus_infinity())).equals(IntervalValue(-2, 7))); assert((IntervalValue(-6, -3) >> IntervalValue(2, 3)).equals(IntervalValue(-2, -1))); assert((IntervalValue(-6, 6) >> IntervalValue(2, 3)).equals(IntervalValue(-2, 1))); - assert((IntervalValue(-2, 7) >> IntervalValue(IntervalValue::minus_infinity(), -1)).equals(IntervalValue::bottom())); + assert((IntervalValue(-2, 7) >> IntervalValue(IntervalValue::minus_infinity(), -1)) + .equals(IntervalValue::bottom())); assert((IntervalValue(0) >> IntervalValue::top()).equals(IntervalValue(0))); // and & @@ -780,8 +745,8 @@ class AETest // Or | assert((IntervalValue(4) | IntervalValue::bottom()).equals(IntervalValue::bottom())); assert((IntervalValue::bottom() | IntervalValue(2)).equals(IntervalValue::bottom())); - assert((IntervalValue::top() | IntervalValue(-1)).equals(IntervalValue::top()));// - assert((IntervalValue(-1) | IntervalValue::top()).equals(IntervalValue::top()));// + assert((IntervalValue::top() | IntervalValue(-1)).equals(IntervalValue::top())); // + assert((IntervalValue(-1) | IntervalValue::top()).equals(IntervalValue::top())); // assert((IntervalValue(4) | IntervalValue(2)).equals(IntervalValue(6))); assert((IntervalValue(3) | IntervalValue(2)).equals(IntervalValue(3))); assert((IntervalValue(-3) | IntervalValue(2)).equals(IntervalValue(-1))); @@ -840,26 +805,24 @@ class AETest } }; - int main(int argc, char** argv) { int arg_num = 0; int extraArgc = 3; - char **arg_value = new char *[argc + extraArgc]; + char** arg_value = new char*[argc + extraArgc]; for (; arg_num < argc; ++arg_num) { arg_value[arg_num] = argv[arg_num]; } // add extra options - arg_value[arg_num++] = (char*) "-model-consts=true"; - arg_value[arg_num++] = (char*) "-model-arrays=true"; - arg_value[arg_num++] = (char*) "-pre-field-sensitive=false"; + arg_value[arg_num++] = (char*)"-model-consts=true"; + arg_value[arg_num++] = (char*)"-model-arrays=true"; + arg_value[arg_num++] = (char*)"-pre-field-sensitive=false"; assert(arg_num == (argc + extraArgc) && "more extra arguments? Change the value of extraArgc"); std::vector moduleNameVec; - moduleNameVec = OptionBase::parseOptions( - arg_num, arg_value, "Static Symbolic Execution", "[options] " - ); + moduleNameVec = + OptionBase::parseOptions(arg_num, arg_value, "Static Symbolic Execution", "[options] "); delete[] arg_value; if (SYMABS()) { @@ -876,7 +839,7 @@ int main(int argc, char** argv) return 0; } - SVFModule *svfModule = LLVMModuleSet::getLLVMModuleSet()->buildSVFModule(moduleNameVec); + SVFModule* svfModule = LLVMModuleSet::getLLVMModuleSet()->buildSVFModule(moduleNameVec); SVFIRBuilder builder(svfModule); SVFIR* pag = builder.build(); AndersenWaveDiff* ander = AndersenWaveDiff::createAndersenWaveDiff(pag); diff --git a/svf-llvm/tools/CFL/cfl.cpp b/svf-llvm/tools/CFL/cfl.cpp index 1300fc0f0..0d5a4cbae 100644 --- a/svf-llvm/tools/CFL/cfl.cpp +++ b/svf-llvm/tools/CFL/cfl.cpp @@ -35,17 +35,14 @@ #include "CFL/CFLAlias.h" #include "CFL/CFLVF.h" - using namespace llvm; using namespace SVF; -int main(int argc, char ** argv) +int main(int argc, char** argv) { // Parses command-line arguments and stores any module names in moduleNameVec std::vector moduleNameVec; - moduleNameVec = OptionBase::parseOptions( - argc, argv, "CFL Reachability Analysis", "[options] " - ); + moduleNameVec = OptionBase::parseOptions(argc, argv, "CFL Reachability Analysis", "[options] "); // If the WriteAnder option is set to "ir_annotator", pre-processes the bytecodes of the modules if (Options::WriteAnder() == "ir_annotator") @@ -62,14 +59,13 @@ int main(int argc, char ** argv) SVFModule* svfModule = LLVMModuleSet::buildSVFModule(moduleNameVec); SVFIRBuilder builder(svfModule); svfir = builder.build(); - } // if no dot form CFLGraph is specified, we use svfir from .bc. + } // if no dot form CFLGraph is specified, we use svfir from .bc. // The CFLBase pointer that will be used to run the analysis std::unique_ptr cfl; // Determines which type of analysis to run based on the options and sets up cfl accordingly - if (Options::CFLSVFG()) - cfl = std::make_unique(svfir); + if (Options::CFLSVFG()) cfl = std::make_unique(svfir); else if (Options::POCRHybrid()) cfl = std::make_unique(svfir); else if (Options::POCRAlias()) @@ -84,8 +80,5 @@ int main(int argc, char ** argv) SVFIR::releaseSVFIR(); SVF::LLVMModuleSet::releaseLLVMModuleSet(); - return 0; - } - diff --git a/svf-llvm/tools/DDA/dda.cpp b/svf-llvm/tools/DDA/dda.cpp index 84f039606..4a17f7ce0 100644 --- a/svf-llvm/tools/DDA/dda.cpp +++ b/svf-llvm/tools/DDA/dda.cpp @@ -26,8 +26,8 @@ // Author: Yulei Sui, */ -//#include "AliasUtil/AliasAnalysisCounter.h" -//#include "MemoryModel/ComTypeModel.h" +// #include "AliasUtil/AliasAnalysisCounter.h" +// #include "MemoryModel/ComTypeModel.h" #include "SVF-LLVM/LLVMUtil.h" #include "SVF-LLVM/SVFIRBuilder.h" #include "DDA/DDAPass.h" @@ -36,21 +36,16 @@ using namespace llvm; using namespace SVF; -//static cl::list -//PassList(cl::desc("Optimizations available:")); +// static cl::list +// PassList(cl::desc("Optimizations available:")); -static Option DAA( - "daa", - "Demand-Driven Alias Analysis Pass", - false -); +static Option DAA("daa", "Demand-Driven Alias Analysis Pass", false); -int main(int argc, char ** argv) +int main(int argc, char** argv) { std::vector moduleNameVec; - moduleNameVec = OptionBase::parseOptions( - argc, argv, "Demand-Driven Points-to Analysis", "[options] " - ); + moduleNameVec = + OptionBase::parseOptions(argc, argv, "Demand-Driven Points-to Analysis", "[options] "); if (Options::WriteAnder() == "ir_annotator") { @@ -66,6 +61,4 @@ int main(int argc, char ** argv) LLVMModuleSet::releaseLLVMModuleSet(); return 0; - } - diff --git a/svf-llvm/tools/Example/svf-ex.cpp b/svf-llvm/tools/Example/svf-ex.cpp index f271434c6..fbae4d71f 100644 --- a/svf-llvm/tools/Example/svf-ex.cpp +++ b/svf-llvm/tools/Example/svf-ex.cpp @@ -57,19 +57,17 @@ std::string printPts(PointerAnalysis* pta, const SVFValue* svfval) NodeID pNodeId = pta->getPAG()->getValueNode(svfval); const PointsTo& pts = pta->getPts(pNodeId); - for (PointsTo::iterator ii = pts.begin(), ie = pts.end(); - ii != ie; ii++) + for (PointsTo::iterator ii = pts.begin(), ie = pts.end(); ii != ie; ii++) { rawstr << " " << *ii << " "; PAGNode* targetObj = pta->getPAG()->getGNode(*ii); - if(targetObj->hasValue()) + if (targetObj->hasValue()) { rawstr << "(" << targetObj->getValue()->toString() << ")\t "; } } return rawstr.str(); - } /*! * An example to query/collect all successor nodes from a ICFGNode (iNode) along control-flow graph (ICFG) @@ -84,8 +82,7 @@ void traverseOnICFG(ICFG* icfg, const ICFGNode* iNode) while (!worklist.empty()) { const ICFGNode* vNode = worklist.pop(); - for (ICFGNode::const_iterator it = vNode->OutEdgeBegin(), eit = - vNode->OutEdgeEnd(); it != eit; ++it) + for (ICFGNode::const_iterator it = vNode->OutEdgeBegin(), eit = vNode->OutEdgeEnd(); it != eit; ++it) { ICFGEdge* edge = *it; ICFGNode* succNode = edge->getDstNode(); @@ -98,10 +95,7 @@ void traverseOnICFG(ICFG* icfg, const ICFGNode* iNode) } } -void dummyVisit(const VFGNode* node) -{ - -} +void dummyVisit(const VFGNode* node) {} /*! * An example to query/collect all the uses of a definition of a value along value-flow graph (VFG) */ @@ -109,8 +103,7 @@ void traverseOnVFG(const SVFG* vfg, const SVFValue* svfval) { SVFIR* pag = SVFIR::getPAG(); PAGNode* pNode = pag->getGNode(pag->getValueNode(svfval)); - if (!vfg->hasDefSVFGNode(pNode)) - return; + if (!vfg->hasDefSVFGNode(pNode)) return; const VFGNode* vNode = vfg->getDefSVFGNode(pNode); FIFOWorkList worklist; Set visited; @@ -120,8 +113,7 @@ void traverseOnVFG(const SVFG* vfg, const SVFValue* svfval) while (!worklist.empty()) { const VFGNode* vNode = worklist.pop(); - for (VFGNode::const_iterator it = vNode->OutEdgeBegin(), eit = - vNode->OutEdgeEnd(); it != eit; ++it) + for (VFGNode::const_iterator it = vNode->OutEdgeBegin(), eit = vNode->OutEdgeEnd(); it != eit; ++it) { VFGEdge* edge = *it; VFGNode* succNode = edge->getDstNode(); @@ -134,7 +126,7 @@ void traverseOnVFG(const SVFG* vfg, const SVFValue* svfval) } /// Collect all LLVM Values - for(Set::const_iterator it = visited.begin(), eit = visited.end(); it!=eit; ++it) + for (Set::const_iterator it = visited.begin(), eit = visited.end(); it != eit; ++it) { const VFGNode* node = *it; dummyVisit(node); @@ -144,13 +136,12 @@ void traverseOnVFG(const SVFG* vfg, const SVFValue* svfval) } } -int main(int argc, char ** argv) +int main(int argc, char** argv) { std::vector moduleNameVec; - moduleNameVec = OptionBase::parseOptions( - argc, argv, "Whole Program Points-to Analysis", "[options] " - ); + moduleNameVec = + OptionBase::parseOptions(argc, argv, "Whole Program Points-to Analysis", "[options] "); if (Options::WriteAnder() == "ir_annotator") { @@ -166,7 +157,6 @@ int main(int argc, char ** argv) /// Create Andersen's pointer analysis Andersen* ander = AndersenWaveDiff::createAndersenWaveDiff(pag); - /// Call Graph CallGraph* callgraph = ander->getCallGraph(); @@ -194,8 +184,7 @@ int main(int argc, char ** argv) for (const SVFGEdge* edge : node->getOutEdges()) { const SVFGNode* node2 = edge->getDstNode(); - if (node2->getValue()) - aliasQuery(ander, node->getValue(), node2->getValue()); + if (node2->getValue()) aliasQuery(ander, node->getValue(), node2->getValue()); } } } @@ -221,4 +210,3 @@ int main(int argc, char ** argv) llvm::llvm_shutdown(); return 0; } - diff --git a/svf-llvm/tools/LLVM2SVF/llvm2svf.cpp b/svf-llvm/tools/LLVM2SVF/llvm2svf.cpp index 0b765de74..67dd58459 100644 --- a/svf-llvm/tools/LLVM2SVF/llvm2svf.cpp +++ b/svf-llvm/tools/LLVM2SVF/llvm2svf.cpp @@ -32,7 +32,6 @@ #include "Util/Options.h" #include "SVFIR/SVFFileSystem.h" - using namespace std; using namespace SVF; @@ -42,8 +41,7 @@ using namespace SVF; std::string replaceExtension(const std::string& path) { size_t pos = path.rfind('.'); - if (pos == std::string::npos || - (path.substr(pos) != ".bc" && path.substr(pos) != ".ll")) + if (pos == std::string::npos || (path.substr(pos) != ".bc" && path.substr(pos) != ".ll")) { SVFUtil::errs() << "Error: expect file with extension .bc or .ll\n"; exit(EXIT_FAILURE); @@ -53,8 +51,7 @@ std::string replaceExtension(const std::string& path) int main(int argc, char** argv) { - auto moduleNameVec = OptionBase::parseOptions( - argc, argv, "llvm2svf", "[options] "); + auto moduleNameVec = OptionBase::parseOptions(argc, argv, "llvm2svf", "[options] "); if (Options::WriteAnder() == "ir_annotator") { diff --git a/svf-llvm/tools/MTA/mta.cpp b/svf-llvm/tools/MTA/mta.cpp index 5e40c7955..e8e2cd0a7 100644 --- a/svf-llvm/tools/MTA/mta.cpp +++ b/svf-llvm/tools/MTA/mta.cpp @@ -30,13 +30,11 @@ using namespace llvm; using namespace std; using namespace SVF; -int main(int argc, char ** argv) +int main(int argc, char** argv) { std::vector moduleNameVec; - moduleNameVec = OptionBase::parseOptions( - argc, argv, "MTA Analysis", "[options] " - ); + moduleNameVec = OptionBase::parseOptions(argc, argv, "MTA Analysis", "[options] "); if (Options::WriteAnder() == "ir_annotator") { @@ -47,12 +45,10 @@ int main(int argc, char ** argv) SVFIRBuilder builder(svfModule); SVFIR* pag = builder.build(); - MTA mta; mta.runOnModule(pag); LLVMModuleSet::releaseLLVMModuleSet(); - return 0; } diff --git a/svf-llvm/tools/SABER/saber.cpp b/svf-llvm/tools/SABER/saber.cpp index c129dc947..7a43c355c 100644 --- a/svf-llvm/tools/SABER/saber.cpp +++ b/svf-llvm/tools/SABER/saber.cpp @@ -35,17 +35,14 @@ #include "Util/Options.h" #include "Util/Z3Expr.h" - using namespace llvm; using namespace SVF; -int main(int argc, char ** argv) +int main(int argc, char** argv) { std::vector moduleNameVec; - moduleNameVec = OptionBase::parseOptions( - argc, argv, "Source-Sink Bug Detector", "[options] " - ); + moduleNameVec = OptionBase::parseOptions(argc, argv, "Source-Sink Bug Detector", "[options] "); if (Options::WriteAnder() == "ir_annotator") { @@ -56,22 +53,18 @@ int main(int argc, char ** argv) SVFIRBuilder builder(svfModule); SVFIR* pag = builder.build(); - std::unique_ptr saber; - if(Options::MemoryLeakCheck()) - saber = std::make_unique(); - else if(Options::FileCheck()) + if (Options::MemoryLeakCheck()) saber = std::make_unique(); + else if (Options::FileCheck()) saber = std::make_unique(); - else if(Options::DFreeCheck()) + else if (Options::DFreeCheck()) saber = std::make_unique(); else - saber = std::make_unique(); // if no checker is specified, we use leak checker as the default one. + saber = std::make_unique(); // if no checker is specified, we use leak checker as the default one. saber->runOnModule(pag); LLVMModuleSet::releaseLLVMModuleSet(); - return 0; - } diff --git a/svf-llvm/tools/WPA/wpa.cpp b/svf-llvm/tools/WPA/wpa.cpp index afa86d0f7..5aea7b52f 100644 --- a/svf-llvm/tools/WPA/wpa.cpp +++ b/svf-llvm/tools/WPA/wpa.cpp @@ -33,7 +33,6 @@ #include "Util/Options.h" #include "SVFIR/SVFFileSystem.h" - using namespace llvm; using namespace std; using namespace SVF; @@ -41,8 +40,7 @@ using namespace SVF; int main(int argc, char** argv) { auto moduleNameVec = - OptionBase::parseOptions(argc, argv, "Whole Program Points-to Analysis", - "[options] "); + OptionBase::parseOptions(argc, argv, "Whole Program Points-to Analysis", "[options] "); // Refers to content of a singleton unique_ptr in SVFIR. SVFIR* pag; @@ -63,7 +61,6 @@ int main(int argc, char** argv) /// Build SVFIR SVFIRBuilder builder(svfModule); pag = builder.build(); - } WPAPass wpa; diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index 860413114..3a5c0aa79 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -59,6 +59,7 @@ class AbstractState { friend class SVFIR2AbsState; friend class RelationSolver; + public: typedef Map VarToAbsValMap; @@ -66,17 +67,15 @@ class AbstractState public: /// default constructor - AbstractState() + AbstractState() {} + + AbstractState(VarToAbsValMap& _varToValMap, AddrToAbsValMap& _locToValMap) + : _varToAbsVal(_varToValMap), _addrToAbsVal(_locToValMap) { } - AbstractState(VarToAbsValMap&_varToValMap, AddrToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), _addrToAbsVal(_locToValMap) {} - /// copy constructor - AbstractState(const AbstractState&rhs) : _varToAbsVal(rhs.getVarToVal()), _addrToAbsVal(rhs.getLocToVal()) - { - - } + AbstractState(const AbstractState& rhs) : _varToAbsVal(rhs.getVarToVal()), _addrToAbsVal(rhs.getLocToVal()) {} virtual ~AbstractState() = default; @@ -95,7 +94,6 @@ class AbstractState // storeValue void storeValue(NodeID varId, AbstractValue val); - /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { @@ -119,7 +117,7 @@ class AbstractState return getInternalID(addr) == 0; } - AbstractState&operator=(const AbstractState&rhs) + AbstractState& operator=(const AbstractState& rhs) { if (rhs != *this) { @@ -130,14 +128,13 @@ class AbstractState } /// move constructor - AbstractState(AbstractState&&rhs) : _varToAbsVal(std::move(rhs._varToAbsVal)), - _addrToAbsVal(std::move(rhs._addrToAbsVal)) + AbstractState(AbstractState&& rhs) + : _varToAbsVal(std::move(rhs._varToAbsVal)), _addrToAbsVal(std::move(rhs._addrToAbsVal)) { - } /// operator= move constructor - AbstractState&operator=(AbstractState&&rhs) + AbstractState& operator=(AbstractState&& rhs) { if (&rhs != this) { @@ -151,10 +148,9 @@ class AbstractState AbstractState bottom() const { AbstractState inv = *this; - for (auto &item: inv._varToAbsVal) + for (auto& item : inv._varToAbsVal) { - if (item.second.isInterval()) - item.second.getInterval().set_to_bottom(); + if (item.second.isInterval()) item.second.getInterval().set_to_bottom(); } return inv; } @@ -163,19 +159,18 @@ class AbstractState AbstractState top() const { AbstractState inv = *this; - for (auto &item: inv._varToAbsVal) + for (auto& item : inv._varToAbsVal) { - if (item.second.isInterval()) - item.second.getInterval().set_to_top(); + if (item.second.isInterval()) item.second.getInterval().set_to_top(); } return inv; } /// Copy some values and return a new IntervalExeState - AbstractState sliceState(Set &sl) + AbstractState sliceState(Set& sl) { AbstractState inv; - for (u32_t id: sl) + for (u32_t id : sl) { inv._varToAbsVal[id] = _varToAbsVal[id]; } @@ -183,21 +178,18 @@ class AbstractState } protected: - VarToAbsValMap _varToAbsVal; ///< Map a variable (symbol) to its abstract value - AddrToAbsValMap - _addrToAbsVal; ///< Map a memory address to its stored abstract value + VarToAbsValMap _varToAbsVal; ///< Map a variable (symbol) to its abstract value + AddrToAbsValMap _addrToAbsVal; ///< Map a memory address to its stored abstract value public: - - /// get abstract value of variable - inline virtual AbstractValue &operator[](u32_t varId) + inline virtual AbstractValue& operator[](u32_t varId) { return _varToAbsVal[varId]; } /// get abstract value of variable - inline virtual const AbstractValue &operator[](u32_t varId) const + inline virtual const AbstractValue& operator[](u32_t varId) const { return _varToAbsVal.at(varId); } @@ -205,7 +197,7 @@ class AbstractState /// whether the variable is in varToAddrs table inline bool inVarToAddrsTable(u32_t id) const { - if (_varToAbsVal.find(id)!= _varToAbsVal.end()) + if (_varToAbsVal.find(id) != _varToAbsVal.end()) { if (_varToAbsVal.at(id).isAddr()) { @@ -231,7 +223,7 @@ class AbstractState /// whether the memory address stores memory addresses inline bool inAddrToAddrsTable(u32_t id) const { - if (_addrToAbsVal.find(id)!= _addrToAbsVal.end()) + if (_addrToAbsVal.find(id) != _addrToAbsVal.end()) { if (_addrToAbsVal.at(id).isAddr()) { @@ -255,45 +247,41 @@ class AbstractState } /// get var2val map - const VarToAbsValMap&getVarToVal() const + const VarToAbsValMap& getVarToVal() const { return _varToAbsVal; } /// get loc2val map - const AddrToAbsValMap&getLocToVal() const + const AddrToAbsValMap& getLocToVal() const { return _addrToAbsVal; } public: - /// domain widen with other, and return the widened domain - AbstractState widening(const AbstractState&other); + AbstractState widening(const AbstractState& other); /// domain narrow with other, and return the narrowed domain - AbstractState narrowing(const AbstractState&other); + AbstractState narrowing(const AbstractState& other); /// domain join with other, important! other widen this. - void joinWith(const AbstractState&other); - + void joinWith(const AbstractState& other); /// domain meet with other, important! other widen this. - void meetWith(const AbstractState&other); - + void meetWith(const AbstractState& other); /// Return int value from an expression if it is a numeral, otherwise return an approximate value - inline s32_t Interval2NumValue(const IntervalValue &e) const + inline s32_t Interval2NumValue(const IntervalValue& e) const { - //TODO: return concrete value; - return (s32_t) e.lb().getNumeral(); + // TODO: return concrete value; + return (s32_t)e.lb().getNumeral(); } - u32_t hash() const; public: - inline void store(u32_t addr, const AbstractValue &val) + inline void store(u32_t addr, const AbstractValue& val) { assert(isVirtualMemAddress(addr) && "not virtual address?"); if (isNullPtr(addr)) return; @@ -301,15 +289,13 @@ class AbstractState _addrToAbsVal[objId] = val; } - inline virtual AbstractValue &load(u32_t addr) + inline virtual AbstractValue& load(u32_t addr) { assert(isVirtualMemAddress(addr) && "not virtual address?"); u32_t objId = getInternalID(addr); return _addrToAbsVal[objId]; - } - void printAbstractState() const; std::string toString() const @@ -317,19 +303,16 @@ class AbstractState return ""; } - bool equals(const AbstractState&other) const; - + bool equals(const AbstractState& other) const; - static bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) + static bool eqVarToValMap(const VarToAbsValMap& lhs, const VarToAbsValMap& rhs) { if (lhs.size() != rhs.size()) return false; - for (const auto &item: lhs) + for (const auto& item : lhs) { auto it = rhs.find(item.first); - if (it == rhs.end()) - return false; - if (!item.second.equals(it->second)) - return false; + if (it == rhs.end()) return false; + if (!item.second.equals(it->second)) return false; else { } @@ -337,10 +320,10 @@ class AbstractState return true; } - static bool lessThanVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) + static bool lessThanVarToValMap(const VarToAbsValMap& lhs, const VarToAbsValMap& rhs) { if (lhs.empty()) return !rhs.empty(); - for (const auto &item: lhs) + for (const auto& item : lhs) { auto it = rhs.find(item.first); if (it == rhs.end()) return false; @@ -351,40 +334,35 @@ class AbstractState } // lhs >= rhs - static bool geqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) + static bool geqVarToValMap(const VarToAbsValMap& lhs, const VarToAbsValMap& rhs) { if (rhs.empty()) return true; - for (const auto &item: rhs) + for (const auto& item : rhs) { auto it = lhs.find(item.first); if (it == lhs.end()) return false; // judge from expr id - if (!it->second.getInterval().contain( - item.second.getInterval())) - return false; - + if (!it->second.getInterval().contain(item.second.getInterval())) return false; } return true; } - bool operator==(const AbstractState&rhs) const + bool operator==(const AbstractState& rhs) const { - return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && - eqVarToValMap(_addrToAbsVal, rhs.getLocToVal()); + return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && eqVarToValMap(_addrToAbsVal, rhs.getLocToVal()); } - bool operator!=(const AbstractState&rhs) const + bool operator!=(const AbstractState& rhs) const { return !(*this == rhs); } - bool operator<(const AbstractState&rhs) const + bool operator<(const AbstractState& rhs) const { return !(*this >= rhs); } - - bool operator>=(const AbstractState&rhs) const + bool operator>=(const AbstractState& rhs) const { return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal()); } @@ -394,11 +372,8 @@ class AbstractState _addrToAbsVal.clear(); _varToAbsVal.clear(); } - - }; -} - +} // namespace SVF -#endif //Z3_EXAMPLE_INTERVAL_DOMAIN_H +#endif // Z3_EXAMPLE_INTERVAL_DOMAIN_H diff --git a/svf/include/AE/Core/AbstractValue.h b/svf/include/AE/Core/AbstractValue.h index 1430d37c1..df9fa7f70 100644 --- a/svf/include/AE/Core/AbstractValue.h +++ b/svf/include/AE/Core/AbstractValue.h @@ -59,7 +59,7 @@ class AbstractValue return !addrs.isBottom(); } - AbstractValue(AbstractValue &&other) + AbstractValue(AbstractValue&& other) { interval = SVFUtil::move(other.interval); addrs = SVFUtil::move(other.addrs); @@ -118,32 +118,32 @@ class AbstractValue return addrs; } - ~AbstractValue() {}; + ~AbstractValue(){}; - bool equals(const AbstractValue &rhs) const + bool equals(const AbstractValue& rhs) const { return interval.equals(rhs.interval) && addrs.equals(rhs.addrs); } - void join_with(const AbstractValue &other) + void join_with(const AbstractValue& other) { interval.join_with(other.interval); addrs.join_with(other.addrs); } - void meet_with(const AbstractValue &other) + void meet_with(const AbstractValue& other) { interval.meet_with(other.interval); addrs.meet_with(other.addrs); } - void widen_with(const AbstractValue &other) + void widen_with(const AbstractValue& other) { interval.widen_with(other.interval); // TODO: widen Addrs } - void narrow_with(const AbstractValue &other) + void narrow_with(const AbstractValue& other) { interval.narrow_with(other.interval); // TODO: narrow Addrs @@ -154,4 +154,4 @@ class AbstractValue return "<" + interval.toString() + ", " + addrs.toString() + ">"; } }; -} \ No newline at end of file +} // namespace SVF \ No newline at end of file diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index 3fb4ab49c..e8f35920d 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -31,7 +31,7 @@ #define Z3_EXAMPLE_ADDRESSVALUE_H #define AddressMask 0x7f000000 -#define FlippedAddressMask (AddressMask^0xffffffff) +#define FlippedAddressMask (AddressMask ^ 0xffffffff) // the address of the black hole, getVirtualMemAddress(2); #define BlackHoleAddr 0x7f000000 + 2 @@ -44,28 +44,30 @@ class AddressValue { public: typedef Set AddrSet; + private: AddrSet _addrs; + public: /// Default constructor AddressValue() {} /// Constructor - AddressValue(const Set &addrs) : _addrs(addrs) {} + AddressValue(const Set& addrs) : _addrs(addrs) {} - AddressValue(u32_t addr) : _addrs({addr}) {} + AddressValue(u32_t addr) : _addrs({addr}) {} /// Default destructor ~AddressValue() = default; /// Copy constructor - AddressValue(const AddressValue &other) : _addrs(other._addrs) {} + AddressValue(const AddressValue& other) : _addrs(other._addrs) {} /// Move constructor - AddressValue(AddressValue &&other) noexcept: _addrs(std::move(other._addrs)) {} + AddressValue(AddressValue&& other) noexcept : _addrs(std::move(other._addrs)) {} /// Copy operator= - AddressValue &operator=(const AddressValue &other) + AddressValue& operator=(const AddressValue& other) { if (!this->equals(other)) { @@ -75,7 +77,7 @@ class AddressValue } /// Move operator= - AddressValue &operator=(AddressValue &&other) noexcept + AddressValue& operator=(AddressValue&& other) noexcept { if (this != &other) { @@ -84,7 +86,7 @@ class AddressValue return *this; } - bool equals(const AddressValue &rhs) const + bool equals(const AddressValue& rhs) const { return _addrs == rhs._addrs; } @@ -114,36 +116,35 @@ class AddressValue return _addrs.insert(id); } - const AddrSet &getVals() const + const AddrSet& getVals() const { return _addrs; } - void setVals(const AddrSet &vals) + void setVals(const AddrSet& vals) { _addrs = vals; } /// Current AddressValue joins with another AddressValue - bool join_with(const AddressValue &other) + bool join_with(const AddressValue& other) { bool changed = false; - for (const auto &addr: other) + for (const auto& addr : other) { if (!_addrs.count(addr)) { - if (insert(addr).second) - changed = true; + if (insert(addr).second) changed = true; } } return changed; } /// Return a intersected AddressValue - bool meet_with(const AddressValue &other) + bool meet_with(const AddressValue& other) { AddrSet s; - for (const auto &id: other._addrs) + for (const auto& id : other._addrs) { if (_addrs.find(id) != _addrs.end()) { @@ -161,7 +162,7 @@ class AddressValue return _addrs.count(id); } - bool hasIntersect(const AddressValue &other) + bool hasIntersect(const AddressValue& other) { AddressValue v = *this; v.meet_with(other); @@ -199,7 +200,7 @@ class AddressValue else { rawStr << "["; - for (auto it = _addrs.begin(), eit = _addrs.end(); it!= eit; ++it) + for (auto it = _addrs.begin(), eit = _addrs.end(); it != eit; ++it) { rawStr << *it << ", "; } @@ -229,4 +230,4 @@ class AddressValue } }; } // end namespace SVF -#endif //Z3_EXAMPLE_ADDRESSVALUE_H +#endif // Z3_EXAMPLE_ADDRESSVALUE_H diff --git a/svf/include/AE/Core/ICFGWTO.h b/svf/include/AE/Core/ICFGWTO.h index 986a6348e..04c9826db 100644 --- a/svf/include/AE/Core/ICFGWTO.h +++ b/svf/include/AE/Core/ICFGWTO.h @@ -52,13 +52,9 @@ class ICFGWTO : public WTO explicit ICFGWTO(ICFG* graph, const ICFGNode* node) : Base(graph, node) {} - virtual ~ICFGWTO() - { - } + virtual ~ICFGWTO() {} - inline void forEachSuccessor( - const ICFGNode* node, - std::function func) const override + inline void forEachSuccessor(const ICFGNode* node, std::function func) const override { if (const auto* callNode = SVFUtil::dyn_cast(node)) { @@ -69,9 +65,7 @@ class ICFGWTO : public WTO { for (const auto& e : node->getOutEdges()) { - if (!e->isIntraCFGEdge() || - node->getFun() != e->getDstNode()->getFun()) - continue; + if (!e->isIntraCFGEdge() || node->getFun() != e->getDstNode()->getFun()) continue; func(e->getDstNode()); } } diff --git a/svf/include/AE/Core/IntervalValue.h b/svf/include/AE/Core/IntervalValue.h index 35a3a9a9a..894f7341a 100644 --- a/svf/include/AE/Core/IntervalValue.h +++ b/svf/include/AE/Core/IntervalValue.h @@ -53,15 +53,15 @@ class IntervalValue // Invariant: isBottom() <=> _lb = +inf && _ub = -inf public: - friend IntervalValue operator+(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator-(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator*(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator/(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator<<(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator>>(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator&(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator|(const IntervalValue &lhs, const IntervalValue &rhs); - friend IntervalValue operator^(const IntervalValue &lhs, const IntervalValue &rhs); + friend IntervalValue operator+(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator-(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator*(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator/(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator<<(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator>>(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator&(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator|(const IntervalValue& lhs, const IntervalValue& rhs); + friend IntervalValue operator^(const IntervalValue& lhs, const IntervalValue& rhs); bool isTop() const { @@ -85,7 +85,7 @@ class IntervalValue return BoundedInt::plus_infinity(); } - static bool is_infinite(const BoundedInt &e) + static bool is_infinite(const BoundedInt& e) { return e.is_infinity(); } @@ -108,9 +108,9 @@ class IntervalValue /// Create the IntervalValue [n, n] explicit IntervalValue(s64_t n) : _lb(n), _ub(n) {} - explicit IntervalValue(s32_t n) : IntervalValue((s64_t) n) {} + explicit IntervalValue(s32_t n) : IntervalValue((s64_t)n) {} - explicit IntervalValue(u32_t n) : IntervalValue((s64_t) n) {} + explicit IntervalValue(u32_t n) : IntervalValue((s64_t)n) {} explicit IntervalValue(double n) : _lb(n), _ub(n) {} @@ -128,26 +128,26 @@ class IntervalValue explicit IntervalValue(float lb, float ub) : IntervalValue(BoundedInt(lb), BoundedInt(ub)) {} - explicit IntervalValue(s32_t lb, s32_t ub) : IntervalValue((s64_t) lb, (s64_t) ub) {} + explicit IntervalValue(s32_t lb, s32_t ub) : IntervalValue((s64_t)lb, (s64_t)ub) {} - explicit IntervalValue(u32_t lb, u32_t ub) : IntervalValue((s64_t) lb, (s64_t) ub) {} + explicit IntervalValue(u32_t lb, u32_t ub) : IntervalValue((s64_t)lb, (s64_t)ub) {} - explicit IntervalValue(u64_t lb, u64_t ub) : IntervalValue((s64_t) lb, (s64_t) ub) {} + explicit IntervalValue(u64_t lb, u64_t ub) : IntervalValue((s64_t)lb, (s64_t)ub) {} /// Copy constructor - IntervalValue(const IntervalValue &) = default; + IntervalValue(const IntervalValue&) = default; /// Move constructor - IntervalValue(IntervalValue &&) = default; + IntervalValue(IntervalValue&&) = default; /// Copy assignment operator - IntervalValue &operator=(const IntervalValue &a) = default; + IntervalValue& operator=(const IntervalValue& a) = default; /// Move assignment operator - IntervalValue &operator=(IntervalValue &&) = default; + IntervalValue& operator=(IntervalValue&&) = default; /// Equality comparison - IntervalValue operator==(const IntervalValue &other) const + IntervalValue operator==(const IntervalValue& other) const { if (this->isBottom() || other.isBottom()) { @@ -181,7 +181,7 @@ class IntervalValue } /// Equality comparison - IntervalValue operator!=(const IntervalValue &other) const + IntervalValue operator!=(const IntervalValue& other) const { if (this->isBottom() || other.isBottom()) { @@ -214,17 +214,17 @@ class IntervalValue } /// Destructor - ~IntervalValue() = default; + ~IntervalValue() = default; /// Return the lower bound - const BoundedInt &lb() const + const BoundedInt& lb() const { assert(!this->isBottom() && "bottom interval does not have lower bound"); return this->_lb; } /// Return the upper bound - const BoundedInt &ub() const + const BoundedInt& ub() const { assert(!this->isBottom() && "bottom interval does not have upper bound"); return this->_ub; @@ -297,7 +297,7 @@ class IntervalValue /// Example: this: [2, 3], other: [1, 4] -> returns true /// Note: If the current interval is 'bottom', it is considered contained within any interval. /// If the other interval is 'bottom', it cannot contain any interval. - bool containedWithin(const IntervalValue &other) const + bool containedWithin(const IntervalValue& other) const { if (this->isBottom()) { @@ -311,14 +311,13 @@ class IntervalValue { return other._lb.leq(this->_lb) && this->_ub.leq(other._ub); } - } /// Determines if the current IntervalValue fully contains another IntervalValue. /// Example: this: [1, 4], other: [2, 3] -> returns true /// Note: If the current interval is 'bottom', it is considered to contain any interval. /// If the other interval is 'bottom', it cannot be contained by any interval. - bool contain(const IntervalValue &other) const + bool contain(const IntervalValue& other) const { if (this->isBottom()) { @@ -336,7 +335,7 @@ class IntervalValue /// Check the upper bound of this Interval is less than or equal to the lower bound /// e.g. [1, 3] < [3, 5] return true, lhs.ub <= rhs.lb - bool leq(const IntervalValue &other) const + bool leq(const IntervalValue& other) const { if (this->isBottom()) { @@ -354,7 +353,7 @@ class IntervalValue /// Check the lower bound of this Interval is greater than or equal to the upper bound /// e.g. [3, 5] > [1, 3] return true, lhs.lb >= rhs.ub - bool geq(const IntervalValue &other) const + bool geq(const IntervalValue& other) const { if (this->isBottom()) { @@ -370,9 +369,8 @@ class IntervalValue } } - /// Equality comparison - bool equals(const IntervalValue &other) const + bool equals(const IntervalValue& other) const { if (this->isBottom()) { @@ -413,7 +411,7 @@ class IntervalValue } /// Current IntervalValue joins with another IntervalValue - void join_with(const IntervalValue &other) + void join_with(const IntervalValue& other) { if (this->isBottom()) { @@ -437,7 +435,7 @@ class IntervalValue } /// Current IntervalValue widen with another IntervalValue - void widen_with(const IntervalValue &other) + void widen_with(const IntervalValue& other) { if (this->isBottom()) { @@ -450,12 +448,13 @@ class IntervalValue } else { - setValue(!lb().leq(other.lb()) ? minus_infinity() : this->lb(), !ub().geq(other.ub()) ? plus_infinity() : this->ub()); + setValue(!lb().leq(other.lb()) ? minus_infinity() : this->lb(), + !ub().geq(other.ub()) ? plus_infinity() : this->ub()); } } /// Current IntervalValue narrow with another IntervalValue - void narrow_with(const IntervalValue &other) + void narrow_with(const IntervalValue& other) { if (this->isBottom() || other.isBottom()) { @@ -472,7 +471,7 @@ class IntervalValue } /// Return a intersected IntervalValue - void meet_with(const IntervalValue &other) + void meet_with(const IntervalValue& other) { if (this->isBottom() || other.isBottom()) { @@ -497,7 +496,7 @@ class IntervalValue return this->_lb.leq(n) && this->_ub.geq(n); } - void dump(std::ostream &o) const + void dump(std::ostream& o) const { if (this->isBottom()) { @@ -523,9 +522,10 @@ class IntervalValue } return rawStr.str(); } + private: /// Set the lower bound - void setValue(const BoundedInt &lb, const BoundedInt &ub) + void setValue(const BoundedInt& lb, const BoundedInt& ub) { assert((isBottom() || _lb.leq(_ub)) && "lower bound should be less than or equal to upper bound"); this->_lb = lb; @@ -536,16 +536,14 @@ class IntervalValue // internal use for create bottom-tolerant IntervalValue static IntervalValue create(const BoundedInt& lb, const BoundedInt& ub) { - if (!lb.leq(ub)) - return IntervalValue::bottom(); + if (!lb.leq(ub)) return IntervalValue::bottom(); else return IntervalValue(lb, ub); } }; // end class IntervalValue /// Add IntervalValues -inline IntervalValue operator+(const IntervalValue &lhs, - const IntervalValue &rhs) +inline IntervalValue operator+(const IntervalValue& lhs, const IntervalValue& rhs) { if (lhs.isBottom() || rhs.isBottom()) { @@ -562,8 +560,7 @@ inline IntervalValue operator+(const IntervalValue &lhs, } /// Subtract IntervalValues -inline IntervalValue operator-(const IntervalValue &lhs, - const IntervalValue &rhs) +inline IntervalValue operator-(const IntervalValue& lhs, const IntervalValue& rhs) { if (lhs.isBottom() || rhs.isBottom()) { @@ -580,8 +577,7 @@ inline IntervalValue operator-(const IntervalValue &lhs, } /// Multiply IntervalValues -inline IntervalValue operator*(const IntervalValue &lhs, - const IntervalValue &rhs) +inline IntervalValue operator*(const IntervalValue& lhs, const IntervalValue& rhs) { if (lhs.isBottom() || rhs.isBottom()) { @@ -594,14 +590,12 @@ inline IntervalValue operator*(const IntervalValue &lhs, BoundedInt ul = lhs.ub() * rhs.lb(); BoundedInt uu = lhs.ub() * rhs.ub(); std::vector vec{ll, lu, ul, uu}; - return IntervalValue(BoundedInt::min(vec), - BoundedInt::max(vec)); + return IntervalValue(BoundedInt::min(vec), BoundedInt::max(vec)); } } /// Divide IntervalValues -inline IntervalValue operator/(const IntervalValue &lhs, - const IntervalValue &rhs) +inline IntervalValue operator/(const IntervalValue& lhs, const IntervalValue& rhs) { if (lhs.isBottom() || rhs.isBottom()) { @@ -635,15 +629,13 @@ inline IntervalValue operator/(const IntervalValue &lhs, BoundedInt uu = lhs.ub() / rhs.ub(); std::vector vec{ll, lu, ul, uu}; - IntervalValue res = IntervalValue(BoundedInt::min(vec), - BoundedInt::max(vec)); + IntervalValue res = IntervalValue(BoundedInt::min(vec), BoundedInt::max(vec)); return res; } } /// Divide IntervalValues -inline IntervalValue operator%(const IntervalValue &lhs, - const IntervalValue &rhs) +inline IntervalValue operator%(const IntervalValue& lhs, const IntervalValue& rhs) { if (lhs.isBottom() || rhs.isBottom()) { @@ -682,7 +674,7 @@ inline IntervalValue operator%(const IntervalValue &lhs, } // Compare two IntervalValues for greater than -inline IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator>(const IntervalValue& lhs, const IntervalValue& rhs) { // If either lhs or rhs is bottom, the result is bottom if (lhs.isBottom() || rhs.isBottom()) @@ -733,7 +725,7 @@ inline IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rh } // Compare two IntervalValues for less than -inline IntervalValue operator<(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator<(const IntervalValue& lhs, const IntervalValue& rhs) { // If either lhs or rhs is bottom, the result is bottom if (lhs.isBottom() || rhs.isBottom()) @@ -783,9 +775,8 @@ inline IntervalValue operator<(const IntervalValue &lhs, const IntervalValue &rh } } - // Compare two IntervalValues for greater than or equal to -inline IntervalValue operator>=(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator>=(const IntervalValue& lhs, const IntervalValue& rhs) { // If either lhs or rhs is bottom, the result is bottom if (lhs.isBottom() || rhs.isBottom()) @@ -835,7 +826,7 @@ inline IntervalValue operator>=(const IntervalValue &lhs, const IntervalValue &r } // Compare two IntervalValues for less than or equal to -inline IntervalValue operator<=(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator<=(const IntervalValue& lhs, const IntervalValue& rhs) { // If either lhs or rhs is bottom, the result is bottom if (lhs.isBottom() || rhs.isBottom()) @@ -885,28 +876,25 @@ inline IntervalValue operator<=(const IntervalValue &lhs, const IntervalValue &r } /// Left binary shift of IntervalValues -inline IntervalValue operator<<(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator<<(const IntervalValue& lhs, const IntervalValue& rhs) { - //TODO: implement << - if (lhs.isBottom() || rhs.isBottom()) - return IntervalValue::bottom(); - if (lhs.isTop() && rhs.isTop()) - return IntervalValue::top(); + // TODO: implement << + if (lhs.isBottom() || rhs.isBottom()) return IntervalValue::bottom(); + if (lhs.isTop() && rhs.isTop()) return IntervalValue::top(); else { IntervalValue shift = rhs; shift.meet_with(IntervalValue(0, IntervalValue::plus_infinity())); - if (shift.isBottom()) - return IntervalValue::bottom(); + if (shift.isBottom()) return IntervalValue::bottom(); BoundedInt lb = 0; // If the shift is greater than 32, the result is always 0 - if ((s32_t) shift.lb().getNumeral() >= 32 || shift.lb().is_infinity()) + if ((s32_t)shift.lb().getNumeral() >= 32 || shift.lb().is_infinity()) { lb = IntervalValue::minus_infinity(); } else { - lb = (1 << (s32_t) shift.lb().getNumeral()); + lb = (1 << (s32_t)shift.lb().getNumeral()); } BoundedInt ub = 0; if (shift.ub().is_infinity()) @@ -915,7 +903,7 @@ inline IntervalValue operator<<(const IntervalValue &lhs, const IntervalValue &r } else { - ub = (1 << (s32_t) shift.ub().getNumeral()); + ub = (1 << (s32_t)shift.ub().getNumeral()); } IntervalValue coeff(lb, ub); return lhs * coeff; @@ -923,19 +911,17 @@ inline IntervalValue operator<<(const IntervalValue &lhs, const IntervalValue &r } /// Left binary shift of IntervalValues -inline IntervalValue operator>>(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator>>(const IntervalValue& lhs, const IntervalValue& rhs) { - //TODO: implement >> - if (lhs.isBottom() || rhs.isBottom()) - return IntervalValue::bottom(); + // TODO: implement >> + if (lhs.isBottom() || rhs.isBottom()) return IntervalValue::bottom(); else if (lhs.isTop() && rhs.isTop()) return IntervalValue::top(); else { IntervalValue shift = rhs; shift.meet_with(IntervalValue(0, IntervalValue::plus_infinity())); - if (shift.isBottom()) - return IntervalValue::bottom(); + if (shift.isBottom()) return IntervalValue::bottom(); if (lhs.contains(0)) { IntervalValue l = IntervalValue::create(lhs.lb(), -1); @@ -952,32 +938,30 @@ inline IntervalValue operator>>(const IntervalValue &lhs, const IntervalValue &r BoundedInt ul = lhs.ub() >> shift.lb(); BoundedInt uu = lhs.ub() >> shift.ub(); std::vector vec{ll, lu, ul, uu}; - return IntervalValue(BoundedInt::min(vec), - BoundedInt::max(vec)); + return IntervalValue(BoundedInt::min(vec), BoundedInt::max(vec)); } } } /// Bitwise AND of IntervalValues -inline IntervalValue operator&(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator&(const IntervalValue& lhs, const IntervalValue& rhs) { - if (lhs.isBottom() || rhs.isBottom()) - return IntervalValue::bottom(); + if (lhs.isBottom() || rhs.isBottom()) return IntervalValue::bottom(); else if (lhs.is_numeral() && rhs.is_numeral()) { return IntervalValue(lhs.lb() & rhs.lb()); } else if (lhs.lb().getNumeral() >= 0 && rhs.lb().getNumeral() >= 0) { - return IntervalValue((s64_t) 0, min(lhs.ub(), rhs.ub())); + return IntervalValue((s64_t)0, min(lhs.ub(), rhs.ub())); } else if (lhs.lb().getNumeral() >= 0) { - return IntervalValue((s64_t) 0, lhs.ub()); + return IntervalValue((s64_t)0, lhs.ub()); } else if (rhs.lb().getNumeral() >= 0) { - return IntervalValue((s64_t) 0, rhs.ub()); + return IntervalValue((s64_t)0, rhs.ub()); } else { @@ -986,10 +970,9 @@ inline IntervalValue operator&(const IntervalValue &lhs, const IntervalValue &rh } /// Bitwise OR of IntervalValues -inline IntervalValue operator|(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator|(const IntervalValue& lhs, const IntervalValue& rhs) { - auto next_power_of_2 = [](s64_t num) - { + auto next_power_of_2 = [](s64_t num) { int i = 1; while ((num >> i) != 0) { @@ -997,16 +980,15 @@ inline IntervalValue operator|(const IntervalValue &lhs, const IntervalValue &rh } return 1 << i; }; - if (lhs.isBottom() || rhs.isBottom()) - return IntervalValue::bottom(); + if (lhs.isBottom() || rhs.isBottom()) return IntervalValue::bottom(); else if (lhs.is_numeral() && rhs.is_numeral()) return IntervalValue(lhs.lb() | rhs.lb()); - else if (lhs.lb().getNumeral() >= 0 && !lhs.ub().is_infinity() && - rhs.lb().getNumeral() >= 0 && !rhs.ub().is_infinity()) + else if (lhs.lb().getNumeral() >= 0 && !lhs.ub().is_infinity() && rhs.lb().getNumeral() >= 0 && + !rhs.ub().is_infinity()) { s64_t m = std::max(lhs.ub().getNumeral(), rhs.ub().getNumeral()); s64_t ub = next_power_of_2(s64_t(m)) - 1; - return IntervalValue((s64_t) 0, (s64_t) ub); + return IntervalValue((s64_t)0, (s64_t)ub); } else { @@ -1015,10 +997,9 @@ inline IntervalValue operator|(const IntervalValue &lhs, const IntervalValue &rh } /// Bitwise XOR of IntervalValues -inline IntervalValue operator^(const IntervalValue &lhs, const IntervalValue &rhs) +inline IntervalValue operator^(const IntervalValue& lhs, const IntervalValue& rhs) { - auto next_power_of_2 = [](s64_t num) - { + auto next_power_of_2 = [](s64_t num) { int i = 1; while ((num >> i) != 0) { @@ -1026,16 +1007,15 @@ inline IntervalValue operator^(const IntervalValue &lhs, const IntervalValue &rh } return 1 << i; }; - if (lhs.isBottom() || rhs.isBottom()) - return IntervalValue::bottom(); + if (lhs.isBottom() || rhs.isBottom()) return IntervalValue::bottom(); else if (lhs.is_numeral() && rhs.is_numeral()) return IntervalValue(lhs.lb() ^ rhs.lb()); - else if (lhs.lb().getNumeral() >= 0 && !lhs.ub().is_infinity() && - rhs.lb().getNumeral() >= 0 && !rhs.ub().is_infinity()) + else if (lhs.lb().getNumeral() >= 0 && !lhs.ub().is_infinity() && rhs.lb().getNumeral() >= 0 && + !rhs.ub().is_infinity()) { s64_t m = std::max(lhs.ub().getNumeral(), rhs.ub().getNumeral()); s64_t ub = next_power_of_2(s64_t(m)) - 1; - return IntervalValue((s64_t) 0, (s64_t) ub); + return IntervalValue((s64_t)0, (s64_t)ub); } else { @@ -1044,12 +1024,11 @@ inline IntervalValue operator^(const IntervalValue &lhs, const IntervalValue &rh } /// Write an IntervalValue on a stream -inline std::ostream &operator<<(std::ostream &o, - const IntervalValue &IntervalValue) +inline std::ostream& operator<<(std::ostream& o, const IntervalValue& IntervalValue) { IntervalValue.dump(o); return o; } } // end namespace SVF -#endif //Z3_EXAMPLE_IntervalValue_H +#endif // Z3_EXAMPLE_IntervalValue_H diff --git a/svf/include/AE/Core/NumericValue.h b/svf/include/AE/Core/NumericValue.h index 181cbca20..3d55a8d6c 100644 --- a/svf/include/AE/Core/NumericValue.h +++ b/svf/include/AE/Core/NumericValue.h @@ -175,8 +175,7 @@ class BoundedInt // If both BoundedInts are infinite. if (is_infinity() && rhs.is_infinity()) { - if (is_minus_infinity()) - return true; + if (is_minus_infinity()) return true; else return rhs.is_plus_infinity(); } @@ -203,8 +202,7 @@ class BoundedInt // If both BoundedInts are infinite. if (is_infinity() && rhs.is_infinity()) { - if (is_plus_infinity()) - return true; + if (is_plus_infinity()) return true; else return rhs.is_minus_infinity(); } @@ -281,8 +279,7 @@ class BoundedInt { // If one number is positive infinity and the other is negative // infinity, this is an invalid operation, so we assert false. - if ((lhs.is_plus_infinity() && rhs.is_minus_infinity()) || - (lhs.is_minus_infinity() && rhs.is_plus_infinity())) + if ((lhs.is_plus_infinity() && rhs.is_minus_infinity()) || (lhs.is_minus_infinity() && rhs.is_plus_infinity())) { assert(false && "invalid add"); } @@ -303,16 +300,14 @@ class BoundedInt // If both numbers are positive and their sum would exceed the maximum // representable number, the result is positive infinity. - if (lhs._iVal > 0 && rhs._iVal > 0 && - (std::numeric_limits::max() - lhs._iVal) < rhs._iVal) + if (lhs._iVal > 0 && rhs._iVal > 0 && (std::numeric_limits::max() - lhs._iVal) < rhs._iVal) { return plus_infinity(); } // If both numbers are negative and their sum would be less than the // most negative representable number, the result is negative infinity. - if (lhs._iVal < 0 && rhs._iVal < 0 && - (-std::numeric_limits::max() - lhs._iVal) > rhs._iVal) + if (lhs._iVal < 0 && rhs._iVal < 0 && (-std::numeric_limits::max() - lhs._iVal) > rhs._iVal) { return minus_infinity(); } @@ -364,8 +359,7 @@ class BoundedInt static BoundedInt safeMul(const BoundedInt& lhs, const BoundedInt& rhs) { // If either number is zero, the result is zero. - if (lhs._iVal == 0 || rhs._iVal == 0) - return 0; + if (lhs._iVal == 0 || rhs._iVal == 0) return 0; // If either number is infinity, the result depends on the signs of the // numbers. @@ -386,16 +380,14 @@ class BoundedInt // If both numbers are positive and their product would exceed the // maximum representable number, the result is positive infinity. - if (lhs._iVal > 0 && rhs._iVal > 0 && - (std::numeric_limits::max() / lhs._iVal) < rhs._iVal) + if (lhs._iVal > 0 && rhs._iVal > 0 && (std::numeric_limits::max() / lhs._iVal) < rhs._iVal) { return plus_infinity(); } // If both numbers are negative and their product would exceed the // maximum representable number, the result is positive infinity. - if (lhs._iVal < 0 && rhs._iVal < 0 && - (std::numeric_limits::max() / lhs._iVal) > rhs._iVal) + if (lhs._iVal < 0 && rhs._iVal < 0 && (std::numeric_limits::max() / lhs._iVal) > rhs._iVal) { return plus_infinity(); } @@ -403,10 +395,8 @@ class BoundedInt // If one number is positive and the other is negative and their product // would be less than the most negative representable number, the result // is negative infinity. - if ((lhs._iVal > 0 && rhs._iVal < 0 && - (-std::numeric_limits::max() / lhs._iVal) > rhs._iVal) || - (lhs._iVal < 0 && rhs._iVal > 0 && - (-std::numeric_limits::max() / rhs._iVal) > lhs._iVal)) + if ((lhs._iVal > 0 && rhs._iVal < 0 && (-std::numeric_limits::max() / lhs._iVal) > rhs._iVal) || + (lhs._iVal < 0 && rhs._iVal > 0 && (-std::numeric_limits::max() / rhs._iVal) > lhs._iVal)) { return minus_infinity(); } @@ -416,11 +406,9 @@ class BoundedInt return lhs._iVal * rhs._iVal; } - friend BoundedInt operator%(const BoundedInt& lhs, const BoundedInt& rhs) { - if (rhs.is_zero()) - assert(false && "divide by zero"); + if (rhs.is_zero()) assert(false && "divide by zero"); else if (!lhs.is_infinity() && !rhs.is_infinity()) return lhs._iVal % rhs._iVal; else if (!lhs.is_infinity() && rhs.is_infinity()) @@ -445,8 +433,7 @@ class BoundedInt // and overflow. friend BoundedInt operator/(const BoundedInt& lhs, const BoundedInt& rhs) { - if (rhs.is_zero()) - assert(false && "divide by zero"); + if (rhs.is_zero()) assert(false && "divide by zero"); else if (!lhs.is_infinity() && !rhs.is_infinity()) return lhs._iVal / rhs._iVal; else if (!lhs.is_infinity() && rhs.is_infinity()) @@ -509,8 +496,7 @@ class BoundedInt friend BoundedInt operator>>(const BoundedInt& lhs, const BoundedInt& rhs) { assert(rhs.geq(0) && "rhs should be greater or equal than 0"); - if (lhs.is_zero()) - return lhs; + if (lhs.is_zero()) return lhs; else if (lhs.is_infinity()) return lhs; else if (rhs.is_infinity()) @@ -527,8 +513,7 @@ class BoundedInt friend BoundedInt operator<<(const BoundedInt& lhs, const BoundedInt& rhs) { assert(rhs.geq(0) && "rhs should be greater or equal than 0"); - if (lhs.is_zero()) - return lhs; + if (lhs.is_zero()) return lhs; else if (lhs.is_infinity()) return lhs; else if (rhs.is_infinity()) @@ -540,8 +525,7 @@ class BoundedInt // Overloads the ternary if-then-else operator for BoundedInt objects. // The condition is evaluated as a boolean, and the result is either the // second or third argument depending on the condition. - friend BoundedInt ite(const BoundedInt& cond, const BoundedInt& lhs, - const BoundedInt& rhs) + friend BoundedInt ite(const BoundedInt& cond, const BoundedInt& lhs, const BoundedInt& rhs) { return cond._iVal != 0 ? lhs : rhs; } @@ -568,33 +552,29 @@ class BoundedInt // and also checks if either of them represents infinity. friend BoundedInt min(const BoundedInt& lhs, const BoundedInt& rhs) { - if (lhs.is_minus_infinity() || rhs.is_minus_infinity()) - return minus_infinity(); - else if(lhs.is_plus_infinity()) + if (lhs.is_minus_infinity() || rhs.is_minus_infinity()) return minus_infinity(); + else if (lhs.is_plus_infinity()) return rhs; - else if(rhs.is_plus_infinity()) + else if (rhs.is_plus_infinity()) return lhs; else return BoundedInt(std::min(lhs._iVal, rhs._iVal)); } - // Defines a function to find the maximum of two BoundedInt objects. // This function directly compares the internal integer values of the BoundedInt objects, // and also checks if either of them represents infinity. friend BoundedInt max(const BoundedInt& lhs, const BoundedInt& rhs) { - if (lhs.is_plus_infinity() || rhs.is_plus_infinity()) - return plus_infinity(); - else if(lhs.is_minus_infinity()) + if (lhs.is_plus_infinity() || rhs.is_plus_infinity()) return plus_infinity(); + else if (lhs.is_minus_infinity()) return rhs; - else if(rhs.is_minus_infinity()) + else if (rhs.is_minus_infinity()) return lhs; else return BoundedInt(std::max(lhs._iVal, rhs._iVal)); } - // Defines a function to find the minimum of a vector of BoundedInt objects. // This function iterates over the vector and returns the smallest // BoundedInt object. @@ -603,8 +583,7 @@ class BoundedInt BoundedInt ret(plus_infinity()); for (const auto& it : _l) { - if (it.is_minus_infinity()) - return minus_infinity(); + if (it.is_minus_infinity()) return minus_infinity(); else if (!it.geq(ret)) { ret = it; @@ -621,8 +600,7 @@ class BoundedInt BoundedInt ret(minus_infinity()); for (const auto& it : _l) { - if (it.is_plus_infinity()) - return plus_infinity(); + if (it.is_plus_infinity()) return plus_infinity(); else if (!it.leq(ret)) { ret = it; @@ -750,8 +728,7 @@ class BoundedDouble static bool doubleEqual(double a, double b) { - if (std::isinf(a) && std::isinf(b)) - return a == b; + if (std::isinf(a) && std::isinf(b)) return a == b; return std::fabs(a - b) < epsilon; } @@ -825,8 +802,7 @@ class BoundedDouble } if (is_infinity() && rhs.is_infinity()) { - if (is_minus_infinity()) - return true; + if (is_minus_infinity()) return true; else return rhs.is_plus_infinity(); } @@ -849,8 +825,7 @@ class BoundedDouble } if (is_infinity() && rhs.is_infinity()) { - if (is_plus_infinity()) - return true; + if (is_plus_infinity()) return true; else return rhs.is_minus_infinity(); } @@ -860,38 +835,32 @@ class BoundedDouble /// Reload operator //{% - friend BoundedDouble operator==(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator==(const BoundedDouble& lhs, const BoundedDouble& rhs) { return lhs.equal(rhs); } - friend BoundedDouble operator!=(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator!=(const BoundedDouble& lhs, const BoundedDouble& rhs) { return !lhs.equal(rhs); } - friend BoundedDouble operator>(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator>(const BoundedDouble& lhs, const BoundedDouble& rhs) { return !lhs.leq(rhs); } - friend BoundedDouble operator<(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator<(const BoundedDouble& lhs, const BoundedDouble& rhs) { return !lhs.geq(rhs); } - friend BoundedDouble operator<=(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator<=(const BoundedDouble& lhs, const BoundedDouble& rhs) { return lhs.leq(rhs); } - friend BoundedDouble operator>=(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator>=(const BoundedDouble& lhs, const BoundedDouble& rhs) { return lhs.geq(rhs); } @@ -907,15 +876,12 @@ class BoundedDouble */ static double safeAdd(double lhs, double rhs) { - if ((lhs == std::numeric_limits::infinity() && - rhs == -std::numeric_limits::infinity()) || - (lhs == -std::numeric_limits::infinity() && - rhs == std::numeric_limits::infinity())) + if ((lhs == std::numeric_limits::infinity() && rhs == -std::numeric_limits::infinity()) || + (lhs == -std::numeric_limits::infinity() && rhs == std::numeric_limits::infinity())) { assert(false && "invalid add"); } - double res = - lhs + rhs; // Perform the addition and store the result in 'res' + double res = lhs + rhs; // Perform the addition and store the result in 'res' // Check if the result is positive infinity due to overflow if (res == std::numeric_limits::infinity()) @@ -934,8 +900,7 @@ class BoundedDouble // Check for positive overflow: verify if both operands are positive and // their sum exceeds the maximum double value - if (lhs > 0 && rhs > 0 && - (std::numeric_limits::max() - lhs) < rhs) + if (lhs > 0 && rhs > 0 && (std::numeric_limits::max() - lhs) < rhs) { res = std::numeric_limits::infinity(); // Set result to // positive infinity to @@ -945,11 +910,9 @@ class BoundedDouble // Check for an underflow scenario: both numbers are negative and their // sum is more negative than what double can represent - if (lhs < 0 && rhs < 0 && - (-std::numeric_limits::max() - lhs) > rhs) + if (lhs < 0 && rhs < 0 && (-std::numeric_limits::max() - lhs) > rhs) { - res = -std::numeric_limits< - double>::infinity(); // Set result to negative infinity to + res = -std::numeric_limits::infinity(); // Set result to negative infinity to // clarify extreme negative sum return res; } @@ -959,8 +922,7 @@ class BoundedDouble return res; } - friend BoundedDouble operator+(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator+(const BoundedDouble& lhs, const BoundedDouble& rhs) { return safeAdd(lhs._fVal, rhs._fVal); } @@ -970,8 +932,7 @@ class BoundedDouble return -lhs._fVal; } - friend BoundedDouble operator-(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator-(const BoundedDouble& lhs, const BoundedDouble& rhs) { return safeAdd(lhs._fVal, -rhs._fVal); } @@ -987,8 +948,7 @@ class BoundedDouble */ static double safeMul(double lhs, double rhs) { - if (doubleEqual(lhs, 0.0f) || doubleEqual(rhs, 0.0f)) - return 0.0f; + if (doubleEqual(lhs, 0.0f) || doubleEqual(rhs, 0.0f)) return 0.0f; double res = lhs * rhs; // Check if the result is positive infinity due to overflow if (res == std::numeric_limits::infinity()) @@ -1005,25 +965,21 @@ class BoundedDouble // negative infinity } // Check for overflow scenarios - if (lhs > 0 && rhs > 0 && - lhs > std::numeric_limits::max() / rhs) + if (lhs > 0 && rhs > 0 && lhs > std::numeric_limits::max() / rhs) { return std::numeric_limits::infinity(); } - if (lhs < 0 && rhs < 0 && - lhs < std::numeric_limits::max() / rhs) + if (lhs < 0 && rhs < 0 && lhs < std::numeric_limits::max() / rhs) { return std::numeric_limits::infinity(); } // Check for "underflow" scenarios (negative overflow) - if (lhs > 0 && rhs < 0 && - rhs < std::numeric_limits::lowest() / lhs) + if (lhs > 0 && rhs < 0 && rhs < std::numeric_limits::lowest() / lhs) { return -std::numeric_limits::infinity(); } - if (lhs < 0 && rhs > 0 && - lhs < std::numeric_limits::lowest() / rhs) + if (lhs < 0 && rhs > 0 && lhs < std::numeric_limits::lowest() / rhs) { return -std::numeric_limits::infinity(); } @@ -1031,8 +987,7 @@ class BoundedDouble return res; // If no overflow or underflow, return the product } - friend BoundedDouble operator*(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator*(const BoundedDouble& lhs, const BoundedDouble& rhs) { return safeMul(lhs._fVal, rhs._fVal); } @@ -1051,8 +1006,7 @@ class BoundedDouble // Check for division by zero if (doubleEqual(rhs, 0.0f)) { - return (lhs >= 0.0f) ? std::numeric_limits::infinity() - : -std::numeric_limits::infinity(); + return (lhs >= 0.0f) ? std::numeric_limits::infinity() : -std::numeric_limits::infinity(); } double res = lhs / rhs; // Check if the result is positive infinity due to overflow @@ -1071,13 +1025,11 @@ class BoundedDouble } // Check for overflow when dividing small numbers - if (rhs > 0 && rhs < std::numeric_limits::min() && - lhs > std::numeric_limits::max() * rhs) + if (rhs > 0 && rhs < std::numeric_limits::min() && lhs > std::numeric_limits::max() * rhs) { return std::numeric_limits::infinity(); } - if (rhs < 0 && rhs > -std::numeric_limits::min() && - lhs > std::numeric_limits::max() * rhs) + if (rhs < 0 && rhs > -std::numeric_limits::min() && lhs > std::numeric_limits::max() * rhs) { return -std::numeric_limits::infinity(); } @@ -1085,17 +1037,14 @@ class BoundedDouble return res; // If no special cases, return the quotient } - friend BoundedDouble operator/(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator/(const BoundedDouble& lhs, const BoundedDouble& rhs) { return safeDiv(lhs._fVal, rhs._fVal); } - friend BoundedDouble operator%(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator%(const BoundedDouble& lhs, const BoundedDouble& rhs) { - if (rhs.is_zero()) - assert(false && "divide by zero"); + if (rhs.is_zero()) assert(false && "divide by zero"); else if (!lhs.is_infinity() && !rhs.is_infinity()) return std::fmod(lhs._fVal, rhs._fVal); else if (!lhs.is_infinity() && rhs.is_infinity()) @@ -1118,35 +1067,30 @@ class BoundedDouble return !is_int(); } - friend BoundedDouble operator^(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator^(const BoundedDouble& lhs, const BoundedDouble& rhs) { int lInt = std::round(lhs._fVal), rInt = std::round(rhs._fVal); return lInt ^ rInt; } - friend BoundedDouble operator&(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator&(const BoundedDouble& lhs, const BoundedDouble& rhs) { int lInt = std::round(lhs._fVal), rInt = std::round(rhs._fVal); return lInt & rInt; } - friend BoundedDouble operator|(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator|(const BoundedDouble& lhs, const BoundedDouble& rhs) { int lInt = std::round(lhs._fVal), rInt = std::round(rhs._fVal); return lInt | rInt; } - friend BoundedDouble operator&&(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator&&(const BoundedDouble& lhs, const BoundedDouble& rhs) { return lhs._fVal && rhs._fVal; } - friend BoundedDouble operator||(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator||(const BoundedDouble& lhs, const BoundedDouble& rhs) { return lhs._fVal || rhs._fVal; } @@ -1156,12 +1100,10 @@ class BoundedDouble return !lhs._fVal; } - friend BoundedDouble operator>>(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator>>(const BoundedDouble& lhs, const BoundedDouble& rhs) { assert(rhs.geq(0) && "rhs should be greater or equal than 0"); - if (lhs.is_zero()) - return lhs; + if (lhs.is_zero()) return lhs; else if (lhs.is_infinity()) return lhs; else if (rhs.is_infinity()) @@ -1170,12 +1112,10 @@ class BoundedDouble return (s32_t)lhs.getNumeral() >> (s32_t)rhs.getNumeral(); } - friend BoundedDouble operator<<(const BoundedDouble& lhs, - const BoundedDouble& rhs) + friend BoundedDouble operator<<(const BoundedDouble& lhs, const BoundedDouble& rhs) { assert(rhs.geq(0) && "rhs should be greater or equal than 0"); - if (lhs.is_zero()) - return lhs; + if (lhs.is_zero()) return lhs; else if (lhs.is_infinity()) return lhs; else if (rhs.is_infinity()) @@ -1184,14 +1124,12 @@ class BoundedDouble return (s32_t)lhs.getNumeral() << (s32_t)rhs.getNumeral(); } - friend BoundedDouble ite(const BoundedDouble& cond, - const BoundedDouble& lhs, const BoundedDouble& rhs) + friend BoundedDouble ite(const BoundedDouble& cond, const BoundedDouble& lhs, const BoundedDouble& rhs) { return cond._fVal != 0.0f ? lhs._fVal : rhs._fVal; } - friend std::ostream& operator<<(std::ostream& out, - const BoundedDouble& expr) + friend std::ostream& operator<<(std::ostream& out, const BoundedDouble& expr) { out << expr._fVal; return out; @@ -1217,8 +1155,7 @@ class BoundedDouble BoundedDouble ret(plus_infinity()); for (const auto& it : _l) { - if (it.is_minus_infinity()) - return minus_infinity(); + if (it.is_minus_infinity()) return minus_infinity(); else if (!it.geq(ret)) { ret = it; @@ -1232,8 +1169,7 @@ class BoundedDouble BoundedDouble ret(minus_infinity()); for (const auto& it : _l) { - if (it.is_plus_infinity()) - return plus_infinity(); + if (it.is_plus_infinity()) return plus_infinity(); else if (!it.leq(ret)) { ret = it; diff --git a/svf/include/AE/Core/RelExeState.h b/svf/include/AE/Core/RelExeState.h index e43c1f035..b8e4ac86a 100644 --- a/svf/include/AE/Core/RelExeState.h +++ b/svf/include/AE/Core/RelExeState.h @@ -51,24 +51,19 @@ class RelExeState public: RelExeState() = default; - RelExeState(VarToValMap &varToVal, AddrToValMap&locToVal) : _varToVal(varToVal), _addrToVal(locToVal) {} + RelExeState(VarToValMap& varToVal, AddrToValMap& locToVal) : _varToVal(varToVal), _addrToVal(locToVal) {} - RelExeState(const RelExeState &rhs) : _varToVal(rhs.getVarToVal()), _addrToVal(rhs.getLocToVal()) - { - - } + RelExeState(const RelExeState& rhs) : _varToVal(rhs.getVarToVal()), _addrToVal(rhs.getLocToVal()) {} virtual ~RelExeState() = default; - RelExeState &operator=(const RelExeState &rhs); + RelExeState& operator=(const RelExeState& rhs); - RelExeState(RelExeState &&rhs) noexcept: _varToVal(std::move(rhs._varToVal)), - _addrToVal(std::move(rhs._addrToVal)) + RelExeState(RelExeState&& rhs) noexcept : _varToVal(std::move(rhs._varToVal)), _addrToVal(std::move(rhs._addrToVal)) { - } - RelExeState &operator=(RelExeState &&rhs) noexcept + RelExeState& operator=(RelExeState&& rhs) noexcept { if (&rhs != this) { @@ -79,34 +74,33 @@ class RelExeState } /// Overloading Operator== - bool operator==(const RelExeState &rhs) const; + bool operator==(const RelExeState& rhs) const; /// Overloading Operator!= - inline bool operator!=(const RelExeState &rhs) const + inline bool operator!=(const RelExeState& rhs) const { return !(*this == rhs); } /// Overloading Operator== - bool operator<(const RelExeState &rhs) const; - + bool operator<(const RelExeState& rhs) const; - static z3::context &getContext() + static z3::context& getContext() { return Z3Expr::getContext(); } - const VarToValMap &getVarToVal() const + const VarToValMap& getVarToVal() const { return _varToVal; } - const AddrToValMap&getLocToVal() const + const AddrToValMap& getLocToVal() const { return _addrToVal; } - inline Z3Expr &operator[](u32_t varId) + inline Z3Expr& operator[](u32_t varId) { return getZ3Expr(varId); } @@ -115,7 +109,7 @@ class RelExeState { size_t h = getVarToVal().size() * 2; SVF::Hash hf; - for (const auto &t: getVarToVal()) + for (const auto& t : getVarToVal()) { h ^= hf(t.first) + 0x9e3779b9 + (h << 6) + (h >> 2); h ^= hf(t.second.id()) + 0x9e3779b9 + (h << 6) + (h >> 2); @@ -123,7 +117,7 @@ class RelExeState size_t h2 = getVarToVal().size() * 2; - for (const auto &t: getLocToVal()) + for (const auto& t : getLocToVal()) { h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); h2 ^= hf(t.second.id()) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); @@ -140,7 +134,7 @@ class RelExeState } /// Return Z3 expression eagerly based on SVFVar ID - virtual inline Z3Expr &getZ3Expr(u32_t varId) + virtual inline Z3Expr& getZ3Expr(u32_t varId) { return _varToVal[varId]; } @@ -152,19 +146,19 @@ class RelExeState } /// Extract sub SVFVar IDs of a Z3Expr - void extractSubVars(const Z3Expr &expr, Set &res); + void extractSubVars(const Z3Expr& expr, Set& res); /// Extract all related SVFVar IDs based on compare expr - void extractCmpVars(const Z3Expr &expr, Set &res); + void extractCmpVars(const Z3Expr& expr, Set& res); /// Build relational Z3Expr - Z3Expr buildRelZ3Expr(u32_t cmp, s32_t succ, Set &vars, Set &initVars); + Z3Expr buildRelZ3Expr(u32_t cmp, s32_t succ, Set& vars, Set& initVars); /// Store value to location - void store(const Z3Expr &loc, const Z3Expr &value); + void store(const Z3Expr& loc, const Z3Expr& value); /// Load value at location - Z3Expr &load(const Z3Expr &loc); + Z3Expr& load(const Z3Expr& loc); /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) @@ -175,8 +169,7 @@ class RelExeState /// Check bit value of val start with 0x7F000000, filter by 0xFF000000 static inline bool isVirtualMemAddress(u32_t val) { - if (val == 0) - assert(false && "val cannot be 0"); + if (val == 0) assert(false && "val cannot be 0"); return AddressValue::isVirtualMemAddress(val); } @@ -187,7 +180,7 @@ class RelExeState } /// Return int value from an expression if it is a numeral, otherwise return an approximate value - static inline s32_t z3Expr2NumValue(const Z3Expr &e) + static inline s32_t z3Expr2NumValue(const Z3Expr& e) { assert(e.is_numeral() && "not numeral?"); return e.get_numeral_int64(); @@ -197,30 +190,29 @@ class RelExeState void printExprValues(); private: - bool eqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const; + bool eqVarToValMap(const VarToValMap& lhs, const VarToValMap& rhs) const; - bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const; + bool lessThanVarToValMap(const VarToValMap& lhs, const VarToValMap& rhs) const; protected: - inline void store(u32_t objId, const Z3Expr &z3Expr) + inline void store(u32_t objId, const Z3Expr& z3Expr) { _addrToVal[objId] = z3Expr.simplify(); } - inline Z3Expr &load(u32_t objId) + inline Z3Expr& load(u32_t objId) { return _addrToVal[objId]; } }; // end class RelExeState } // end namespace SVF -template<> -struct std::hash +template <> struct std::hash { - size_t operator()(const SVF::RelExeState &exeState) const + size_t operator()(const SVF::RelExeState& exeState) const { return exeState.hash(); } }; -#endif //Z3_EXAMPLE_RELEXESTATE_H +#endif // Z3_EXAMPLE_RELEXESTATE_H diff --git a/svf/include/AE/Core/RelationSolver.h b/svf/include/AE/Core/RelationSolver.h index ac9131eb5..e64018833 100644 --- a/svf/include/AE/Core/RelationSolver.h +++ b/svf/include/AE/Core/RelationSolver.h @@ -44,18 +44,18 @@ class RelationSolver IntervalESBase (the last element of inputs) for RSY or bilateral solver */ /// Return Z3Expr according to valToValMap - Z3Expr gamma_hat(const AbstractState&exeState) const; + Z3Expr gamma_hat(const AbstractState& exeState) const; /// Return Z3Expr according to another valToValMap - Z3Expr gamma_hat(const AbstractState&alpha, const AbstractState&exeState) const; + Z3Expr gamma_hat(const AbstractState& alpha, const AbstractState& exeState) const; /// Return Z3Expr from a NodeID - Z3Expr gamma_hat(u32_t id, const AbstractState&exeState) const; + Z3Expr gamma_hat(u32_t id, const AbstractState& exeState) const; - AbstractState abstract_consequence(const AbstractState&lower, const AbstractState&upper, const AbstractState&domain) const; - - AbstractState beta(const Map &sigma, const AbstractState&exeState) const; + AbstractState abstract_consequence(const AbstractState& lower, const AbstractState& upper, + const AbstractState& domain) const; + AbstractState beta(const Map& sigma, const AbstractState& exeState) const; /// Return Z3 expression lazily based on SVFVar ID virtual inline Z3Expr toIntZ3Expr(u32_t varId) const @@ -74,18 +74,20 @@ class RelationSolver /* two optional solvers: RSY and bilateral */ - AbstractState bilateral(const AbstractState& domain, const Z3Expr &phi, u32_t descend_check = 0); + AbstractState bilateral(const AbstractState& domain, const Z3Expr& phi, u32_t descend_check = 0); - AbstractState RSY(const AbstractState& domain, const Z3Expr &phi); + AbstractState RSY(const AbstractState& domain, const Z3Expr& phi); - Map BoxedOptSolver(const Z3Expr& phi, Map& ret, Map& low_values, Map& high_values); + Map BoxedOptSolver(const Z3Expr& phi, Map& ret, Map& low_values, + Map& high_values); - AbstractState BS(const AbstractState& domain, const Z3Expr &phi); + AbstractState BS(const AbstractState& domain, const Z3Expr& phi); void updateMap(Map& map, u32_t key, const s32_t& value); - void decide_cpa_ext(const Z3Expr &phi, Map&, Map&, Map&, Map&, Map&); + void decide_cpa_ext(const Z3Expr& phi, Map&, Map&, Map&, + Map&, Map&); }; -} +} // namespace SVF -#endif //Z3_EXAMPLE_RELATIONSOLVER_H +#endif // Z3_EXAMPLE_RELATIONSOLVER_H diff --git a/svf/include/AE/Svfexe/AbstractInterpretation.h b/svf/include/AE/Svfexe/AbstractInterpretation.h index 8b4d90ae8..cf1adc0a0 100644 --- a/svf/include/AE/Svfexe/AbstractInterpretation.h +++ b/svf/include/AE/Svfexe/AbstractInterpretation.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - // // Created by Jiawei Wang on 2024/1/10. // The implementation is based on @@ -39,7 +38,7 @@ class AbstractInterpretation; class AEStat; class AEAPI; -template class FILOWorkList; +template class FILOWorkList; enum class AEKind { @@ -56,9 +55,7 @@ class AEStat : public SVFStat { startTime = getClk(true); } - ~AEStat() - { - } + ~AEStat() {} inline std::string getMemUsage() { u32_t vmrss, vmsize; @@ -76,7 +73,6 @@ class AEStat : public SVFStat std::string memUsage; std::string bugStr; - u32_t& getFunctionTrace() { if (generalNumMap.count("Function_Trace") == 0) @@ -110,7 +106,14 @@ class AbstractInterpretation friend class AEAPI; public: - enum ExtAPIType { UNCLASSIFIED, MEMCPY, MEMSET, STRCPY, STRCAT }; + enum ExtAPIType + { + UNCLASSIFIED, + MEMCPY, + MEMSET, + STRCPY, + STRCAT + }; typedef SCCDetection CallGraphSCC; /// Constructor AbstractInterpretation(); @@ -146,7 +149,7 @@ class AbstractInterpretation * @param icfgNode The icfg node to analyse * @return if this node has preceding execution state */ - bool mergeStatesFromPredecessors(const ICFGNode * icfgNode); + bool mergeStatesFromPredecessors(const ICFGNode* icfgNode); /** * Check if execution state exist at the branch edge @@ -161,7 +164,7 @@ class AbstractInterpretation * * @param block basic block that has one instruction or a series of instructions */ - virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto); + virtual void handleSingletonWTO(const ICFGSingletonWTO* icfgSingletonWto); /** * handle call node in ICFGNode @@ -181,7 +184,6 @@ class AbstractInterpretation void handleWTOComponent(const ICFGWTOComp* wtoComp); - /** * handle SVF Statement like CmpStmt, CallStmt, GepStmt, LoadStmt, StoreStmt, etc. * @@ -196,158 +198,157 @@ class AbstractInterpretation */ virtual void SkipRecursiveCall(const CallICFGNode* callnode); - /** - * Check if this cmpStmt and succ are satisfiable to the execution state. - * - * @param cmpStmt CmpStmt is a conditional branch statement - * @param succ the value of cmpStmt (True or False) - * @return if this ICFGNode has preceding execution state - */ - bool isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t succ, - AbstractState& as); + * Check if this cmpStmt and succ are satisfiable to the execution state. + * + * @param cmpStmt CmpStmt is a conditional branch statement + * @param succ the value of cmpStmt (True or False) + * @return if this ICFGNode has preceding execution state + */ + bool isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t succ, AbstractState& as); /** - * Check if this SwitchInst and succ are satisfiable to the execution state. - * - * @param var var in switch inst - * @param succ the case value of switch inst - * @return if this ICFGNode has preceding execution state - */ - bool isSwitchBranchFeasible(const SVFVar* var, s64_t succ, - AbstractState& as); - + * Check if this SwitchInst and succ are satisfiable to the execution state. + * + * @param var var in switch inst + * @param succ the case value of switch inst + * @return if this ICFGNode has preceding execution state + */ + bool isSwitchBranchFeasible(const SVFVar* var, s64_t succ, AbstractState& as); /** - * handle external function call - * - * @param call call node whose callee is external function - */ - virtual void handleExtAPI(const CallICFGNode *call); + * handle external function call + * + * @param call call node whose callee is external function + */ + virtual void handleExtAPI(const CallICFGNode* call); /** - * the map of external function to its API type - * - * In AEAPI, this function is mainly used for abstract explanation. - * In subclasses, this function is mainly used to check specific bugs - */ + * the map of external function to its API type + * + * In AEAPI, this function is mainly used for abstract explanation. + * In subclasses, this function is mainly used to check specific bugs + */ virtual void initExtFunMap(); /** - * get byte size of alloca inst - * - * @param addr Address Stmt like malloc/calloc/ALLOCA/StackAlloc - * @return the byte size e.g. int32_t a[10] -> return 40 - */ - u32_t getAllocaInstByteSize(AbstractState& as, const AddrStmt *addr); + * get byte size of alloca inst + * + * @param addr Address Stmt like malloc/calloc/ALLOCA/StackAlloc + * @return the byte size e.g. int32_t a[10] -> return 40 + */ + u32_t getAllocaInstByteSize(AbstractState& as, const AddrStmt* addr); /** - * get byte size of alloca inst - * e.g. source code str = "abc", there are str value, return "abc" - * - * @param rhs SVFValue of string - * @return the string - */ - std::string strRead(AbstractState& as,const SVFValue* rhs); + * get byte size of alloca inst + * e.g. source code str = "abc", there are str value, return "abc" + * + * @param rhs SVFValue of string + * @return the string + */ + std::string strRead(AbstractState& as, const SVFValue* rhs); /** - * get length of string - * e.g. source code str = "abc", return 3 - * - * @param strValue SVFValue of string - * @return IntervalValue of string length - */ - IntervalValue getStrlen(AbstractState& as, const SVF::SVFValue *strValue); + * get length of string + * e.g. source code str = "abc", return 3 + * + * @param strValue SVFValue of string + * @return IntervalValue of string length + */ + IntervalValue getStrlen(AbstractState& as, const SVF::SVFValue* strValue); /** - * get memory allocation size - * e.g arr = new int[10] - * .... - * memset(arr, 1, 10* sizeof(int)) - * when we trace the 'arr', we can get the alloc size [40, 40] - * @param value to be traced - * @return IntervalValue of allocation size - */ - IntervalValue traceMemoryAllocationSize(AbstractState& as, const SVFValue *value); + * get memory allocation size + * e.g arr = new int[10] + * .... + * memset(arr, 1, 10* sizeof(int)) + * when we trace the 'arr', we can get the alloc size [40, 40] + * @param value to be traced + * @return IntervalValue of allocation size + */ + IntervalValue traceMemoryAllocationSize(AbstractState& as, const SVFValue* value); /** - * execute strcpy in abstract execution - * e.g arr = new char[10] - * str = "abc" - * strcpy(arr, str) - * we can set arr[0]='a', arr[1]='b', arr[2]='c', arr[3]='\0' - * @param call callnode of strcpy like api - */ - virtual void handleStrcpy(const CallICFGNode *call); + * execute strcpy in abstract execution + * e.g arr = new char[10] + * str = "abc" + * strcpy(arr, str) + * we can set arr[0]='a', arr[1]='b', arr[2]='c', arr[3]='\0' + * @param call callnode of strcpy like api + */ + virtual void handleStrcpy(const CallICFGNode* call); /** - * execute strcpy in abstract execution - * e.g arr[10] = "abc" - * str = "de" - * strcat(arr, str) - * we can set arr[3]='d', arr[4]='e', arr[5]='\0' - * @param call callnode of strcat like api - */ - virtual void handleStrcat(const CallICFGNode *call); + * execute strcpy in abstract execution + * e.g arr[10] = "abc" + * str = "de" + * strcat(arr, str) + * we can set arr[3]='d', arr[4]='e', arr[5]='\0' + * @param call callnode of strcat like api + */ + virtual void handleStrcat(const CallICFGNode* call); /** - * execute memcpy in abstract execution - * e.g arr = new char[10] - * str = "abcd" - * memcpy(arr, str, 5) - * we can set arr[3]='d', arr[4]='e', arr[5]='\0' - * @param call callnode of memcpy like api - */ - virtual void handleMemcpy(AbstractState& as, const SVFValue* dst, const SVFValue* src, IntervalValue len, u32_t start_idx); + * execute memcpy in abstract execution + * e.g arr = new char[10] + * str = "abcd" + * memcpy(arr, str, 5) + * we can set arr[3]='d', arr[4]='e', arr[5]='\0' + * @param call callnode of memcpy like api + */ + virtual void handleMemcpy(AbstractState& as, const SVFValue* dst, const SVFValue* src, IntervalValue len, + u32_t start_idx); /** - * execute memset in abstract execution - * e.g arr = new char[10] - * memset(arr, 'c', 2) - * we can set arr[0]='c', arr[1]='c', arr[2]='\0' - * @param call callnode of memset like api - */ + * execute memset in abstract execution + * e.g arr = new char[10] + * memset(arr, 'c', 2) + * we can set arr[0]='c', arr[1]='c', arr[2]='\0' + * @param call callnode of memset like api + */ virtual void handleMemset(AbstractState& as, const SVFValue* dst, IntervalValue elem, IntervalValue len); /** - * if this NodeID in SVFIR is a pointer, get the pointee type - * e.g arr = (int*) malloc(10*sizeof(int)) - * getPointeeType(arr) -> return int - * we can set arr[0]='c', arr[1]='c', arr[2]='\0' - * @param call callnode of memset like api - */ + * if this NodeID in SVFIR is a pointer, get the pointee type + * e.g arr = (int*) malloc(10*sizeof(int)) + * getPointeeType(arr) -> return int + * we can set arr[0]='c', arr[1]='c', arr[2]='\0' + * @param call callnode of memset like api + */ const SVFType* getPointeeElement(AbstractState& as, NodeID id); void collectCheckPoint(); void checkPointAllSet(); // helper functions for traceMemoryAllocationSize and canSafelyAccessMemory - void AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList& worklist, Set& visited); - void AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList& worklist, Set& visited); - void AccessMemoryViaLoadStmt(AbstractState& as, const LoadStmt *load, SVF::FILOWorkList& worklist, Set& visited); - void AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, SVF::FILOWorkList& worklist, Set& visited); + void AccessMemoryViaRetNode(const CallICFGNode* callnode, SVF::FILOWorkList& worklist, + Set& visited); + void AccessMemoryViaCopyStmt(const CopyStmt* copy, SVF::FILOWorkList& worklist, + Set& visited); + void AccessMemoryViaLoadStmt(AbstractState& as, const LoadStmt* load, SVF::FILOWorkList& worklist, + Set& visited); + void AccessMemoryViaCallArgs(const SVF::SVFArgument* arg, SVF::FILOWorkList& worklist, + Set& visited); + void updateStateOnAddr(const AddrStmt* addr); - void updateStateOnAddr(const AddrStmt *addr); + void updateStateOnBinary(const BinaryOPStmt* binary); - void updateStateOnBinary(const BinaryOPStmt *binary); + void updateStateOnCmp(const CmpStmt* cmp); - void updateStateOnCmp(const CmpStmt *cmp); + void updateStateOnLoad(const LoadStmt* load); - void updateStateOnLoad(const LoadStmt *load); + void updateStateOnStore(const StoreStmt* store); - void updateStateOnStore(const StoreStmt *store); + void updateStateOnCopy(const CopyStmt* copy); - void updateStateOnCopy(const CopyStmt *copy); + void updateStateOnCall(const CallPE* callPE); - void updateStateOnCall(const CallPE *callPE); + void updateStateOnRet(const RetPE* retPE); - void updateStateOnRet(const RetPE *retPE); + void updateStateOnGep(const GepStmt* gep); - void updateStateOnGep(const GepStmt *gep); + void updateStateOnSelect(const SelectStmt* select); - void updateStateOnSelect(const SelectStmt *select); - - void updateStateOnPhi(const PhiStmt *phi); + void updateStateOnPhi(const PhiStmt* phi); IntervalValue getRangeLimitFromType(const SVFType* type); - /// protected data members, also used in subclasses SVFIR* _svfir; /// Execution State, used to store the Interval Value of every SVF variable @@ -376,7 +377,6 @@ class AbstractInterpretation virtual void indirectCallFunPass(const CallICFGNode* callNode); protected: - AbstractState& getAbsStateFromTrace(const ICFGNode* node) { const ICFGNode* repNode = _icfg->getRepNode(node); @@ -398,10 +398,10 @@ class AbstractInterpretation protected: // there data should be shared with subclasses - Map> _func_map; + Map> _func_map; Set _checkpoints; Set _checkpoint_names; Map _abstractTrace; // abstract states immediately after nodes std::string _moduleName; }; -} \ No newline at end of file +} // namespace SVF \ No newline at end of file diff --git a/svf/include/AE/Svfexe/BufOverflowChecker.h b/svf/include/AE/Svfexe/BufOverflowChecker.h index 733738d6e..56d6519be 100644 --- a/svf/include/AE/Svfexe/BufOverflowChecker.h +++ b/svf/include/AE/Svfexe/BufOverflowChecker.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - // // Created by Jiawei Wang on 2024/1/12. // The implementation is based on @@ -33,13 +32,12 @@ namespace SVF { -struct BufOverflowException: public std::exception +struct BufOverflowException : public std::exception { public: - BufOverflowException(std::string msg, u32_t allocLb, - u32_t allocUb, u32_t accessLb, u32_t accessUb, const SVFValue* allocVal) : - _msg(msg), _allocLb(allocLb), _allocUb(allocUb), - _accessLb(accessLb), _accessUb(accessUb), _allocVar(allocVal) + BufOverflowException(std::string msg, u32_t allocLb, u32_t allocUb, u32_t accessLb, u32_t accessUb, + const SVFValue* allocVal) + : _msg(msg), _allocLb(allocLb), _allocUb(allocUb), _accessLb(accessLb), _accessUb(accessUb), _allocVar(allocVal) { } @@ -93,14 +91,13 @@ struct BufOverflowException: public std::exception return _msg.c_str(); } - protected: std::string _msg; u32_t _allocLb, _allocUb, _accessLb, _accessUb; const SVFValue* _allocVar; }; -class BufOverflowChecker: public AbstractInterpretation +class BufOverflowChecker : public AbstractInterpretation { public: BufOverflowChecker() : AbstractInterpretation() @@ -117,43 +114,43 @@ class BufOverflowChecker: public AbstractInterpretation protected: /** - * the map of external function to its API type - * - * it initialize the ext apis about buffer overflow checking - */ + * the map of external function to its API type + * + * it initialize the ext apis about buffer overflow checking + */ virtual void initExtFunMap() override; /** - * the map of ext apis of buffer overflow checking rules - * - * it initialize the rules of extapis about buffer overflow checking - * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz - */ + * the map of ext apis of buffer overflow checking rules + * + * it initialize the rules of extapis about buffer overflow checking + * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz + */ void initExtAPIBufOverflowCheckRules(); /** - * handle external function call regarding buffer overflow checking - * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz - * - * @param call call node whose callee is external function - */ - void handleExtAPI(const CallICFGNode *call) override; + * handle external function call regarding buffer overflow checking + * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz + * + * @param call call node whose callee is external function + */ + void handleExtAPI(const CallICFGNode* call) override; /** - * detect buffer overflow from strcpy like apis - * e.g. strcpy(dst, src), if dst is shorter than src, we will throw buffer overflow - * - * @param call call node whose callee is strcpy-like external function - * @return true if the buffer overflow is detected - */ - bool detectStrcpy(const CallICFGNode *call); + * detect buffer overflow from strcpy like apis + * e.g. strcpy(dst, src), if dst is shorter than src, we will throw buffer overflow + * + * @param call call node whose callee is strcpy-like external function + * @return true if the buffer overflow is detected + */ + bool detectStrcpy(const CallICFGNode* call); /** - * detect buffer overflow from strcat like apis - * e.g. strcat(dst, src), if dst is shorter than src, we will throw buffer overflow - * - * @param call call node whose callee is strcpy-like external function - * @return true if the buffer overflow is detected - */ - bool detectStrcat(const CallICFGNode *call); + * detect buffer overflow from strcat like apis + * e.g. strcat(dst, src), if dst is shorter than src, we will throw buffer overflow + * + * @param call call node whose callee is strcpy-like external function + * @return true if the buffer overflow is detected + */ + bool detectStrcat(const CallICFGNode* call); /** * detect buffer overflow by giving a var and a length @@ -164,18 +161,18 @@ class BufOverflowChecker: public AbstractInterpretation * @param len the length of the buffer overflow checkpoint * @return true if the buffer overflow is detected */ - bool canSafelyAccessMemory(const SVFValue *value, const IntervalValue &len, const ICFGNode *curNode); + bool canSafelyAccessMemory(const SVFValue* value, const IntervalValue& len, const ICFGNode* curNode); private: /** - * handle SVF statement regarding buffer overflow checking - * - * @param stmt SVF statement - */ - virtual void handleSVFStatement(const SVFStmt *stmt) override; + * handle SVF statement regarding buffer overflow checking + * + * @param stmt SVF statement + */ + virtual void handleSVFStatement(const SVFStmt* stmt) override; // TODO: will delete later - virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto) override + virtual void handleSingletonWTO(const ICFGSingletonWTO* icfgSingletonWto) override { AbstractInterpretation::handleSingletonWTO(icfgSingletonWto); const ICFGNode* repNode = _icfg->getRepNode(icfgSingletonWto->getICFGNode()); @@ -193,24 +190,23 @@ class BufOverflowChecker: public AbstractInterpretation } /** - * check buffer overflow at ICFGNode which is a checkpoint - * - * @param node ICFGNode - * @return true if the buffer overflow is detected - */ - bool detectBufOverflow(const ICFGNode *node); + * check buffer overflow at ICFGNode which is a checkpoint + * + * @param node ICFGNode + * @return true if the buffer overflow is detected + */ + bool detectBufOverflow(const ICFGNode* node); /** - * add buffer overflow bug to recoder - * - * @param e the exception that is thrown by BufOverflowChecker - * @param node ICFGNode that causes the exception - */ + * add buffer overflow bug to recoder + * + * @param e the exception that is thrown by BufOverflowChecker + * @param node ICFGNode that causes the exception + */ void addBugToRecoder(const BufOverflowException& e, const ICFGNode* node); private: Map _addrToGep; Map>> _extAPIBufOverflowCheckRules; - }; -} \ No newline at end of file +} // namespace SVF \ No newline at end of file diff --git a/svf/include/AE/Svfexe/ICFGSimplification.h b/svf/include/AE/Svfexe/ICFGSimplification.h index 9c846d42b..cd84655a5 100644 --- a/svf/include/AE/Svfexe/ICFGSimplification.h +++ b/svf/include/AE/Svfexe/ICFGSimplification.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - // // Created by Jiawei Wang on 2024/2/25. // @@ -41,4 +40,4 @@ class ICFGSimplification static void mergeAdjacentNodes(ICFG* icfg); }; -} \ No newline at end of file +} // namespace SVF \ No newline at end of file diff --git a/svf/include/CFL/CFGNormalizer.h b/svf/include/CFL/CFGNormalizer.h index 26d44288f..19245eee8 100644 --- a/svf/include/CFL/CFGNormalizer.h +++ b/svf/include/CFL/CFGNormalizer.h @@ -48,35 +48,35 @@ class CFGNormalizer { public: - CFGNormalizer() - { - } + CFGNormalizer() {} /// Binary Normal Form(BNF) normalization with variable attribute expanded - CFGrammar* normalize(GrammarBase *generalGrammar); + CFGrammar* normalize(GrammarBase* generalGrammar); /// Expand every variable attribute in rawProductions of grammarbase - CFGrammar* fillAttribute(CFGrammar *grammar, const Map>& kindToAttrsMap); + CFGrammar* fillAttribute(CFGrammar* grammar, const Map>& kindToAttrsMap); private: /// Add nonterminal to tranfer long rules to binary rules - void ebnf_bin(CFGrammar *grammar); + void ebnf_bin(CFGrammar* grammar); - void ebnfSignReplace(char sign, CFGrammar *grammar); + void ebnfSignReplace(char sign, CFGrammar* grammar); - void barReplace(CFGrammar *grammar); + void barReplace(CFGrammar* grammar); - void insertToCFLGrammar(CFGrammar *grammar, GrammarBase::Production &prod); + void insertToCFLGrammar(CFGrammar* grammar, GrammarBase::Production& prod); - int ebnfBracketMatch(GrammarBase::Production& prod, int i, CFGrammar *grammar) ; + int ebnfBracketMatch(GrammarBase::Production& prod, int i, CFGrammar* grammar); - GrammarBase::Symbol check_head(GrammarBase::SymbolMap& grammar, GrammarBase::Production& rule); + GrammarBase::Symbol check_head(GrammarBase::SymbolMap& grammar, + GrammarBase::Production& rule); - void strTrans(std::string strPro, CFGrammar *grammar, GrammarBase::Production& normalProd); + void strTrans(std::string strPro, CFGrammar* grammar, GrammarBase::Production& normalProd); - void getFilledProductions(GrammarBase::Production &prod,const NodeSet& nodeSet, CFGrammar *grammar, GrammarBase::Productions& normalProds); + void getFilledProductions(GrammarBase::Production& prod, const NodeSet& nodeSet, CFGrammar* grammar, + GrammarBase::Productions& normalProds); - void removeFirstSymbol(CFGrammar *grammar); + void removeFirstSymbol(CFGrammar* grammar); }; } // End namespace SVF diff --git a/svf/include/CFL/CFGrammar.h b/svf/include/CFL/CFGrammar.h index 50ecebef4..50a50aea5 100644 --- a/svf/include/CFL/CFGrammar.h +++ b/svf/include/CFL/CFGrammar.h @@ -41,20 +41,20 @@ class GrammarBase typedef u32_t VariableAttribute; typedef struct Symbol { - Kind kind: 8; - Attribute attribute: 16; - VariableAttribute variableAttribute: 8; + Kind kind : 8; + Attribute attribute : 16; + VariableAttribute variableAttribute : 8; /// Default Value for Symbol is 0. Symbol() : kind(0), attribute(0), variableAttribute(0) {} /// Construct from u32_t move the bit to right field - Symbol(const u32_t& num) : kind(num & 0xFF), attribute((num >> 8 ) & 0xFFFF), variableAttribute((num >> 24)) {} + Symbol(const u32_t& num) : kind(num & 0xFF), attribute((num >> 8) & 0xFFFF), variableAttribute((num >> 24)) {} /// Conversion of u32_t operator u32_t() { - static_assert(sizeof(struct Symbol)==sizeof(u32_t), "sizeof(struct Symbol)!=sizeof(u32_t)"); + static_assert(sizeof(struct Symbol) == sizeof(u32_t), "sizeof(struct Symbol)!=sizeof(u32_t)"); u32_t num = 0; num += this->variableAttribute << 24; num += this->attribute << 8; @@ -64,7 +64,7 @@ class GrammarBase operator u32_t() const { - static_assert(sizeof(struct Symbol)==sizeof(u32_t), "sizeof(struct Symbol)!=sizeof(u32_t)"); + static_assert(sizeof(struct Symbol) == sizeof(u32_t), "sizeof(struct Symbol)!=sizeof(u32_t)"); u32_t num = 0; num += this->variableAttribute << 24; num += this->attribute << 8; @@ -87,13 +87,14 @@ class GrammarBase void operator=(unsigned long long num) { this->kind = num & 0xFF; - this->attribute = (num >> 8 ) & 0xFFFF; + this->attribute = (num >> 8) & 0xFFFF; this->variableAttribute = num >> 24; } bool operator==(const Symbol& s) { - return ((this->kind == s.kind) && (this->attribute == s.attribute) && (this->variableAttribute == s.variableAttribute)); + return ((this->kind == s.kind) && (this->attribute == s.attribute) && + (this->variableAttribute == s.variableAttribute)); } bool operator==(const Symbol& s) const @@ -103,12 +104,12 @@ class GrammarBase bool operator!=(const Symbol& s) const { - return ! (*this == s) ; + return !(*this == s); } bool operator==(const u32_t& i) { - return u32_t(*this) == u32_t(i); + return u32_t(*this) == u32_t(i); } bool operator==(const Kind& k) const @@ -120,22 +121,21 @@ class GrammarBase class SymbolHash { public: - size_t operator()(const Symbol &s) const + size_t operator()(const Symbol& s) const { std::hash h; return h(u32_t(s)); } }; - struct SymbolVectorHash { - size_t operator()(const std::vector &v) const + size_t operator()(const std::vector& v) const { size_t h = v.size(); SymbolHash hf; - for (const Symbol &t : v) + for (const Symbol& t : v) { h ^= hf(t) + 0x9e3779b9 + (h << 6) + (h >> 2); } @@ -144,20 +144,18 @@ class GrammarBase } }; - template, - typename Allocator = std::allocator>> - using SymbolMap = std::unordered_map; - - template , - typename Allocator = std::allocator> - using SymbolSet = std::unordered_set; + template , + typename Allocator = std::allocator>> + using SymbolMap = std::unordered_map; - typedef std::vector Production; - typedef SymbolSet Productions; + template , + typename Allocator = std::allocator> + using SymbolSet = std::unordered_set; + typedef std::vector Production; + typedef SymbolSet Productions; - inline Map& getNonterminals() + inline Map& getNonterminals() { return this->nonterminals; } @@ -192,7 +190,7 @@ class GrammarBase return this->rawProductions; } - inline const Map>& getKindToAttrsMap() const + inline const Map>& getKindToAttrsMap() const { return this->kindToAttrsMap; } @@ -223,7 +221,7 @@ class GrammarBase void setRawProductions(SymbolMap& rawProductions); - void setKindToAttrsMap(const Map>& kindToAttrsMap); + void setKindToAttrsMap(const Map>& kindToAttrsMap); void setAttributeKinds(const Set& attributeKind); @@ -264,7 +262,7 @@ class GrammarBase inline static Kind getAttributedKind(Attribute attribute, Kind kind) { - return ((attribute << EdgeKindMaskBits)| kind ); + return ((attribute << EdgeKindMaskBits) | kind); } inline static Kind getVariabledKind(VariableAttribute variableAttribute, Kind kind) @@ -273,16 +271,17 @@ class GrammarBase } protected: - static constexpr unsigned char EdgeKindMaskBits = 8; ///< We use the lower 8 bits to denote edge kind + static constexpr unsigned char EdgeKindMaskBits = 8; ///< We use the lower 8 bits to denote edge kind static constexpr unsigned char AttributedKindMaskBits = 24; ///< We use the lower 24 bits to denote attributed kind static constexpr u64_t EdgeKindMask = (~0ULL) >> (64 - EdgeKindMaskBits); Kind startKind; + private: Map nonterminals; Map terminals; Map EBNFSigns; /// Map contains Signs' String and associated Symbols Set attributeKinds; - Map> kindToAttrsMap; + Map> kindToAttrsMap; SymbolMap rawProductions; u32_t totalKind; }; @@ -295,12 +294,12 @@ class CFGrammar : public GrammarBase /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CFGrammar *) + static inline bool classof(const CFGrammar*) { return true; } - static inline bool classof(const GrammarBase *node) + static inline bool classof(const GrammarBase* node) { return true; } @@ -328,43 +327,42 @@ class CFGrammar : public GrammarBase const bool hasProdsFromFirstRHS(const Symbol sym) const { auto it = firstRHSToProds.find(sym); - return it!=firstRHSToProds.end(); + return it != firstRHSToProds.end(); } const bool hasProdsFromSingleRHS(const Symbol sym) const { auto it = singleRHSToProds.find(sym); - return it!=singleRHSToProds.end(); + return it != singleRHSToProds.end(); } const bool hasProdsFromSecondRHS(const Symbol sym) const { auto it = secondRHSToProds.find(sym); - return it!=secondRHSToProds.end(); + return it != secondRHSToProds.end(); } const Productions& getProdsFromSingleRHS(const Symbol sym) const { auto it = singleRHSToProds.find(sym); - assert(it!=singleRHSToProds.end() && "production (X -> sym) not found for sym!!"); + assert(it != singleRHSToProds.end() && "production (X -> sym) not found for sym!!"); return it->second; } const Productions& getProdsFromFirstRHS(const Symbol sym) const { auto it = firstRHSToProds.find(sym); - assert(it!=firstRHSToProds.end() && "production (X -> sym Y ) not found for sym!!"); + assert(it != firstRHSToProds.end() && "production (X -> sym Y ) not found for sym!!"); return it->second; } const Productions& getProdsFromSecondRHS(const Symbol sym) const { auto it = secondRHSToProds.find(sym); - assert(it!=secondRHSToProds.end() && "production (X -> Y sym) not found for sym!!"); + assert(it != secondRHSToProds.end() && "production (X -> Y sym) not found for sym!!"); return it->second; } - const Symbol& getLHSSymbol(const Production& prod) const { return prod.at(0); @@ -384,7 +382,6 @@ class CFGrammar : public GrammarBase void dump(std::string fileName) const; - const inline u32_t num_generator() { return newTerminalSubscript++; @@ -403,11 +400,11 @@ class CFGrammar : public GrammarBase * New nodes will be pushed at back and popped from front. * Elements in the list are unique as they're recorded by Set. */ -template -class CFLFIFOWorkList +template class CFLFIFOWorkList { typedef GrammarBase::SymbolSet DataSet; typedef std::deque DataDeque; + public: CFLFIFOWorkList() {} @@ -460,9 +457,9 @@ class CFLFIFOWorkList } private: - DataSet data_set; ///< store all data in the work list. - DataDeque data_list; ///< work list using std::vector. + DataSet data_set; ///< store all data in the work list. + DataDeque data_list; ///< work list using std::vector. }; -} +} // namespace SVF #endif /* CFLGrammar_H_ */ \ No newline at end of file diff --git a/svf/include/CFL/CFLAlias.h b/svf/include/CFL/CFLAlias.h index 40c4d6cd4..04f42fccf 100644 --- a/svf/include/CFL/CFLAlias.h +++ b/svf/include/CFL/CFLAlias.h @@ -44,9 +44,7 @@ class CFLAlias : public CFLBase public: typedef OrderedMap CallSite2DummyValPN; - CFLAlias(SVFIR* ir) : CFLBase(ir, PointerAnalysis::CFLFICI_WPA) - { - } + CFLAlias(SVFIR* ir) : CFLBase(ir, PointerAnalysis::CFLFICI_WPA) {} /// Initialize the grammar, graph, solver virtual void initialize(); @@ -54,7 +52,6 @@ class CFLAlias : public CFLBase /// Initialize Solver virtual void initializeSolver(); - /// Print grammar and graph virtual void finalize(); @@ -66,13 +63,13 @@ class CFLAlias : public CFLBase { NodeID n1 = svfir->getValueNode(v1); NodeID n2 = svfir->getValueNode(v2); - return alias(n1,n2); + return alias(n1, n2); } /// Interface exposed to users of our Alias analysis, given PAGNodeID virtual AliasResult alias(NodeID node1, NodeID node2) { - if(graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->startKind)) + if (graph->hasEdge(graph->getGNode(node1), graph->getGNode(node2), graph->startKind)) return AliasResult::MayAlias; else return AliasResult::NoAlias; @@ -82,13 +79,13 @@ class CFLAlias : public CFLBase virtual const PointsTo& getCFLPts(NodeID ptr) { /// Check V Dst of ptr. - CFLNode *funNode = graph->getGNode(ptr); - for(auto outedge = funNode->getOutEdges().begin(); outedge!=funNode->getOutEdges().end(); outedge++) + CFLNode* funNode = graph->getGNode(ptr); + for (auto outedge = funNode->getOutEdges().begin(); outedge != funNode->getOutEdges().end(); outedge++) { - if((*outedge)->getEdgeKind() == graph->getStartKind()) + if ((*outedge)->getEdgeKind() == graph->getStartKind()) { // Need to Find dst addr src - SVFVar *vNode = svfir->getGNode((*outedge)->getDstID()); + SVFVar* vNode = svfir->getGNode((*outedge)->getDstID()); NodeID basevNodeID; // Remove svfir->getBaseValVar, SVF IR api change if (vNode->hasIncomingEdges(SVFStmt::Gep)) @@ -100,9 +97,9 @@ class CFLAlias : public CFLBase else basevNodeID = vNode->getId(); addPts(ptr, basevNodeID); - for(auto inEdge = vNode->getInEdges().begin(); inEdge!=vNode->getInEdges().end(); inEdge++) + for (auto inEdge = vNode->getInEdges().begin(); inEdge != vNode->getInEdges().end(); inEdge++) { - if((*inEdge)->getEdgeKind() == 0) + if ((*inEdge)->getEdgeKind() == 0) { addPts(ptr, (*inEdge)->getSrcID()); } @@ -117,15 +114,15 @@ class CFLAlias : public CFLBase /// Add copy edge on constraint graph virtual inline bool addCopyEdge(NodeID src, NodeID dst) { - const CFLEdge *edge = graph->hasEdge(graph->getGNode(src),graph->getGNode(dst), 1); - if (edge != nullptr ) + const CFLEdge* edge = graph->hasEdge(graph->getGNode(src), graph->getGNode(dst), 1); + if (edge != nullptr) { return false; } CFGrammar::Kind copyKind = grammar->strToKind("copy"); CFGrammar::Kind copybarKind = grammar->strToKind("copybar"); - solver->pushIntoWorklist(graph->addCFLEdge(graph->getGNode(src),graph->getGNode(dst), copyKind)); - solver->pushIntoWorklist(graph->addCFLEdge(graph->getGNode(dst),graph->getGNode(src), copybarKind)); + solver->pushIntoWorklist(graph->addCFLEdge(graph->getGNode(src), graph->getGNode(dst), copyKind)); + solver->pushIntoWorklist(graph->addCFLEdge(graph->getGNode(dst), graph->getGNode(src), copybarKind)); return true; } @@ -148,15 +145,14 @@ class CFLAlias : public CFLBase void heapAllocatorViaIndCall(CallSite cs); private: - CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocator + CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which created at an indirect + ///< callsite, which invokes a heap allocator }; class POCRAlias : public CFLAlias { public: - POCRAlias(SVFIR* ir) : CFLAlias(ir) - { - } + POCRAlias(SVFIR* ir) : CFLAlias(ir) {} /// Initialize POCR Solver virtual void initializeSolver(); }; @@ -164,9 +160,7 @@ class POCRAlias : public CFLAlias class POCRHybrid : public CFLAlias { public: - POCRHybrid(SVFIR* ir) : CFLAlias(ir) - { - } + POCRHybrid(SVFIR* ir) : CFLAlias(ir) {} /// Initialize POCRHybrid Solver virtual void initializeSolver(); diff --git a/svf/include/CFL/CFLBase.h b/svf/include/CFL/CFLBase.h index c88db8362..3ddb63ab9 100644 --- a/svf/include/CFL/CFLBase.h +++ b/svf/include/CFL/CFLBase.h @@ -50,7 +50,8 @@ class CFLBase : public BVDataPTAImpl { public: - CFLBase(SVFIR* ir, PointerAnalysis::PTATY pty) : BVDataPTAImpl(ir, pty), svfir(ir), graph(nullptr), grammar(nullptr), solver(nullptr) + CFLBase(SVFIR* ir, PointerAnalysis::PTATY pty) + : BVDataPTAImpl(ir, pty), svfir(ir), graph(nullptr), grammar(nullptr), solver(nullptr) { } @@ -91,18 +92,18 @@ class CFLBase : public BVDataPTAImpl /// Statistics //@{ // Grammar - static double timeOfBuildCFLGrammar; // Time of building grammarBase from text file - static double timeOfNormalizeGrammar; // Time of normalizing grammarBase to CFGrammar + static double timeOfBuildCFLGrammar; // Time of building grammarBase from text file + static double timeOfNormalizeGrammar; // Time of normalizing grammarBase to CFGrammar // Graph - static double timeOfBuildCFLGraph; // Time of building CFLGraph - static double numOfTerminalEdges; // Number of terminal labeled edges - static double numOfTemporaryNonterminalEdges; // Number of temporary (ie. X0, X1..) nonterminal labeled edges - static double numOfNonterminalEdges; // Number of nonterminal labeled edges - static double numOfStartEdges; // Number of start nonterminal labeled edges + static double timeOfBuildCFLGraph; // Time of building CFLGraph + static double numOfTerminalEdges; // Number of terminal labeled edges + static double numOfTemporaryNonterminalEdges; // Number of temporary (ie. X0, X1..) nonterminal labeled edges + static double numOfNonterminalEdges; // Number of nonterminal labeled edges + static double numOfStartEdges; // Number of start nonterminal labeled edges // Solver - static double numOfIteration; // Number solving Iteration - static double numOfChecks; // Number of checks - static double timeOfSolving; // time of solving CFL Reachability + static double numOfIteration; // Number solving Iteration + static double numOfChecks; // Number of checks + static double timeOfSolving; // time of solving CFL Reachability //@} protected: diff --git a/svf/include/CFL/CFLGramGraphChecker.h b/svf/include/CFL/CFLGramGraphChecker.h index 201716375..3e100b792 100644 --- a/svf/include/CFL/CFLGramGraphChecker.h +++ b/svf/include/CFL/CFLGramGraphChecker.h @@ -37,10 +37,10 @@ namespace SVF class CFLGramGraphChecker { public: - void check(GrammarBase *grammar, CFLGraphBuilder *graphBuilder, CFLGraph *graph) + void check(GrammarBase* grammar, CFLGraphBuilder* graphBuilder, CFLGraph* graph) { /// Check all kinds in grammar in graphBuilder with the same label - for(auto pairV : grammar->getTerminals()) + for (auto pairV : grammar->getTerminals()) { if (graphBuilder->getLabelToKindMap().find(pairV.first) != graphBuilder->getLabelToKindMap().end()) { @@ -49,7 +49,7 @@ class CFLGramGraphChecker } } - for(auto pairV : grammar->getNonterminals()) + for (auto pairV : grammar->getNonterminals()) { if (graphBuilder->getLabelToKindMap().find(pairV.first) != graphBuilder->getLabelToKindMap().end()) { @@ -58,8 +58,8 @@ class CFLGramGraphChecker } else { - graphBuilder->getLabelToKindMap().insert(std::make_pair (pairV.first,pairV.second)); - graphBuilder->getKindToLabelMap().insert(std::make_pair (pairV.second, pairV.first)); + graphBuilder->getLabelToKindMap().insert(std::make_pair(pairV.first, pairV.second)); + graphBuilder->getKindToLabelMap().insert(std::make_pair(pairV.second, pairV.first)); } } @@ -69,6 +69,6 @@ class CFLGramGraphChecker } }; -}// SVF +} // namespace SVF #endif /* INCLUDE_CFL_CFLGRAMGRAPHCHECKER_H_*/ \ No newline at end of file diff --git a/svf/include/CFL/CFLGraphBuilder.h b/svf/include/CFL/CFLGraphBuilder.h index 055933377..01efd2a2a 100644 --- a/svf/include/CFL/CFLGraphBuilder.h +++ b/svf/include/CFL/CFLGraphBuilder.h @@ -60,37 +60,40 @@ class CFLGraphBuilder Map kindToLabelMap; /// Map to maintain attributes associated with each kind - Map> kindToAttrsMap; + Map> kindToAttrsMap; Kind current; - CFLGraph *cflGraph; + CFLGraph* cflGraph; /// Method to add an attribute to a specific kind void addAttribute(CFGrammar::Kind kind, CFGrammar::Attribute attribute); /// build label and kind connect from the grammar - void buildlabelToKindMap(GrammarBase *grammar); + void buildlabelToKindMap(GrammarBase* grammar); /// add src and dst node from file CFLNode* addGNode(u32_t NodeID); /// Method to build a CFL graph from a Text file - CFLGraph* buildFromText(std::string fileName, GrammarBase *grammar, BuildDirection direction = BuildDirection::plain); + CFLGraph* buildFromText(std::string fileName, GrammarBase* grammar, + BuildDirection direction = BuildDirection::plain); /// Method to build a CFL graph from a Dot file - CFLGraph *buildFromDot(std::string filename, GrammarBase *grammar, BuildDirection direction = BuildDirection::plain); + CFLGraph* buildFromDot(std::string filename, GrammarBase* grammar, + BuildDirection direction = BuildDirection::plain); /// Method to build a CFL graph from a Json file - CFLGraph *buildFromJson(std::string filename, GrammarBase *grammar, BuildDirection direction = BuildDirection::plain); + CFLGraph* buildFromJson(std::string filename, GrammarBase* grammar, + BuildDirection direction = BuildDirection::plain); public: /// Method to build a CFL graph by copying nodes and edges from any graph /// inherited from GenericGraph - template - CFLGraph* build(GenericGraph* graph, GrammarBase *grammar, BuildDirection direction = BuildDirection::plain); + template + CFLGraph* build(GenericGraph* graph, GrammarBase* grammar, BuildDirection direction = BuildDirection::plain); /// Method to build a CFL graph from external file - CFLGraph* build(std::string fileName, GrammarBase *grammar, BuildDirection direction = BuildDirection::plain); + CFLGraph* build(std::string fileName, GrammarBase* grammar, BuildDirection direction = BuildDirection::plain); /// @{ /// Getter methods for accessing class variables @@ -108,7 +111,7 @@ class CFLGraphBuilder } /// Returns a reference to the map that associates Kinds with their corresponding attributes - Map>& getKindToAttrsMap() + Map>& getKindToAttrsMap() { return this->kindToAttrsMap; } @@ -121,21 +124,22 @@ class AliasCFLGraphBuilder : public CFLGraphBuilder { public: /// Builds a bidirectional CFL graph by copying nodes and edges from a const graph that inherits from GenericGraph - CFLGraph* buildBigraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar); + CFLGraph* buildBigraph(ConstraintGraph* graph, Kind startKind, GrammarBase* grammar); /// Builds a bidirectional CFL graph by copying nodes and edges from any graph that inherits from GenericGraph /// Transfers Load and Store to copy edge and address edge to construct PEG style CFLGraph - CFLGraph* buildBiPEGgraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar, SVFIR* pag); + CFLGraph* buildBiPEGgraph(ConstraintGraph* graph, Kind startKind, GrammarBase* grammar, SVFIR* pag); private: /// Connects VGep (Variable GEP) - void connectVGep(CFLGraph *cflGraph, ConstraintGraph *graph, ConstraintNode *src, ConstraintNode *dst, u32_t level, SVFIR* pag); + void connectVGep(CFLGraph* cflGraph, ConstraintGraph* graph, ConstraintNode* src, ConstraintNode* dst, u32_t level, + SVFIR* pag); /// Handles edges, with the exception of the GEP - void addBiCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Kind label); + void addBiCFLEdge(CFLGraph* cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Kind label); /// Adds bidirectional GEP edges with attributes - void addBiGepCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Attribute attri); + void addBiGepCFLEdge(CFLGraph* cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Attribute attri); }; /// VFCFLGraphBuilder: a CFLGraphBuilder specialized for handling value-flow @@ -143,24 +147,24 @@ class VFCFLGraphBuilder : public CFLGraphBuilder { public: /// Builds a bidirectional CFL graph by copying nodes and edges from a const graph that inherits from SVFG - CFLGraph* buildBigraph(SVFG *graph, Kind startKind, GrammarBase *grammar); + CFLGraph* buildBigraph(SVFG* graph, Kind startKind, GrammarBase* grammar); /// Builds a bidirectional CFL graph by copying nodes and edges from any graph that inherits from GenericGraph /// Transfers Load and Store to copy edge and address edge to construct PEG style CFLGraph - CFLGraph* buildBiPEGgraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar, SVFIR* pag); + CFLGraph* buildBiPEGgraph(ConstraintGraph* graph, Kind startKind, GrammarBase* grammar, SVFIR* pag); private: /// Connects VGep (Variable GEP) - void connectVGep(CFLGraph *cflGraph, ConstraintGraph *graph, ConstraintNode *src, ConstraintNode *dst, u32_t level, SVFIR* pag); + void connectVGep(CFLGraph* cflGraph, ConstraintGraph* graph, ConstraintNode* src, ConstraintNode* dst, u32_t level, + SVFIR* pag); /// Handles edges, with the exception of the GEP - void addBiCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Kind label); + void addBiCFLEdge(CFLGraph* cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Kind label); /// Adds bidirectional GEP edges with attributes - void addBiGepCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Attribute attri); + void addBiGepCFLEdge(CFLGraph* cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Attribute attri); }; - -}// SVF +} // namespace SVF #endif /* INCLUDE_CFL_CFLGRAPHBUILDER_H_*/ diff --git a/svf/include/CFL/CFLSVFGBuilder.h b/svf/include/CFL/CFLSVFGBuilder.h index e6a951c97..af4ecfe1a 100644 --- a/svf/include/CFL/CFLSVFGBuilder.h +++ b/svf/include/CFL/CFLSVFGBuilder.h @@ -32,7 +32,7 @@ namespace SVF { -class CFLSVFGBuilder: public SaberSVFGBuilder +class CFLSVFGBuilder : public SaberSVFGBuilder { public: typedef Set SVFGNodeSet; @@ -54,5 +54,5 @@ class CFLSVFGBuilder: public SaberSVFGBuilder virtual void rmIncomingEdgeForSUStore(BVDataPTAImpl* pta); }; -} -#endif //SVF_CFLSVFGBUILDER_H +} // namespace SVF +#endif // SVF_CFLSVFGBUILDER_H diff --git a/svf/include/CFL/CFLSolver.h b/svf/include/CFL/CFLSolver.h index 1a91611a9..3707cfead 100644 --- a/svf/include/CFL/CFLSolver.h +++ b/svf/include/CFL/CFLSolver.h @@ -51,9 +51,7 @@ class CFLSolver static double numOfChecks; - CFLSolver(CFLGraph* _graph, CFGrammar* _grammar): graph(_graph), grammar(_grammar) - { - } + CFLSolver(CFLGraph* _graph, CFGrammar* _grammar) : graph(_graph), grammar(_grammar) {} virtual ~CFLSolver() { @@ -109,22 +107,21 @@ class CFLSolver CFGrammar* grammar; /// Worklist for resolution WorkList worklist; - }; /// Solver Utilize CFLData class POCRSolver : public CFLSolver { public: - typedef std::map TypeMap; // Label with SparseBitVector of NodeID - typedef std::unordered_map DataMap; // Each Node has a TypeMap - typedef typename DataMap::iterator iterator; // iterator for each node + typedef std::map TypeMap; // Label with SparseBitVector of NodeID + typedef std::unordered_map DataMap; // Each Node has a TypeMap + typedef typename DataMap::iterator iterator; // iterator for each node typedef typename DataMap::const_iterator const_iterator; protected: - DataMap succMap; // succ map for nodes contains Label: Edgeset - DataMap predMap; // pred map for nodes contains Label: edgeset - const NodeBS emptyData; // ?? + DataMap succMap; // succ map for nodes contains Label: Edgeset + DataMap predMap; // pred map for nodes contains Label: edgeset + const NodeBS emptyData; // ?? NodeBS diff; // union/add data //@{ @@ -140,20 +137,17 @@ class POCRSolver : public CFLSolver inline bool addPreds(const NodeID key, const NodeBS& data, const Label ty) { - if (data.empty()) - return false; - return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS) + if (data.empty()) return false; + return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS) } inline bool addSuccs(const NodeID key, const NodeBS& data, const Label ty) { - if (data.empty()) - return false; - return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS) + if (data.empty()) return false; + return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS) } //@} public: - virtual void clear() { succMap.clear(); @@ -224,9 +218,8 @@ class POCRSolver : public CFLSolver NodeBS newDsts; if (addSuccs(src, dstData, ty)) { - for (const NodeID datum: dstData) - if (addPred(datum, src, ty)) - newDsts.set(datum); + for (const NodeID datum : dstData) + if (addPred(datum, src, ty)) newDsts.set(datum); } return newDsts; } @@ -237,9 +230,8 @@ class POCRSolver : public CFLSolver NodeBS newSrcs; if (addPreds(dst, srcData, ty)) { - for (const NodeID datum: srcData) - if (addSucc(datum, dst, ty)) - newSrcs.set(datum); + for (const NodeID datum : srcData) + if (addSucc(datum, dst, ty)) newSrcs.set(datum); } return newSrcs; } @@ -248,12 +240,10 @@ class POCRSolver : public CFLSolver inline bool hasEdge(const NodeID src, const NodeID dst, const Label ty) { const_iterator iter1 = succMap.find(src); - if (iter1 == succMap.end()) - return false; + if (iter1 == succMap.end()) return false; auto iter2 = iter1->second.find(ty); - if (iter2 == iter1->second.end()) - return false; + if (iter2 == iter1->second.end()) return false; return iter2->second.test(dst); } @@ -271,9 +261,7 @@ class POCRSolver : public CFLSolver buildCFLData(); } /// Destructor - virtual ~POCRSolver() - { - } + virtual ~POCRSolver() {} /// Process CFLEdge virtual void processCFLEdge(const CFLEdge* Y_edge); @@ -293,20 +281,17 @@ class POCRSolver : public CFLSolver /// Solver Utilize Hybrid Representation of Graph class POCRHybridSolver : public POCRSolver { -//Hybrid -//{@ + // Hybrid + //{@ public: struct TreeNode { NodeID id; std::unordered_set children; - TreeNode(NodeID nId) : id(nId) - {} + TreeNode(NodeID nId) : id(nId) {} - ~TreeNode() - { - } + ~TreeNode() {} inline bool operator==(const TreeNode& rhs) const { @@ -320,7 +305,7 @@ class POCRHybridSolver : public POCRSolver }; public: - Map> indMap; // indMap[v][u] points to node v in tree(u) + Map> indMap; // indMap[v][u] points to node v in tree(u) bool hasInd_h(NodeID src, NodeID dst); @@ -342,17 +327,15 @@ class POCRHybridSolver : public POCRSolver void addArc_h(NodeID src, NodeID dst); void meld_h(NodeID x, TreeNode* uNode, TreeNode* vNode); -//@} + //@} public: - POCRHybridSolver(CFLGraph* _graph, CFGrammar* _grammar) : POCRSolver(_graph, _grammar) - { - } + POCRHybridSolver(CFLGraph* _graph, CFGrammar* _grammar) : POCRSolver(_graph, _grammar) {} /// Destructor virtual ~POCRHybridSolver() { - for (auto iter1: indMap) + for (auto iter1 : indMap) { - for (auto iter2: iter1.second) + for (auto iter2 : iter1.second) { delete iter2.second; iter2.second = NULL; @@ -369,6 +352,6 @@ class POCRHybridSolver : public POCRSolver void addArc(NodeID src, NodeID dst); void meld(NodeID x, TreeNode* uNode, TreeNode* vNode); }; -} +} // namespace SVF #endif /* INCLUDE_CFL_CFLSolver_H_*/ \ No newline at end of file diff --git a/svf/include/CFL/CFLStat.h b/svf/include/CFL/CFLStat.h index fa9e76be8..d5de1d5c1 100644 --- a/svf/include/CFL/CFLStat.h +++ b/svf/include/CFL/CFLStat.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * CFLStat.h * @@ -49,9 +48,7 @@ class CFLStat : public PTAStat public: CFLStat(CFLBase* p); - virtual ~CFLStat() - { - } + virtual ~CFLStat() {} virtual void performStat(); diff --git a/svf/include/CFL/CFLVF.h b/svf/include/CFL/CFLVF.h index 51ea64c52..62da554f5 100644 --- a/svf/include/CFL/CFLVF.h +++ b/svf/include/CFL/CFLVF.h @@ -30,7 +30,6 @@ #ifndef INCLUDE_CFL_CFLVF_H_ #define INCLUDE_CFL_CFLVF_H_ - #include "CFL/CFLBase.h" #include "CFL/CFLStat.h" #include "CFL/CFLSVFGBuilder.h" @@ -42,9 +41,7 @@ class CFLVF : public CFLBase { public: - CFLVF(SVFIR* ir) : CFLBase(ir, PointerAnalysis::CFLFSCS_WPA) - { - } + CFLVF(SVFIR* ir) : CFLBase(ir, PointerAnalysis::CFLFSCS_WPA) {} /// Parameter Checking virtual void checkParameter(); diff --git a/svf/include/CFL/GrammarBuilder.h b/svf/include/CFL/GrammarBuilder.h index 22be0a3d1..f0f49afb6 100644 --- a/svf/include/CFL/GrammarBuilder.h +++ b/svf/include/CFL/GrammarBuilder.h @@ -71,7 +71,7 @@ class GrammarBuilder { private: std::string fileName; - GrammarBase *grammar; + GrammarBase* grammar; /// Parse start symbol and production from file string const inline std::string parseProductionsString() const; @@ -83,7 +83,7 @@ class GrammarBuilder const inline std::string stripSpace(std::string s) const; public: - GrammarBuilder(std::string fileName): fileName(fileName), grammar(nullptr) + GrammarBuilder(std::string fileName) : fileName(fileName), grammar(nullptr) { grammar = new GrammarBase(); }; @@ -92,9 +92,9 @@ class GrammarBuilder GrammarBase* build() const; /// Build grammarBase from fileName with preset str2KindMap - GrammarBase* build(Map &preMap) const; + GrammarBase* build(Map& preMap) const; }; -} // SVF +} // namespace SVF #endif /* INCLUDE_CFL_GRAMMARBUILDER_H_ */ diff --git a/svf/include/DDA/ContextDDA.h b/svf/include/DDA/ContextDDA.h index 5aa8dc9e1..8158fd282 100644 --- a/svf/include/DDA/ContextDDA.h +++ b/svf/include/DDA/ContextDDA.h @@ -51,7 +51,7 @@ typedef CxtStmtDPItem CxtLocDPItem; /*! * Context-, Flow- Sensitive Demand-driven Analysis */ -class ContextDDA : public CondPTAImpl, public DDAVFSolver +class ContextDDA : public CondPTAImpl, public DDAVFSolver { public: @@ -85,12 +85,12 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolvergetPts(dpm.getCurNodeID()); + const PointsTo& pts = getAndersenAnalysis()->getPts(dpm.getCurNodeID()); CxtPtSet tmpCPts; ContextCond cxt; for (PointsTo::iterator piter = pts.begin(); piter != pts.end(); ++piter) { - CxtVar var(cxt,*piter); + CxtVar var(cxt, *piter); tmpCPts.set(var); } return tmpCPts; @@ -118,14 +118,13 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolver, public DDAVFSolverfirst; - const FunctionSet & functions = iter->second; + const FunctionSet& functions = iter->second; for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* func = *func_iter; + const SVFFunction* func = *func_iter; getSVFG()->connectCallerAndCallee(newcs, func, svfgEdges); } } @@ -162,10 +162,9 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolvergetSrcNode()->getFun(); const SVFFunction* dstfun = edge->getDstNode()->getFun(); - if(srcfun && dstfun) - return inSameCallGraphSCC(srcfun,dstfun); + if (srcfun && dstfun) return inSameCallGraphSCC(srcfun, dstfun); - assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge" ); + assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge"); return false; } @@ -174,15 +173,14 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolvergetPAGSrcNodeID(); /// whether this object is set field-insensitive during pre-analysis - if (isFieldInsensitive(srcID)) - srcID = getFIObjVar(srcID); + if (isFieldInsensitive(srcID)) srcID = getFIObjVar(srcID); - CxtVar var(dpm.getCond(),srcID); - addDDAPts(pts,var); + CxtVar var(dpm.getCond(), srcID); + addDDAPts(pts, var); DBOUT(DDDA, SVFUtil::outs() << "\t add points-to target " << var << " to dpm "); DBOUT(DDDA, dpm.dump()); } @@ -190,13 +188,14 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolver, public DDAVFSolvergetAllValidPtrs(); + if (solveAll) candidateQueries = pag->getAllValidPtrs(); else { for (OrderedNodeSet::iterator it = userInput.begin(), eit = userInput.end(); it != eit; ++it) @@ -101,32 +98,32 @@ class DDAClient virtual inline void performStat(PointerAnalysis*) {} virtual inline void collectWPANum(SVFModule*) {} + protected: void addCandidate(NodeID id) { - if (pag->isValidTopLevelPtr(pag->getGNode(id))) - candidateQueries.insert(id); + if (pag->isValidTopLevelPtr(pag->getGNode(id))) candidateQueries.insert(id); } - SVFIR* pag; ///< SVFIR graph used by current DDA analysis - SVFModule* module; ///< LLVM module - NodeID curPtr; ///< current pointer being queried - OrderedNodeSet candidateQueries; ///< store all candidate pointers to be queried + SVFIR* pag; ///< SVFIR graph used by current DDA analysis + SVFModule* module; ///< LLVM module + NodeID curPtr; ///< current pointer being queried + OrderedNodeSet candidateQueries; ///< store all candidate pointers to be queried private: - OrderedNodeSet userInput; ///< User input queries - bool solveAll; ///< TRUE if all top level pointers are being queried + OrderedNodeSet userInput; ///< User input queries + bool solveAll; ///< TRUE if all top level pointers are being queried }; - /** * DDA client with function pointers as query candidates. */ class FunptrDDAClient : public DDAClient { private: - typedef OrderedMap VTablePtrToCallSiteMap; + typedef OrderedMap VTablePtrToCallSiteMap; VTablePtrToCallSiteMap vtableToCallSiteMap; + public: FunptrDDAClient(SVFModule* module) : DDAClient(module) {} ~FunptrDDAClient() {} @@ -136,8 +133,6 @@ class FunptrDDAClient : public DDAClient virtual void performStat(PointerAnalysis* pta); }; - - /** * DDA client with function pointers as query candidates. */ @@ -156,7 +151,7 @@ class AliasDDAClient : public DDAClient virtual void performStat(PointerAnalysis* pta); private: - typedef OrderedMap VTablePtrToCallSiteMap; + typedef OrderedMap VTablePtrToCallSiteMap; VTablePtrToCallSiteMap vtableToCallSiteMap; PAGNodeSet loadSrcNodes; PAGNodeSet storeDstNodes; diff --git a/svf/include/DDA/DDAPass.h b/svf/include/DDA/DDAPass.h index 66aaab581..c212bc256 100644 --- a/svf/include/DDA/DDAPass.h +++ b/svf/include/DDA/DDAPass.h @@ -28,7 +28,6 @@ * */ - #ifndef DDAPASS_H_ #define DDAPASS_H_ @@ -57,7 +56,7 @@ class DDAPass ~DDAPass(); /// Interface expose to users of our pointer analysis, given Value infos - virtual AliasResult alias(const SVFValue* V1, const SVFValue* V2); + virtual AliasResult alias(const SVFValue* V1, const SVFValue* V2); /// Interface expose to users of our pointer analysis, given PAGNodes virtual AliasResult alias(NodeID V1, NodeID V2); @@ -80,18 +79,19 @@ class DDAPass /// Create pointer analysis according to specified kind and analyze the module. void runPointerAnalysis(SVFIR* module, u32_t kind); /// Context insensitive Edge for DDA - void initCxtInsensitiveEdges(PointerAnalysis* pta, const SVFG* svfg,const SVFGSCC* svfgSCC, SVFGEdgeSet& insensitveEdges); + void initCxtInsensitiveEdges(PointerAnalysis* pta, const SVFG* svfg, const SVFGSCC* svfgSCC, + SVFGEdgeSet& insensitveEdges); /// Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the SVFG. - bool edgeInSVFGSCC(const SVFGSCC* svfgSCC,const SVFGEdge* edge); + bool edgeInSVFGSCC(const SVFGSCC* svfgSCC, const SVFGEdge* edge); /// Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the SVFG. - bool edgeInCallGraphSCC(PointerAnalysis* pta,const SVFGEdge* edge); - - void collectCxtInsenEdgeForRecur(PointerAnalysis* pta, const SVFG* svfg,SVFGEdgeSet& insensitveEdges); - void collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* svfg,const SVFGSCC* svfgSCC, SVFGEdgeSet& insensitveEdges); + bool edgeInCallGraphSCC(PointerAnalysis* pta, const SVFGEdge* edge); - std::unique_ptr _pta; ///< pointer analysis to be executed. - DDAClient* _client; ///< DDA client used + void collectCxtInsenEdgeForRecur(PointerAnalysis* pta, const SVFG* svfg, SVFGEdgeSet& insensitveEdges); + void collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* svfg, const SVFGSCC* svfgSCC, + SVFGEdgeSet& insensitveEdges); + std::unique_ptr _pta; ///< pointer analysis to be executed. + DDAClient* _client; ///< DDA client used }; } // End namespace SVF diff --git a/svf/include/DDA/DDAVFSolver.h b/svf/include/DDA/DDAVFSolver.h index 7067245eb..a39b738b5 100644 --- a/svf/include/DDA/DDAVFSolver.h +++ b/svf/include/DDA/DDAVFSolver.h @@ -43,10 +43,10 @@ namespace SVF /*! * Value-Flow Based Demand-Driven Points-to Analysis */ -template -class DDAVFSolver +template class DDAVFSolver { friend class DDAStat; + public: typedef SCCDetection SVFGSCC; typedef SCCDetection CallGraphSCC; @@ -54,21 +54,23 @@ class DDAVFSolver typedef SVFIR::CallSiteSet CallSiteSet; typedef OrderedSet DPTItemSet; typedef OrderedMap DPImToCPtSetMap; - typedef OrderedMap DPMToCVarMap; - typedef OrderedMap DPMToDPMMap; + typedef OrderedMap DPMToCVarMap; + typedef OrderedMap DPMToDPMMap; typedef OrderedMap LocToDPMVecMap; - typedef OrderedSet ConstSVFGEdgeSet; + typedef OrderedSet ConstSVFGEdgeSet; typedef SVFGEdge::SVFGEdgeSetTy SVFGEdgeSet; typedef OrderedMap StoreToPMSetMap; - ///Constructor - DDAVFSolver(): outOfBudgetQuery(false),_pag(nullptr),_svfg(nullptr),_ander(nullptr),_callGraph(nullptr), _callGraphSCC(nullptr), _svfgSCC(nullptr), ddaStat(nullptr) + /// Constructor + DDAVFSolver() + : outOfBudgetQuery(false), _pag(nullptr), _svfg(nullptr), _ander(nullptr), _callGraph(nullptr), + _callGraphSCC(nullptr), _svfgSCC(nullptr), ddaStat(nullptr) { } /// Destructor virtual ~DDAVFSolver() { - if(_ander != nullptr) + if (_ander != nullptr) { // AndersenWaveDiff::releaseAndersenWaveDiff(); _ander = nullptr; @@ -80,8 +82,7 @@ class DDAVFSolver _svfg = nullptr; } - if (_svfgSCC != nullptr) - delete _svfgSCC; + if (_svfgSCC != nullptr) delete _svfgSCC; _svfgSCC = nullptr; _callGraph = nullptr; @@ -95,7 +96,7 @@ class DDAVFSolver /// Given CVar and location (SVFGNode) return a new DPItem virtual inline DPIm getDPIm(const CVar& var, const SVFGNode* loc) const { - DPIm dpm(var,loc); + DPIm dpm(var, loc); return dpm; } /// Union pts @@ -128,7 +129,7 @@ class DDAVFSolver inline void dumpCPtSet(const CPtSet& cpts) const { SVFUtil::outs() << "{"; - for(typename CPtSet::iterator it = cpts.begin(), eit = cpts.end(); it!=eit; ++it) + for (typename CPtSet::iterator it = cpts.begin(), eit = cpts.end(); it != eit; ++it) { SVFUtil::outs() << (*it) << " "; } @@ -138,7 +139,7 @@ class DDAVFSolver virtual const CPtSet& findPT(const DPIm& dpm) { - if(isbkVisited(dpm)) + if (isbkVisited(dpm)) { const CPtSet& cpts = getCachedPointsTo(dpm); DBOUT(DDDA, SVFUtil::outs() << "\t already backward visited dpm: "); @@ -153,7 +154,7 @@ class DDAVFSolver markbkVisited(dpm); addDpmToLoc(dpm); - if(testOutOfBudget(dpm) == false) + if (testOutOfBudget(dpm) == false) { CPtSet pts; @@ -173,79 +174,77 @@ class DDAVFSolver resolveFunPtr(dpm); const SVFGNode* node = dpm.getLoc(); - if(SVFUtil::isa(node)) + if (SVFUtil::isa(node)) { - handleAddr(pts,dpm,SVFUtil::cast(node)); + handleAddr(pts, dpm, SVFUtil::cast(node)); } - else if (SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - backtraceAlongDirectVF(pts,dpm); + backtraceAlongDirectVF(pts, dpm); } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { CPtSet gepPts; - backtraceAlongDirectVF(gepPts,dpm); - unionDDAPts(pts, processGepPts(SVFUtil::cast(node),gepPts)); + backtraceAlongDirectVF(gepPts, dpm); + unionDDAPts(pts, processGepPts(SVFUtil::cast(node), gepPts)); } - else if(const LoadSVFGNode* load = SVFUtil::dyn_cast(node)) + else if (const LoadSVFGNode* load = SVFUtil::dyn_cast(node)) { - if(load->getPAGDstNode()->isPointer() == false) - return; + if (load->getPAGDstNode()->isPointer() == false) return; CPtSet loadpts; - startNewPTCompFromLoadSrc(loadpts,dpm); - for(typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it) + startNewPTCompFromLoadSrc(loadpts, dpm); + for (typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it != eit; ++it) { - backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,load)); + backtraceAlongIndirectVF(pts, getDPImWithOldCond(dpm, *it, load)); } } - else if(const StoreSVFGNode* store = SVFUtil::dyn_cast(node)) + else if (const StoreSVFGNode* store = SVFUtil::dyn_cast(node)) { - if(store->getPAGSrcNode()->isPointer() == false) - return; + if (store->getPAGSrcNode()->isPointer() == false) return; - if(isMustAlias(getLoadDpm(dpm),dpm)) + if (isMustAlias(getLoadDpm(dpm), dpm)) { DBOUT(DDDA, SVFUtil::outs() << "+++must alias for load and store:"); DBOUT(DDDA, getLoadDpm(dpm).dump()); DBOUT(DDDA, dpm.dump()); DBOUT(DDDA, SVFUtil::outs() << "+++\n"); DOSTAT(ddaStat->_NumOfMustAliases++); - backtraceToStoreSrc(pts,dpm); + backtraceToStoreSrc(pts, dpm); } else { CPtSet storepts; - startNewPTCompFromStoreDst(storepts,dpm); - for(typename CPtSet::iterator it = storepts.begin(), eit = storepts.end(); it!=eit; ++it) + startNewPTCompFromStoreDst(storepts, dpm); + for (typename CPtSet::iterator it = storepts.begin(), eit = storepts.end(); it != eit; ++it) { - if(propagateViaObj(*it,getLoadCVar(dpm))) + if (propagateViaObj(*it, getLoadCVar(dpm))) { - backtraceToStoreSrc(pts,getDPImWithOldCond(dpm,*it,store)); + backtraceToStoreSrc(pts, getDPImWithOldCond(dpm, *it, store)); - if(isStrongUpdate(storepts,store)) + if (isStrongUpdate(storepts, store)) { - DBOUT(DDDA, SVFUtil::outs() << "backward strong update for obj " << dpm.getCurNodeID() << "\n"); - DOSTAT(addSUStat(dpm,store);) + DBOUT(DDDA, SVFUtil::outs() + << "backward strong update for obj " << dpm.getCurNodeID() << "\n"); + DOSTAT(addSUStat(dpm, store);) } else { - DOSTAT(rmSUStat(dpm,store);) - backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,store)); + DOSTAT(rmSUStat(dpm, store);) + backtraceAlongIndirectVF(pts, getDPImWithOldCond(dpm, *it, store)); } } else { - backtraceAlongIndirectVF(pts,dpm); + backtraceAlongIndirectVF(pts, dpm); } } } } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - backtraceAlongIndirectVF(pts,dpm); + backtraceAlongIndirectVF(pts, dpm); } else assert(false && "unexpected kind of SVFG nodes"); @@ -256,20 +255,19 @@ class DDAVFSolver { /// re-compute due to indirect calls SVFGEdgeSet newIndirectEdges; - if(_pag->isFunPtr(dpm.getCurNodeID())) + if (_pag->isFunPtr(dpm.getCurNodeID())) { const CallSiteSet& csSet = _pag->getIndCallSites(dpm.getCurNodeID()); - for(CallSiteSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it) - updateCallGraphAndSVFG(dpm, (*it),newIndirectEdges); + for (CallSiteSet::const_iterator it = csSet.begin(), eit = csSet.end(); it != eit; ++it) + updateCallGraphAndSVFG(dpm, (*it), newIndirectEdges); } /// callgraph scc detection for local variable in recursion - if(!newIndirectEdges.empty()) - _callGraphSCC->find(); - reComputeForEdges(dpm,newIndirectEdges,true); + if (!newIndirectEdges.empty()) _callGraphSCC->find(); + reComputeForEdges(dpm, newIndirectEdges, true); /// re-compute for transitive closures SVFGEdgeSet edgeSet(dpm.getLoc()->getOutEdges()); - reComputeForEdges(dpm,edgeSet,false); + reComputeForEdges(dpm, edgeSet, false); } /// Traverse along out edges to find all nodes which may be affected by locDPM. @@ -281,17 +279,17 @@ class DDAVFSolver const SVFGNode* dst = edge->getDstNode(); typename LocToDPMVecMap::const_iterator locIt = getLocToDPMVecMap().find(dst->getId()); /// Only collect nodes we have traversed - if (locIt == getLocToDPMVecMap().end()) - continue; + if (locIt == getLocToDPMVecMap().end()) continue; DPTItemSet dpmSet(locIt->second.begin(), locIt->second.end()); - for(typename DPTItemSet::const_iterator it = dpmSet.begin(),eit = dpmSet.end(); it!=eit; ++it) + for (typename DPTItemSet::const_iterator it = dpmSet.begin(), eit = dpmSet.end(); it != eit; ++it) { const DPIm& dstDpm = *it; - if(!indirectCall && SVFUtil::isa(edge) && !SVFUtil::isa(edge->getDstNode())) + if (!indirectCall && SVFUtil::isa(edge) && + !SVFUtil::isa(edge->getDstNode())) { - if(dstDpm.getCurNodeID() == dpm.getCurNodeID()) + if (dstDpm.getCurNodeID() == dpm.getCurNodeID()) { - DBOUT(DDDA,SVFUtil::outs() << "\t Recompute, forward from :"); + DBOUT(DDDA, SVFUtil::outs() << "\t Recompute, forward from :"); DBOUT(DDDA, dpm.dump()); DOSTAT(ddaStat->_NumOfStepInCycle++); clearbkVisited(dstDpm); @@ -300,10 +298,9 @@ class DDAVFSolver } else { - if(indirectCall) - DBOUT(DDDA,SVFUtil::outs() << "\t Recompute for indirect call from :"); + if (indirectCall) DBOUT(DDDA, SVFUtil::outs() << "\t Recompute for indirect call from :"); else - DBOUT(DDDA,SVFUtil::outs() << "\t Recompute forward from :"); + DBOUT(DDDA, SVFUtil::outs() << "\t Recompute forward from :"); DBOUT(DDDA, dpm.dump()); DOSTAT(ddaStat->_NumOfStepInCycle++); clearbkVisited(dstDpm); @@ -323,8 +320,7 @@ class DDAVFSolver /// Reset visited map for next points-to query virtual inline void resetQuery() { - if(outOfBudgetQuery) - OOBResetVisited(); + if (outOfBudgetQuery) OOBResetVisited(); locToDpmSetMap.clear(); dpmToloadDpmMap.clear(); @@ -335,12 +331,12 @@ class DDAVFSolver /// Reset visited map if the current query is out-of-budget inline void OOBResetVisited() { - for(typename LocToDPMVecMap::const_iterator it = locToDpmSetMap.begin(),eit = locToDpmSetMap.end(); it!=eit; ++it) + for (typename LocToDPMVecMap::const_iterator it = locToDpmSetMap.begin(), eit = locToDpmSetMap.end(); it != eit; + ++it) { DPTItemSet dpmSet(it->second.begin(), it->second.end()); - for(typename DPTItemSet::const_iterator dit = dpmSet.begin(),deit=dpmSet.end(); dit!=deit; ++dit) - if(isOutOfBudgetDpm(*dit)==false) - clearbkVisited(*dit); + for (typename DPTItemSet::const_iterator dit = dpmSet.begin(), deit = dpmSet.end(); dit != deit; ++dit) + if (isOutOfBudgetDpm(*dit) == false) clearbkVisited(*dit); } } /// GetDefinition SVFG @@ -353,19 +349,18 @@ class DDAVFSolver { const SVFGNode* node = oldDpm.getLoc(); NodeID obj = oldDpm.getCurNodeID(); - if (_pag->isConstantObj(obj)) - return; + if (_pag->isConstantObj(obj)) return; const SVFGEdgeSet edgeSet(node->getInEdges()); for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it) { - if(const IndirectSVFGEdge* indirEdge = SVFUtil::dyn_cast(*it)) + if (const IndirectSVFGEdge* indirEdge = SVFUtil::dyn_cast(*it)) { const NodeBS& guard = indirEdge->getPointsTo(); - if(guard.test(obj)) + if (guard.test(obj)) { - DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace indirectVF svfgNode " << - indirEdge->getDstID() << " --> " << indirEdge->getSrcID() << "\n"); - backwardPropDpm(pts,oldDpm.getCurNodeID(),oldDpm,indirEdge); + DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace indirectVF svfgNode " << indirEdge->getDstID() + << " --> " << indirEdge->getSrcID() << "\n"); + backwardPropDpm(pts, oldDpm.getCurNodeID(), oldDpm, indirEdge); } } } @@ -377,12 +372,12 @@ class DDAVFSolver const SVFGEdgeSet edgeSet(node->getInEdges()); for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it) { - if(const DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast(*it)) + if (const DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast(*it)) { - DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace directVF svfgNode " << - dirEdge->getDstID() << " --> " << dirEdge->getSrcID() << "\n"); + DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace directVF svfgNode " << dirEdge->getDstID() << " --> " + << dirEdge->getSrcID() << "\n"); const SVFGNode* srcNode = dirEdge->getSrcNode(); - backwardPropDpm(pts,getSVFG()->getLHSTopLevPtr(srcNode)->getId(),oldDpm,dirEdge); + backwardPropDpm(pts, getSVFG()->getLHSTopLevPtr(srcNode)->getId(), oldDpm, dirEdge); } } } @@ -393,57 +388,56 @@ class DDAVFSolver { const LoadSVFGNode* load = SVFUtil::cast(oldDpm.getLoc()); const SVFGNode* loadSrc = getDefSVFGNode(load->getPAGSrcNode()); - DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from loadSrc svfgNode " << - load->getId() << " --> " << loadSrc->getId() << "\n"); - const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(loadSrc,load,SVFGEdge::IntraDirectVF); + DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from loadSrc svfgNode " << load->getId() << " --> " + << loadSrc->getId() << "\n"); + const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(loadSrc, load, SVFGEdge::IntraDirectVF); assert(edge && "Edge not found!!"); - backwardPropDpm(pts,load->getPAGSrcNodeID(),oldDpm,edge); - + backwardPropDpm(pts, load->getPAGSrcNodeID(), oldDpm, edge); } inline void startNewPTCompFromStoreDst(CPtSet& pts, const DPIm& oldDpm) { const StoreSVFGNode* store = SVFUtil::cast(oldDpm.getLoc()); const SVFGNode* storeDst = getDefSVFGNode(store->getPAGDstNode()); - DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from storeDst svfgNode " << - store->getId() << " --> " << storeDst->getId() << "\n"); - const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(storeDst,store,SVFGEdge::IntraDirectVF); + DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from storeDst svfgNode " << store->getId() << " --> " + << storeDst->getId() << "\n"); + const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(storeDst, store, SVFGEdge::IntraDirectVF); assert(edge && "Edge not found!!"); - backwardPropDpm(pts,store->getPAGDstNodeID(),oldDpm,edge); + backwardPropDpm(pts, store->getPAGDstNodeID(), oldDpm, edge); } inline void backtraceToStoreSrc(CPtSet& pts, const DPIm& oldDpm) { const StoreSVFGNode* store = SVFUtil::cast(oldDpm.getLoc()); const SVFGNode* storeSrc = getDefSVFGNode(store->getPAGSrcNode()); - DBOUT(DDDA, SVFUtil::outs() << "++backtrace to storeSrc from svfgNode " << getLoadDpm(oldDpm).getLoc()->getId() << " to "<< - store->getId() << " to " << storeSrc->getId() <<"\n"); - const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(storeSrc,store,SVFGEdge::IntraDirectVF); + DBOUT(DDDA, SVFUtil::outs() << "++backtrace to storeSrc from svfgNode " << getLoadDpm(oldDpm).getLoc()->getId() + << " to " << store->getId() << " to " << storeSrc->getId() << "\n"); + const SVFGEdge* edge = getSVFG()->getIntraVFGEdge(storeSrc, store, SVFGEdge::IntraDirectVF); assert(edge && "Edge not found!!"); - backwardPropDpm(pts,store->getPAGSrcNodeID(),oldDpm,edge); + backwardPropDpm(pts, store->getPAGSrcNodeID(), oldDpm, edge); } //@} /// dpm transit during backward tracing - virtual void backwardPropDpm(CPtSet& pts, NodeID ptr,const DPIm& oldDpm,const SVFGEdge* edge) + virtual void backwardPropDpm(CPtSet& pts, NodeID ptr, const DPIm& oldDpm, const SVFGEdge* edge) { DPIm dpm(oldDpm); - dpm.setLocVar(edge->getSrcNode(),ptr); + dpm.setLocVar(edge->getSrcNode(), ptr); DOTIMESTAT(double start = DDAStat::getClk(true)); /// handle context-/path- sensitivity - if(handleBKCondition(dpm,edge)==false) + if (handleBKCondition(dpm, edge) == false) { DOTIMESTAT(ddaStat->_TotalTimeOfBKCondition += DDAStat::getClk(true) - start); - DBOUT(DDDA, SVFUtil::outs() << "\t!!! infeasible path svfgNode: " << edge->getDstID() << " --| " << edge->getSrcID() << "\n"); + DBOUT(DDDA, SVFUtil::outs() << "\t!!! infeasible path svfgNode: " << edge->getDstID() << " --| " + << edge->getSrcID() << "\n"); DOSTAT(ddaStat->_NumOfInfeasiblePath++); return; } /// record the source of load dpm - if(SVFUtil::isa(edge)) - addLoadDpmAndCVar(dpm,getLoadDpm(oldDpm),getLoadCVar(oldDpm)); + if (SVFUtil::isa(edge)) addLoadDpmAndCVar(dpm, getLoadDpm(oldDpm), getLoadCVar(oldDpm)); DOSTAT(ddaStat->_NumOfDPM++); /// handle out of budget case - unionDDAPts(pts,findPT(dpm)); + unionDDAPts(pts, findPT(dpm)); } /// whether load and store are aliased virtual bool isMustAlias(const DPIm&, const DPIm&) @@ -459,8 +453,8 @@ class DDAVFSolver typename CPtSet::iterator it = dstCPSet.begin(); const CVar& var = *it; // Strong update can be made if this points-to target is not heap, array or field-insensitive. - if (!isHeapCondMemObj(var,store) && !isArrayCondMemObj(var) - && !isFieldInsenCondMemObj(var) && !isLocalCVarInRecursion(var)) + if (!isHeapCondMemObj(var, store) && !isArrayCondMemObj(var) && !isFieldInsenCondMemObj(var) && + !isLocalCVarInRecursion(var)) { return true; } @@ -473,9 +467,9 @@ class DDAVFSolver NodeID id = getPtrNodeID(var); const MemObj* obj = _pag->getObject(id); assert(obj && "object not found!!"); - if(obj->isStack()) + if (obj->isStack()) { - if(const SVFFunction* svffun = _pag->getGNode(id)->getFunction()) + if (const SVFFunction* svffun = _pag->getGNode(id)->getFunction()) { return _callGraphSCC->isInCycle(_callGraph->getCallGraphNode(svffun)->getId()); } @@ -491,26 +485,26 @@ class DDAVFSolver /// resolve function pointer void resolveFunPtr(const DPIm& dpm) { - if(const CallICFGNode* cbn= getSVFG()->isCallSiteRetSVFGNode(dpm.getLoc())) + if (const CallICFGNode* cbn = getSVFG()->isCallSiteRetSVFGNode(dpm.getLoc())) { - if(_pag->isIndirectCallSites(cbn)) + if (_pag->isIndirectCallSites(cbn)) { NodeID funPtr = _pag->getFunPtr(cbn); DPIm funPtrDpm(dpm); - funPtrDpm.setLocVar(getSVFG()->getDefSVFGNode(_pag->getGNode(funPtr)),funPtr); + funPtrDpm.setLocVar(getSVFG()->getDefSVFGNode(_pag->getGNode(funPtr)), funPtr); findPT(funPtrDpm); } } - else if(const SVFFunction* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc())) + else if (const SVFFunction* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc())) { CallInstSet csSet; /// use pre-analysis call graph to approximate all potential callsites - _ander->getCallGraph()->getIndCallSitesInvokingCallee(fun,csSet); - for(CallInstSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it) + _ander->getCallGraph()->getIndCallSitesInvokingCallee(fun, csSet); + for (CallInstSet::const_iterator it = csSet.begin(), eit = csSet.end(); it != eit; ++it) { NodeID funPtr = _pag->getFunPtr(*it); DPIm funPtrDpm(dpm); - funPtrDpm.setLocVar(getSVFG()->getDefSVFGNode(_pag->getGNode(funPtr)),funPtr); + funPtrDpm.setLocVar(getSVFG()->getDefSVFGNode(_pag->getGNode(funPtr)), funPtr); findPT(funPtrDpm); } } @@ -522,7 +516,7 @@ class DDAVFSolver /// ProcessGep node to generate field object nodes of a struct virtual CPtSet processGepPts(const GepSVFGNode* gep, const CPtSet& srcPts) = 0; /// Handle AddrSVFGNode to add proper points-to - virtual void handleAddr(CPtSet& pts,const DPIm& dpm,const AddrSVFGNode* addr) = 0; + virtual void handleAddr(CPtSet& pts, const DPIm& dpm, const AddrSVFGNode* addr) = 0; /// Get conservative points-to results when the query is out of budget virtual CPtSet getConservativeCPts(const DPIm& dpm) = 0; /// Handle condition for context or path analysis (backward analysis) @@ -534,7 +528,7 @@ class DDAVFSolver virtual inline void updateCallGraphAndSVFG(const DPIm&, const CallICFGNode*, SVFGEdgeSet&) {} //@} - ///Visited flags to avoid cycles + /// Visited flags to avoid cycles //@{ inline void markbkVisited(const DPIm& dpm) { @@ -542,11 +536,11 @@ class DDAVFSolver } inline bool isbkVisited(const DPIm& dpm) { - return backwardVisited.find(dpm)!=backwardVisited.end(); + return backwardVisited.find(dpm) != backwardVisited.end(); } inline void clearbkVisited(const DPIm& dpm) { - assert(backwardVisited.find(dpm)!=backwardVisited.end() && "dpm not found!"); + assert(backwardVisited.find(dpm) != backwardVisited.end() && "dpm not found!"); backwardVisited.erase(dpm); } //@} @@ -555,8 +549,7 @@ class DDAVFSolver //@{ virtual inline const CPtSet& getCachedPointsTo(const DPIm& dpm) { - if (isTopLevelPtrStmt(dpm.getLoc())) - return getCachedTLPointsTo(dpm); + if (isTopLevelPtrStmt(dpm.getLoc())) return getCachedTLPointsTo(dpm); else return getCachedADPointsTo(dpm); } @@ -585,16 +578,14 @@ class DDAVFSolver return !SVFUtil::isa(stmt); } /// Return dpm with old context and path conditions - virtual inline DPIm getDPImWithOldCond(const DPIm& oldDpm,const CVar& var, const SVFGNode* loc) + virtual inline DPIm getDPImWithOldCond(const DPIm& oldDpm, const CVar& var, const SVFGNode* loc) { DPIm dpm(oldDpm); - dpm.setLocVar(loc,getPtrNodeID(var)); + dpm.setLocVar(loc, getPtrNodeID(var)); - if(SVFUtil::isa(loc)) - addLoadDpmAndCVar(dpm,getLoadDpm(oldDpm),var); + if (SVFUtil::isa(loc)) addLoadDpmAndCVar(dpm, getLoadDpm(oldDpm), var); - if(SVFUtil::isa(loc)) - addLoadDpmAndCVar(dpm,oldDpm,var); + if (SVFUtil::isa(loc)) addLoadDpmAndCVar(dpm, oldDpm, var); DOSTAT(ddaStat->_NumOfDPM++); return dpm; @@ -602,7 +593,7 @@ class DDAVFSolver /// SVFG SCC detection inline void SVFGSCCDetection() { - if(_svfgSCC==nullptr) + if (_svfgSCC == nullptr) { _svfgSCC = new SVFGSCC(getSVFG()); } @@ -624,12 +615,12 @@ class DDAVFSolver return (getSVFGSCCRepNode(edge->getSrcID()) == getSVFGSCCRepNode(edge->getDstID())); } /// Set callgraph - inline void setCallGraph (CallGraph* cg) + inline void setCallGraph(CallGraph* cg) { _callGraph = cg; } /// Set callgraphSCC - inline void setCallGraphSCC (CallGraphSCC* scc) + inline void setCallGraphSCC(CallGraphSCC* scc) { _callGraphSCC = scc; } @@ -650,7 +641,7 @@ class DDAVFSolver } inline bool isFieldInsenCondMemObj(const CVar& var) const { - const MemObj* mem = _pag->getBaseObj(getPtrNodeID(var)); + const MemObj* mem = _pag->getBaseObj(getPtrNodeID(var)); return mem->isFieldInsensitive(); } //@} @@ -678,38 +669,36 @@ class DDAVFSolver protected: /// LoadDpm for must-alias analysis //@{ - inline void addLoadDpmAndCVar(const DPIm& dpm,const DPIm& loadDpm,const CVar& loadVar) + inline void addLoadDpmAndCVar(const DPIm& dpm, const DPIm& loadDpm, const CVar& loadVar) { - addLoadCVar(dpm,loadVar); - addLoadDpm(dpm,loadDpm); + addLoadCVar(dpm, loadVar); + addLoadDpm(dpm, loadDpm); } /// Note that simply use "dpmToloadDpmMap[dpm]=loadDpm", requires DPIm have a default constructor - inline void addLoadDpm(const DPIm& dpm,const DPIm& loadDpm) + inline void addLoadDpm(const DPIm& dpm, const DPIm& loadDpm) { typename DPMToDPMMap::iterator it = dpmToloadDpmMap.find(dpm); - if(it!=dpmToloadDpmMap.end()) - it->second = loadDpm; + if (it != dpmToloadDpmMap.end()) it->second = loadDpm; else - dpmToloadDpmMap.insert(std::make_pair(dpm,loadDpm)); + dpmToloadDpmMap.insert(std::make_pair(dpm, loadDpm)); } inline const DPIm& getLoadDpm(const DPIm& dpm) const { typename DPMToDPMMap::const_iterator it = dpmToloadDpmMap.find(dpm); - assert(it!=dpmToloadDpmMap.end() && "not found??"); + assert(it != dpmToloadDpmMap.end() && "not found??"); return it->second; } inline void addLoadCVar(const DPIm& dpm, const CVar& loadVar) { typename DPMToCVarMap::iterator it = loadToPTCVarMap.find(dpm); - if(it!=loadToPTCVarMap.end()) - it->second = loadVar; + if (it != loadToPTCVarMap.end()) it->second = loadVar; else - loadToPTCVarMap.insert(std::make_pair(dpm,loadVar)); + loadToPTCVarMap.insert(std::make_pair(dpm, loadVar)); } inline const CVar& getLoadCVar(const DPIm& dpm) const { typename DPMToCVarMap::const_iterator it = loadToPTCVarMap.find(dpm); - assert(it!=loadToPTCVarMap.end() && "not found??"); + assert(it != loadToPTCVarMap.end() && "not found??"); return it->second; } //@} @@ -724,9 +713,8 @@ class DDAVFSolver inline void handleOutOfBudgetDpm(const DPIm& dpm) {} inline bool testOutOfBudget(const DPIm& dpm) { - if(outOfBudgetQuery) return true; - if(++ddaStat->_NumOfStep > DPIm::getMaxBudget()) - outOfBudgetQuery = true; + if (outOfBudgetQuery) return true; + if (++ddaStat->_NumOfStep > DPIm::getMaxBudget()) outOfBudgetQuery = true; return isOutOfBudgetDpm(dpm) || outOfBudgetQuery; } inline bool isOutOfBudgetQuery() const @@ -765,29 +753,28 @@ class DDAVFSolver if (dpmSet.erase(dpm)) { ddaStat->_NumOfStrongUpdates--; - if(dpmSet.empty()) - ddaStat->_StrongUpdateStores.reset(node->getId()); + if (dpmSet.empty()) ddaStat->_StrongUpdateStores.reset(node->getId()); } } - bool outOfBudgetQuery; ///< Whether the current query is out of step limits - SVFIR* _pag; ///< SVFIR - SVFG* _svfg; ///< SVFG - AndersenWaveDiff* _ander; ///< Andersen's analysis - NodeBS candidateQueries; ///< candidate pointers; - CallGraph* _callGraph; ///< CallGraph - CallGraphSCC* _callGraphSCC; ///< SCC for CallGraph - SVFGSCC* _svfgSCC; ///< SCC for SVFG - DPTItemSet backwardVisited; ///< visited map during backward traversing - DPImToCPtSetMap dpmToTLCPtSetMap; ///< points-to caching map for top-level vars - DPImToCPtSetMap dpmToADCPtSetMap; ///< points-to caching map for address-taken vars - LocToDPMVecMap locToDpmSetMap; ///< map location to its dpms - DPMToDPMMap dpmToloadDpmMap; ///< dpms at loads for may/must-alias analysis with stores - DPMToCVarMap loadToPTCVarMap; ///< map a load dpm to its cvar pointed by its pointer operand - DPTItemSet outOfBudgetDpms; ///< out of budget dpm set - StoreToPMSetMap storeToDPMs; ///< map store to set of DPM which have been stong updated there - DDAStat* ddaStat; ///< DDA stat - SVFGBuilder svfgBuilder; ///< SVFG Builder + bool outOfBudgetQuery; ///< Whether the current query is out of step limits + SVFIR* _pag; ///< SVFIR + SVFG* _svfg; ///< SVFG + AndersenWaveDiff* _ander; ///< Andersen's analysis + NodeBS candidateQueries; ///< candidate pointers; + CallGraph* _callGraph; ///< CallGraph + CallGraphSCC* _callGraphSCC; ///< SCC for CallGraph + SVFGSCC* _svfgSCC; ///< SCC for SVFG + DPTItemSet backwardVisited; ///< visited map during backward traversing + DPImToCPtSetMap dpmToTLCPtSetMap; ///< points-to caching map for top-level vars + DPImToCPtSetMap dpmToADCPtSetMap; ///< points-to caching map for address-taken vars + LocToDPMVecMap locToDpmSetMap; ///< map location to its dpms + DPMToDPMMap dpmToloadDpmMap; ///< dpms at loads for may/must-alias analysis with stores + DPMToCVarMap loadToPTCVarMap; ///< map a load dpm to its cvar pointed by its pointer operand + DPTItemSet outOfBudgetDpms; ///< out of budget dpm set + StoreToPMSetMap storeToDPMs; ///< map store to set of DPM which have been stong updated there + DDAStat* ddaStat; ///< DDA stat + SVFGBuilder svfgBuilder; ///< SVFG Builder }; } // End namespace SVF diff --git a/svf/include/DDA/FlowDDA.h b/svf/include/DDA/FlowDDA.h index ed4d30441..3a7ef4575 100644 --- a/svf/include/DDA/FlowDDA.h +++ b/svf/include/DDA/FlowDDA.h @@ -50,23 +50,20 @@ typedef StmtDPItem LocDPItem; /*! * Flow sensitive demand-driven analysis on value-flow graph */ -class FlowDDA : public BVDataPTAImpl, public DDAVFSolver +class FlowDDA : public BVDataPTAImpl, public DDAVFSolver { public: typedef BVDataPTAImpl::CallSiteSet CallSiteSet; - typedef BVDataPTAImpl::CallEdgeMap CallEdgeMap; - typedef BVDataPTAImpl::FunctionSet FunctionSet; + typedef BVDataPTAImpl::CallEdgeMap CallEdgeMap; + typedef BVDataPTAImpl::FunctionSet FunctionSet; /// Constructor - FlowDDA(SVFIR* _pag, DDAClient* client): BVDataPTAImpl(_pag, PointerAnalysis::FlowS_DDA), - DDAVFSolver(), - _client(client) + FlowDDA(SVFIR* _pag, DDAClient* client) + : BVDataPTAImpl(_pag, PointerAnalysis::FlowS_DDA), DDAVFSolver(), _client(client) { } /// Destructor - inline virtual ~FlowDDA() - { - } + inline virtual ~FlowDDA() {} /// dummy analyze method virtual void analyze() override {} @@ -116,14 +113,13 @@ class FlowDDA : public BVDataPTAImpl, public DDAVFSolvergetPAGSrcNodeID(); /// whether this object is set field-insensitive during pre-analysis - if (isFieldInsensitive(srcID)) - srcID = getFIObjVar(srcID); + if (isFieldInsensitive(srcID)) srcID = getFIObjVar(srcID); - addDDAPts(pts,srcID); + addDDAPts(pts, srcID); DBOUT(DDDA, SVFUtil::outs() << "\t add points-to target " << srcID << " to dpm "); DBOUT(DDDA, dpm.dump()); } @@ -132,14 +128,14 @@ class FlowDDA : public BVDataPTAImpl, public DDAVFSolverfirst; - const FunctionSet & functions = iter->second; + const FunctionSet& functions = iter->second; for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { const SVFFunction* func = *func_iter; @@ -161,7 +157,8 @@ class FlowDDA : public BVDataPTAImpl, public DDAVFSolver GenericCDGEdgeTy; class CDGEdge : public GenericCDGEdgeTy { public: - typedef std::pair BranchCondition; + typedef std::pair BranchCondition; /// Constructor - CDGEdge(CDGNode *s, CDGNode *d) : GenericCDGEdgeTy(s, d, 0) - { - } + CDGEdge(CDGNode* s, CDGNode* d) : GenericCDGEdgeTy(s, d, 0) {} /// Destructor - ~CDGEdge() - { - } + ~CDGEdge() {} typedef GenericNode::GEdgeSetTy CDGEdgeSetTy; typedef CDGEdgeSetTy SVFGEdgeSetTy; @@ -61,25 +57,25 @@ class CDGEdge : public GenericCDGEdgeTy { std::string str; std::stringstream rawstr(str); - rawstr << "CDGEdge " << " ["; + rawstr << "CDGEdge " + << " ["; rawstr << getDstID() << "<--" << getSrcID() << "\t"; return rawstr.str(); } /// get/set branch condition //{@ - const Set &getBranchConditions() const + const Set& getBranchConditions() const { return brConditions; } - void insertBranchCondition(const SVFValue *pNode, s32_t branchID) + void insertBranchCondition(const SVFValue* pNode, s32_t branchID) { brConditions.insert(std::make_pair(pNode, branchID)); } //@} - private: Set brConditions; }; @@ -90,16 +86,12 @@ class CDGNode : public GenericCDGNodeTy { public: - typedef CDGEdge::CDGEdgeSetTy::iterator iterator; typedef CDGEdge::CDGEdgeSetTy::const_iterator const_iterator; public: /// Constructor - CDGNode(const ICFGNode *icfgNode) : GenericCDGNodeTy(icfgNode->getId(), 0), _icfgNode(icfgNode) - { - - } + CDGNode(const ICFGNode* icfgNode) : GenericCDGNodeTy(icfgNode->getId(), 0), _icfgNode(icfgNode) {} virtual const std::string toString() const { @@ -109,14 +101,13 @@ class CDGNode : public GenericCDGNodeTy return rawstr.str(); } - const ICFGNode *getICFGNode() const + const ICFGNode* getICFGNode() const { return _icfgNode; } - private: - const ICFGNode *_icfgNode; + const ICFGNode* _icfgNode; }; typedef std::vector> NodePairVector; @@ -126,27 +117,22 @@ class CDG : public GenericCDGTy { public: - - typedef Map CDGNodeIDToNodeMapTy; + typedef Map CDGNodeIDToNodeMapTy; typedef CDGEdge::CDGEdgeSetTy CDGEdgeSetTy; typedef CDGNodeIDToNodeMapTy::iterator iterator; typedef CDGNodeIDToNodeMapTy::const_iterator const_iterator; - typedef std::vector ICFGNodeVector; - typedef std::vector> ICFGNodePairVector; + typedef std::vector ICFGNodeVector; + typedef std::vector> ICFGNodePairVector; private: - static CDG *controlDg; ///< Singleton pattern here + static CDG* controlDg; ///< Singleton pattern here /// Constructor - CDG() - { - - } - + CDG() {} public: /// Singleton design here to make sure we only have one instance during any analysis //@{ - static inline CDG * getCDG() + static inline CDG* getCDG() { if (controlDg == nullptr) { @@ -157,8 +143,7 @@ class CDG : public GenericCDGTy static void releaseCDG() { - if (controlDg) - delete controlDg; + if (controlDg) delete controlDg; controlDg = nullptr; } //@} @@ -167,10 +152,9 @@ class CDG : public GenericCDGTy virtual ~CDG() {} /// Get a CDG node - inline CDGNode *getCDGNode(NodeID id) const + inline CDGNode* getCDGNode(NodeID id) const { - if (!hasCDGNode(id)) - return nullptr; + if (!hasCDGNode(id)) return nullptr; return getGNode(id); } @@ -181,11 +165,11 @@ class CDG : public GenericCDGTy } /// Whether we has a CDG edge - bool hasCDGEdge(CDGNode *src, CDGNode *dst) + bool hasCDGEdge(CDGNode* src, CDGNode* dst) { CDGEdge edge(src, dst); - CDGEdge *outEdge = src->hasOutgoingEdge(&edge); - CDGEdge *inEdge = dst->hasIncomingEdge(&edge); + CDGEdge* outEdge = src->hasOutgoingEdge(&edge); + CDGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) { assert(outEdge == inEdge && "edges not match"); @@ -196,12 +180,11 @@ class CDG : public GenericCDGTy } /// Get a control dependence edge according to src and dst - CDGEdge *getCDGEdge(const CDGNode *src, const CDGNode *dst) + CDGEdge* getCDGEdge(const CDGNode* src, const CDGNode* dst) { - CDGEdge *edge = nullptr; + CDGEdge* edge = nullptr; size_t counter = 0; - for (CDGEdge::CDGEdgeSetTy::iterator iter = src->OutEdgeBegin(); - iter != src->OutEdgeEnd(); ++iter) + for (CDGEdge::CDGEdgeSetTy::iterator iter = src->OutEdgeBegin(); iter != src->OutEdgeEnd(); ++iter) { if ((*iter)->getDstID() == dst->getId()) { @@ -220,14 +203,14 @@ class CDG : public GenericCDGTy } /// Dump graph into dot file - void dump(const std::string &filename) + void dump(const std::string& filename) { GraphPrinter::WriteGraphToFile(SVFUtil::outs(), filename, this); } public: /// Remove a control dependence edge - inline void removeCDGEdge(CDGEdge *edge) + inline void removeCDGEdge(CDGEdge* edge) { edge->getDstNode()->removeIncomingEdge(edge); edge->getSrcNode()->removeOutgoingEdge(edge); @@ -235,14 +218,12 @@ class CDG : public GenericCDGTy } /// Remove a CDGNode - inline void removeCDGNode(CDGNode *node) + inline void removeCDGNode(CDGNode* node) { - std::set temp; - for (CDGEdge *e: node->getInEdges()) - temp.insert(e); - for (CDGEdge *e: node->getOutEdges()) - temp.insert(e); - for (CDGEdge *e: temp) + std::set temp; + for (CDGEdge* e : node->getInEdges()) temp.insert(e); + for (CDGEdge* e : node->getOutEdges()) temp.insert(e); + for (CDGEdge* e : temp) { removeCDGEdge(e); } @@ -261,7 +242,7 @@ class CDG : public GenericCDGTy } /// Add CDG edge - inline bool addCDGEdge(CDGEdge *edge) + inline bool addCDGEdge(CDGEdge* edge) { bool added1 = edge->getDstNode()->addIncomingEdge(edge); bool added2 = edge->getSrcNode()->addOutgoingEdge(edge); @@ -270,7 +251,7 @@ class CDG : public GenericCDGTy } /// Add a CDG node - virtual inline void addCDGNode(CDGNode *node) + virtual inline void addCDGNode(CDGNode* node) { addGNode(node->getId(), node); } @@ -278,7 +259,7 @@ class CDG : public GenericCDGTy /// Add CDG nodes from nodeid vector inline void addCDGNodesFromVector(ICFGNodeVector nodes) { - for (const ICFGNode *icfgNode: nodes) + for (const ICFGNode* icfgNode : nodes) { if (!IDToNodeMap.count(icfgNode->getId())) { @@ -288,8 +269,7 @@ class CDG : public GenericCDGTy } /// Add CDG edges from nodeid pair - void addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const SVFValue *pNode, s32_t branchID); - + void addCDGEdgeFromSrcDst(const ICFGNode* src, const ICFGNode* dst, const SVFValue* pNode, s32_t branchID); }; } // end namespace SVF @@ -299,59 +279,53 @@ namespace SVF * GenericGraphTraits specializations for generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph ICFGTraversals. */ -template<> -struct GenericGraphTraits - : public GenericGraphTraits *> +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse ICFGTraversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits< - Inverse *> > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> -struct GenericGraphTraits - : public GenericGraphTraits *> +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::CDGNode *NodeRef; + typedef SVF::CDGNode* NodeRef; }; -template<> -struct DOTGraphTraits : public DOTGraphTraits +template <> struct DOTGraphTraits : public DOTGraphTraits { typedef SVF::CDGNode NodeType; - DOTGraphTraits(bool isSimple = false) : - DOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DOTGraphTraits(isSimple) {} /// Return name of the graph - static std::string getGraphName(SVF::CDG *) + static std::string getGraphName(SVF::CDG*) { return "Control Dependence Graph"; } - std::string getNodeLabel(NodeType *node, SVF::CDG *graph) + std::string getNodeLabel(NodeType* node, SVF::CDG* graph) { return getSimpleNodeLabel(node, graph); } /// Return the label of an ICFG node - static std::string getSimpleNodeLabel(NodeType *node, SVF::CDG *) + static std::string getSimpleNodeLabel(NodeType* node, SVF::CDG*) { std::string str; std::stringstream rawstr(str); rawstr << "NodeID: " << node->getId() << "\n"; - const SVF::ICFGNode *icfgNode = node->getICFGNode(); - if (const SVF::IntraICFGNode *bNode = SVF::SVFUtil::dyn_cast(icfgNode)) + const SVF::ICFGNode* icfgNode = node->getICFGNode(); + if (const SVF::IntraICFGNode* bNode = SVF::SVFUtil::dyn_cast(icfgNode)) { rawstr << "IntraBlockNode ID: " << bNode->getId() << " \t"; - SVF::PAG::SVFStmtList &edges = SVF::PAG::getPAG()->getPTASVFStmtList(bNode); + SVF::PAG::SVFStmtList& edges = SVF::PAG::getPAG()->getPTASVFStmtList(bNode); if (edges.empty()) { rawstr << bNode->getInst()->toString() << " \t"; @@ -360,34 +334,34 @@ struct DOTGraphTraits : public DOTGraphTraits { for (SVF::PAG::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it) { - const SVF::PAGEdge *edge = *it; + const SVF::PAGEdge* edge = *it; rawstr << edge->toString(); } } rawstr << " {fun: " << bNode->getFun()->getName() << "}"; } - else if (const SVF::FunEntryICFGNode *entry = SVF::SVFUtil::dyn_cast(icfgNode)) + else if (const SVF::FunEntryICFGNode* entry = SVF::SVFUtil::dyn_cast(icfgNode)) { rawstr << entry->toString(); } - else if (const SVF::FunExitICFGNode *exit = SVF::SVFUtil::dyn_cast(icfgNode)) + else if (const SVF::FunExitICFGNode* exit = SVF::SVFUtil::dyn_cast(icfgNode)) { rawstr << exit->toString(); } - else if (const SVF::CallICFGNode *call = SVF::SVFUtil::dyn_cast(icfgNode)) + else if (const SVF::CallICFGNode* call = SVF::SVFUtil::dyn_cast(icfgNode)) { rawstr << call->toString(); } - else if (const SVF::RetICFGNode *ret = SVF::SVFUtil::dyn_cast(icfgNode)) + else if (const SVF::RetICFGNode* ret = SVF::SVFUtil::dyn_cast(icfgNode)) { rawstr << ret->toString(); } - else if (const SVF::GlobalICFGNode *glob = SVF::SVFUtil::dyn_cast(icfgNode)) + else if (const SVF::GlobalICFGNode* glob = SVF::SVFUtil::dyn_cast(icfgNode)) { - SVF::PAG::SVFStmtList &edges = SVF::PAG::getPAG()->getPTASVFStmtList(glob); + SVF::PAG::SVFStmtList& edges = SVF::PAG::getPAG()->getPTASVFStmtList(glob); for (SVF::PAG::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it) { - const SVF::PAGEdge *edge = *it; + const SVF::PAGEdge* edge = *it; rawstr << edge->toString(); } } @@ -397,11 +371,11 @@ struct DOTGraphTraits : public DOTGraphTraits return rawstr.str(); } - static std::string getNodeAttributes(NodeType *node, SVF::CDG *) + static std::string getNodeAttributes(NodeType* node, SVF::CDG*) { std::string str; std::stringstream rawstr(str); - const SVF::ICFGNode *icfgNode = node->getICFGNode(); + const SVF::ICFGNode* icfgNode = node->getICFGNode(); if (SVF::SVFUtil::isa(icfgNode)) { @@ -435,22 +409,20 @@ struct DOTGraphTraits : public DOTGraphTraits return rawstr.str(); } - template - static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CDG *) + template static std::string getEdgeAttributes(NodeType*, EdgeIter EI, SVF::CDG*) { assert(*(EI.getCurrent()) && "No edge found!!"); return "style=solid"; } - template - static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) { - SVF::CDGEdge *edge = *(EI.getCurrent()); + SVF::CDGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); std::string str; std::stringstream rawstr(str); - for (const auto &cond: edge->getBranchConditions()) + for (const auto& cond : edge->getBranchConditions()) { rawstr << std::to_string(cond.second) << "|"; } @@ -462,4 +434,4 @@ struct DOTGraphTraits : public DOTGraphTraits }; } // End namespace SVF -#endif //SVF_CONTROLDG_H \ No newline at end of file +#endif // SVF_CONTROLDG_H \ No newline at end of file diff --git a/svf/include/Graphs/CFLGraph.h b/svf/include/Graphs/CFLGraph.h index a0468ca08..3d8dc4ddd 100644 --- a/svf/include/Graphs/CFLGraph.h +++ b/svf/include/Graphs/CFLGraph.h @@ -44,15 +44,12 @@ class CFLNode; typedef GenericEdge GenericCFLEdgeTy; -class CFLEdge: public GenericCFLEdgeTy +class CFLEdge : public GenericCFLEdgeTy { public: typedef GenericNode::GEdgeSetTy CFLEdgeSetTy; - CFLEdge(CFLNode *s, CFLNode *d, GEdgeFlag k = 0): - GenericCFLEdgeTy(s,d,k) - { - } + CFLEdge(CFLNode* s, CFLNode* d, GEdgeFlag k = 0) : GenericCFLEdgeTy(s, d, k) {} ~CFLEdge() override = default; inline GEdgeKind getEdgeKind() const @@ -71,20 +68,16 @@ class CFLEdge: public GenericCFLEdgeTy } }; - -typedef GenericNode GenericCFLNodeTy; -class CFLNode: public GenericCFLNodeTy +typedef GenericNode GenericCFLNodeTy; +class CFLNode : public GenericCFLNodeTy { public: - CFLNode (NodeID i = 0, GNodeK k = 0): - GenericCFLNodeTy(i, k) - { - } + CFLNode(NodeID i = 0, GNodeK k = 0) : GenericCFLNodeTy(i, k) {} ~CFLNode() override = default; /// Different Kind(label) associated edges set - typedef std::map CFLEdgeDataTy; + typedef std::map CFLEdgeDataTy; private: CFLEdgeDataTy inCFLEdges; @@ -151,13 +144,13 @@ class CFLNode: public GenericCFLNodeTy }; /// Edge-labeled graph for CFL Reachability analysis -typedef GenericGraph GenericCFLGraphTy; -class CFLGraph: public GenericCFLGraphTy +typedef GenericGraph GenericCFLGraphTy; +class CFLGraph : public GenericCFLGraphTy { public: typedef CFGrammar::Symbol Symbol; typedef CFGrammar::Kind Kind; - typedef GenericNode::GEdgeSetTy CFLEdgeSet; + typedef GenericNode::GEdgeSetTy CFLEdgeSet; Kind startKind; CFLGraph(Kind kind) @@ -187,7 +180,7 @@ class CFLGraph: public GenericCFLGraphTy CFLEdgeSet cflEdgeSet; }; -} +} // namespace SVF namespace SVF { @@ -195,21 +188,24 @@ namespace SVF * GenericGraphTraits specializations for generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::CFLNode *NodeRef; + typedef SVF::CFLNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* CFLG_H_ */ \ No newline at end of file diff --git a/svf/include/Graphs/CHG.h b/svf/include/Graphs/CHG.h index 3a9ba2b5b..f0705083e 100644 --- a/svf/include/Graphs/CHG.h +++ b/svf/include/Graphs/CHG.h @@ -50,7 +50,7 @@ typedef Set VFunSet; class CommonCHGraph { public: - virtual ~CommonCHGraph() { }; + virtual ~CommonCHGraph(){}; enum CHGKind { Standard, @@ -58,11 +58,10 @@ class CommonCHGraph }; virtual bool csHasVFnsBasedonCHA(CallSite cs) = 0; - virtual const VFunSet &getCSVFsBasedonCHA(CallSite cs) = 0; + virtual const VFunSet& getCSVFsBasedonCHA(CallSite cs) = 0; virtual bool csHasVtblsBasedonCHA(CallSite cs) = 0; - virtual const VTableSet &getCSVtblsBasedonCHA(CallSite cs) = 0; - virtual void getVFnsFromVtbls(CallSite cs, const VTableSet& vtbls, - VFunSet& virtualFunctions) = 0; + virtual const VTableSet& getCSVtblsBasedonCHA(CallSite cs) = 0; + virtual void getVFnsFromVtbls(CallSite cs, const VTableSet& vtbls, VFunSet& virtualFunctions) = 0; CHGKind getKind(void) const { @@ -73,9 +72,8 @@ class CommonCHGraph CHGKind kind; }; - typedef GenericEdge GenericCHEdgeTy; -class CHEdge: public GenericCHEdgeTy +class CHEdge : public GenericCHEdgeTy { friend class SVFIRWriter; friend class SVFIRReader; @@ -89,8 +87,7 @@ class CHEdge: public GenericCHEdgeTy typedef GenericNode::GEdgeSetTy CHEdgeSetTy; - CHEdge(CHNode* s, CHNode* d, CHEDGETYPE et, GEdgeFlag k = 0) - : GenericCHEdgeTy(s, d, k) + CHEdge(CHNode* s, CHNode* d, CHEDGETYPE et, GEdgeFlag k = 0) : GenericCHEdgeTy(s, d, k) { edgeType = et; } @@ -105,7 +102,7 @@ class CHEdge: public GenericCHEdgeTy }; typedef GenericNode GenericCHNodeTy; -class CHNode: public GenericCHNodeTy +class CHNode : public GenericCHNodeTy { friend class SVFIRWriter; friend class SVFIRReader; @@ -113,20 +110,18 @@ class CHNode: public GenericCHNodeTy public: typedef enum { - PURE_ABSTRACT = 0x1, // pure virtual abstract class + PURE_ABSTRACT = 0x1, // pure virtual abstract class MULTI_INHERITANCE = 0x2, // multi inheritance class - TEMPLATE = 0x04 // template class + TEMPLATE = 0x04 // template class } CLASSATTR; typedef std::vector FuncVector; - CHNode (const std::string& name, NodeID i = 0, GNodeK k = 0): - GenericCHNodeTy(i, k), vtable(nullptr), className(name), flags(0) - { - } - ~CHNode() + CHNode(const std::string& name, NodeID i = 0, GNodeK k = 0) + : GenericCHNodeTy(i, k), vtable(nullptr), className(name), flags(0) { } + ~CHNode() {} std::string getName() const { return className; @@ -175,18 +170,18 @@ class CHNode: public GenericCHNodeTy { virtualFunctionVectors.push_back(vfuncvec); } - const std::vector &getVirtualFunctionVectors() const + const std::vector& getVirtualFunctionVectors() const { return virtualFunctionVectors; } - void getVirtualFunctions(u32_t idx, FuncVector &virtualFunctions) const; + void getVirtualFunctions(u32_t idx, FuncVector& virtualFunctions) const; - const SVFGlobalValue *getVTable() const + const SVFGlobalValue* getVTable() const { return vtable; } - void setVTable(const SVFGlobalValue *vtbl) + void setVTable(const SVFGlobalValue* vtbl) { vtable = vtbl; } @@ -212,7 +207,7 @@ class CHNode: public GenericCHNodeTy /// class hierarchy graph typedef GenericGraph GenericCHGraphTy; -class CHGraph: public CommonCHGraph, public GenericCHGraphTy +class CHGraph : public CommonCHGraph, public GenericCHGraphTy { friend class SVFIRWriter; friend class SVFIRReader; @@ -229,59 +224,51 @@ class CHGraph: public CommonCHGraph, public GenericCHGraphTy typedef enum { CONSTRUCTOR = 0x1, // connect node based on constructor - DESTRUCTOR = 0x2 // connect node based on destructor + DESTRUCTOR = 0x2 // connect node based on destructor } RELATIONTYPE; - CHGraph(SVFModule* svfModule): svfMod(svfModule), classNum(0), vfID(0), buildingCHGTime(0) + CHGraph(SVFModule* svfModule) : svfMod(svfModule), classNum(0), vfID(0), buildingCHGTime(0) { this->kind = Standard; } ~CHGraph() override = default; - void addEdge(const std::string className, - const std::string baseClassName, - CHEdge::CHEDGETYPE edgeType); - CHNode *getNode(const std::string name) const; - void getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override; + void addEdge(const std::string className, const std::string baseClassName, CHEdge::CHEDGETYPE edgeType); + CHNode* getNode(const std::string name) const; + void getVFnsFromVtbls(CallSite cs, const VTableSet& vtbls, VFunSet& virtualFunctions) override; void dump(const std::string& filename); void view(); void printCH(); inline u32_t getVirtualFunctionID(const SVFFunction* vfn) const { - Map::const_iterator it = - virtualFunctionToIDMap.find(vfn); - if (it != virtualFunctionToIDMap.end()) - return it->second; + Map::const_iterator it = virtualFunctionToIDMap.find(vfn); + if (it != virtualFunctionToIDMap.end()) return it->second; else return -1; } inline const SVFFunction* getVirtualFunctionBasedonID(u32_t id) const { Map::const_iterator it, eit; - for (it = virtualFunctionToIDMap.begin(), eit = - virtualFunctionToIDMap.end(); it != eit; ++it) + for (it = virtualFunctionToIDMap.begin(), eit = virtualFunctionToIDMap.end(); it != eit; ++it) { - if (it->second == id) - return it->first; + if (it->second == id) return it->first; } return nullptr; } inline void addInstances(const std::string templateName, CHNode* node) { - NameToCHNodesMap::iterator it = templateNameToInstancesMap.find( - templateName); - if (it != templateNameToInstancesMap.end()) - it->second.insert(node); + NameToCHNodesMap::iterator it = templateNameToInstancesMap.find(templateName); + if (it != templateNameToInstancesMap.end()) it->second.insert(node); else templateNameToInstancesMap[templateName].insert(node); } - inline const CHNodeSetTy &getDescendants(const std::string className) + inline const CHNodeSetTy& getDescendants(const std::string className) { return classNameToDescendantsMap[className]; } - inline const CHNodeSetTy &getInstances(const std::string className) + inline const CHNodeSetTy& getInstances(const std::string className) { return templateNameToInstancesMap[className]; } @@ -296,25 +283,24 @@ class CHGraph: public CommonCHGraph, public GenericCHGraphTy CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs); return it != csToCHAVFnsMap.end(); } - inline const VTableSet &getCSVtblsBasedonCHA(CallSite cs) override + inline const VTableSet& getCSVtblsBasedonCHA(CallSite cs) override { CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs); assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA."); return it->second; } - inline const VFunSet &getCSVFsBasedonCHA(CallSite cs) override + inline const VFunSet& getCSVFsBasedonCHA(CallSite cs) override { CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs); assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA."); return it->second; } - static inline bool classof(const CommonCHGraph *chg) + static inline bool classof(const CommonCHGraph* chg) { return chg->getKind() == Standard; } - private: SVFModule* svfMod; u32_t classNum; @@ -341,8 +327,7 @@ namespace SVF * Provide graph traits for traversing from a constraint node using standard graph traversals. */ template <> -struct GenericGraphTraits - : public GenericGraphTraits*> +struct GenericGraphTraits : public GenericGraphTraits*> { }; @@ -350,18 +335,16 @@ struct GenericGraphTraits /// for inverse traversal. template <> struct GenericGraphTraits> - : public GenericGraphTraits< - Inverse*>> + : public GenericGraphTraits*>> { }; template <> -struct GenericGraphTraits - : public GenericGraphTraits*> +struct GenericGraphTraits : public GenericGraphTraits*> { typedef SVF::CHNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* CHA_H_ */ diff --git a/svf/include/Graphs/CallGraph.h b/svf/include/Graphs/CallGraph.h index 65ee61e0a..414265e06 100644 --- a/svf/include/Graphs/CallGraph.h +++ b/svf/include/Graphs/CallGraph.h @@ -41,7 +41,6 @@ namespace SVF class CallGraphNode; class SVFModule; - /* * Call Graph edge representing a calling relation between two functions * Multiple calls from function A to B are merged into one call edge @@ -55,24 +54,25 @@ class CallGraphEdge : public GenericCallGraphEdgeTy typedef Set CallInstSet; enum CEDGEK { - CallRetEdge,TDForkEdge,TDJoinEdge,HareParForEdge + CallRetEdge, + TDForkEdge, + TDJoinEdge, + HareParForEdge }; - private: CallInstSet directCalls; CallInstSet indirectCalls; CallSiteID csId; + public: /// Constructor - CallGraphEdge(CallGraphNode* s, CallGraphNode* d, CEDGEK kind, CallSiteID cs) : - GenericCallGraphEdgeTy(s, d, makeEdgeFlagWithInvokeID(kind, cs)), csId(cs) + CallGraphEdge(CallGraphNode* s, CallGraphNode* d, CEDGEK kind, CallSiteID cs) + : GenericCallGraphEdgeTy(s, d, makeEdgeFlagWithInvokeID(kind, cs)), csId(cs) { } /// Destructor - virtual ~CallGraphEdge() - { - } + virtual ~CallGraphEdge() {} /// Compute the unique edgeFlag value from edge kind and CallSiteID. static inline GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs) { @@ -144,17 +144,16 @@ class CallGraphEdge : public GenericCallGraphEdgeTy { return true; } - static inline bool classof(const GenericCallGraphEdgeTy *edge) + static inline bool classof(const GenericCallGraphEdgeTy* edge) { - return edge->getEdgeKind() == CallGraphEdge::CallRetEdge || - edge->getEdgeKind() == CallGraphEdge::TDForkEdge || + return edge->getEdgeKind() == CallGraphEdge::CallRetEdge || edge->getEdgeKind() == CallGraphEdge::TDForkEdge || edge->getEdgeKind() == CallGraphEdge::TDJoinEdge; } //@} /// Overloading operator << for dumping ICFG node ID //@{ - friend OutStream& operator<< (OutStream &o, const CallGraphEdge &edge) + friend OutStream& operator<<(OutStream& o, const CallGraphEdge& edge) { o << edge.toString(); return o; @@ -163,14 +162,13 @@ class CallGraphEdge : public GenericCallGraphEdgeTy virtual const std::string toString() const; - typedef GenericNode::GEdgeSetTy CallGraphEdgeSet; - + typedef GenericNode::GEdgeSetTy CallGraphEdgeSet; }; /* * Call Graph node representing a function */ -typedef GenericNode GenericCallGraphNodeTy; +typedef GenericNode GenericCallGraphNodeTy; class CallGraphNode : public GenericCallGraphNodeTy { @@ -184,10 +182,7 @@ class CallGraphNode : public GenericCallGraphNodeTy public: /// Constructor - CallGraphNode(NodeID i, const SVFFunction* f) : GenericCallGraphNodeTy(i,0), fun(f) - { - - } + CallGraphNode(NodeID i, const SVFFunction* f) : GenericCallGraphNodeTy(i, 0), fun(f) {} /// Get function of this call node inline const SVFFunction* getFunction() const @@ -198,10 +193,9 @@ class CallGraphNode : public GenericCallGraphNodeTy /// Return TRUE if this function can be reached from main. bool isReachableFromProgEntry() const; - /// Overloading operator << for dumping ICFG node ID //@{ - friend OutStream& operator<< (OutStream &o, const CallGraphNode &node) + friend OutStream& operator<<(OutStream& o, const CallGraphNode& node) { o << node.toString(); return o; @@ -214,13 +208,13 @@ class CallGraphNode : public GenericCallGraphNodeTy /*! * Pointer Analysis Call Graph used internally for various pointer analysis */ -typedef GenericGraph GenericCallGraphTy; +typedef GenericGraph GenericCallGraphTy; class CallGraph : public GenericCallGraphTy { public: typedef CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; - typedef Map FunToCallGraphNodeMap; + typedef Map FunToCallGraphNodeMap; typedef Map CallInstToCallGraphEdgesMap; typedef std::pair CallSitePair; typedef Map CallSiteToIdMap; @@ -232,7 +226,8 @@ class CallGraph : public GenericCallGraphTy enum CGEK { - NormCallGraph, ThdCallGraph + NormCallGraph, + ThdCallGraph }; private: @@ -242,12 +237,12 @@ class CallGraph : public GenericCallGraphTy CallEdgeMap indirectCallMap; /// Call site information - static CallSiteToIdMap csToIdMap; ///< Map a pair of call instruction and callee to a callsite ID - static IdToCallSiteMap idToCSMap; ///< Map a callsite ID to a pair of call instruction and callee - static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1; + static CallSiteToIdMap csToIdMap; ///< Map a pair of call instruction and callee to a callsite ID + static IdToCallSiteMap idToCSMap; ///< Map a callsite ID to a pair of call instruction and callee + static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1; protected: - FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map + FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges NodeID callGraphNodeNum; @@ -288,7 +283,7 @@ class CallGraph : public GenericCallGraphTy inline const FunctionSet& getIndCSCallees(const CallICFGNode* cs) const { CallEdgeMap::const_iterator it = indirectCallMap.find(cs); - assert(it!=indirectCallMap.end() && "not an indirect callsite!"); + assert(it != indirectCallMap.end() && "not an indirect callsite!"); return it->second; } //@} @@ -319,7 +314,7 @@ class CallGraph : public GenericCallGraphTy inline CallGraphNode* getCallGraphNode(const SVFFunction* fun) const { FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun); - assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!"); + assert(it != funToCallGraphNodeMap.end() && "call graph node not found!!"); return it->second; } @@ -331,8 +326,8 @@ class CallGraph : public GenericCallGraphTy { std::pair newCS(std::make_pair(cs, callee)); CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); - //assert(it == csToIdMap.end() && "cannot add a callsite twice"); - if(it == csToIdMap.end()) + // assert(it == csToIdMap.end() && "cannot add a callsite twice"); + if (it == csToIdMap.end()) { CallSiteID id = totalCallSiteNum++; csToIdMap.insert(std::make_pair(newCS, id)); @@ -345,7 +340,8 @@ class CallGraph : public GenericCallGraphTy { CallSitePair newCS(std::make_pair(cs, callee)); CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); - assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit"); + assert(it != csToIdMap.end() && + "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit"); return it->second; } inline bool hasCallSiteID(const CallICFGNode* cs, const SVFFunction* callee) const @@ -374,17 +370,17 @@ class CallGraph : public GenericCallGraphTy } //@} /// Whether we have already created this call graph edge - CallGraphEdge* hasGraphEdge(CallGraphNode* src, CallGraphNode* dst,CallGraphEdge::CEDGEK kind, CallSiteID csId) const; + CallGraphEdge* hasGraphEdge(CallGraphNode* src, CallGraphNode* dst, CallGraphEdge::CEDGEK kind, + CallSiteID csId) const; /// Get call graph edge via nodes - CallGraphEdge* getGraphEdge(CallGraphNode* src, CallGraphNode* dst,CallGraphEdge::CEDGEK kind, CallSiteID csId); + CallGraphEdge* getGraphEdge(CallGraphNode* src, CallGraphNode* dst, CallGraphEdge::CEDGEK kind, CallSiteID csId); /// Get all callees for a callsite inline void getCallees(const CallICFGNode* cs, FunctionSet& callees) { - if(hasCallGraphEdge(cs)) + if (hasCallGraphEdge(cs)) { - for (CallGraphEdgeSet::const_iterator it = getCallEdgeBegin(cs), eit = - getCallEdgeEnd(cs); it != eit; ++it) + for (CallGraphEdgeSet::const_iterator it = getCallEdgeBegin(cs), eit = getCallEdgeEnd(cs); it != eit; ++it) { callees.insert((*it)->getDstNode()->getFunction()); } @@ -396,20 +392,18 @@ class CallGraph : public GenericCallGraphTy /// whether this call instruction has a valid call graph edge inline bool hasCallGraphEdge(const CallICFGNode* inst) const { - return callinstToCallGraphEdgesMap.find(inst)!=callinstToCallGraphEdgesMap.end(); + return callinstToCallGraphEdgesMap.find(inst) != callinstToCallGraphEdgesMap.end(); } inline CallGraphEdgeSet::const_iterator getCallEdgeBegin(const CallICFGNode* inst) const { CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); - assert(it!=callinstToCallGraphEdgesMap.end() - && "call instruction does not have a valid callee"); + assert(it != callinstToCallGraphEdgesMap.end() && "call instruction does not have a valid callee"); return it->second.begin(); } inline CallGraphEdgeSet::const_iterator getCallEdgeEnd(const CallICFGNode* inst) const { CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); - assert(it!=callinstToCallGraphEdgesMap.end() - && "call instruction does not have a valid callee"); + assert(it != callinstToCallGraphEdgesMap.end() && "call instruction does not have a valid callee"); return it->second.end(); } //@} @@ -423,7 +417,7 @@ class CallGraph : public GenericCallGraphTy /// Add direct/indirect call edges //@{ void addDirectCallGraphEdge(const CallICFGNode* call, const SVFFunction* callerFun, const SVFFunction* calleeFun); - void addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun); + void addIndirectCallGraphEdge(const CallICFGNode* cs, const SVFFunction* callerFun, const SVFFunction* calleeFun); //@} /// Get callsites invoking the callee @@ -451,21 +445,26 @@ namespace SVF * GenericGraphTraits specializations for generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits + : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits + : public GenericGraphTraits*> { - typedef SVF::CallGraphNode *NodeRef; + typedef SVF::CallGraphNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* CALLGRAPH_H_ */ diff --git a/svf/include/Graphs/ConsG.h b/svf/include/Graphs/ConsG.h index 109d50af5..8643c1c99 100644 --- a/svf/include/Graphs/ConsG.h +++ b/svf/include/Graphs/ConsG.h @@ -41,11 +41,11 @@ namespace SVF * ConstraintNodes are same as PAGNodes * ConstraintEdges are self-defined edges (initialized with ConstraintEdges) */ -class ConstraintGraph : public GenericGraph +class ConstraintGraph : public GenericGraph { public: - typedef OrderedMap ConstraintNodeIDToNodeMapTy; + typedef OrderedMap ConstraintNodeIDToNodeMapTy; typedef ConstraintEdge::ConstraintEdgeSetTy::iterator ConstraintNodeIter; typedef Map NodeToRepMap; typedef Map NodeToSubsMap; @@ -67,7 +67,7 @@ class ConstraintGraph : public GenericGraph void destroy(); - void clearSolitaries(); // remove nodes that are neither pointers nor connected with any edge + void clearSolitaries(); // remove nodes that are neither pointers nor connected with any edge SVFStmt::SVFStmtSetTy& getPAGEdgeSet(SVFStmt::PEDGEK kind) { @@ -94,7 +94,7 @@ class ConstraintGraph : public GenericGraph public: /// Constructor - ConstraintGraph(SVFIR* p): pag(p), edgeIndex(0) + ConstraintGraph(SVFIR* p) : pag(p), edgeIndex(0) { buildCG(); } @@ -113,7 +113,7 @@ class ConstraintGraph : public GenericGraph } inline void addConstraintNode(ConstraintNode* node, NodeID id) { - addGNode(id,node); + addGNode(id, node); } inline bool hasConstraintNode(NodeID id) const { @@ -129,15 +129,14 @@ class ConstraintGraph : public GenericGraph //// Return true if this edge exits inline bool hasEdge(ConstraintNode* src, ConstraintNode* dst, ConstraintEdge::ConstraintEdgeK kind) { - ConstraintEdge edge(src,dst,kind); - if(kind == ConstraintEdge::Copy || - kind == ConstraintEdge::NormalGep || kind == ConstraintEdge::VariantGep) + ConstraintEdge edge(src, dst, kind); + if (kind == ConstraintEdge::Copy || kind == ConstraintEdge::NormalGep || kind == ConstraintEdge::VariantGep) return directEdgeSet.find(&edge) != directEdgeSet.end(); - else if(kind == ConstraintEdge::Addr) + else if (kind == ConstraintEdge::Addr) return AddrCGEdgeSet.find(&edge) != AddrCGEdgeSet.end(); - else if(kind == ConstraintEdge::Store) + else if (kind == ConstraintEdge::Store) return StoreCGEdgeSet.find(&edge) != StoreCGEdgeSet.end(); - else if(kind == ConstraintEdge::Load) + else if (kind == ConstraintEdge::Load) return LoadCGEdgeSet.find(&edge) != LoadCGEdgeSet.end(); else assert(false && "no other kind!"); @@ -147,23 +146,23 @@ class ConstraintGraph : public GenericGraph /// Get an edge via its src and dst nodes and kind inline ConstraintEdge* getEdge(ConstraintNode* src, ConstraintNode* dst, ConstraintEdge::ConstraintEdgeK kind) { - ConstraintEdge edge(src,dst,kind); - if(kind == ConstraintEdge::Copy || kind == ConstraintEdge::NormalGep || kind == ConstraintEdge::VariantGep) + ConstraintEdge edge(src, dst, kind); + if (kind == ConstraintEdge::Copy || kind == ConstraintEdge::NormalGep || kind == ConstraintEdge::VariantGep) { auto eit = directEdgeSet.find(&edge); return *eit; } - else if(kind == ConstraintEdge::Addr) + else if (kind == ConstraintEdge::Addr) { auto eit = AddrCGEdgeSet.find(&edge); return *eit; } - else if(kind == ConstraintEdge::Store) + else if (kind == ConstraintEdge::Store) { auto eit = StoreCGEdgeSet.find(&edge); return *eit; } - else if(kind == ConstraintEdge::Load) + else if (kind == ConstraintEdge::Load) { auto eit = LoadCGEdgeSet.find(&edge); return *eit; @@ -175,7 +174,7 @@ class ConstraintGraph : public GenericGraph } } - ///Add a SVFIR edge into Edge map + /// Add a SVFIR edge into Edge map //@{ /// Add Address edge AddrCGEdge* addAddrCGEdge(NodeID src, NodeID dst); @@ -190,7 +189,7 @@ class ConstraintGraph : public GenericGraph StoreCGEdge* addStoreCGEdge(NodeID src, NodeID dst); //@} - ///Get SVFIR edge + /// Get SVFIR edge //@{ /// Get Address edges inline ConstraintEdge::ConstraintEdgeSetTy& getAddrCGEdges() @@ -235,8 +234,7 @@ class ConstraintGraph : public GenericGraph inline NodeID sccRepNode(NodeID id) const { NodeToRepMap::const_iterator it = nodeToRepMap.find(id); - if(it==nodeToRepMap.end()) - return id; + if (it == nodeToRepMap.end()) return id; else return it->second; } @@ -274,16 +272,16 @@ class ConstraintGraph : public GenericGraph /// Move incoming direct edges of a sub node which is outside the SCC to its rep node /// Remove incoming direct edges of a sub node which is inside the SCC from its rep node /// Return TRUE if there's a gep edge inside this SCC (PWC). - bool moveInEdgesToRepNode(ConstraintNode*node, ConstraintNode* rep ); + bool moveInEdgesToRepNode(ConstraintNode* node, ConstraintNode* rep); /// Move outgoing direct edges of a sub node which is outside the SCC to its rep node /// Remove outgoing direct edges of sub node which is inside the SCC from its rep node /// Return TRUE if there's a gep edge inside this SCC (PWC). - bool moveOutEdgesToRepNode(ConstraintNode*node, ConstraintNode* rep ); + bool moveOutEdgesToRepNode(ConstraintNode* node, ConstraintNode* rep); /// Move incoming/outgoing direct edges of a sub node to its rep node /// Return TRUE if there's a gep edge inside this SCC (PWC). - inline bool moveEdgesToRepNode(ConstraintNode*node, ConstraintNode* rep ) + inline bool moveEdgesToRepNode(ConstraintNode* node, ConstraintNode* rep) { bool gepIn = moveInEdgesToRepNode(node, rep); bool gepOut = moveOutEdgesToRepNode(node, rep); @@ -291,11 +289,10 @@ class ConstraintGraph : public GenericGraph } /// Check if a given edge is a NormalGepCGEdge with 0 offset. - inline bool isZeroOffsettedGepCGEdge(ConstraintEdge *edge) const + inline bool isZeroOffsettedGepCGEdge(ConstraintEdge* edge) const { - if (NormalGepCGEdge *normalGepCGEdge = SVFUtil::dyn_cast(edge)) - if (0 == normalGepCGEdge->getConstantFieldIdx()) - return true; + if (NormalGepCGEdge* normalGepCGEdge = SVFUtil::dyn_cast(edge)) + if (0 == normalGepCGEdge->getConstantFieldIdx()) return true; return false; } @@ -329,10 +326,9 @@ class ConstraintGraph : public GenericGraph /// Get a field of a memory object inline NodeID getGepObjVar(NodeID id, const APOffset& apOffset) { - NodeID gep = pag->getGepObjVar(id, apOffset); + NodeID gep = pag->getGepObjVar(id, apOffset); /// Create a node when it is (1) not exist on graph and (2) not merged - if(sccRepNode(gep)==gep && hasConstraintNode(gep)==false) - addConstraintNode(new ConstraintNode(gep),gep); + if (sccRepNode(gep) == gep && hasConstraintNode(gep) == false) addConstraintNode(new ConstraintNode(gep), gep); return gep; } /// Get a field-insensitive node of a memory object @@ -382,24 +378,28 @@ class ConstraintGraph : public GenericGraph void view(); }; - /* ! * GenericGraphTraits specializations for the generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits + : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for Value flow node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits + : public GenericGraphTraits*> { - typedef SVF::ConstraintNode *NodeRef; + typedef SVF::ConstraintNode* NodeRef; }; } // End namespace SVF diff --git a/svf/include/Graphs/ConsGEdge.h b/svf/include/Graphs/ConsGEdge.h index 23db2abec..9a6262cb8 100644 --- a/svf/include/Graphs/ConsGEdge.h +++ b/svf/include/Graphs/ConsGEdge.h @@ -53,61 +53,61 @@ class ConstraintEdge : public GenericConsEdgeTy /// Gep edge is used for field sensitivity enum ConstraintEdgeK { - Addr, Copy, Store, Load, NormalGep, VariantGep + Addr, + Copy, + Store, + Load, + NormalGep, + VariantGep }; + private: EdgeID edgeId; + public: /// Constructor - ConstraintEdge(ConstraintNode* s, ConstraintNode* d, ConstraintEdgeK k, EdgeID id = 0) : GenericConsEdgeTy(s,d,k),edgeId(id) + ConstraintEdge(ConstraintNode* s, ConstraintNode* d, ConstraintEdgeK k, EdgeID id = 0) + : GenericConsEdgeTy(s, d, k), edgeId(id) { } /// Destructor - ~ConstraintEdge() - { - } + ~ConstraintEdge() {} /// Return edge ID inline EdgeID getEdgeID() const { return edgeId; } /// ClassOf - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { - return edge->getEdgeKind() == Addr || - edge->getEdgeKind() == Copy || - edge->getEdgeKind() == Store || - edge->getEdgeKind() == Load || - edge->getEdgeKind() == NormalGep || - edge->getEdgeKind() == VariantGep; + return edge->getEdgeKind() == Addr || edge->getEdgeKind() == Copy || edge->getEdgeKind() == Store || + edge->getEdgeKind() == Load || edge->getEdgeKind() == NormalGep || edge->getEdgeKind() == VariantGep; } /// Constraint edge type - typedef GenericNode::GEdgeSetTy ConstraintEdgeSetTy; - + typedef GenericNode::GEdgeSetTy ConstraintEdgeSetTy; }; - /*! * Copy edge */ -class AddrCGEdge: public ConstraintEdge +class AddrCGEdge : public ConstraintEdge { private: AddrCGEdge(); ///< place holder - AddrCGEdge(const AddrCGEdge &); ///< place holder - void operator=(const AddrCGEdge &); ///< place holder + AddrCGEdge(const AddrCGEdge&); ///< place holder + void operator=(const AddrCGEdge&); ///< place holder public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const AddrCGEdge *) + static inline bool classof(const AddrCGEdge*) { return true; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { return edge->getEdgeKind() == Addr; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { return edge->getEdgeKind() == Addr; } @@ -117,146 +117,128 @@ class AddrCGEdge: public ConstraintEdge AddrCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id); }; - /*! * Copy edge */ -class CopyCGEdge: public ConstraintEdge +class CopyCGEdge : public ConstraintEdge { private: CopyCGEdge(); ///< place holder - CopyCGEdge(const CopyCGEdge &); ///< place holder - void operator=(const CopyCGEdge &); ///< place holder + CopyCGEdge(const CopyCGEdge&); ///< place holder + void operator=(const CopyCGEdge&); ///< place holder public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CopyCGEdge *) + static inline bool classof(const CopyCGEdge*) { return true; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { return edge->getEdgeKind() == Copy; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { return edge->getEdgeKind() == Copy; } //@} /// constructor - CopyCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s,d,Copy,id) - { - } + CopyCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s, d, Copy, id) {} }; - /*! * Store edge */ -class StoreCGEdge: public ConstraintEdge +class StoreCGEdge : public ConstraintEdge { private: StoreCGEdge(); ///< place holder - StoreCGEdge(const StoreCGEdge &); ///< place holder - void operator=(const StoreCGEdge &); ///< place holder + StoreCGEdge(const StoreCGEdge&); ///< place holder + void operator=(const StoreCGEdge&); ///< place holder public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const StoreCGEdge *) + static inline bool classof(const StoreCGEdge*) { return true; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { return edge->getEdgeKind() == Store; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { return edge->getEdgeKind() == Store; } //@} /// constructor - StoreCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s,d,Store,id) - { - } + StoreCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s, d, Store, id) {} }; - /*! * Load edge */ -class LoadCGEdge: public ConstraintEdge +class LoadCGEdge : public ConstraintEdge { private: LoadCGEdge(); ///< place holder - LoadCGEdge(const LoadCGEdge &); ///< place holder - void operator=(const LoadCGEdge &); ///< place holder + LoadCGEdge(const LoadCGEdge&); ///< place holder + void operator=(const LoadCGEdge&); ///< place holder public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const LoadCGEdge *) + static inline bool classof(const LoadCGEdge*) { return true; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { return edge->getEdgeKind() == Load; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { return edge->getEdgeKind() == Load; } //@} /// Constructor - LoadCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s,d,Load,id) - { - } + LoadCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s, d, Load, id) {} }; - /*! * Gep edge */ -class GepCGEdge: public ConstraintEdge +class GepCGEdge : public ConstraintEdge { private: GepCGEdge(); ///< place holder - GepCGEdge(const GepCGEdge &); ///< place holder - void operator=(const GepCGEdge &); ///< place holder + GepCGEdge(const GepCGEdge&); ///< place holder + void operator=(const GepCGEdge&); ///< place holder protected: - /// Constructor - GepCGEdge(ConstraintNode* s, ConstraintNode* d, ConstraintEdgeK k, EdgeID id) - : ConstraintEdge(s,d,k,id) - { - - } + GepCGEdge(ConstraintNode* s, ConstraintNode* d, ConstraintEdgeK k, EdgeID id) : ConstraintEdge(s, d, k, id) {} public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const GepCGEdge *) + static inline bool classof(const GepCGEdge*) { return true; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { - return edge->getEdgeKind() == NormalGep || - edge->getEdgeKind() == VariantGep; + return edge->getEdgeKind() == NormalGep || edge->getEdgeKind() == VariantGep; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { - return edge->getEdgeKind() == NormalGep || - edge->getEdgeKind() == VariantGep; + return edge->getEdgeKind() == NormalGep || edge->getEdgeKind() == VariantGep; } //@} - }; /*! @@ -265,36 +247,35 @@ class GepCGEdge: public ConstraintEdge class NormalGepCGEdge : public GepCGEdge { private: - NormalGepCGEdge(); ///< place holder - NormalGepCGEdge(const NormalGepCGEdge &); ///< place holder - void operator=(const NormalGepCGEdge &); ///< place holder + NormalGepCGEdge(); ///< place holder + NormalGepCGEdge(const NormalGepCGEdge&); ///< place holder + void operator=(const NormalGepCGEdge&); ///< place holder - AccessPath ap; ///< Access path of the gep edge + AccessPath ap; ///< Access path of the gep edge public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const NormalGepCGEdge *) + static inline bool classof(const NormalGepCGEdge*) { return true; } - static inline bool classof(const GepCGEdge *edge) + static inline bool classof(const GepCGEdge* edge) { return edge->getEdgeKind() == NormalGep; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { return edge->getEdgeKind() == NormalGep; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { return edge->getEdgeKind() == NormalGep; } //@} /// Constructor - NormalGepCGEdge(ConstraintNode* s, ConstraintNode* d, const AccessPath& ap, - EdgeID id) + NormalGepCGEdge(ConstraintNode* s, ConstraintNode* d, const AccessPath& ap, EdgeID id) : GepCGEdge(s, d, NormalGep, id), ap(ap) { } @@ -310,7 +291,6 @@ class NormalGepCGEdge : public GepCGEdge { return ap.getConstantStructFldIdx(); } - }; /*! @@ -319,35 +299,33 @@ class NormalGepCGEdge : public GepCGEdge class VariantGepCGEdge : public GepCGEdge { private: - VariantGepCGEdge(); ///< place holder - VariantGepCGEdge(const VariantGepCGEdge &); ///< place holder - void operator=(const VariantGepCGEdge &); ///< place holder + VariantGepCGEdge(); ///< place holder + VariantGepCGEdge(const VariantGepCGEdge&); ///< place holder + void operator=(const VariantGepCGEdge&); ///< place holder public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const VariantGepCGEdge *) + static inline bool classof(const VariantGepCGEdge*) { return true; } - static inline bool classof(const GepCGEdge *edge) + static inline bool classof(const GepCGEdge* edge) { return edge->getEdgeKind() == VariantGep; } - static inline bool classof(const ConstraintEdge *edge) + static inline bool classof(const ConstraintEdge* edge) { return edge->getEdgeKind() == VariantGep; } - static inline bool classof(const GenericConsEdgeTy *edge) + static inline bool classof(const GenericConsEdgeTy* edge) { return edge->getEdgeKind() == VariantGep; } //@} /// Constructor - VariantGepCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) - : GepCGEdge(s,d,VariantGep,id) - {} + VariantGepCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : GepCGEdge(s, d, VariantGep, id) {} }; } // End namespace SVF diff --git a/svf/include/Graphs/ConsGNode.h b/svf/include/Graphs/ConsGNode.h index b6e2ee608..df0d6a737 100644 --- a/svf/include/Graphs/ConsGNode.h +++ b/svf/include/Graphs/ConsGNode.h @@ -36,7 +36,7 @@ namespace SVF /*! * Constraint node */ -typedef GenericNode GenericConsNodeTy; +typedef GenericNode GenericConsNodeTy; class ConstraintNode : public GenericConsNodeTy { @@ -46,10 +46,10 @@ class ConstraintNode : public GenericConsNodeTy bool _isPWCNode; private: - ConstraintEdge::ConstraintEdgeSetTy loadInEdges; ///< all incoming load edge of this node + ConstraintEdge::ConstraintEdgeSetTy loadInEdges; ///< all incoming load edge of this node ConstraintEdge::ConstraintEdgeSetTy loadOutEdges; ///< all outgoing load edge of this node - ConstraintEdge::ConstraintEdgeSetTy storeInEdges; ///< all incoming store edge of this node + ConstraintEdge::ConstraintEdgeSetTy storeInEdges; ///< all incoming store edge of this node ConstraintEdge::ConstraintEdgeSetTy storeOutEdges; ///< all outgoing store edge of this node /// Copy/call/ret/gep incoming edge of this node, @@ -63,7 +63,7 @@ class ConstraintNode : public GenericConsNodeTy ConstraintEdge::ConstraintEdgeSetTy gepInEdges; ConstraintEdge::ConstraintEdgeSetTy gepOutEdges; - ConstraintEdge::ConstraintEdgeSetTy addressInEdges; ///< all incoming address edge of this node + ConstraintEdge::ConstraintEdgeSetTy addressInEdges; ///< all incoming address edge of this node ConstraintEdge::ConstraintEdgeSetTy addressOutEdges; ///< all outgoing address edge of this node public: @@ -71,10 +71,7 @@ class ConstraintNode : public GenericConsNodeTy NodeBS strides; NodeBS baseIds; - ConstraintNode(NodeID i) : GenericConsNodeTy(i, 0), _isPWCNode(false) - { - - } + ConstraintNode(NodeID i) : GenericConsNodeTy(i, 0), _isPWCNode(false) {} /// Whether a node involves in PWC, if so, all its points-to elements should become field-insensitive. //@{ @@ -91,7 +88,8 @@ class ConstraintNode : public GenericConsNodeTy /// Direct and Indirect SVFIR edges inline bool isdirectEdge(ConstraintEdge::ConstraintEdgeK kind) { - return (kind == ConstraintEdge::Copy || kind == ConstraintEdge::NormalGep || kind == ConstraintEdge::VariantGep ); + return (kind == ConstraintEdge::Copy || kind == ConstraintEdge::NormalGep || + kind == ConstraintEdge::VariantGep); } inline bool isIndirectEdge(ConstraintEdge::ConstraintEdgeK kind) { @@ -224,7 +222,7 @@ class ConstraintNode : public GenericConsNodeTy /// Add constraint graph edges //@{ - inline void addIncomingCopyEdge(CopyCGEdge *inEdge) + inline void addIncomingCopyEdge(CopyCGEdge* inEdge) { addIncomingDirectEdge(inEdge); copyInEdges.insert(inEdge); @@ -234,7 +232,7 @@ class ConstraintNode : public GenericConsNodeTy addIncomingDirectEdge(inEdge); gepInEdges.insert(inEdge); } - inline void addOutgoingCopyEdge(CopyCGEdge *outEdge) + inline void addOutgoingCopyEdge(CopyCGEdge* outEdge) { addOutgoingDirectEdge(outEdge); copyOutEdges.insert(outEdge); @@ -322,8 +320,7 @@ class ConstraintNode : public GenericConsNodeTy inline bool removeOutgoingDirectEdge(ConstraintEdge* outEdge) { - if (SVFUtil::isa(outEdge)) - gepOutEdges.erase(outEdge); + if (SVFUtil::isa(outEdge)) gepOutEdges.erase(outEdge); else copyOutEdges.erase(outEdge); u32_t num1 = directOutEdges.erase(outEdge); @@ -335,8 +332,7 @@ class ConstraintNode : public GenericConsNodeTy inline bool removeIncomingDirectEdge(ConstraintEdge* inEdge) { - if (SVFUtil::isa(inEdge)) - gepInEdges.erase(inEdge); + if (SVFUtil::isa(inEdge)) gepInEdges.erase(inEdge); else copyInEdges.erase(inEdge); u32_t num1 = directInEdges.erase(inEdge); @@ -387,7 +383,7 @@ class ConstraintNode : public GenericConsNodeTy /// Overloading operator << for dumping node //@{ - friend OutStream &operator<<(OutStream &o, const ConstraintNode &node) + friend OutStream& operator<<(OutStream& o, const ConstraintNode& node) { o << node.toString(); return o; diff --git a/svf/include/Graphs/DOTGraphTraits.h b/svf/include/Graphs/DOTGraphTraits.h index 66fc33aaa..f22efea8f 100644 --- a/svf/include/Graphs/DOTGraphTraits.h +++ b/svf/include/Graphs/DOTGraphTraits.h @@ -38,13 +38,12 @@ struct DefaultDOTGraphTraits } public: - explicit DefaultDOTGraphTraits(bool simple=false) : IsSimple (simple) {} + explicit DefaultDOTGraphTraits(bool simple = false) : IsSimple(simple) {} /// getGraphName - Return the label for the graph as a whole. Printed at the /// top of the graph. /// - template - static std::string getGraphName(const GraphType &) + template static std::string getGraphName(const GraphType&) { return ""; } @@ -52,8 +51,7 @@ struct DefaultDOTGraphTraits /// getGraphProperties - Return any custom properties that should be included /// in the top level graph structure for dot. /// - template - static std::string getGraphProperties(const GraphType &) + template static std::string getGraphProperties(const GraphType&) { return ""; } @@ -68,16 +66,14 @@ struct DefaultDOTGraphTraits /// isNodeHidden - If the function returns true, the given node is not /// displayed in the graph. - template - static bool isNodeHidden(const void *, const GraphType &) + template static bool isNodeHidden(const void*, const GraphType&) { return false; } /// getNodeLabel - Given a node and a pointer to the top level graph, return /// the label to print in the node. - template - std::string getNodeLabel(const void *, const GraphType &) + template std::string getNodeLabel(const void*, const GraphType&) { return ""; } @@ -85,40 +81,34 @@ struct DefaultDOTGraphTraits // getNodeIdentifierLabel - Returns a string representing the // address or other unique identifier of the node. (Only used if // non-empty.) - template - static std::string getNodeIdentifierLabel(const void *, const GraphType &) + template static std::string getNodeIdentifierLabel(const void*, const GraphType&) { return ""; } - template - static std::string getNodeDescription(const void *, const GraphType &) + template static std::string getNodeDescription(const void*, const GraphType&) { return ""; } /// If you want to specify custom node attributes, this is the place to do so /// - template - static std::string getNodeAttributes(const void *, - const GraphType &) + template static std::string getNodeAttributes(const void*, const GraphType&) { return ""; } /// If you want to override the dot attributes printed for a particular edge, /// override this method. - template - static std::string getEdgeAttributes(const void *, EdgeIter, - const GraphType &) + template + static std::string getEdgeAttributes(const void*, EdgeIter, const GraphType&) { return ""; } /// getEdgeSourceLabel - If you want to label the edge source itself, /// implement this method. - template - static std::string getEdgeSourceLabel(const void *, EdgeIter) + template static std::string getEdgeSourceLabel(const void*, EdgeIter) { return ""; } @@ -126,8 +116,7 @@ struct DefaultDOTGraphTraits /// edgeTargetsEdgeSource - This method returns true if this outgoing edge /// should actually target another edge source, not a node. If this method is /// implemented, getEdgeTarget should be implemented. - template - static bool edgeTargetsEdgeSource(const void *, EdgeIter) + template static bool edgeTargetsEdgeSource(const void*, EdgeIter) { return false; } @@ -135,8 +124,7 @@ struct DefaultDOTGraphTraits /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is /// called to determine which outgoing edge of Node is the target of this /// edge. - template - static EdgeIter getEdgeTarget(const void *, EdgeIter I) + template static EdgeIter getEdgeTarget(const void*, EdgeIter I) { return I; } @@ -150,14 +138,14 @@ struct DefaultDOTGraphTraits /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the /// number of incoming edge labels the given node has. - static unsigned numEdgeDestLabels(const void *) + static unsigned numEdgeDestLabels(const void*) { return 0; } /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the /// incoming edge label with the given index in the given node. - static std::string getEdgeDestLabel(const void *, unsigned) + static std::string getEdgeDestLabel(const void*, unsigned) { return ""; } @@ -168,21 +156,21 @@ struct DefaultDOTGraphTraits /// GraphType is passed in as an argument. You may call arbitrary methods on /// it to add things to the output graph. /// - template - static void addCustomGraphFeatures(const GraphType &, GraphWriter &) {} + template + static void addCustomGraphFeatures(const GraphType&, GraphWriter&) + { + } }; - /// DOTGraphTraits - Template class that can be specialized to customize how /// graphs are converted to 'dot' graphs. When specializing, you may inherit /// from DefaultDOTGraphTraits if you don't need to override everything. /// -template -struct DOTGraphTraits : public DefaultDOTGraphTraits +template struct DOTGraphTraits : public DefaultDOTGraphTraits { - DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {} + DOTGraphTraits(bool simple = false) : DefaultDOTGraphTraits(simple) {} }; -} // End llvm namespace +} // namespace SVF #endif diff --git a/svf/include/Graphs/GenericGraph.h b/svf/include/Graphs/GenericGraph.h index b04277490..d7bf5b767 100644 --- a/svf/include/Graphs/GenericGraph.h +++ b/svf/include/Graphs/GenericGraph.h @@ -45,8 +45,7 @@ template class GenericGraphReader; /*! * Generic edge on the graph as base class */ -template -class GenericEdge +template class GenericEdge { friend class SVFIRWriter; friend class SVFIRReader; @@ -60,21 +59,18 @@ class GenericEdge /// (2) 8-63 bits encode a callsite instruction typedef u64_t GEdgeFlag; typedef s64_t GEdgeKind; + private: - NodeTy* src; ///< source node - NodeTy* dst; ///< destination node - GEdgeFlag edgeFlag; ///< edge kind + NodeTy* src; ///< source node + NodeTy* dst; ///< destination node + GEdgeFlag edgeFlag; ///< edge kind public: /// Constructor - GenericEdge(NodeTy* s, NodeTy* d, GEdgeFlag k) : src(s), dst(d), edgeFlag(k) - { - } + GenericEdge(NodeTy* s, NodeTy* d, GEdgeFlag k) : src(s), dst(d), edgeFlag(k) {} /// Destructor - virtual ~GenericEdge() - { - } + virtual ~GenericEdge() {} /// get methods of the components //@{ @@ -111,8 +107,7 @@ class GenericEdge { bool operator()(const GenericEdge* lhs, const GenericEdge* rhs) const { - if (lhs->edgeFlag != rhs->edgeFlag) - return lhs->edgeFlag < rhs->edgeFlag; + if (lhs->edgeFlag != rhs->edgeFlag) return lhs->edgeFlag < rhs->edgeFlag; else if (lhs->getSrcID() != rhs->getSrcID()) return lhs->getSrcID() < rhs->getSrcID(); else @@ -122,23 +117,20 @@ class GenericEdge virtual inline bool operator==(const GenericEdge* rhs) const { - return (rhs->edgeFlag == this->edgeFlag && - rhs->getSrcID() == this->getSrcID() && + return (rhs->edgeFlag == this->edgeFlag && rhs->getSrcID() == this->getSrcID() && rhs->getDstID() == this->getDstID()); } //@} protected: - static constexpr unsigned char EdgeKindMaskBits = 8; ///< We use the lower 8 bits to denote edge kind + static constexpr unsigned char EdgeKindMaskBits = 8; ///< We use the lower 8 bits to denote edge kind static constexpr u64_t EdgeKindMask = (~0ULL) >> (64 - EdgeKindMaskBits); }; - /*! * Generic node on the graph as base class */ -template -class GenericNode +template class GenericNode { friend class SVFIRWriter; friend class SVFIRReader; @@ -156,24 +148,20 @@ class GenericNode ///@} private: - NodeID id; ///< Node ID - GNodeK nodeKind; ///< Node kind + NodeID id; ///< Node ID + GNodeK nodeKind; ///< Node kind - GEdgeSetTy InEdges; ///< all incoming edge of this node + GEdgeSetTy InEdges; ///< all incoming edge of this node GEdgeSetTy OutEdges; ///< all outgoing edge of this node public: /// Constructor - GenericNode(NodeID i, GNodeK k): id(i),nodeKind(k) - { - - } + GenericNode(NodeID i, GNodeK k) : id(i), nodeKind(k) {} /// Destructor virtual ~GenericNode() { - for (auto * edge : OutEdges) - delete edge; + for (auto* edge : OutEdges) delete edge; } /// Get ID @@ -320,16 +308,14 @@ class GenericNode inline EdgeType* hasIncomingEdge(EdgeType* edge) const { const_iterator it = InEdges.find(edge); - if (it != InEdges.end()) - return *it; + if (it != InEdges.end()) return *it; else return nullptr; } inline EdgeType* hasOutgoingEdge(EdgeType* edge) const { const_iterator it = OutEdges.find(edge); - if (it != OutEdges.end()) - return *it; + if (it != OutEdges.end()) return *it; else return nullptr; } @@ -340,8 +326,7 @@ class GenericNode * Generic graph for program representation * It is base class and needs to be instantiated */ -template -class GenericGraph +template class GenericGraph { friend class SVFIRWriter; friend class SVFIRReader; @@ -372,8 +357,7 @@ class GenericGraph /// Release memory void destroy() { - for (auto &entry : IDToNodeMap) - delete entry.second; + for (auto& entry : IDToNodeMap) delete entry.second; } /// Iterators //@{ @@ -420,9 +404,8 @@ class GenericGraph /// Delete a node inline void removeGNode(NodeType* node) { - assert(node->hasIncomingEdge() == false - && node->hasOutgoingEdge() == false - && "node which have edges can't be deleted"); + assert(node->hasIncomingEdge() == false && node->hasOutgoingEdge() == false && + "node which have edges can't be deleted"); iterator it = IDToNodeMap.find(node->getId()); assert(it != IDToNodeMap.end() && "can not find the node"); IDToNodeMap.erase(it); @@ -452,8 +435,8 @@ class GenericGraph IDToNodeMapTy IDToNodeMap; ///< node map public: - u32_t edgeNum; ///< total num of node - u32_t nodeNum; ///< total num of edge + u32_t edgeNum; ///< total num of node + u32_t nodeNum; ///< total num of edge }; } // End namespace SVF @@ -469,17 +452,13 @@ namespace SVF // be applied whenever operator* is invoked on the iterator. template ()(*std::declval()))> + typename FuncReturnTy = decltype(std::declval()(*std::declval()))> class mapped_iter - : public iter_adaptor_base< - mapped_iter, ItTy, - typename std::iterator_traits::iterator_category, - typename std::remove_reference::type> + : public iter_adaptor_base, ItTy, typename std::iterator_traits::iterator_category, + typename std::remove_reference::type> { public: - mapped_iter(ItTy U, FuncTy F) - : mapped_iter::iter_adaptor_base(std::move(U)), F(std::move(F)) {} + mapped_iter(ItTy U, FuncTy F) : mapped_iter::iter_adaptor_base(std::move(U)), F(std::move(F)) {} ItTy getCurrent() { @@ -497,8 +476,7 @@ class mapped_iter // map_iter - Provide a convenient way to create mapped_iters, just like // make_pair is useful for creating pairs... -template -inline mapped_iter map_iter(ItTy I, FuncTy F) +template inline mapped_iter map_iter(ItTy I, FuncTy F) { return mapped_iter(std::move(I), std::move(F)); } @@ -506,7 +484,7 @@ inline mapped_iter map_iter(ItTy I, FuncTy F) /*! * GenericGraphTraits for nodes */ -template struct GenericGraphTraits* > +template struct GenericGraphTraits*> { typedef NodeTy NodeType; typedef EdgeTy EdgeType; @@ -517,7 +495,7 @@ template struct GenericGraphTraits::iterator, decltype(&edge_dest)> ChildIteratorType; + typedef mapped_iter::iterator, decltype(&edge_dest)> ChildIteratorType; static NodeType* getEntryNode(NodeType* pagN) { @@ -532,11 +510,11 @@ template struct GenericGraphTraitsOutEdgeEnd(), &edge_dest); } - static inline ChildIteratorType direct_child_begin(const NodeType *N) + static inline ChildIteratorType direct_child_begin(const NodeType* N) { return map_iter(N->directOutEdgeBegin(), &edge_dest); } - static inline ChildIteratorType direct_child_end(const NodeType *N) + static inline ChildIteratorType direct_child_end(const NodeType* N) { return map_iter(N->directOutEdgeEnd(), &edge_dest); } @@ -545,8 +523,7 @@ template struct GenericGraphTraits -struct GenericGraphTraits* > > +template struct GenericGraphTraits*>> { typedef NodeTy NodeType; typedef EdgeTy EdgeType; @@ -557,9 +534,9 @@ struct GenericGraphTraits* > > } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef mapped_iter::iterator, decltype(&edge_dest)> ChildIteratorType; + typedef mapped_iter::iterator, decltype(&edge_dest)> ChildIteratorType; - static inline NodeType* getEntryNode(Inverse G) + static inline NodeType* getEntryNode(Inverse G) { return G.Graph; } @@ -582,9 +559,11 @@ struct GenericGraphTraits* > > /*! * GraphTraints */ -template struct GenericGraphTraits* > : public GenericGraphTraits* > +template +struct GenericGraphTraits*> + : public GenericGraphTraits*> { - typedef SVF::GenericGraph GenericGraphTy; + typedef SVF::GenericGraph GenericGraphTy; typedef NodeTy NodeType; typedef EdgeTy EdgeType; @@ -602,11 +581,11 @@ template struct GenericGraphTraits nodes_iterator; - static nodes_iterator nodes_begin(GenericGraphTy *G) + static nodes_iterator nodes_begin(GenericGraphTy* G) { return map_iter(G->begin(), &deref_val); } - static nodes_iterator nodes_end(GenericGraphTy *G) + static nodes_iterator nodes_end(GenericGraphTy* G) { return map_iter(G->end(), &deref_val); } @@ -620,12 +599,12 @@ template struct GenericGraphTraitsgetId(); } - static NodeType* getNode(GenericGraphTy *G, SVF::NodeID id) + static NodeType* getNode(GenericGraphTy* G, SVF::NodeID id) { return G->getGNode(id); } }; -} // End namespace llvm +} // namespace SVF #endif /* GENERICGRAPH_H_ */ diff --git a/svf/include/Graphs/GraphPrinter.h b/svf/include/Graphs/GraphPrinter.h index 20f3df5fb..b05865e00 100644 --- a/svf/include/Graphs/GraphPrinter.h +++ b/svf/include/Graphs/GraphPrinter.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * GraphPrinter.h * @@ -32,7 +31,7 @@ #define INCLUDE_GRAPHS_GRAPHPRINTER_H_ #include -#include "Graphs/GraphWriter.h" // for graph write +#include "Graphs/GraphWriter.h" // for graph write #include namespace SVF @@ -45,16 +44,14 @@ class GraphPrinter { public: - GraphPrinter() - { - } + GraphPrinter() {} /*! * Write the graph into dot file for debugging purpose */ - template - static void WriteGraphToFile(SVF::OutStream &O, - const std::string &GraphName, const GraphType >, bool simple = false) + template + static void WriteGraphToFile(SVF::OutStream& O, const std::string& GraphName, const GraphType& GT, + bool simple = false) { // Filename of the output dot file std::string Filename = GraphName + ".dot"; @@ -75,24 +72,24 @@ class GraphPrinter /*! * Print the graph to command line */ - template - static void PrintGraph(SVF::OutStream &O, const std::string &GraphName, - const GraphType >) + template + static void PrintGraph(SVF::OutStream& O, const std::string& GraphName, const GraphType& GT) { - ///Define the GTraits and node iterator for printing + /// Define the GTraits and node iterator for printing typedef GenericGraphTraits GTraits; typedef typename GTraits::NodeRef NodeRef; typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::ChildIteratorType child_iterator; - O << "Printing VFG Graph" << "'...\n"; + O << "Printing VFG Graph" + << "'...\n"; // Print each node name and its edges node_iterator I = GTraits::nodes_begin(GT); node_iterator E = GTraits::nodes_end(GT); for (; I != E; ++I) { - NodeRef *Node = *I; + NodeRef* Node = *I; O << "node :" << Node << "'\n"; child_iterator EI = GTraits::child_begin(Node); child_iterator EE = GTraits::child_end(Node); @@ -104,8 +101,6 @@ class GraphPrinter } }; -} // End namespace llvm - - +} // namespace SVF #endif /* INCLUDE_GRAPHS_GRAPHPRINTER_H_ */ diff --git a/svf/include/Graphs/GraphTraits.h b/svf/include/Graphs/GraphTraits.h index eeaadaaf6..202f3efff 100644 --- a/svf/include/Graphs/GraphTraits.h +++ b/svf/include/Graphs/GraphTraits.h @@ -32,8 +32,7 @@ namespace SVF // differently without requiring a copy of the original graph. This could // be achieved by carrying more data in NodeRef. See LoopBodyTraits for one // example. -template -struct GenericGraphTraits +template struct GenericGraphTraits { // Elements to provide: @@ -93,58 +92,54 @@ struct GenericGraphTraits // df_iterator> I = idf_begin(M), E = idf_end(M); // for (; I != E; ++I) { ... } // -template -struct Inverse +template struct Inverse { - const GraphType &Graph; + const GraphType& Graph; - inline Inverse(const GraphType &G) : Graph(G) {} + inline Inverse(const GraphType& G) : Graph(G) {} }; // Provide a partial specialization of GenericGraphTraits so that the inverse of an // inverse falls back to the original graph. -template struct GenericGraphTraits>> : GenericGraphTraits {}; +template struct GenericGraphTraits>> : GenericGraphTraits +{ +}; // Provide iterator ranges for the graph traits nodes and children -template -iter_range::nodes_iterator> -nodes(const GraphType &G) +template iter_range::nodes_iterator> nodes(const GraphType& G) { - return make_range(GenericGraphTraits::nodes_begin(G), - GenericGraphTraits::nodes_end(G)); + return make_range(GenericGraphTraits::nodes_begin(G), GenericGraphTraits::nodes_end(G)); } template -iter_range>::nodes_iterator> - inverse_nodes(const GraphType &G) +iter_range>::nodes_iterator> inverse_nodes(const GraphType& G) { return make_range(GenericGraphTraits>::nodes_begin(G), GenericGraphTraits>::nodes_end(G)); } template -iter_range::ChildIteratorType> -children(const typename GenericGraphTraits::NodeRef &G) +iter_range::ChildIteratorType> children( + const typename GenericGraphTraits::NodeRef& G) { - return make_range(GenericGraphTraits::child_begin(G), - GenericGraphTraits::child_end(G)); + return make_range(GenericGraphTraits::child_begin(G), GenericGraphTraits::child_end(G)); } template -iter_range>::ChildIteratorType> - inverse_children(const typename GenericGraphTraits::NodeRef &G) +iter_range>::ChildIteratorType> inverse_children( + const typename GenericGraphTraits::NodeRef& G) { return make_range(GenericGraphTraits>::child_begin(G), GenericGraphTraits>::child_end(G)); } template -iter_range::ChildEdgeIteratorType> -children_edges(const typename GenericGraphTraits::NodeRef &G) +iter_range::ChildEdgeIteratorType> children_edges( + const typename GenericGraphTraits::NodeRef& G) { return make_range(GenericGraphTraits::child_edge_begin(G), GenericGraphTraits::child_edge_end(G)); } -} // end namespace llvm +} // namespace SVF #endif // LLVM_ADT_GRAPHTRAITS_H diff --git a/svf/include/Graphs/GraphWriter.h b/svf/include/Graphs/GraphWriter.h index 60795adc5..014ce23aa 100644 --- a/svf/include/Graphs/GraphWriter.h +++ b/svf/include/Graphs/GraphWriter.h @@ -37,10 +37,10 @@ namespace SVF { -namespace DOT // Private functions... +namespace DOT // Private functions... { -std::string EscapeStr(const std::string &Label); +std::string EscapeStr(const std::string& Label); } // end namespace DOT @@ -58,11 +58,10 @@ enum Name } // end namespace GraphProgram -template -class GraphWriter +template class GraphWriter { - std::ofstream &O; - const GraphType &G; + std::ofstream& O; + const GraphType& G; using DOTTraits = DOTGraphTraits; using GTraits = GenericGraphTraits; @@ -71,14 +70,13 @@ class GraphWriter using child_iterator = typename GTraits::ChildIteratorType; DOTTraits DTraits; - static_assert(std::is_pointer::value, - "FIXME: Currently GraphWriter requires the NodeRef type to be " - "a pointer.\nThe pointer usage should be moved to " - "DOTGraphTraits, and removed from GraphWriter itself."); + static_assert(std::is_pointer::value, "FIXME: Currently GraphWriter requires the NodeRef type to be " + "a pointer.\nThe pointer usage should be moved to " + "DOTGraphTraits, and removed from GraphWriter itself."); // Writes the edge labels of the node to O and returns true if there are any // edge labels not equal to the empty string "". - bool getEdgeSourceLabels(std::stringstream &O2, NodeRef Node) + bool getEdgeSourceLabels(std::stringstream& O2, NodeRef Node) { child_iterator EI = GTraits::child_begin(Node); child_iterator EE = GTraits::child_end(Node); @@ -88,30 +86,27 @@ class GraphWriter { std::string label = DTraits.getEdgeSourceLabel(Node, EI); - if (label.empty()) - continue; + if (label.empty()) continue; hasEdgeSourceLabels = true; - if (i) - O2 << "|"; + if (i) O2 << "|"; O2 << "" << DOT::EscapeStr(label); } - if (EI != EE && hasEdgeSourceLabels) - O2 << "|truncated..."; + if (EI != EE && hasEdgeSourceLabels) O2 << "|truncated..."; return hasEdgeSourceLabels; } public: - GraphWriter(std::ofstream &o, const GraphType &g, bool SN) : O(o), G(g) + GraphWriter(std::ofstream& o, const GraphType& g, bool SN) : O(o), G(g) { DTraits = DOTTraits(SN); } - void writeGraph(const std::string &Title = "") + void writeGraph(const std::string& Title = "") { // Output the header for the graph... writeHeader(Title); @@ -126,22 +121,19 @@ class GraphWriter writeFooter(); } - void writeHeader(const std::string &Title) + void writeHeader(const std::string& Title) { std::string GraphName(DTraits.getGraphName(G)); - if (!Title.empty()) - O << "digraph \"" << DOT::EscapeStr(Title) << "\" {\n"; + if (!Title.empty()) O << "digraph \"" << DOT::EscapeStr(Title) << "\" {\n"; else if (!GraphName.empty()) O << "digraph \"" << DOT::EscapeStr(GraphName) << "\" {\n"; else O << "digraph unnamed {\n"; - if (DTraits.renderGraphFromBottomUp()) - O << "\trankdir=\"BT\";\n"; + if (DTraits.renderGraphFromBottomUp()) O << "\trankdir=\"BT\";\n"; - if (!Title.empty()) - O << "\tlabel=\"" << DOT::EscapeStr(Title) << "\";\n"; + if (!Title.empty()) O << "\tlabel=\"" << DOT::EscapeStr(Title) << "\";\n"; else if (!GraphName.empty()) O << "\tlabel=\"" << DOT::EscapeStr(GraphName) << "\";\n"; O << DTraits.getGraphProperties(G); @@ -158,8 +150,7 @@ class GraphWriter { // Loop over the graph, printing it out... for (const auto Node : nodes(G)) - if (!isNodeHidden(Node)) - writeNode(Node); + if (!isNodeHidden(Node)) writeNode(Node); } bool isNodeHidden(NodeRef Node) @@ -181,12 +172,10 @@ class GraphWriter // If we should include the address of the node in the label, do so now. std::string Id = DTraits.getNodeIdentifierLabel(Node, G); - if (!Id.empty()) - O << "|" << DOT::EscapeStr(Id); + if (!Id.empty()) O << "|" << DOT::EscapeStr(Id); std::string NodeDesc = DTraits.getNodeDescription(Node, G); - if (!NodeDesc.empty()) - O << "|" << DOT::EscapeStr(NodeDesc); + if (!NodeDesc.empty()) O << "|" << DOT::EscapeStr(NodeDesc); } std::string edgeSourceLabels; @@ -208,12 +197,10 @@ class GraphWriter // If we should include the address of the node in the label, do so now. std::string Id = DTraits.getNodeIdentifierLabel(Node, G); - if (!Id.empty()) - O << "|" << DOT::EscapeStr(Id); + if (!Id.empty()) O << "|" << DOT::EscapeStr(Id); std::string NodeDesc = DTraits.getNodeDescription(Node, G); - if (!NodeDesc.empty()) - O << "|" << DOT::EscapeStr(NodeDesc); + if (!NodeDesc.empty()) O << "|" << DOT::EscapeStr(NodeDesc); } if (DTraits.hasEdgeDestLabels()) @@ -224,26 +211,22 @@ class GraphWriter for (; i != e && i != 64; ++i) { if (i) O << "|"; - O << "" - << DOT::EscapeStr(DTraits.getEdgeDestLabel(Node, i)); + O << "" << DOT::EscapeStr(DTraits.getEdgeDestLabel(Node, i)); } - if (i != e) - O << "|truncated..."; + if (i != e) O << "|truncated..."; O << "}"; } - O << "}\"];\n"; // Finish printing the "node" line + O << "}\"];\n"; // Finish printing the "node" line // Output all of the edges now child_iterator EI = GTraits::child_begin(Node); child_iterator EE = GTraits::child_end(Node); for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) - if (!DTraits.isNodeHidden(*EI, G)) - writeEdge(Node, i, EI); + if (!DTraits.isNodeHidden(*EI, G)) writeEdge(Node, i, EI); for (; EI != EE; ++EI) - if (!DTraits.isNodeHidden(*EI, G)) - writeEdge(Node, 64, EI); + if (!DTraits.isNodeHidden(*EI, G)) writeEdge(Node, 64, EI); } void writeEdge(NodeRef Node, unsigned edgeidx, child_iterator EI) @@ -256,28 +239,23 @@ class GraphWriter child_iterator TargetIt = DTraits.getEdgeTarget(Node, EI); // Figure out which edge this targets... - unsigned Offset = - (unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt); + unsigned Offset = (unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt); DestPort = static_cast(Offset); } - if (DTraits.getEdgeSourceLabel(Node, EI).empty()) - edgeidx = -1; + if (DTraits.getEdgeSourceLabel(Node, EI).empty()) edgeidx = -1; - emitEdge(static_cast(Node), edgeidx, - static_cast(TargetNode), DestPort, + emitEdge(static_cast(Node), edgeidx, static_cast(TargetNode), DestPort, DTraits.getEdgeAttributes(Node, EI, G)); } } /// emitSimpleNode - Outputs a simple (non-record) node - void emitSimpleNode(const void *ID, const std::string &Attr, - const std::string &Label, unsigned NumEdgeSources = 0, - const std::vector *EdgeSourceLabels = nullptr) + void emitSimpleNode(const void* ID, const std::string& Attr, const std::string& Label, unsigned NumEdgeSources = 0, + const std::vector* EdgeSourceLabels = nullptr) { O << "\tNode" << ID << "[ "; - if (!Attr.empty()) - O << Attr << ","; + if (!Attr.empty()) O << Attr << ","; O << " label =\""; if (NumEdgeSources) O << "{"; O << DOT::EscapeStr(Label); @@ -297,36 +275,30 @@ class GraphWriter } /// emitEdge - Output an edge from a simple node into the graph... - void emitEdge(const void *SrcNodeID, int SrcNodePort, - const void *DestNodeID, int DestNodePort, - const std::string &Attrs) + void emitEdge(const void* SrcNodeID, int SrcNodePort, const void* DestNodeID, int DestNodePort, + const std::string& Attrs) { - if (SrcNodePort > 64) return; // Emanating from truncated part? - if (DestNodePort > 64) DestNodePort = 64; // Targeting the truncated part? + if (SrcNodePort > 64) return; // Emanating from truncated part? + if (DestNodePort > 64) DestNodePort = 64; // Targeting the truncated part? O << "\tNode" << SrcNodeID; - if (SrcNodePort >= 0) - O << ":s" << SrcNodePort; + if (SrcNodePort >= 0) O << ":s" << SrcNodePort; O << " -> Node" << DestNodeID; - if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels()) - O << ":d" << DestNodePort; + if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels()) O << ":d" << DestNodePort; - if (!Attrs.empty()) - O << "[" << Attrs << "]"; + if (!Attrs.empty()) O << "[" << Attrs << "]"; O << ";\n"; } /// getOStream - Get the raw output stream into the graph file. Useful to /// write fancy things using addCustomGraphFeatures(). - std::ofstream &getOStream() + std::ofstream& getOStream() { return O; } }; -template -std::ofstream &WriteGraph(std::ofstream &O, const GraphType &G, - bool ShortNames = false) +template std::ofstream& WriteGraph(std::ofstream& O, const GraphType& G, bool ShortNames = false) { // Start the graph emission process... GraphWriter W(O, G, ShortNames); @@ -342,9 +314,7 @@ std::ofstream &WriteGraph(std::ofstream &O, const GraphType &G, /// \return The resulting filename, or an empty string if writing /// failed. template -std::string WriteGraph(const GraphType &G, - bool ShortNames = false, - std::string Filename = "") +std::string WriteGraph(const GraphType& G, bool ShortNames = false, std::string Filename = "") { std::ofstream O(Filename); @@ -367,14 +337,13 @@ std::string WriteGraph(const GraphType &G, /// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, /// then cleanup. For use from the debugger. /// -template -void ViewGraph(const GraphType &G,const std::string& name, - bool ShortNames = false, +template +void ViewGraph(const GraphType& G, const std::string& name, bool ShortNames = false, GraphProgram::Name Program = GraphProgram::DOT) { SVF::WriteGraph(G, ShortNames); } -} // end namespace llvm +} // namespace SVF #endif // LLVM_SUPPORT_GRAPHWRITER_H diff --git a/svf/include/Graphs/ICFG.h b/svf/include/Graphs/ICFG.h index 45368c71e..cf0109bfa 100644 --- a/svf/include/Graphs/ICFG.h +++ b/svf/include/Graphs/ICFG.h @@ -43,7 +43,7 @@ class CallGraph; /*! * Interprocedural Control-Flow Graph (ICFG) */ -typedef GenericGraph GenericICFGTy; +typedef GenericGraph GenericICFGTy; class ICFG : public GenericICFGTy { friend class ICFGBuilder; @@ -52,34 +52,34 @@ class ICFG : public GenericICFGTy friend class ICFGSimplification; public: - - typedef OrderedMap ICFGNodeIDToNodeMapTy; + typedef OrderedMap ICFGNodeIDToNodeMapTy; typedef ICFGEdge::ICFGEdgeSetTy ICFGEdgeSetTy; typedef ICFGNodeIDToNodeMapTy::iterator iterator; typedef ICFGNodeIDToNodeMapTy::const_iterator const_iterator; - typedef Map FunToFunEntryNodeMapTy; - typedef Map FunToFunExitNodeMapTy; - typedef Map CSToCallNodeMapTy; - typedef Map CSToRetNodeMapTy; - typedef Map InstToBlockNodeMapTy; - typedef std::vector SVFLoopVec; - typedef Map ICFGNodeToSVFLoopVec; + typedef Map FunToFunEntryNodeMapTy; + typedef Map FunToFunExitNodeMapTy; + typedef Map CSToCallNodeMapTy; + typedef Map CSToRetNodeMapTy; + typedef Map InstToBlockNodeMapTy; + typedef std::vector SVFLoopVec; + typedef Map ICFGNodeToSVFLoopVec; NodeID totalICFGNode; private: FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode - FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode - CSToCallNodeMapTy CSToCallNodeMap; ///< map a callsite to its CallICFGNode - CSToRetNodeMapTy CSToRetNodeMap; ///< map a callsite to its RetICFGNode - InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode - GlobalICFGNode* globalBlockNode; ///< unique basic block for all globals - ICFGNodeToSVFLoopVec icfgNodeToSVFLoopVec; ///< map ICFG node to the SVF loops where it resides - - Map> _subNodes; /// _repNode; ///> _subNodes; ///< map a node(1st node of basicblock) to its + ///< subnodes + Map _repNode; ///< map a subnode to its representative node(1st node of + ///< basicblock) public: /// Constructor @@ -120,7 +120,7 @@ class ICFG : public GenericICFGTy void updateCallGraph(CallGraph* callgraph); /// Whether node is in a loop - inline bool isInLoop(const ICFGNode *node) + inline bool isInLoop(const ICFGNode* node) { auto it = icfgNodeToSVFLoopVec.find(node); return it != icfgNodeToSVFLoopVec.end(); @@ -133,13 +133,13 @@ class ICFG : public GenericICFGTy } /// Insert (node, loop) to icfgNodeToSVFLoopVec - inline void addNodeToSVFLoop(const ICFGNode *node, const SVFLoop* loop) + inline void addNodeToSVFLoop(const ICFGNode* node, const SVFLoop* loop) { icfgNodeToSVFLoopVec[node].push_back(loop); } /// Get loops where a node resides - inline SVFLoopVec& getSVFLoops(const ICFGNode *node) + inline SVFLoopVec& getSVFLoops(const ICFGNode* node) { auto it = icfgNodeToSVFLoopVec.find(node); assert(it != icfgNodeToSVFLoopVec.end() && "node not in loop"); @@ -155,7 +155,8 @@ class ICFG : public GenericICFGTy /// Add intraprocedural and interprocedural control-flow edges. //@{ ICFGEdge* addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode); - ICFGEdge* addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, s32_t branchCondVal); + ICFGEdge* addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, + s32_t branchCondVal); ICFGEdge* addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs); ICFGEdge* addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs); //@} @@ -174,20 +175,20 @@ class ICFG : public GenericICFGTy } /// sanitize Intra edges, verify that both nodes belong to the same function. - inline void checkIntraEdgeParents(const ICFGNode *srcNode, const ICFGNode *dstNode) + inline void checkIntraEdgeParents(const ICFGNode* srcNode, const ICFGNode* dstNode) { const SVFFunction* srcfun = srcNode->getFun(); const SVFFunction* dstfun = dstNode->getFun(); - if(srcfun != nullptr && dstfun != nullptr) + if (srcfun != nullptr && dstfun != nullptr) { - assert((srcfun == dstfun) && "src and dst nodes of an intra edge should in the same function!" ); + assert((srcfun == dstfun) && "src and dst nodes of an intra edge should in the same function!"); } } /// Add a ICFG node virtual inline void addICFGNode(ICFGNode* node) { - addGNode(node->getId(),node); + addGNode(node->getId(), node); _repNode[node] = node; _subNodes[node].push_back(node); } @@ -204,9 +205,9 @@ class ICFG : public GenericICFGTy IntraICFGNode* getIntraICFGNode(const SVFInstruction* inst); - FunEntryICFGNode* getFunEntryICFGNode(const SVFFunction* fun); + FunEntryICFGNode* getFunEntryICFGNode(const SVFFunction* fun); - FunExitICFGNode* getFunExitICFGNode(const SVFFunction* fun); + FunExitICFGNode* getFunExitICFGNode(const SVFFunction* fun); inline GlobalICFGNode* getGlobalICFGNode() const { @@ -228,7 +229,6 @@ class ICFG : public GenericICFGTy return _repNode.at(node); } - void updateSubAndRep(const ICFGNode* rep, const ICFGNode* sub) { addSubNode(rep, sub); @@ -241,7 +241,7 @@ class ICFG : public GenericICFGTy void addSubNode(const ICFGNode* rep, const ICFGNode* sub) { std::vector& subNodes = _subNodes[sub]; - if(std::find(subNodes.begin(), subNodes.end(), rep) == subNodes.end()) + if (std::find(subNodes.begin(), subNodes.end(), rep) == subNodes.end()) { subNodes.push_back(rep); } @@ -267,13 +267,12 @@ class ICFG : public GenericICFGTy inline IntraICFGNode* getIntraBlock(const SVFInstruction* inst) { InstToBlockNodeMapTy::const_iterator it = InstToBlockNodeMap.find(inst); - if (it == InstToBlockNodeMap.end()) - return nullptr; + if (it == InstToBlockNodeMap.end()) return nullptr; return it->second; } inline IntraICFGNode* addIntraBlock(const SVFInstruction* inst) { - IntraICFGNode* sNode = new IntraICFGNode(totalICFGNode++,inst); + IntraICFGNode* sNode = new IntraICFGNode(totalICFGNode++, inst); addICFGNode(sNode); InstToBlockNodeMap[inst] = sNode; return sNode; @@ -283,13 +282,12 @@ class ICFG : public GenericICFGTy inline FunEntryICFGNode* getFunEntryBlock(const SVFFunction* fun) { FunToFunEntryNodeMapTy::const_iterator it = FunToFunEntryNodeMap.find(fun); - if (it == FunToFunEntryNodeMap.end()) - return nullptr; + if (it == FunToFunEntryNodeMap.end()) return nullptr; return it->second; } inline FunEntryICFGNode* addFunEntryBlock(const SVFFunction* fun) { - FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++,fun); + FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++, fun); addICFGNode(sNode); FunToFunEntryNodeMap[fun] = sNode; return sNode; @@ -299,8 +297,7 @@ class ICFG : public GenericICFGTy inline FunExitICFGNode* getFunExitBlock(const SVFFunction* fun) { FunToFunExitNodeMapTy::const_iterator it = FunToFunExitNodeMap.find(fun); - if (it == FunToFunExitNodeMap.end()) - return nullptr; + if (it == FunToFunExitNodeMap.end()) return nullptr; return it->second; } inline FunExitICFGNode* addFunExitBlock(const SVFFunction* fun) @@ -322,8 +319,7 @@ class ICFG : public GenericICFGTy inline CallICFGNode* getCallBlock(const SVFInstruction* cs) { CSToCallNodeMapTy::const_iterator it = CSToCallNodeMap.find(cs); - if (it == CSToCallNodeMap.end()) - return nullptr; + if (it == CSToCallNodeMap.end()) return nullptr; return it->second; } @@ -331,8 +327,7 @@ class ICFG : public GenericICFGTy inline RetICFGNode* getRetBlock(const SVFInstruction* cs) { CSToRetNodeMapTy::const_iterator it = CSToRetNodeMap.find(cs); - if (it == CSToRetNodeMap.end()) - return nullptr; + if (it == CSToRetNodeMap.end()) return nullptr; return it->second; } inline RetICFGNode* addRetBlock(const SVFInstruction* cs) @@ -344,7 +339,6 @@ class ICFG : public GenericICFGTy CSToRetNodeMap[cs] = sNode; return sNode; } - }; } // End namespace SVF @@ -355,21 +349,24 @@ namespace SVF * GenericGraphTraits specializations for generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::ICFGNode *NodeRef; + typedef SVF::ICFGNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* INCLUDE_UTIL_ICFG_H_ */ diff --git a/svf/include/Graphs/ICFGEdge.h b/svf/include/Graphs/ICFGEdge.h index 23fee2d0d..49643675b 100644 --- a/svf/include/Graphs/ICFGEdge.h +++ b/svf/include/Graphs/ICFGEdge.h @@ -38,7 +38,8 @@ class CallPE; class RetPE; /*! - * Interprocedural control-flow and value-flow edge, representing the control- and value-flow dependence between two nodes + * Interprocedural control-flow and value-flow edge, representing the control- and value-flow dependence between two + * nodes */ typedef GenericEdge GenericICFGEdgeTy; class ICFGEdge : public GenericICFGEdgeTy @@ -61,9 +62,7 @@ class ICFGEdge : public GenericICFGEdgeTy public: /// Constructor - ICFGEdge(ICFGNode* s, ICFGNode* d, GEdgeFlag k) : GenericICFGEdgeTy(s, d, k) - { - } + ICFGEdge(ICFGNode* s, ICFGNode* d, GEdgeFlag k) : GenericICFGEdgeTy(s, d, k) {} /// Destructor ~ICFGEdge() {} @@ -71,8 +70,7 @@ class ICFGEdge : public GenericICFGEdgeTy //@{ inline bool isCFGEdge() const { - return getEdgeKind() == IntraCF || getEdgeKind() == CallCF || - getEdgeKind() == RetCF; + return getEdgeKind() == IntraCF || getEdgeKind() == CallCF || getEdgeKind() == RetCF; } inline bool isCallCFGEdge() const { @@ -117,10 +115,7 @@ class IntraCFGEdge : public ICFGEdge public: /// Constructor - IntraCFGEdge(ICFGNode* s, ICFGNode* d) - : ICFGEdge(s, d, IntraCF), conditionVar(nullptr), branchCondVal(0) - { - } + IntraCFGEdge(ICFGNode* s, ICFGNode* d) : ICFGEdge(s, d, IntraCF), conditionVar(nullptr), branchCondVal(0) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ static inline bool classof(const IntraCFGEdge*) @@ -184,10 +179,7 @@ class CallCFGEdge : public ICFGEdge public: /// Constructor - CallCFGEdge(ICFGNode* s, ICFGNode* d, const SVFInstruction* c) - : ICFGEdge(s, d, CallCF), cs(c) - { - } + CallCFGEdge(ICFGNode* s, ICFGNode* d, const SVFInstruction* c) : ICFGEdge(s, d, CallCF), cs(c) {} /// Return callsite ID inline const SVFInstruction* getCallSite() const { @@ -235,10 +227,7 @@ class RetCFGEdge : public ICFGEdge public: /// Constructor - RetCFGEdge(ICFGNode* s, ICFGNode* d, const SVFInstruction* c) - : ICFGEdge(s, d, RetCF), cs(c), retPE(nullptr) - { - } + RetCFGEdge(ICFGNode* s, ICFGNode* d, const SVFInstruction* c) : ICFGEdge(s, d, RetCF), cs(c), retPE(nullptr) {} /// Return callsite ID inline const SVFInstruction* getCallSite() const { diff --git a/svf/include/Graphs/ICFGNode.h b/svf/include/Graphs/ICFGNode.h index 8ad646ae5..0bfe142ca 100644 --- a/svf/include/Graphs/ICFGNode.h +++ b/svf/include/Graphs/ICFGNode.h @@ -71,16 +71,14 @@ class ICFGNode : public GenericICFGNodeTy typedef ICFGEdge::ICFGEdgeSetTy::iterator iterator; typedef ICFGEdge::ICFGEdgeSetTy::const_iterator const_iterator; - typedef Set CallPESet; - typedef Set RetPESet; + typedef Set CallPESet; + typedef Set RetPESet; typedef std::list VFGNodeList; typedef std::list SVFStmtList; public: /// Constructor - ICFGNode(NodeID i, ICFGNodeK k) : GenericICFGNodeTy(i, k), fun(nullptr), bb(nullptr) - { - } + ICFGNode(NodeID i, ICFGNodeK k) : GenericICFGNodeTy(i, k), fun(nullptr), bb(nullptr) {} /// Return the function of this ICFGNode virtual const SVFFunction* getFun() const @@ -94,10 +92,9 @@ class ICFGNode : public GenericICFGNodeTy return bb; } - /// Overloading operator << for dumping ICFG node ID //@{ - friend OutStream &operator<<(OutStream &o, const ICFGNode &node) + friend OutStream& operator<<(OutStream& o, const ICFGNode& node) { o << node.toString(); return o; @@ -106,7 +103,7 @@ class ICFGNode : public GenericICFGNodeTy /// Set/Get methods of VFGNodes ///@{ - inline void addVFGNode(const VFGNode *vfgNode) + inline void addVFGNode(const VFGNode* vfgNode) { VFGNodes.push_back(vfgNode); } @@ -119,7 +116,7 @@ class ICFGNode : public GenericICFGNodeTy /// Set/Get methods of VFGNodes ///@{ - inline void addSVFStmt(const SVFStmt *edge) + inline void addSVFStmt(const SVFStmt* edge) { pagEdges.push_back(edge); } @@ -139,7 +136,6 @@ class ICFGNode : public GenericICFGNodeTy const SVFBasicBlock* bb; VFGNodeList VFGNodes; //< a list of VFGNodes SVFStmtList pagEdges; //< a list of PAGEdges - }; /*! @@ -149,23 +145,21 @@ class GlobalICFGNode : public ICFGNode { public: - GlobalICFGNode(NodeID id) : ICFGNode(id, GlobalBlock) - { - } + GlobalICFGNode(NodeID id) : ICFGNode(id, GlobalBlock) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const GlobalICFGNode *) + static inline bool classof(const GlobalICFGNode*) { return true; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { return node->getNodeKind() == GlobalBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { return node->getNodeKind() == GlobalBlock; } @@ -181,37 +175,38 @@ class IntraICFGNode : public ICFGNode { friend class SVFIRWriter; friend class SVFIRReader; + private: - const SVFInstruction *inst; + const SVFInstruction* inst; /// Constructor to create empty IntraICFGNode (for SVFIRReader/deserialization) IntraICFGNode(NodeID id) : ICFGNode(id, IntraBlock), inst(nullptr) {} public: - IntraICFGNode(NodeID id, const SVFInstruction *i) : ICFGNode(id, IntraBlock), inst(i) + IntraICFGNode(NodeID id, const SVFInstruction* i) : ICFGNode(id, IntraBlock), inst(i) { fun = inst->getFunction(); bb = inst->getParent(); } - inline const SVFInstruction *getInst() const + inline const SVFInstruction* getInst() const { return inst; } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const IntraICFGNode *) + static inline bool classof(const IntraICFGNode*) { return true; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { return node->getNodeKind() == IntraBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { return node->getNodeKind() == IntraBlock; } @@ -225,36 +220,29 @@ class InterICFGNode : public ICFGNode public: /// Constructor - InterICFGNode(NodeID id, ICFGNodeK k) : ICFGNode(id, k) - { - } + InterICFGNode(NodeID id, ICFGNodeK k) : ICFGNode(id, k) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const InterICFGNode *) + static inline bool classof(const InterICFGNode*) { return true; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { - return node->getNodeKind() == FunEntryBlock - || node->getNodeKind() == FunExitBlock - || node->getNodeKind() == FunCallBlock - || node->getNodeKind() == FunRetBlock; + return node->getNodeKind() == FunEntryBlock || node->getNodeKind() == FunExitBlock || + node->getNodeKind() == FunCallBlock || node->getNodeKind() == FunRetBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { - return node->getNodeKind() == FunEntryBlock - || node->getNodeKind() == FunExitBlock - || node->getNodeKind() == FunCallBlock - || node->getNodeKind() == FunRetBlock; + return node->getNodeKind() == FunEntryBlock || node->getNodeKind() == FunExitBlock || + node->getNodeKind() == FunCallBlock || node->getNodeKind() == FunRetBlock; } //@} }; - /*! * Function entry ICFGNode containing a set of FormalParmVFGNodes of a function */ @@ -264,7 +252,8 @@ class FunEntryICFGNode : public InterICFGNode friend class SVFIRReader; public: - typedef std::vector FormalParmNodeVec; + typedef std::vector FormalParmNodeVec; + private: FormalParmNodeVec FPNodes; @@ -281,35 +270,35 @@ class FunEntryICFGNode : public InterICFGNode } /// Return the set of formal parameters - inline const FormalParmNodeVec &getFormalParms() const + inline const FormalParmNodeVec& getFormalParms() const { return FPNodes; } /// Add formal parameters - inline void addFormalParms(const SVFVar *fp) + inline void addFormalParms(const SVFVar* fp) { FPNodes.push_back(fp); } - ///Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const FunEntryICFGNode *) + static inline bool classof(const FunEntryICFGNode*) { return true; } - static inline bool classof(const InterICFGNode *node) + static inline bool classof(const InterICFGNode* node) { return node->getNodeKind() == FunEntryBlock; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { return node->getNodeKind() == FunEntryBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { return node->getNodeKind() == FunEntryBlock; } @@ -327,7 +316,7 @@ class FunExitICFGNode : public InterICFGNode friend class SVFIRReader; private: - const SVFVar *formalRet; + const SVFVar* formalRet; /// Constructor to create empty FunExitICFGNode (for SVFIRReader/deserialization) FunExitICFGNode(NodeID id) : InterICFGNode(id, FunExitBlock), formalRet{} {} @@ -342,35 +331,35 @@ class FunExitICFGNode : public InterICFGNode } /// Return formal return parameter - inline const SVFVar *getFormalRet() const + inline const SVFVar* getFormalRet() const { return formalRet; } /// Add formal return parameter - inline void addFormalRet(const SVFVar *fr) + inline void addFormalRet(const SVFVar* fr) { formalRet = fr; } - ///Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const FunEntryICFGNode *) + static inline bool classof(const FunEntryICFGNode*) { return true; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { return node->getNodeKind() == FunExitBlock; } - static inline bool classof(const InterICFGNode *node) + static inline bool classof(const InterICFGNode* node) { return node->getNodeKind() == FunExitBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { return node->getNodeKind() == FunExitBlock; } @@ -388,7 +377,8 @@ class CallICFGNode : public InterICFGNode friend class SVFIRReader; public: - typedef std::vector ActualParmNodeVec; + typedef std::vector ActualParmNodeVec; + private: const SVFInstruction* cs; const RetICFGNode* ret; @@ -398,8 +388,7 @@ class CallICFGNode : public InterICFGNode CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), cs{}, ret{} {} public: - CallICFGNode(NodeID id, const SVFInstruction* c) - : InterICFGNode(id, FunCallBlock), cs(c), ret(nullptr) + CallICFGNode(NodeID id, const SVFInstruction* c) : InterICFGNode(id, FunCallBlock), cs(c), ret(nullptr) { fun = cs->getFunction(); bb = cs->getParent(); @@ -443,35 +432,35 @@ class CallICFGNode : public InterICFGNode } /// Return the set of actual parameters - inline const ActualParmNodeVec &getActualParms() const + inline const ActualParmNodeVec& getActualParms() const { return APNodes; } /// Add actual parameters - inline void addActualParms(const SVFVar *ap) + inline void addActualParms(const SVFVar* ap) { APNodes.push_back(ap); } - ///Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CallICFGNode *) + static inline bool classof(const CallICFGNode*) { return true; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { return node->getNodeKind() == FunCallBlock; } - static inline bool classof(const InterICFGNode *node) + static inline bool classof(const InterICFGNode* node) { return node->getNodeKind() == FunCallBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { return node->getNodeKind() == FunCallBlock; } @@ -480,7 +469,6 @@ class CallICFGNode : public InterICFGNode virtual const std::string toString() const; }; - /*! * Return ICFGNode containing (at most one) ActualRetVFGNode at a callsite */ @@ -491,18 +479,15 @@ class RetICFGNode : public InterICFGNode private: const SVFInstruction* cs; - const SVFVar *actualRet; + const SVFVar* actualRet; const CallICFGNode* callBlockNode; /// Constructor to create empty RetICFGNode (for SVFIRReader/deserialization) - RetICFGNode(NodeID id) - : InterICFGNode(id, FunRetBlock), cs{}, actualRet{}, callBlockNode{} - { - } + RetICFGNode(NodeID id) : InterICFGNode(id, FunRetBlock), cs{}, actualRet{}, callBlockNode{} {} public: - RetICFGNode(NodeID id, const SVFInstruction* c, CallICFGNode* cb) : - InterICFGNode(id, FunRetBlock), cs(c), actualRet(nullptr), callBlockNode(cb) + RetICFGNode(NodeID id, const SVFInstruction* c, CallICFGNode* cb) + : InterICFGNode(id, FunRetBlock), cs(c), actualRet(nullptr), callBlockNode(cb) { fun = cs->getFunction(); bb = cs->getParent(); @@ -519,35 +504,35 @@ class RetICFGNode : public InterICFGNode return callBlockNode; } /// Return actual return parameter - inline const SVFVar *getActualRet() const + inline const SVFVar* getActualRet() const { return actualRet; } /// Add actual return parameter - inline void addActualRet(const SVFVar *ar) + inline void addActualRet(const SVFVar* ar) { actualRet = ar; } - ///Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const RetICFGNode *) + static inline bool classof(const RetICFGNode*) { return true; } - static inline bool classof(const InterICFGNode *node) + static inline bool classof(const InterICFGNode* node) { return node->getNodeKind() == FunRetBlock; } - static inline bool classof(const ICFGNode *node) + static inline bool classof(const ICFGNode* node) { return node->getNodeKind() == FunRetBlock; } - static inline bool classof(const GenericICFGNodeTy *node) + static inline bool classof(const GenericICFGNodeTy* node) { return node->getNodeKind() == FunRetBlock; } diff --git a/svf/include/Graphs/ICFGStat.h b/svf/include/Graphs/ICFGStat.h index 5adc71e6e..cc35d9133 100644 --- a/svf/include/Graphs/ICFGStat.h +++ b/svf/include/Graphs/ICFGStat.h @@ -40,7 +40,7 @@ class ICFGStat : public PTAStat { private: - ICFG *icfg; + ICFG* icfg; int numOfNodes; int numOfCallNodes; int numOfRetNodes; @@ -54,9 +54,9 @@ class ICFGStat : public PTAStat int numOfIntraEdges; public: - typedef Set ICFGNodeSet; + typedef Set ICFGNodeSet; - ICFGStat(ICFG *cfg) : PTAStat(nullptr), icfg(cfg) + ICFGStat(ICFG* cfg) : PTAStat(nullptr), icfg(cfg) { numOfNodes = 0; numOfCallNodes = 0; @@ -69,7 +69,6 @@ class ICFGStat : public PTAStat numOfCallEdges = 0; numOfRetEdges = 0; numOfIntraEdges = 0; - } void performStat() @@ -110,10 +109,9 @@ class ICFGStat : public PTAStat { numOfNodes++; - ICFGNode *node = it->second; + ICFGNode* node = it->second; - if (SVFUtil::isa(node)) - numOfIntraNodes++; + if (SVFUtil::isa(node)) numOfIntraNodes++; else if (SVFUtil::isa(node)) numOfCallNodes++; else if (SVFUtil::isa(node)) @@ -123,17 +121,13 @@ class ICFGStat : public PTAStat else if (SVFUtil::isa(node)) numOfExitNodes++; - - ICFGEdge::ICFGEdgeSetTy::iterator edgeIt = - it->second->OutEdgeBegin(); - ICFGEdge::ICFGEdgeSetTy::iterator edgeEit = - it->second->OutEdgeEnd(); + ICFGEdge::ICFGEdgeSetTy::iterator edgeIt = it->second->OutEdgeBegin(); + ICFGEdge::ICFGEdgeSetTy::iterator edgeEit = it->second->OutEdgeEnd(); for (; edgeIt != edgeEit; ++edgeIt) { - const ICFGEdge *edge = *edgeIt; + const ICFGEdge* edge = *edgeIt; numOfEdges++; - if (edge->isCallCFGEdge()) - numOfCallEdges++; + if (edge->isCallCFGEdge()) numOfCallEdges++; else if (edge->isRetCFGEdge()) numOfRetEdges++; else if (edge->isIntraCFGEdge()) @@ -148,7 +142,7 @@ class ICFGStat : public PTAStat SVFUtil::outs() << "\n************ " << statname << " ***************\n"; SVFUtil::outs().flags(std::ios::left); unsigned field_width = 20; - for(NUMStatMap::iterator it = PTNumStatMap.begin(), eit = PTNumStatMap.end(); it!=eit; ++it) + for (NUMStatMap::iterator it = PTNumStatMap.begin(), eit = PTNumStatMap.end(); it != eit; ++it) { // format out put with width 20 space SVFUtil::outs() << std::setw(field_width) << it->first << it->second << "\n"; @@ -161,4 +155,3 @@ class ICFGStat : public PTAStat } // End namespace SVF #endif /* INCLUDE_UTIL_ICFGSTAT_H_ */ - diff --git a/svf/include/Graphs/IRGraph.h b/svf/include/Graphs/IRGraph.h index 33de35613..66c322307 100644 --- a/svf/include/Graphs/IRGraph.h +++ b/svf/include/Graphs/IRGraph.h @@ -27,7 +27,6 @@ * Author: Yulei Sui */ - #ifndef IRGRAPH_H_ #define IRGRAPH_H_ @@ -53,13 +52,15 @@ class IRGraph : public GenericGraph public: typedef Set SVFStmtSet; - typedef Map ValueToEdgeMap; + typedef Map ValueToEdgeMap; protected: - SVFStmt::KindToSVFStmtMapTy KindToSVFStmtSetMap; ///< SVFIR edge map containing all PAGEdges - SVFStmt::KindToSVFStmtMapTy KindToPTASVFStmtSetMap; ///< SVFIR edge map containing only pointer-related edges, i.e., both LHS and RHS are of pointer type - bool fromFile; ///< Whether the SVFIR is built according to user specified data from a txt file - NodeID nodeNumAfterPAGBuild; ///< initial node number after building SVFIR, excluding later added nodes, e.g., gepobj nodes + SVFStmt::KindToSVFStmtMapTy KindToSVFStmtSetMap; ///< SVFIR edge map containing all PAGEdges + SVFStmt::KindToSVFStmtMapTy KindToPTASVFStmtSetMap; ///< SVFIR edge map containing only pointer-related edges, i.e., + ///< both LHS and RHS are of pointer type + bool fromFile; ///< Whether the SVFIR is built according to user specified data from a txt file + NodeID nodeNumAfterPAGBuild; ///< initial node number after building SVFIR, excluding later added nodes, e.g., + ///< gepobj nodes u32_t totalPTAPAGEdge; ValueToEdgeMap valueToEdgeMap; ///< Map SVFValues (e.g., ICFGNodes) to all corresponding PAGEdges SymbolTableInfo* symInfo; @@ -67,7 +68,7 @@ class IRGraph : public GenericGraph /// Add a node into the graph inline NodeID addNode(SVFVar* node, NodeID i) { - addGNode(i,node); + addGNode(i, node); return i; } /// Add an edge into the graph @@ -78,15 +79,13 @@ class IRGraph : public GenericGraph /// Return true if this labeled edge exits, including store, call and load /// two store edge can have same dst and src but located in different basic /// blocks, thus flags are needed to distinguish them - SVFStmt* hasLabeledEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind, - const ICFGNode* cs); + SVFStmt* hasLabeledEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind, const ICFGNode* cs); /// Return MultiOpndStmt since it has more than one operands (we use operand /// 2 here to make the flag) - SVFStmt* hasLabeledEdge(SVFVar* src, SVFVar* op1, SVFStmt::PEDGEK kind, - const SVFVar* op2); + SVFStmt* hasLabeledEdge(SVFVar* src, SVFVar* op1, SVFStmt::PEDGEK kind, const SVFVar* op2); /// Map a value to a set of edges - inline void mapValueToEdge(const SVFValue* V, SVFStmt *edge) + inline void mapValueToEdge(const SVFValue* V, SVFStmt* edge) { auto inserted = valueToEdgeMap.emplace(V, SVFStmtSet{edge}); if (!inserted.second) @@ -101,8 +100,7 @@ class IRGraph : public GenericGraph } public: - IRGraph(bool buildFromFile) - : fromFile(buildFromFile), nodeNumAfterPAGBuild(0), totalPTAPAGEdge(0) + IRGraph(bool buildFromFile) : fromFile(buildFromFile), nodeNumAfterPAGBuild(0), totalPTAPAGEdge(0) { symInfo = SymbolTableInfo::SymbolInfo(); // insert dummy value if a correct value cannot be found @@ -126,14 +124,14 @@ class IRGraph : public GenericGraph auto it = valueToEdgeMap.find(V); if (it == valueToEdgeMap.end()) { - //special empty set + // special empty set return valueToEdgeMap.at(nullptr); } return it->second; } /// Get SVFIR Node according to LLVM value - ///getNode - Return the node corresponding to the specified pointer. + /// getNode - Return the node corresponding to the specified pointer. inline NodeID getValueNode(const SVFValue* V) { return symInfo->getValSym(V); @@ -225,7 +223,7 @@ class IRGraph : public GenericGraph void view(); }; -} +} // namespace SVF namespace SVF { @@ -234,19 +232,23 @@ namespace SVF * GenericGraphTraits specializations of SVFIR to be used for the generic graph algorithms. * Provide graph traits for traversing from a SVFIR node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for SVFIR node, it is used for inverse traversal. -template<> struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { typedef SVF::SVFVar* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* IRGRAPH_H_ */ diff --git a/svf/include/Graphs/SCC.h b/svf/include/Graphs/SCC.h index 1cf895212..c20570e96 100644 --- a/svf/include/Graphs/SCC.h +++ b/svf/include/Graphs/SCC.h @@ -40,7 +40,7 @@ #ifndef SCC_H_ #define SCC_H_ -#include "SVFIR/SVFValue.h" // for NodeBS +#include "SVFIR/SVFValue.h" // for NodeBS #include #include #include @@ -50,17 +50,16 @@ namespace SVF class GNodeSCCInfo; -template -class SCCDetection +template class SCCDetection { private: - ///Define the GTraits and node iterator for printing + /// Define the GTraits and node iterator for printing typedef SVF::GenericGraphTraits GTraits; - typedef typename GTraits::NodeRef GNODE; + typedef typename GTraits::NodeRef GNODE; typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::ChildIteratorType child_iterator; - typedef unsigned NodeID ; + typedef unsigned NodeID; public: typedef std::stack GNodeStack; @@ -78,7 +77,7 @@ class SCCDetection { _visited = v; } - inline bool inSCC(void) const + inline bool inSCC(void) const { return _inSCC; } @@ -86,7 +85,7 @@ class SCCDetection { _inSCC = v; } - inline NodeID rep(void)const + inline NodeID rep(void) const { return _rep; } @@ -106,31 +105,28 @@ class SCCDetection { return _subNodes; } + private: - bool _visited; - bool _inSCC; - NodeID _rep; + bool _visited; + bool _inSCC; + NodeID _rep; NodeBS _subNodes; /// nodes in the scc represented by this node }; - typedef Map GNODESCCInfoMap; + typedef Map GNODESCCInfoMap; typedef Map NodeToNodeMap; - SCCDetection(const GraphType >) - : _graph(GT), - _I(0) - {} - + SCCDetection(const GraphType& GT) : _graph(GT), _I(0) {} // Return a handle to the stack of nodes in topological // order. This will be used to seed the initial solution // and improve efficiency. - inline GNodeStack &topoNodeStack() + inline GNodeStack& topoNodeStack() { return _T; } - const inline GNODESCCInfoMap &GNodeSCCInfo() const + const inline GNODESCCInfoMap& GNodeSCCInfo() const { return _NodeSCCAuxInfo; } @@ -139,12 +135,11 @@ class SCCDetection inline NodeID repNode(NodeID n) const { typename GNODESCCInfoMap::const_iterator it = _NodeSCCAuxInfo.find(n); - assert(it!=_NodeSCCAuxInfo.end() && "scc rep not found"); + assert(it != _NodeSCCAuxInfo.end() && "scc rep not found"); NodeID rep = it->second.rep(); - return rep!= UINT_MAX ? rep : n ; + return rep != UINT_MAX ? rep : n; } - /// whether the node is in a cycle inline bool isInCycle(NodeID n) const { @@ -162,40 +157,39 @@ class SCCDetection for (; EI != EE; ++EI) { NodeID w = Node_Index(*EI); - if(w==rep) - return true; + if (w == rep) return true; } return false; } } /// get all subnodes in one scc, if size is empty insert itself into the set - inline const NodeBS& subNodes(NodeID n) const + inline const NodeBS& subNodes(NodeID n) const { typename GNODESCCInfoMap::const_iterator it = _NodeSCCAuxInfo.find(n); - assert(it!=_NodeSCCAuxInfo.end() && "scc rep not found"); + assert(it != _NodeSCCAuxInfo.end() && "scc rep not found"); return it->second.subNodes(); } /// get all repNodeID - inline const NodeBS &getRepNodes() const + inline const NodeBS& getRepNodes() const { return repNodes; } - const inline GraphType & graph() + const inline GraphType& graph() { return _graph; } -private: - GNODESCCInfoMap _NodeSCCAuxInfo; +private: + GNODESCCInfoMap _NodeSCCAuxInfo; - const GraphType & _graph; - NodeID _I; - NodeToNodeMap _D; - GNodeStack _SS; - GNodeStack _T; + const GraphType& _graph; + NodeID _I; + NodeToNodeMap _D; + GNodeStack _SS; + GNodeStack _T; NodeBS repNodes; inline bool visited(NodeID n) @@ -207,11 +201,11 @@ class SCCDetection return _NodeSCCAuxInfo[n].inSCC(); } - inline void setVisited(NodeID n,bool v) + inline void setVisited(NodeID n, bool v) { _NodeSCCAuxInfo[n].visited(v); } - inline void setInSCC(NodeID n,bool v) + inline void setInSCC(NodeID n, bool v) { _NodeSCCAuxInfo[n].inSCC(v); } @@ -251,8 +245,8 @@ class SCCDetection // SVFUtil::outs() << "visit GNODE: " << Node_Index(v)<< "\n"; _I += 1; _D[v] = _I; - this->rep(v,v); - this->setVisited(v,true); + this->rep(v, v); + this->setVisited(v, true); child_iterator EI = GTraits::direct_child_begin(Node(v)); child_iterator EE = GTraits::direct_child_end(Node(v)); @@ -261,29 +255,26 @@ class SCCDetection { NodeID w = Node_Index(*EI); - if (!this->visited(w)) - visit(w); + if (!this->visited(w)) visit(w); if (!this->inSCC(w)) { NodeID rep; - rep = _D[this->rep(v)] < _D[this->rep(w)] ? - this->rep(v) : this->rep(w); - this->rep(v,rep); + rep = _D[this->rep(v)] < _D[this->rep(w)] ? this->rep(v) : this->rep(w); + this->rep(v, rep); } } if (this->rep(v) == v) { - this->setInSCC(v,true); + this->setInSCC(v, true); while (!_SS.empty()) { NodeID w = _SS.top(); - if (_D[w] <= _D[v]) - break; + if (_D[w] <= _D[v]) break; else { _SS.pop(); - this->setInSCC(w,true); - this->rep(w,v); + this->setInSCC(w, true); + this->rep(w, v); } } _T.push(v); @@ -298,13 +289,11 @@ class SCCDetection _I = 0; _D.clear(); repNodes.clear(); - while(!_SS.empty()) - _SS.pop(); - while(!_T.empty()) - _T.pop(); + while (!_SS.empty()) _SS.pop(); + while (!_T.empty()) _T.pop(); } -public: +public: void find(void) { // Visit each unvisited root node. A root node is defined @@ -323,15 +312,14 @@ class SCCDetection // merging optimizations. Any such node should have no // outgoing edges and therefore should no longer be a member // of an SCC. - if (this->rep(node) == UINT_MAX || this->rep(node) == node) - visit(node); + if (this->rep(node) == UINT_MAX || this->rep(node) == node) visit(node); else this->visited(node); } } } - void find(NodeSet &candidates) + void find(NodeSet& candidates) { // This function is reloaded to only visit candidate NODES clear(); @@ -339,14 +327,12 @@ class SCCDetection { if (!this->visited(node)) { - if (this->rep(node) == UINT_MAX || this->rep(node) == node) - visit(node); + if (this->rep(node) == UINT_MAX || this->rep(node) == node) visit(node); else this->visited(node); } } } - }; } // End namespace SVF diff --git a/svf/include/Graphs/SVFG.h b/svf/include/Graphs/SVFG.h index 9c193103a..c375d8118 100644 --- a/svf/include/Graphs/SVFG.h +++ b/svf/include/Graphs/SVFG.h @@ -57,7 +57,6 @@ typedef PHIVFGNode PHISVFGNode; typedef IntraPHIVFGNode IntraPHISVFGNode; typedef InterPHIVFGNode InterPHISVFGNode; - /*! * Sparse value flow graph * Each node stands for a definition, each edge stands for value flow relations @@ -80,10 +79,10 @@ class SVFG : public VFG typedef NodeBS ActualOUTSVFGNodeSet; typedef NodeBS FormalINSVFGNodeSet; typedef NodeBS FormalOUTSVFGNodeSet; - typedef Map CallSiteToActualINsMapTy; - typedef Map CallSiteToActualOUTsMapTy; - typedef Map FunctionToFormalINsMapTy; - typedef Map FunctionToFormalOUTsMapTy; + typedef Map CallSiteToActualINsMapTy; + typedef Map CallSiteToActualOUTsMapTy; + typedef Map FunctionToFormalINsMapTy; + typedef Map FunctionToFormalOUTsMapTy; typedef MemSSA::MUSet MUSet; typedef MemSSA::CHISet CHISet; typedef MemSSA::PHISet PHISet; @@ -97,12 +96,12 @@ class SVFG : public VFG typedef MemSSA::CALLMU CALLMU; protected: - MSSAVarToDefMapTy MSSAVarToDefMap; ///< map a memory SSA operator to its definition SVFG node + MSSAVarToDefMapTy MSSAVarToDefMap; ///< map a memory SSA operator to its definition SVFG node CallSiteToActualINsMapTy callSiteToActualINMap; CallSiteToActualOUTsMapTy callSiteToActualOUTMap; FunctionToFormalINsMapTy funToFormalINMap; FunctionToFormalOUTsMapTy funToFormalOUTMap; - SVFGStat * stat; + SVFGStat* stat; std::unique_ptr mssa; PointerAnalysis* pta; @@ -186,22 +185,22 @@ class SVFG : public VFG //@{ inline bool hasActualINSVFGNodes(const CallICFGNode* cs) const { - return callSiteToActualINMap.find(cs)!=callSiteToActualINMap.end(); + return callSiteToActualINMap.find(cs) != callSiteToActualINMap.end(); } inline bool hasActualOUTSVFGNodes(const CallICFGNode* cs) const { - return callSiteToActualOUTMap.find(cs)!=callSiteToActualOUTMap.end(); + return callSiteToActualOUTMap.find(cs) != callSiteToActualOUTMap.end(); } inline bool hasFormalINSVFGNodes(const SVFFunction* fun) const { - return funToFormalINMap.find(fun)!=funToFormalINMap.end(); + return funToFormalINMap.find(fun) != funToFormalINMap.end(); } inline bool hasFormalOUTSVFGNodes(const SVFFunction* fun) const { - return funToFormalOUTMap.find(fun)!=funToFormalOUTMap.end(); + return funToFormalOUTMap.find(fun) != funToFormalOUTMap.end(); } //@} @@ -260,9 +259,9 @@ class SVFG : public VFG /// Used *only* for Versioned FSPTA to encode propagation of versions /// in the worklist (allowing for breadth-first propagation). /// Returns the created node. - inline const DummyVersionPropSVFGNode *addDummyVersionPropSVFGNode(const NodeID object, const NodeID version) + inline const DummyVersionPropSVFGNode* addDummyVersionPropSVFGNode(const NodeID object, const NodeID version) { - DummyVersionPropSVFGNode *dvpNode = new DummyVersionPropSVFGNode(totalVFGNode++, object, version); + DummyVersionPropSVFGNode* dvpNode = new DummyVersionPropSVFGNode(totalVFGNode++, object, version); // Not going through add[S]VFGNode because we have no ICFG edge. addGNode(dvpNode->getId(), dvpNode); return dvpNode; @@ -276,38 +275,39 @@ class SVFG : public VFG /// Add indirect def-use edges of a memory region between two statements, //@{ SVFGEdge* addIntraIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts); - SVFGEdge* addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts,CallSiteID csId); - SVFGEdge* addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts,CallSiteID csId); + SVFGEdge* addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts, CallSiteID csId); + SVFGEdge* addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts, CallSiteID csId); SVFGEdge* addThreadMHPIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts); //@} /// Add inter VF edge from callsite mu to function entry chi - SVFGEdge* addInterIndirectVFCallEdge(const ActualINSVFGNode* src, const FormalINSVFGNode* dst,CallSiteID csId); + SVFGEdge* addInterIndirectVFCallEdge(const ActualINSVFGNode* src, const FormalINSVFGNode* dst, CallSiteID csId); /// Add inter VF edge from function exit mu to callsite chi - SVFGEdge* addInterIndirectVFRetEdge(const FormalOUTSVFGNode* src, const ActualOUTSVFGNode* dst,CallSiteID csId); + SVFGEdge* addInterIndirectVFRetEdge(const FormalOUTSVFGNode* src, const ActualOUTSVFGNode* dst, CallSiteID csId); /// Connect SVFG nodes between caller and callee for indirect call site //@{ /// Connect actual-in and formal-in - virtual inline void connectAInAndFIn(const ActualINSVFGNode* actualIn, const FormalINSVFGNode* formalIn, CallSiteID csId, SVFGEdgeSetTy& edges) + virtual inline void connectAInAndFIn(const ActualINSVFGNode* actualIn, const FormalINSVFGNode* formalIn, + CallSiteID csId, SVFGEdgeSetTy& edges) { - SVFGEdge* edge = addInterIndirectVFCallEdge(actualIn, formalIn,csId); - if (edge != nullptr) - edges.insert(edge); + SVFGEdge* edge = addInterIndirectVFCallEdge(actualIn, formalIn, csId); + if (edge != nullptr) edges.insert(edge); } /// Connect formal-out and actual-out - virtual inline void connectFOutAndAOut(const FormalOUTSVFGNode* formalOut, const ActualOUTSVFGNode* actualOut, CallSiteID csId, SVFGEdgeSetTy& edges) + virtual inline void connectFOutAndAOut(const FormalOUTSVFGNode* formalOut, const ActualOUTSVFGNode* actualOut, + CallSiteID csId, SVFGEdgeSetTy& edges) { - SVFGEdge* edge = addInterIndirectVFRetEdge(formalOut, actualOut,csId); - if (edge != nullptr) - edges.insert(edge); + SVFGEdge* edge = addInterIndirectVFRetEdge(formalOut, actualOut, csId); + if (edge != nullptr) edges.insert(edge); } //@} /// Get inter value flow edges between indirect call site and callee. //@{ - virtual inline void getInterVFEdgeAtIndCSFromAPToFP(const PAGNode* cs_arg, const PAGNode* fun_arg, const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) + virtual inline void getInterVFEdgeAtIndCSFromAPToFP(const PAGNode* cs_arg, const PAGNode* fun_arg, + const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) { SVFGNode* actualParam = getSVFGNode(getDef(cs_arg)); SVFGNode* formalParam = getSVFGNode(getDef(fun_arg)); @@ -316,7 +316,8 @@ class SVFG : public VFG edges.insert(edge); } - virtual inline void getInterVFEdgeAtIndCSFromFRToAR(const PAGNode* fun_ret, const PAGNode* cs_ret, CallSiteID csId, SVFGEdgeSetTy& edges) + virtual inline void getInterVFEdgeAtIndCSFromFRToAR(const PAGNode* fun_ret, const PAGNode* cs_ret, CallSiteID csId, + SVFGEdgeSetTy& edges) { SVFGNode* formalRet = getSVFGNode(getDef(fun_ret)); SVFGNode* actualRet = getSVFGNode(getDef(cs_ret)); @@ -325,28 +326,29 @@ class SVFG : public VFG edges.insert(edge); } - virtual inline void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode* actualIn, const SVFFunction* callee, SVFGEdgeSetTy& edges) + virtual inline void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode* actualIn, const SVFFunction* callee, + SVFGEdgeSetTy& edges) { - for (SVFGNode::const_iterator outIt = actualIn->OutEdgeBegin(), outEit = actualIn->OutEdgeEnd(); outIt != outEit; ++outIt) + for (SVFGNode::const_iterator outIt = actualIn->OutEdgeBegin(), outEit = actualIn->OutEdgeEnd(); + outIt != outEit; ++outIt) { SVFGEdge* edge = *outIt; - if (edge->getDstNode()->getFun() == callee) - edges.insert(edge); + if (edge->getDstNode()->getFun() == callee) edges.insert(edge); } } - virtual inline void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode* actualOut, const SVFFunction* callee, SVFGEdgeSetTy& edges) + virtual inline void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode* actualOut, const SVFFunction* callee, + SVFGEdgeSetTy& edges) { - for (SVFGNode::const_iterator inIt = actualOut->InEdgeBegin(), inEit = actualOut->InEdgeEnd(); inIt != inEit; ++inIt) + for (SVFGNode::const_iterator inIt = actualOut->InEdgeBegin(), inEit = actualOut->InEdgeEnd(); inIt != inEit; + ++inIt) { SVFGEdge* edge = *inIt; - if (edge->getSrcNode()->getFun() == callee) - edges.insert(edge); + if (edge->getSrcNode()->getFun() == callee) edges.insert(edge); } } //@} - /// Given a PAGNode, set/get its def SVFG node (definition of top level pointers) //@{ inline void setDef(const PAGNode* pagNode, const SVFGNode* node) @@ -368,7 +370,7 @@ class SVFG : public VFG inline void setDef(const MRVer* mvar, const SVFGNode* node) { MSSAVarToDefMapTy::iterator it = MSSAVarToDefMap.find(mvar); - if(it==MSSAVarToDefMap.end()) + if (it == MSSAVarToDefMap.end()) { MSSAVarToDefMap[mvar] = node->getId(); assert(hasSVFGNode(node->getId()) && "not in the map!!"); @@ -381,7 +383,7 @@ class SVFG : public VFG inline NodeID getDef(const MRVer* mvar) const { MSSAVarToDefMapTy::const_iterator it = MSSAVarToDefMap.find(mvar); - assert(it!=MSSAVarToDefMap.end() && "memory SSA does not have a definition??"); + assert(it != MSSAVarToDefMap.end() && "memory SSA does not have a definition??"); return it->second; } //@} @@ -400,11 +402,11 @@ class SVFG : public VFG } /// Add memory Function entry chi SVFG node - inline void addFormalINSVFGNode(const FunEntryICFGNode* funEntry, const MRVer* resVer, const NodeID nodeId) + inline void addFormalINSVFGNode(const FunEntryICFGNode* funEntry, const MRVer* resVer, const NodeID nodeId) { FormalINSVFGNode* sNode = new FormalINSVFGNode(nodeId, resVer, funEntry); addSVFGNode(sNode, pag->getICFG()->getFunEntryICFGNode(funEntry->getFun())); - setDef(resVer,sNode); + setDef(resVer, sNode); funToFormalINMap[funEntry->getFun()].set(sNode->getId()); } @@ -412,7 +414,7 @@ class SVFG : public VFG inline void addFormalOUTSVFGNode(const FunExitICFGNode* funExit, const MRVer* ver, const NodeID nodeId) { FormalOUTSVFGNode* sNode = new FormalOUTSVFGNode(nodeId, ver, funExit); - addSVFGNode(sNode,pag->getICFG()->getFunExitICFGNode(funExit->getFun())); + addSVFGNode(sNode, pag->getICFG()->getFunExitICFGNode(funExit->getFun())); funToFormalOUTMap[funExit->getFun()].set(sNode->getId()); } @@ -420,7 +422,7 @@ class SVFG : public VFG inline void addActualINSVFGNode(const CallICFGNode* callsite, const MRVer* ver, const NodeID nodeId) { ActualINSVFGNode* sNode = new ActualINSVFGNode(nodeId, callsite, ver); - addSVFGNode(sNode,pag->getICFG()->getCallICFGNode(callsite->getCallSite())); + addSVFGNode(sNode, pag->getICFG()->getCallICFGNode(callsite->getCallSite())); callSiteToActualINMap[callsite].set(sNode->getId()); } @@ -429,28 +431,30 @@ class SVFG : public VFG { ActualOUTSVFGNode* sNode = new ActualOUTSVFGNode(nodeId, callsite, resVer); addSVFGNode(sNode, pag->getICFG()->getRetICFGNode(callsite->getCallSite())); - setDef(resVer,sNode); + setDef(resVer, sNode); callSiteToActualOUTMap[callsite].set(sNode->getId()); } /// Add memory SSA PHI SVFG node - inline void addIntraMSSAPHISVFGNode(ICFGNode* BlockICFGNode, const Map::const_iterator opVerBegin, - const Map::const_iterator opVerEnd, const MRVer* resVer, const NodeID nodeId) + inline void addIntraMSSAPHISVFGNode(ICFGNode* BlockICFGNode, + const Map::const_iterator opVerBegin, + const Map::const_iterator opVerEnd, const MRVer* resVer, + const NodeID nodeId) { IntraMSSAPHISVFGNode* sNode = new IntraMSSAPHISVFGNode(nodeId, resVer); addSVFGNode(sNode, BlockICFGNode); - for(MemSSA::PHI::OPVers::const_iterator it = opVerBegin, eit=opVerEnd; it!=eit; ++it) - sNode->setOpVer(it->first,it->second); - setDef(resVer,sNode); + for (MemSSA::PHI::OPVers::const_iterator it = opVerBegin, eit = opVerEnd; it != eit; ++it) + sNode->setOpVer(it->first, it->second); + setDef(resVer, sNode); } /// Has function for EntryCHI/RetMU/CallCHI/CallMU //@{ - inline bool hasFuncEntryChi(const SVFFunction* func) const + inline bool hasFuncEntryChi(const SVFFunction* func) const { return (funToFormalINMap.find(func) != funToFormalINMap.end()); } - inline bool hasFuncRetMu(const SVFFunction* func) const + inline bool hasFuncRetMu(const SVFFunction* func) const { return (funToFormalOUTMap.find(func) != funToFormalOUTMap.end()); } @@ -473,19 +477,22 @@ namespace SVF * GenericGraphTraits specializations for SVFG to be used for generic graph algorithms. * Provide graph traits for traversing from a SVFG node using standard graph traversals. */ -//template<> struct GenericGraphTraits: public GenericGraphTraits* > { -//}; +// template<> struct GenericGraphTraits: public +// GenericGraphTraits* > { +// }; // ///// Inverse GenericGraphTraits specializations for Value flow node, it is used for inverse traversal. -//template<> -//struct GenericGraphTraits > : public GenericGraphTraits* > > { -//}; +// template<> +// struct GenericGraphTraits > : public +// GenericGraphTraits* > > { +// }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::SVFGNode *NodeRef; + typedef SVF::SVFGNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* SVFG_H_ */ diff --git a/svf/include/Graphs/SVFGEdge.h b/svf/include/Graphs/SVFGEdge.h index 750af6b03..69c0df55a 100644 --- a/svf/include/Graphs/SVFGEdge.h +++ b/svf/include/Graphs/SVFGEdge.h @@ -44,13 +44,13 @@ class IndirectSVFGEdge : public VFGEdge public: typedef Set MRVerSet; + private: NodeBS cpts; + public: /// Constructor - IndirectSVFGEdge(VFGNode* s, VFGNode* d, GEdgeFlag k): VFGEdge(s,d,k) - { - } + IndirectSVFGEdge(VFGNode* s, VFGNode* d, GEdgeFlag k) : VFGEdge(s, d, k) {} /// Handle memory region //@{ inline bool addPointsTo(const NodeBS& c) @@ -65,23 +65,19 @@ class IndirectSVFGEdge : public VFGEdge /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const IndirectSVFGEdge *) + static inline bool classof(const IndirectSVFGEdge*) { return true; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { - return edge->getEdgeKind() == IntraIndirectVF || - edge->getEdgeKind() == CallIndVF || - edge->getEdgeKind() == RetIndVF || - edge->getEdgeKind() == TheadMHPIndirectVF; + return edge->getEdgeKind() == IntraIndirectVF || edge->getEdgeKind() == CallIndVF || + edge->getEdgeKind() == RetIndVF || edge->getEdgeKind() == TheadMHPIndirectVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { - return edge->getEdgeKind() == IntraIndirectVF || - edge->getEdgeKind() == CallIndVF || - edge->getEdgeKind() == RetIndVF || - edge->getEdgeKind() == TheadMHPIndirectVF; + return edge->getEdgeKind() == IntraIndirectVF || edge->getEdgeKind() == CallIndVF || + edge->getEdgeKind() == RetIndVF || edge->getEdgeKind() == TheadMHPIndirectVF; } //@} @@ -95,23 +91,21 @@ class IntraIndSVFGEdge : public IndirectSVFGEdge { public: - IntraIndSVFGEdge(VFGNode* s, VFGNode* d): IndirectSVFGEdge(s,d,IntraIndirectVF) - { - } + IntraIndSVFGEdge(VFGNode* s, VFGNode* d) : IndirectSVFGEdge(s, d, IntraIndirectVF) {} //@{ Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntraIndSVFGEdge*) { return true; } - static inline bool classof(const IndirectSVFGEdge *edge) + static inline bool classof(const IndirectSVFGEdge* edge) { return edge->getEdgeKind() == IntraIndirectVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { return edge->getEdgeKind() == IntraIndirectVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { return edge->getEdgeKind() == IntraIndirectVF; } @@ -128,9 +122,10 @@ class CallIndSVFGEdge : public IndirectSVFGEdge private: CallSiteID csId; + public: - CallIndSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id): - IndirectSVFGEdge(s,d,makeEdgeFlagWithInvokeID(CallIndVF,id)),csId(id) + CallIndSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id) + : IndirectSVFGEdge(s, d, makeEdgeFlagWithInvokeID(CallIndVF, id)), csId(id) { } inline CallSiteID getCallSiteId() const @@ -138,21 +133,21 @@ class CallIndSVFGEdge : public IndirectSVFGEdge return csId; } //@{ Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const CallIndSVFGEdge *) + static inline bool classof(const CallIndSVFGEdge*) { return true; } - static inline bool classof(const IndirectSVFGEdge *edge) + static inline bool classof(const IndirectSVFGEdge* edge) { return edge->getEdgeKind() == CallIndVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { - return edge->getEdgeKind() == CallIndVF ; + return edge->getEdgeKind() == CallIndVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { - return edge->getEdgeKind() == CallIndVF ; + return edge->getEdgeKind() == CallIndVF; } //@} @@ -167,9 +162,10 @@ class RetIndSVFGEdge : public IndirectSVFGEdge private: CallSiteID csId; + public: - RetIndSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id): - IndirectSVFGEdge(s,d,makeEdgeFlagWithInvokeID(RetIndVF,id)),csId(id) + RetIndSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id) + : IndirectSVFGEdge(s, d, makeEdgeFlagWithInvokeID(RetIndVF, id)), csId(id) { } inline CallSiteID getCallSiteId() const @@ -177,19 +173,19 @@ class RetIndSVFGEdge : public IndirectSVFGEdge return csId; } //@{ Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const RetIndSVFGEdge *) + static inline bool classof(const RetIndSVFGEdge*) { return true; } - static inline bool classof(const IndirectSVFGEdge *edge) + static inline bool classof(const IndirectSVFGEdge* edge) { return edge->getEdgeKind() == RetIndVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { return edge->getEdgeKind() == RetIndVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { return edge->getEdgeKind() == RetIndVF; } @@ -198,7 +194,6 @@ class RetIndSVFGEdge : public IndirectSVFGEdge virtual const std::string toString() const; }; - /*! * MHP SVFG edge representing indirect value-flows between * two memory access may-happen-in-parallel in multithreaded program @@ -207,23 +202,21 @@ class ThreadMHPIndSVFGEdge : public IndirectSVFGEdge { public: - ThreadMHPIndSVFGEdge(VFGNode* s, VFGNode* d): IndirectSVFGEdge(s,d,TheadMHPIndirectVF) - { - } + ThreadMHPIndSVFGEdge(VFGNode* s, VFGNode* d) : IndirectSVFGEdge(s, d, TheadMHPIndirectVF) {} //@{ Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ThreadMHPIndSVFGEdge*) { return true; } - static inline bool classof(const IndirectSVFGEdge *edge) + static inline bool classof(const IndirectSVFGEdge* edge) { return edge->getEdgeKind() == TheadMHPIndirectVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { return edge->getEdgeKind() == TheadMHPIndirectVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { return edge->getEdgeKind() == TheadMHPIndirectVF; } diff --git a/svf/include/Graphs/SVFGNode.h b/svf/include/Graphs/SVFGNode.h index 1136b074c..76e90c4f9 100644 --- a/svf/include/Graphs/SVFGNode.h +++ b/svf/include/Graphs/SVFGNode.h @@ -58,28 +58,20 @@ class MRSVFGNode : public VFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const MRSVFGNode *) + static inline bool classof(const MRSVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { - return node->getNodeKind() == FPIN || - node->getNodeKind() == FPOUT || - node->getNodeKind() == APIN || - node->getNodeKind() == APOUT || - node->getNodeKind() == MPhi || - node->getNodeKind() == MIntraPhi || + return node->getNodeKind() == FPIN || node->getNodeKind() == FPOUT || node->getNodeKind() == APIN || + node->getNodeKind() == APOUT || node->getNodeKind() == MPhi || node->getNodeKind() == MIntraPhi || node->getNodeKind() == MInterPhi; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { - return node->getNodeKind() == FPIN || - node->getNodeKind() == FPOUT || - node->getNodeKind() == APIN || - node->getNodeKind() == APOUT || - node->getNodeKind() == MPhi || - node->getNodeKind() == MIntraPhi || + return node->getNodeKind() == FPIN || node->getNodeKind() == FPOUT || node->getNodeKind() == APIN || + node->getNodeKind() == APOUT || node->getNodeKind() == MPhi || node->getNodeKind() == MIntraPhi || node->getNodeKind() == MInterPhi; } //@} @@ -98,7 +90,7 @@ class FormalINSVFGNode : public MRSVFGNode public: /// Constructor - FormalINSVFGNode(NodeID id, const MRVer* resVer, const FunEntryICFGNode* funEntry): MRSVFGNode(id, FPIN) + FormalINSVFGNode(NodeID id, const MRVer* resVer, const FunEntryICFGNode* funEntry) : MRSVFGNode(id, FPIN) { cpts = resVer->getMR()->getPointsTo(); ver = resVer; @@ -114,15 +106,15 @@ class FormalINSVFGNode : public MRSVFGNode } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const FormalINSVFGNode *) + static inline bool classof(const FormalINSVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == FPIN; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == FPIN; } @@ -131,7 +123,6 @@ class FormalINSVFGNode : public MRSVFGNode virtual const std::string toString() const; }; - /* * SVFG Node stands for return mu node (address-taken variables) */ @@ -156,15 +147,15 @@ class FormalOUTSVFGNode : public MRSVFGNode } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const FormalOUTSVFGNode *) + static inline bool classof(const FormalOUTSVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == FPOUT; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == FPOUT; } @@ -173,7 +164,6 @@ class FormalOUTSVFGNode : public MRSVFGNode virtual const std::string toString() const; }; - /* * SVFG Node stands for callsite mu node (address-taken variables) */ @@ -182,10 +172,10 @@ class ActualINSVFGNode : public MRSVFGNode private: const CallICFGNode* cs; const MRVer* ver; + public: /// Constructor - ActualINSVFGNode(NodeID id, const CallICFGNode* c, const MRVer* mrver): - MRSVFGNode(id, APIN), cs(c) + ActualINSVFGNode(NodeID id, const CallICFGNode* c, const MRVer* mrver) : MRSVFGNode(id, APIN), cs(c) { cpts = mrver->getMR()->getPointsTo(); ver = mrver; @@ -202,18 +192,17 @@ class ActualINSVFGNode : public MRSVFGNode return ver; } - /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const ActualINSVFGNode *) + static inline bool classof(const ActualINSVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == APIN; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == APIN; } @@ -222,7 +211,6 @@ class ActualINSVFGNode : public MRSVFGNode virtual const std::string toString() const; }; - /* * SVFG Node stands for callsite chi node (address-taken variables) */ @@ -234,8 +222,7 @@ class ActualOUTSVFGNode : public MRSVFGNode public: /// Constructor - ActualOUTSVFGNode(NodeID id, const CallICFGNode* cal, const MRVer* resVer): - MRSVFGNode(id, APOUT), cs(cal) + ActualOUTSVFGNode(NodeID id, const CallICFGNode* cal, const MRVer* resVer) : MRSVFGNode(id, APOUT), cs(cal) { cpts = resVer->getMR()->getPointsTo(); ver = resVer; @@ -252,15 +239,15 @@ class ActualOUTSVFGNode : public MRSVFGNode } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const ActualOUTSVFGNode *) + static inline bool classof(const ActualOUTSVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == APOUT; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == APOUT; } @@ -269,14 +256,13 @@ class ActualOUTSVFGNode : public MRSVFGNode virtual const std::string toString() const; }; - /* * SVFG Node stands for a memory ssa phi node or formalIn or ActualOut */ class MSSAPHISVFGNode : public MRSVFGNode { public: - typedef Map OPVers; + typedef Map OPVers; protected: const MRVer* ver; @@ -284,7 +270,7 @@ class MSSAPHISVFGNode : public MRSVFGNode public: /// Constructor - MSSAPHISVFGNode(NodeID id, const MRVer* resVer,VFGNodeK k = MPhi): MRSVFGNode(id, k) + MSSAPHISVFGNode(NodeID id, const MRVer* resVer, VFGNodeK k = MPhi) : MRSVFGNode(id, k) { cpts = resVer->getMR()->getPointsTo(); ver = resVer; @@ -299,7 +285,7 @@ class MSSAPHISVFGNode : public MRSVFGNode inline const MRVer* getOpVer(u32_t pos) const { OPVers::const_iterator it = opVers.find(pos); - assert(it!=opVers.end() && "version is nullptr, did not rename?"); + assert(it != opVers.end() && "version is nullptr, did not rename?"); return it->second; } inline void setOpVer(u32_t pos, const MRVer* node) @@ -322,19 +308,19 @@ class MSSAPHISVFGNode : public MRSVFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const MSSAPHISVFGNode *) + static inline bool classof(const MSSAPHISVFGNode*) { return true; } - static inline bool classof(const MRSVFGNode *node) + static inline bool classof(const MRSVFGNode* node) { return (node->getNodeKind() == MPhi || node->getNodeKind() == MIntraPhi || node->getNodeKind() == MInterPhi); } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return (node->getNodeKind() == MPhi || node->getNodeKind() == MIntraPhi || node->getNodeKind() == MInterPhi); } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return (node->getNodeKind() == MPhi || node->getNodeKind() == MIntraPhi || node->getNodeKind() == MInterPhi); } @@ -351,9 +337,7 @@ class IntraMSSAPHISVFGNode : public MSSAPHISVFGNode public: /// Constructor - IntraMSSAPHISVFGNode(NodeID id, const MRVer* resVer): MSSAPHISVFGNode(id, resVer, MIntraPhi) - { - } + IntraMSSAPHISVFGNode(NodeID id, const MRVer* resVer) : MSSAPHISVFGNode(id, resVer, MIntraPhi) {} inline const MRVer* getMRVer() const { @@ -372,23 +356,23 @@ class IntraMSSAPHISVFGNode : public MSSAPHISVFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const IntraMSSAPHISVFGNode *) + static inline bool classof(const IntraMSSAPHISVFGNode*) { return true; } - static inline bool classof(const MSSAPHISVFGNode * node) + static inline bool classof(const MSSAPHISVFGNode* node) { return node->getNodeKind() == MIntraPhi; } - static inline bool classof(const MRSVFGNode *node) + static inline bool classof(const MRSVFGNode* node) { return node->getNodeKind() == MIntraPhi; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == MIntraPhi; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == MIntraPhi; } @@ -397,7 +381,6 @@ class IntraMSSAPHISVFGNode : public MSSAPHISVFGNode virtual const std::string toString() const; }; - /* * Inter MSSA PHI (formalIN/ActualOUT) */ @@ -406,18 +389,24 @@ class InterMSSAPHISVFGNode : public MSSAPHISVFGNode public: /// Constructor interPHI for formal parameter - InterMSSAPHISVFGNode(NodeID id, const FormalINSVFGNode* fi) : MSSAPHISVFGNode(id, fi->getMRVer(), MInterPhi),fun(fi->getFun()),callInst(nullptr) {} + InterMSSAPHISVFGNode(NodeID id, const FormalINSVFGNode* fi) + : MSSAPHISVFGNode(id, fi->getMRVer(), MInterPhi), fun(fi->getFun()), callInst(nullptr) + { + } /// Constructor interPHI for actual return - InterMSSAPHISVFGNode(NodeID id, const ActualOUTSVFGNode* ao) : MSSAPHISVFGNode(id, ao->getMRVer(), MInterPhi), fun(nullptr),callInst(ao->getCallSite()) {} + InterMSSAPHISVFGNode(NodeID id, const ActualOUTSVFGNode* ao) + : MSSAPHISVFGNode(id, ao->getMRVer(), MInterPhi), fun(nullptr), callInst(ao->getCallSite()) + { + } inline bool isFormalINPHI() const { - return (fun!=nullptr) && (callInst == nullptr); + return (fun != nullptr) && (callInst == nullptr); } inline bool isActualOUTPHI() const { - return (fun==nullptr) && (callInst != nullptr); + return (fun == nullptr) && (callInst != nullptr); } inline const SVFFunction* getFun() const @@ -434,23 +423,23 @@ class InterMSSAPHISVFGNode : public MSSAPHISVFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const InterMSSAPHISVFGNode *) + static inline bool classof(const InterMSSAPHISVFGNode*) { return true; } - static inline bool classof(const MSSAPHISVFGNode * node) + static inline bool classof(const MSSAPHISVFGNode* node) { return node->getNodeKind() == MInterPhi; } - static inline bool classof(const MRSVFGNode *node) + static inline bool classof(const MRSVFGNode* node) { return node->getNodeKind() == MInterPhi; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == MInterPhi; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == MInterPhi; } @@ -471,7 +460,8 @@ class DummyVersionPropSVFGNode : public VFGNode public: DummyVersionPropSVFGNode(NodeID id, NodeID object, Version version) : VFGNode(id, DummyVProp), object(object), version(version) - { } + { + } NodeID getObject(void) const { @@ -484,17 +474,17 @@ class DummyVersionPropSVFGNode : public VFGNode /// Methods to support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const DummyVersionPropSVFGNode *) + static inline bool classof(const DummyVersionPropSVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == DummyVProp; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == DummyVProp; } @@ -507,7 +497,6 @@ class DummyVersionPropSVFGNode : public VFGNode const Version version; }; - } // End namespace SVF #endif /* INCLUDE_MSSA_SVFGNODE_H_ */ diff --git a/svf/include/Graphs/SVFGOPT.h b/svf/include/Graphs/SVFGOPT.h index f8e739fcf..78e3e7e7f 100644 --- a/svf/include/Graphs/SVFGOPT.h +++ b/svf/include/Graphs/SVFGOPT.h @@ -32,11 +32,9 @@ * */ - #ifndef SVFGOPT_H_ #define SVFGOPT_H_ - #include "Graphs/SVFG.h" #include "Util/WorkList.h" @@ -86,7 +84,8 @@ class SVFGOPT : public SVFG /// Connect SVFG nodes between caller and callee for indirect call sites //@{ - inline void connectAParamAndFParam(const PAGNode* cs_arg, const PAGNode* fun_arg, const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) override + inline void connectAParamAndFParam(const PAGNode* cs_arg, const PAGNode* fun_arg, const CallICFGNode*, + CallSiteID csId, SVFGEdgeSetTy& edges) override { NodeID phiId = getDef(fun_arg); SVFGEdge* edge = addCallEdge(getDef(cs_arg), phiId, csId); @@ -98,15 +97,16 @@ class SVFGOPT : public SVFG } } /// Connect formal-ret and actual ret - inline void connectFRetAndARet(const PAGNode* fun_ret, const PAGNode* cs_ret, CallSiteID csId, SVFGEdgeSetTy& edges) override + inline void connectFRetAndARet(const PAGNode* fun_ret, const PAGNode* cs_ret, CallSiteID csId, + SVFGEdgeSetTy& edges) override { NodeID phiId = getDef(cs_ret); NodeID retdef = getDef(fun_ret); - /// If a function does not have any return instruction. The def of a FormalRetVFGNode is itself (see VFG.h: addFormalRetVFGNode). - /// Therefore, we do not connect return edge from a function without any return instruction (i.e., pag->isPhiNode(fun_ret)==false) - /// because unique fun_ret PAGNode was not collected as a PhiNode in SVFIRBuilder::visitReturnInst - if (pag->isPhiNode(fun_ret)==false) - return; + /// If a function does not have any return instruction. The def of a FormalRetVFGNode is itself (see VFG.h: + /// addFormalRetVFGNode). Therefore, we do not connect return edge from a function without any return + /// instruction (i.e., pag->isPhiNode(fun_ret)==false) because unique fun_ret PAGNode was not collected as a + /// PhiNode in SVFIRBuilder::visitReturnInst + if (pag->isPhiNode(fun_ret) == false) return; SVFGEdge* edge = addRetEdge(retdef, phiId, csId); if (edge != nullptr) @@ -117,29 +117,29 @@ class SVFGOPT : public SVFG } } /// Connect actual-in and formal-in - inline void connectAInAndFIn(const ActualINSVFGNode* actualIn, const FormalINSVFGNode* formalIn, CallSiteID csId, SVFGEdgeSetTy& edges) override + inline void connectAInAndFIn(const ActualINSVFGNode* actualIn, const FormalINSVFGNode* formalIn, CallSiteID csId, + SVFGEdgeSetTy& edges) override { NodeBS intersection = actualIn->getPointsTo(); intersection &= formalIn->getPointsTo(); if (intersection.empty() == false) { NodeID aiDef = getActualINDef(actualIn->getId()); - SVFGEdge* edge = addCallIndirectSVFGEdge(aiDef,formalIn->getId(),csId,intersection); - if (edge != nullptr) - edges.insert(edge); + SVFGEdge* edge = addCallIndirectSVFGEdge(aiDef, formalIn->getId(), csId, intersection); + if (edge != nullptr) edges.insert(edge); } } /// Connect formal-out and actual-out - inline void connectFOutAndAOut(const FormalOUTSVFGNode* formalOut, const ActualOUTSVFGNode* actualOut, CallSiteID csId, SVFGEdgeSetTy& edges) override + inline void connectFOutAndAOut(const FormalOUTSVFGNode* formalOut, const ActualOUTSVFGNode* actualOut, + CallSiteID csId, SVFGEdgeSetTy& edges) override { NodeBS intersection = formalOut->getPointsTo(); intersection &= actualOut->getPointsTo(); if (intersection.empty() == false) { NodeID foDef = getFormalOUTDef(formalOut->getId()); - SVFGEdge* edge = addRetIndirectSVFGEdge(foDef,actualOut->getId(),csId,intersection); - if (edge != nullptr) - edges.insert(edge); + SVFGEdge* edge = addRetIndirectSVFGEdge(foDef, actualOut->getId(), csId, intersection); + if (edge != nullptr) edges.insert(edge); } } //@} @@ -201,8 +201,7 @@ class SVFGOPT : public SVFG /// Initial work list with MSSAPHI nodes which may be removed. inline void initialWorkList() { - for (SVFG::const_iterator it = begin(), eit = end(); it != eit; ++it) - addIntoWorklist(it->second); + for (SVFG::const_iterator it = begin(), eit = end(); it != eit; ++it) addIntoWorklist(it->second); } /// Only MSSAPHI node which satisfy following conditions will be removed: @@ -212,8 +211,7 @@ class SVFGOPT : public SVFG { if (const MSSAPHISVFGNode* phi = SVFUtil::dyn_cast(node)) { - if (isConnectingTwoCallSites(phi) == false && isDefOfAInFOut(phi) == false) - return worklist.push(phi); + if (isConnectingTwoCallSites(phi) == false && isDefOfAInFOut(phi) == false) return worklist.push(phi); } return false; } @@ -243,17 +241,17 @@ class SVFGOPT : public SVFG /// Add inter PHI SVFG node for formal parameter inline InterPHISVFGNode* addInterPHIForFP(const FormalParmSVFGNode* fp) { - InterPHISVFGNode* sNode = new InterPHISVFGNode(totalVFGNode++,fp); + InterPHISVFGNode* sNode = new InterPHISVFGNode(totalVFGNode++, fp); addSVFGNode(sNode, pag->getICFG()->getFunEntryICFGNode(fp->getFun())); - resetDef(fp->getParam(),sNode); + resetDef(fp->getParam(), sNode); return sNode; } /// Add inter PHI SVFG node for actual return inline InterPHISVFGNode* addInterPHIForAR(const ActualRetSVFGNode* ar) { - InterPHISVFGNode* sNode = new InterPHISVFGNode(totalVFGNode++,ar); + InterPHISVFGNode* sNode = new InterPHISVFGNode(totalVFGNode++, ar); addSVFGNode(sNode, pag->getICFG()->getRetICFGNode(ar->getCallSite()->getCallSite())); - resetDef(ar->getRev(),sNode); + resetDef(ar->getRev(), sNode); return sNode; } @@ -276,7 +274,7 @@ class SVFGOPT : public SVFG inline void setFormalOUTDef(NodeID fo, NodeID def) { bool inserted = formalOutToDefMap.emplace(fo, def).second; - (void) inserted; + (void)inserted; assert(inserted && "can not set formal-out's def twice"); defNodes.set(def); } @@ -323,7 +321,7 @@ class SVFGOPT : public SVFG /// 4. ActualOUT if it doesn't reside at indirect call site and it's not definition site /// of FormalOUT /// 5. FormalOUT if it doesn't reside at the exit of address-taken function - bool canBeRemoved(const SVFGNode * node); + bool canBeRemoved(const SVFGNode* node); /// Remove edges of a SVFG node //@{ @@ -335,22 +333,19 @@ class SVFGOPT : public SVFG inline void removeInEdges(const SVFGNode* node) { /// remove incoming edges - while (node->hasIncomingEdge()) - removeSVFGEdge(*(node->InEdgeBegin())); + while (node->hasIncomingEdge()) removeSVFGEdge(*(node->InEdgeBegin())); } inline void removeOutEdges(const SVFGNode* node) { - while (node->hasOutgoingEdge()) - removeSVFGEdge(*(node->OutEdgeBegin())); + while (node->hasOutgoingEdge()) removeSVFGEdge(*(node->OutEdgeBegin())); } //@} + NodeIDToNodeIDMap actualInToDefMap; ///< map actual-in to its def-site node + NodeIDToNodeIDMap formalOutToDefMap; ///< map formal-out to its def-site node + NodeBS defNodes; ///< preserved def nodes of formal-in/actual-out - NodeIDToNodeIDMap actualInToDefMap; ///< map actual-in to its def-site node - NodeIDToNodeIDMap formalOutToDefMap; ///< map formal-out to its def-site node - NodeBS defNodes; ///< preserved def nodes of formal-in/actual-out - - WorkList worklist; ///< storing MSSAPHI nodes which may be removed. + WorkList worklist; ///< storing MSSAPHI nodes which may be removed. bool keepActualOutFormalIn; bool keepAllSelfCycle; diff --git a/svf/include/Graphs/SVFGStat.h b/svf/include/Graphs/SVFGStat.h index c9b289111..728687702 100644 --- a/svf/include/Graphs/SVFGStat.h +++ b/svf/include/Graphs/SVFGStat.h @@ -32,7 +32,6 @@ * */ - #ifndef SVFGSTAT_H_ #define SVFGSTAT_H_ @@ -49,37 +48,34 @@ class MemSSAStat : public PTAStat { public: - static const char* TotalTimeOfConstructMemSSA; ///< Total time for constructing memory SSA - static const char* TimeOfGeneratingMemRegions; ///< Time for allocating regions - static const char* TimeOfCreateMUCHI; ///< Time for generating mu/chi for load/store/calls - static const char* TimeOfInsertingPHI; ///< Time for inserting phis - static const char* TimeOfSSARenaming; ///< Time for SSA rename - - static const char* NumOfMaxRegion; ///< Number of max points-to set in region. - static const char* NumOfAveragePtsInRegion; ///< Number of average points-to set in region. - static const char* NumOfMemRegions; ///< Number of memory regions - static const char* NumOfEntryChi; ///< Number of function entry chi - static const char* NumOfRetMu; ///< Number of function return mu - static const char* NumOfCSChi; ///< Number of call site chi - static const char* NumOfCSMu; ///< Number of call site mu - static const char* NumOfLoadMu; ///< Number of load mu - static const char* NumOfStoreChi; ///< Number of store chi - static const char* NumOfMSSAPhi; ///< Number of mssa phi - - static const char* NumOfFunHasEntryChi; ///< Number of functions which have entry chi - static const char* NumOfFunHasRetMu; ///< Number of functions which have return mu - static const char* NumOfCSHasChi; ///< Number of call sites which have chi - static const char* NumOfCSHasMu; ///< Number of call sites which have mu - static const char* NumOfLoadHasMu; ///< Number of loads which have mu - static const char* NumOfStoreHasChi; ///< Number of stores which have chi - static const char* NumOfBBHasMSSAPhi; ///< Number of basic blocks which have mssa phi + static const char* TotalTimeOfConstructMemSSA; ///< Total time for constructing memory SSA + static const char* TimeOfGeneratingMemRegions; ///< Time for allocating regions + static const char* TimeOfCreateMUCHI; ///< Time for generating mu/chi for load/store/calls + static const char* TimeOfInsertingPHI; ///< Time for inserting phis + static const char* TimeOfSSARenaming; ///< Time for SSA rename + + static const char* NumOfMaxRegion; ///< Number of max points-to set in region. + static const char* NumOfAveragePtsInRegion; ///< Number of average points-to set in region. + static const char* NumOfMemRegions; ///< Number of memory regions + static const char* NumOfEntryChi; ///< Number of function entry chi + static const char* NumOfRetMu; ///< Number of function return mu + static const char* NumOfCSChi; ///< Number of call site chi + static const char* NumOfCSMu; ///< Number of call site mu + static const char* NumOfLoadMu; ///< Number of load mu + static const char* NumOfStoreChi; ///< Number of store chi + static const char* NumOfMSSAPhi; ///< Number of mssa phi + + static const char* NumOfFunHasEntryChi; ///< Number of functions which have entry chi + static const char* NumOfFunHasRetMu; ///< Number of functions which have return mu + static const char* NumOfCSHasChi; ///< Number of call sites which have chi + static const char* NumOfCSHasMu; ///< Number of call sites which have mu + static const char* NumOfLoadHasMu; ///< Number of loads which have mu + static const char* NumOfStoreHasChi; ///< Number of stores which have chi + static const char* NumOfBBHasMSSAPhi; ///< Number of basic blocks which have mssa phi MemSSAStat(MemSSA*); - virtual ~MemSSAStat() - { - - } + virtual ~MemSSAStat() {} virtual void performStat() override; virtual void printStat(std::string str = "") override; @@ -88,7 +84,6 @@ class MemSSAStat : public PTAStat MemSSA* mssa; }; - class SVFGStat : public PTAStat { public: @@ -169,30 +164,30 @@ class SVFGStat : public PTAStat SVFG* graph; - int numOfNodes; ///< number of svfg nodes. + int numOfNodes; ///< number of svfg nodes. - int numOfFormalIn; ///< number of formal in svfg nodes. - int numOfFormalOut; ///< number of formal out svfg nodes. + int numOfFormalIn; ///< number of formal in svfg nodes. + int numOfFormalOut; ///< number of formal out svfg nodes. int numOfFormalParam; int numOfFormalRet; - int numOfActualIn; ///< number of actual in svfg nodes. - int numOfActualOut; ///< number of actual out svfg nodes. + int numOfActualIn; ///< number of actual in svfg nodes. + int numOfActualOut; ///< number of actual out svfg nodes. int numOfActualParam; int numOfActualRet; - int numOfLoad; ///< number of load svfg nodes. - int numOfStore; ///< number of store svfg nodes. + int numOfLoad; ///< number of load svfg nodes. + int numOfStore; ///< number of store svfg nodes. int numOfCopy; int numOfGep; int numOfAddr; - int numOfMSSAPhi; ///< number of mssa phi svfg nodes. + int numOfMSSAPhi; ///< number of mssa phi svfg nodes. int numOfPhi; - int totalInEdge; ///< Total number of incoming SVFG edges - int totalOutEdge; ///< Total number of outgoing SVFG edges - int totalIndInEdge; ///< Total number of indirect SVFG edges + int totalInEdge; ///< Total number of incoming SVFG edges + int totalOutEdge; ///< Total number of outgoing SVFG edges + int totalIndInEdge; ///< Total number of indirect SVFG edges int totalIndOutEdge; int totalIndEdgeLabels; ///< Total number of l --o--> lp @@ -201,17 +196,17 @@ class SVFGStat : public PTAStat int totalDirCallEdge; int totalDirRetEdge; - int avgWeight; ///< average weight. + int avgWeight; ///< average weight. - int avgInDegree; ///< average in degrees of SVFG nodes. - int avgOutDegree; ///< average out degrees of SVFG nodes. - u32_t maxInDegree; ///< max in degrees of SVFG nodes. - u32_t maxOutDegree; ///< max out degrees of SVFG nodes. + int avgInDegree; ///< average in degrees of SVFG nodes. + int avgOutDegree; ///< average out degrees of SVFG nodes. + u32_t maxInDegree; ///< max in degrees of SVFG nodes. + u32_t maxOutDegree; ///< max out degrees of SVFG nodes. - int avgIndInDegree; ///< average indirect in degrees of SVFG nodes. - int avgIndOutDegree; ///< average indirect out degrees of SVFG nodes. - u32_t maxIndInDegree; ///< max indirect in degrees of SVFG nodes. - u32_t maxIndOutDegree; ///< max indirect out degrees of SVFG nodes. + int avgIndInDegree; ///< average indirect in degrees of SVFG nodes. + int avgIndOutDegree; ///< average indirect out degrees of SVFG nodes. + u32_t maxIndInDegree; ///< max indirect in degrees of SVFG nodes. + u32_t maxIndOutDegree; ///< max indirect out degrees of SVFG nodes. double addTopLevelNodeTimeStart; double addTopLevelNodeTimeEnd; @@ -230,8 +225,8 @@ class SVFGStat : public PTAStat SVFGNodeSet forwardSlice; SVFGNodeSet backwardSlice; - SVFGNodeSet sources; - SVFGNodeSet sinks; + SVFGNodeSet sources; + SVFGNodeSet sinks; public: inline void addToSources(const SVFGNode* node) @@ -252,19 +247,19 @@ class SVFGStat : public PTAStat } inline bool inForwardSlice(const SVFGNode* node) const { - return forwardSlice.find(node)!=forwardSlice.end(); + return forwardSlice.find(node) != forwardSlice.end(); } inline bool inBackwardSlice(const SVFGNode* node) const { - return backwardSlice.find(node)!=backwardSlice.end(); + return backwardSlice.find(node) != backwardSlice.end(); } inline bool isSource(const SVFGNode* node) const { - return sources.find(node)!=sources.end(); + return sources.find(node) != sources.end(); } inline bool isSink(const SVFGNode* node) const { - return sinks.find(node)!=sinks.end(); + return sinks.find(node) != sinks.end(); } }; diff --git a/svf/include/Graphs/ThreadCallGraph.h b/svf/include/Graphs/ThreadCallGraph.h index f47de68be..9b52bb879 100644 --- a/svf/include/Graphs/ThreadCallGraph.h +++ b/svf/include/Graphs/ThreadCallGraph.h @@ -41,19 +41,17 @@ class ThreadAPI; /*! * PTA thread fork edge from fork site to the entry of a start routine function */ -class ThreadForkEdge: public CallGraphEdge +class ThreadForkEdge : public CallGraphEdge { public: /// Constructor - ThreadForkEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) : - CallGraphEdge(s, d, CallGraphEdge::TDForkEdge, csId) + ThreadForkEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) + : CallGraphEdge(s, d, CallGraphEdge::TDForkEdge, csId) { } /// Destructor - virtual ~ThreadForkEdge() - { - } + virtual ~ThreadForkEdge() {} /// ClassOf //@{ @@ -61,7 +59,7 @@ class ThreadForkEdge: public CallGraphEdge { return true; } - static inline bool classof(const CallGraphEdge *edge) + static inline bool classof(const CallGraphEdge* edge) { return edge->getEdgeKind() == CallGraphEdge::TDForkEdge; } @@ -84,25 +82,23 @@ class ThreadForkEdge: public CallGraphEdge /*! * PTA thread join edge from the exit of a start routine function to a join point of the thread */ -class ThreadJoinEdge: public CallGraphEdge +class ThreadJoinEdge : public CallGraphEdge { public: /// Constructor - ThreadJoinEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) : - CallGraphEdge(s, d, CallGraphEdge::TDJoinEdge, csId) + ThreadJoinEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) + : CallGraphEdge(s, d, CallGraphEdge::TDJoinEdge, csId) { } /// Destructor - virtual ~ThreadJoinEdge() - { - } + virtual ~ThreadJoinEdge() {} static inline bool classof(const ThreadJoinEdge*) { return true; } - static inline bool classof(const CallGraphEdge *edge) + static inline bool classof(const CallGraphEdge* edge) { return edge->getEdgeKind() == CallGraphEdge::TDJoinEdge; } @@ -124,19 +120,17 @@ class ThreadJoinEdge: public CallGraphEdge /*! * hare_parallel_for edge from fork site to the entry of a start routine function */ -class HareParForEdge: public CallGraphEdge +class HareParForEdge : public CallGraphEdge { public: /// Constructor - HareParForEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) : - CallGraphEdge(s, d, CallGraphEdge::HareParForEdge, csId) + HareParForEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) + : CallGraphEdge(s, d, CallGraphEdge::HareParForEdge, csId) { } /// Destructor - virtual ~HareParForEdge() - { - } + virtual ~HareParForEdge() {} /// ClassOf //@{ @@ -144,7 +138,7 @@ class HareParForEdge: public CallGraphEdge { return true; } - static inline bool classof(const CallGraphEdge *edge) + static inline bool classof(const CallGraphEdge* edge) { return edge->getEdgeKind() == CallGraphEdge::HareParForEdge; } @@ -153,11 +147,10 @@ class HareParForEdge: public CallGraphEdge typedef GenericNode::GEdgeSetTy ParForEdgeSet; }; - /*! * Thread sensitive call graph */ -class ThreadCallGraph: public CallGraph +class ThreadCallGraph : public CallGraph { public: @@ -174,17 +167,15 @@ class ThreadCallGraph: public CallGraph /// Constructor ThreadCallGraph(); /// Destructor - virtual ~ThreadCallGraph() - { - } + virtual ~ThreadCallGraph() {} /// ClassOf //@{ - static inline bool classof(const ThreadCallGraph *) + static inline bool classof(const ThreadCallGraph*) { return true; } - static inline bool classof(const CallGraph *g) + static inline bool classof(const CallGraph* g) { return g->getKind() == CallGraph::ThdCallGraph; } @@ -195,7 +186,6 @@ class ThreadCallGraph: public CallGraph /// Update join edge using pointer analysis results void updateJoinEdge(PointerAnalysis* pta); - /// Get call graph edge via call instruction //@{ /// whether this call instruction has a valid call graph edge @@ -237,11 +227,13 @@ class ThreadCallGraph: public CallGraph } inline void getJoinSites(const CallGraphNode* routine, InstSet& csSet) { - for(CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.begin(), eit = callinstToThreadJoinEdgesMap.end(); it!=eit; ++it) + for (CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.begin(), + eit = callinstToThreadJoinEdgesMap.end(); + it != eit; ++it) { - for(JoinEdgeSet::const_iterator jit = it->second.begin(), ejit = it->second.end(); jit!=ejit; ++jit) + for (JoinEdgeSet::const_iterator jit = it->second.begin(), ejit = it->second.end(); jit != ejit; ++jit) { - if((*jit)->getDstNode() == routine) + if ((*jit)->getDstNode() == routine) { csSet.insert(it->first); } @@ -351,14 +343,13 @@ class ThreadCallGraph: public CallGraph /// Add thread join edges //@{ - void addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forksite); + void addDirectJoinEdge(const CallICFGNode* cs, const CallSiteSet& forksite); //@} - /// map call instruction to its CallGraphEdge map inline void addThreadForkEdgeSetMap(const CallICFGNode* cs, ThreadForkEdge* edge) { - if(edge!=nullptr) + if (edge != nullptr) { callinstToThreadForkEdgesMap[cs].insert(edge); callinstToCallGraphEdgesMap[cs].insert(edge); @@ -368,7 +359,7 @@ class ThreadCallGraph: public CallGraph /// map call instruction to its CallGraphEdge map inline void addThreadJoinEdgeSetMap(const CallICFGNode* cs, ThreadJoinEdge* edge) { - if(edge!=nullptr) + if (edge != nullptr) { callinstToThreadJoinEdgesMap[cs].insert(edge); callinstToCallGraphEdgesMap[cs].insert(edge); @@ -378,7 +369,7 @@ class ThreadCallGraph: public CallGraph /// map call instruction to its CallGraphEdge map inline void addHareParForEdgeSetMap(const CallICFGNode* cs, HareParForEdge* edge) { - if(edge!=nullptr) + if (edge != nullptr) { callinstToHareParForEdgesMap[cs].insert(edge); callinstToCallGraphEdgesMap[cs].insert(edge); @@ -386,27 +377,28 @@ class ThreadCallGraph: public CallGraph } /// has thread join edge - inline ThreadJoinEdge* hasThreadJoinEdge(const CallICFGNode* call, CallGraphNode* joinFunNode, CallGraphNode* threadRoutineFunNode, CallSiteID csId) const + inline ThreadJoinEdge* hasThreadJoinEdge(const CallICFGNode* call, CallGraphNode* joinFunNode, + CallGraphNode* threadRoutineFunNode, CallSiteID csId) const { - ThreadJoinEdge joinEdge(joinFunNode,threadRoutineFunNode, csId); + ThreadJoinEdge joinEdge(joinFunNode, threadRoutineFunNode, csId); CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(call); - if(it != callinstToThreadJoinEdgesMap.end()) + if (it != callinstToThreadJoinEdgesMap.end()) { JoinEdgeSet::const_iterator jit = it->second.find(&joinEdge); - if(jit!=it->second.end()) - return *jit; + if (jit != it->second.end()) return *jit; } return nullptr; } private: - ThreadAPI* tdAPI; ///< Thread API - CallSiteSet forksites; ///< all thread fork sites - CallSiteSet joinsites; ///< all thread fork sites - CallSiteSet parForSites; ///< all parallel for sites + ThreadAPI* tdAPI; ///< Thread API + CallSiteSet forksites; ///< all thread fork sites + CallSiteSet joinsites; ///< all thread fork sites + CallSiteSet parForSites; ///< all parallel for sites CallInstToForkEdgesMap callinstToThreadForkEdgesMap; ///< Map a call instruction to its corresponding fork edges CallInstToJoinEdgesMap callinstToThreadJoinEdgesMap; ///< Map a call instruction to its corresponding join edges - CallInstToParForEdgesMap callinstToHareParForEdgesMap; ///< Map a call instruction to its corresponding hare_parallel_for edges + CallInstToParForEdgesMap + callinstToHareParForEdgesMap; ///< Map a call instruction to its corresponding hare_parallel_for edges }; } // End namespace SVF diff --git a/svf/include/Graphs/VFG.h b/svf/include/Graphs/VFG.h index 9fea72d1f..a9772f72b 100644 --- a/svf/include/Graphs/VFG.h +++ b/svf/include/Graphs/VFG.h @@ -30,7 +30,6 @@ #ifndef INCLUDE_UTIL_VFG_H_ #define INCLUDE_UTIL_VFG_H_ - #include "SVFIR/SVFIR.h" #include "Graphs/CallGraph.h" #include "Graphs/VFGNode.h" @@ -46,7 +45,7 @@ class CallICFGNode; /*! * Value Flow Graph (VFG) */ -typedef GenericGraph GenericVFGTy; +typedef GenericGraph GenericVFGTy; class VFG : public GenericVFGTy { @@ -54,23 +53,26 @@ class VFG : public GenericVFGTy /// VFG kind enum VFGK { - FULLSVFG, PTRONLYSVFG, FULLSVFG_OPT, PTRONLYSVFG_OPT + FULLSVFG, + PTRONLYSVFG, + FULLSVFG_OPT, + PTRONLYSVFG_OPT }; - typedef OrderedMap VFGNodeIDToNodeMapTy; + typedef OrderedMap VFGNodeIDToNodeMapTy; typedef Set VFGNodeSet; typedef Map PAGNodeToDefMapTy; - typedef Map, ActualParmVFGNode *> PAGNodeToActualParmMapTy; - typedef Map PAGNodeToActualRetMapTy; - typedef Map PAGNodeToFormalParmMapTy; - typedef Map PAGNodeToFormalRetMapTy; + typedef Map, ActualParmVFGNode*> PAGNodeToActualParmMapTy; + typedef Map PAGNodeToActualRetMapTy; + typedef Map PAGNodeToFormalParmMapTy; + typedef Map PAGNodeToFormalRetMapTy; typedef Map PAGEdgeToStmtVFGNodeMapTy; typedef Map PAGNodeToPHIVFGNodeMapTy; typedef Map PAGNodeToBinaryOPVFGNodeMapTy; typedef Map PAGNodeToUnaryOPVFGNodeMapTy; typedef Map PAGNodeToBranchVFGNodeMapTy; typedef Map PAGNodeToCmpVFGNodeMapTy; - typedef Map FunToVFGNodesMapTy; + typedef Map FunToVFGNodesMapTy; typedef FormalParmVFGNode::CallPESet CallPESet; typedef FormalRetVFGNode::RetPESet RetPESet; @@ -83,23 +85,22 @@ class VFG : public GenericVFGTy typedef Set GlobalVFGNodeSet; typedef Set PAGNodeSet; - protected: NodeID totalVFGNode; - PAGNodeToDefMapTy PAGNodeToDefMap; ///< map a pag node to its definition SVG node - PAGNodeToActualParmMapTy PAGNodeToActualParmMap; ///< map a PAGNode to an actual parameter - PAGNodeToActualRetMapTy PAGNodeToActualRetMap; ///< map a PAGNode to an actual return - PAGNodeToFormalParmMapTy PAGNodeToFormalParmMap; ///< map a PAGNode to a formal parameter - PAGNodeToFormalRetMapTy PAGNodeToFormalRetMap; ///< map a PAGNode to a formal return - PAGNodeToPHIVFGNodeMapTy PAGNodeToIntraPHIVFGNodeMap; ///< map a PAGNode to its PHIVFGNode - PAGNodeToBinaryOPVFGNodeMapTy PAGNodeToBinaryOPVFGNodeMap; ///< map a PAGNode to its BinaryOPVFGNode - PAGNodeToUnaryOPVFGNodeMapTy PAGNodeToUnaryOPVFGNodeMap; ///< map a PAGNode to its UnaryOPVFGNode - PAGNodeToBranchVFGNodeMapTy PAGNodeToBranchVFGNodeMap; ///< map a PAGNode to its BranchVFGNode - PAGNodeToCmpVFGNodeMapTy PAGNodeToCmpVFGNodeMap; ///< map a PAGNode to its CmpVFGNode - PAGEdgeToStmtVFGNodeMapTy PAGEdgeToStmtVFGNodeMap; ///< map a PAGEdge to its StmtVFGNode - FunToVFGNodesMapTy funToVFGNodesMap; ///< map a function to its VFGNodes; - - GlobalVFGNodeSet globalVFGNodes; ///< set of global store VFG nodes + PAGNodeToDefMapTy PAGNodeToDefMap; ///< map a pag node to its definition SVG node + PAGNodeToActualParmMapTy PAGNodeToActualParmMap; ///< map a PAGNode to an actual parameter + PAGNodeToActualRetMapTy PAGNodeToActualRetMap; ///< map a PAGNode to an actual return + PAGNodeToFormalParmMapTy PAGNodeToFormalParmMap; ///< map a PAGNode to a formal parameter + PAGNodeToFormalRetMapTy PAGNodeToFormalRetMap; ///< map a PAGNode to a formal return + PAGNodeToPHIVFGNodeMapTy PAGNodeToIntraPHIVFGNodeMap; ///< map a PAGNode to its PHIVFGNode + PAGNodeToBinaryOPVFGNodeMapTy PAGNodeToBinaryOPVFGNodeMap; ///< map a PAGNode to its BinaryOPVFGNode + PAGNodeToUnaryOPVFGNodeMapTy PAGNodeToUnaryOPVFGNodeMap; ///< map a PAGNode to its UnaryOPVFGNode + PAGNodeToBranchVFGNodeMapTy PAGNodeToBranchVFGNodeMap; ///< map a PAGNode to its BranchVFGNode + PAGNodeToCmpVFGNodeMapTy PAGNodeToCmpVFGNodeMap; ///< map a PAGNode to its CmpVFGNode + PAGEdgeToStmtVFGNodeMapTy PAGEdgeToStmtVFGNodeMap; ///< map a PAGEdge to its StmtVFGNode + FunToVFGNodesMapTy funToVFGNodesMap; ///< map a function to its VFGNodes; + + GlobalVFGNodeSet globalVFGNodes; ///< set of global store VFG nodes CallGraph* callgraph; SVFIR* pag; VFGK kind; @@ -232,28 +233,28 @@ class VFG : public GenericVFGTy assert(it != PAGNodeToCmpVFGNodeMap.end() && "CmpVFGNode can not be found??"); return it->second; } - inline ActualParmVFGNode* getActualParmVFGNode(const PAGNode* aparm,const CallICFGNode* cs) const + inline ActualParmVFGNode* getActualParmVFGNode(const PAGNode* aparm, const CallICFGNode* cs) const { - PAGNodeToActualParmMapTy::const_iterator it = PAGNodeToActualParmMap.find(std::make_pair(aparm->getId(),cs)); - assert(it!=PAGNodeToActualParmMap.end() && "actual parameter VFG node can not be found??"); + PAGNodeToActualParmMapTy::const_iterator it = PAGNodeToActualParmMap.find(std::make_pair(aparm->getId(), cs)); + assert(it != PAGNodeToActualParmMap.end() && "actual parameter VFG node can not be found??"); return it->second; } inline ActualRetVFGNode* getActualRetVFGNode(const PAGNode* aret) const { PAGNodeToActualRetMapTy::const_iterator it = PAGNodeToActualRetMap.find(aret); - assert(it!=PAGNodeToActualRetMap.end() && "actual return VFG node can not be found??"); + assert(it != PAGNodeToActualRetMap.end() && "actual return VFG node can not be found??"); return it->second; } inline FormalParmVFGNode* getFormalParmVFGNode(const PAGNode* fparm) const { PAGNodeToFormalParmMapTy::const_iterator it = PAGNodeToFormalParmMap.find(fparm); - assert(it!=PAGNodeToFormalParmMap.end() && "formal parameter VFG node can not be found??"); + assert(it != PAGNodeToFormalParmMap.end() && "formal parameter VFG node can not be found??"); return it->second; } inline FormalRetVFGNode* getFormalRetVFGNode(const PAGNode* fret) const { PAGNodeToFormalRetMapTy::const_iterator it = PAGNodeToFormalRetMap.find(fret); - assert(it!=PAGNodeToFormalRetMap.end() && "formal return VFG node can not be found??"); + assert(it != PAGNodeToFormalRetMap.end() && "formal return VFG node can not be found??"); return it->second; } //@} @@ -269,13 +270,11 @@ class VFG : public GenericVFGTy const VFGNode* defNode = getVFGNode(getDef(pagNode)); if (const AddrVFGNode* addr = SVFUtil::dyn_cast(defNode)) { - if (SVFIR::getPAG()->isBlkObjOrConstantObj(addr->getPAGEdge()->getSrcID())) - return true; + if (SVFIR::getPAG()->isBlkObjOrConstantObj(addr->getPAGEdge()->getSrcID())) return true; } - else if(const CopyVFGNode* copy = SVFUtil::dyn_cast(defNode)) + else if (const CopyVFGNode* copy = SVFUtil::dyn_cast(defNode)) { - if (SVFIR::getPAG()->isNullPtr(copy->getPAGEdge()->getSrcID())) - return true; + if (SVFIR::getPAG()->isNullPtr(copy->getPAGEdge()->getSrcID())) return true; } } return false; @@ -283,25 +282,25 @@ class VFG : public GenericVFGTy /// Return all the VFGNodes of a function ///@{ - inline VFGNodeSet& getVFGNodes(const SVFFunction *fun) + inline VFGNodeSet& getVFGNodes(const SVFFunction* fun) { return funToVFGNodesMap[fun]; } - inline bool hasVFGNodes(const SVFFunction *fun) const + inline bool hasVFGNodes(const SVFFunction* fun) const { return funToVFGNodesMap.find(fun) != funToVFGNodesMap.end(); } - inline bool VFGNodes(const SVFFunction *fun) const + inline bool VFGNodes(const SVFFunction* fun) const { return funToVFGNodesMap.find(fun) != funToVFGNodesMap.end(); } - inline VFGNodeSet::const_iterator getVFGNodeBegin(const SVFFunction *fun) const + inline VFGNodeSet::const_iterator getVFGNodeBegin(const SVFFunction* fun) const { FunToVFGNodesMapTy::const_iterator it = funToVFGNodesMap.find(fun); assert(it != funToVFGNodesMap.end() && "this function does not have any VFGNode"); return it->second.begin(); } - inline VFGNodeSet::const_iterator getVFGNodeEnd(const SVFFunction *fun) const + inline VFGNodeSet::const_iterator getVFGNodeEnd(const SVFFunction* fun) const { FunToVFGNodesMapTy::const_iterator it = funToVFGNodesMap.find(fun); assert(it != funToVFGNodesMap.end() && "this function does not have any VFGNode"); @@ -346,13 +345,12 @@ class VFG : public GenericVFGTy } protected: - /// sanitize Intra edges, verify that both nodes belong to the same function. - inline void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode) + inline void checkIntraEdgeParents(const VFGNode* srcNode, const VFGNode* dstNode) { - const SVFFunction *srcfun = srcNode->getFun(); - const SVFFunction *dstfun = dstNode->getFun(); - if(srcfun != nullptr && dstfun != nullptr) + const SVFFunction* srcfun = srcNode->getFun(); + const SVFFunction* dstfun = dstNode->getFun(); + if (srcfun != nullptr && dstfun != nullptr) { assert((srcfun == dstfun) && "src and dst nodes of an intra VFG edge are not in the same function?"); } @@ -361,44 +359,44 @@ class VFG : public GenericVFGTy /// Add inter VF edge from actual to formal parameters inline VFGEdge* addInterEdgeFromAPToFP(ActualParmVFGNode* src, FormalParmVFGNode* dst, CallSiteID csId) { - return addCallEdge(src->getId(),dst->getId(),csId); + return addCallEdge(src->getId(), dst->getId(), csId); } /// Add inter VF edge from callee return to callsite receive parameter inline VFGEdge* addInterEdgeFromFRToAR(FormalRetVFGNode* src, ActualRetVFGNode* dst, CallSiteID csId) { - return addRetEdge(src->getId(),dst->getId(),csId); + return addRetEdge(src->getId(), dst->getId(), csId); } /// Add inter VF edge from actual to formal parameters inline VFGEdge* addInterEdgeFromAPToFP(NodeID src, NodeID dst, CallSiteID csId) { - return addCallEdge(src,dst,csId); + return addCallEdge(src, dst, csId); } /// Add inter VF edge from callee return to callsite receive parameter inline VFGEdge* addInterEdgeFromFRToAR(NodeID src, NodeID dst, CallSiteID csId) { - return addRetEdge(src,dst,csId); + return addRetEdge(src, dst, csId); } /// Connect VFG nodes between caller and callee for indirect call site //@{ /// Connect actual-param and formal param - virtual inline void connectAParamAndFParam(const PAGNode* csArg, const PAGNode* funArg, const CallICFGNode* cbn, CallSiteID csId, VFGEdgeSetTy& edges) + virtual inline void connectAParamAndFParam(const PAGNode* csArg, const PAGNode* funArg, const CallICFGNode* cbn, + CallSiteID csId, VFGEdgeSetTy& edges) { NodeID actualParam = getActualParmVFGNode(csArg, cbn)->getId(); NodeID formalParam = getFormalParmVFGNode(funArg)->getId(); - VFGEdge* edge = addInterEdgeFromAPToFP(actualParam, formalParam,csId); - if (edge != nullptr) - edges.insert(edge); + VFGEdge* edge = addInterEdgeFromAPToFP(actualParam, formalParam, csId); + if (edge != nullptr) edges.insert(edge); } /// Connect formal-ret and actual ret - virtual inline void connectFRetAndARet(const PAGNode* funReturn, const PAGNode* csReturn, CallSiteID csId, VFGEdgeSetTy& edges) + virtual inline void connectFRetAndARet(const PAGNode* funReturn, const PAGNode* csReturn, CallSiteID csId, + VFGEdgeSetTy& edges) { NodeID formalRet = getFormalRetVFGNode(funReturn)->getId(); NodeID actualRet = getActualRetVFGNode(csReturn)->getId(); - VFGEdge* edge = addInterEdgeFromFRToAR(formalRet, actualRet,csId); - if (edge != nullptr) - edges.insert(edge); + VFGEdge* edge = addInterEdgeFromFRToAR(formalRet, actualRet, csId); + if (edge != nullptr) edges.insert(edge); } //@} @@ -407,7 +405,7 @@ class VFG : public GenericVFGTy inline void setDef(const PAGNode* pagNode, const VFGNode* node) { PAGNodeToDefMapTy::iterator it = PAGNodeToDefMap.find(pagNode); - if(it == PAGNodeToDefMap.end()) + if (it == PAGNodeToDefMap.end()) { PAGNodeToDefMap[pagNode] = node->getId(); assert(hasVFGNode(node->getId()) && "not in the map!!"); @@ -420,7 +418,7 @@ class VFG : public GenericVFGTy inline NodeID getDef(const PAGNode* pagNode) const { PAGNodeToDefMapTy::const_iterator it = PAGNodeToDefMap.find(pagNode); - assert(it!=PAGNodeToDefMap.end() && "SVFVar does not have a definition??"); + assert(it != PAGNodeToDefMap.end() && "SVFVar does not have a definition??"); return it->second; } inline bool hasDef(const PAGNode* pagNode) const @@ -435,16 +433,14 @@ class VFG : public GenericVFGTy /// Get PAGEdge set virtual inline SVFStmt::SVFStmtSetTy& getPAGEdgeSet(SVFStmt::PEDGEK kind) { - if (isPtrOnlySVFG()) - return pag->getPTASVFStmtSet(kind); + if (isPtrOnlySVFG()) return pag->getPTASVFStmtSet(kind); else return pag->getSVFStmtSet(kind); } virtual inline bool isInterestedPAGNode(const SVFVar* node) const { - if (isPtrOnlySVFG()) - return node->isPointer(); + if (isPtrOnlySVFG()) return node->isPointer(); else return true; } @@ -467,8 +463,7 @@ class VFG : public GenericVFGTy vfgNode->setICFGNode(icfgNode); icfgNode->addVFGNode(vfgNode); - if(const SVFFunction* fun = icfgNode->getFun()) - funToVFGNodesMap[fun].insert(vfgNode); + if (const SVFFunction* fun = icfgNode->getFun()) funToVFGNodesMap[fun].insert(vfgNode); else globalVFGNodes.insert(vfgNode); } @@ -476,7 +471,7 @@ class VFG : public GenericVFGTy /// Add a VFG node for program statement inline void addStmtVFGNode(StmtVFGNode* node, const PAGEdge* pagEdge) { - assert(PAGEdgeToStmtVFGNodeMap.find(pagEdge)==PAGEdgeToStmtVFGNodeMap.end() && "should not insert twice!"); + assert(PAGEdgeToStmtVFGNodeMap.find(pagEdge) == PAGEdgeToStmtVFGNodeMap.end() && "should not insert twice!"); PAGEdgeToStmtVFGNodeMap[pagEdge] = node; addVFGNode(node, pagEdge->getICFGNode()); } @@ -484,43 +479,43 @@ class VFG : public GenericVFGTy /// To be noted for black hole pointer it has already has address edge connected inline void addNullPtrVFGNode(const PAGNode* pagNode) { - NullPtrVFGNode* sNode = new NullPtrVFGNode(totalVFGNode++,pagNode); + NullPtrVFGNode* sNode = new NullPtrVFGNode(totalVFGNode++, pagNode); addVFGNode(sNode, pag->getICFG()->getGlobalICFGNode()); - setDef(pagNode,sNode); + setDef(pagNode, sNode); } /// Add an Address VFG node inline void addAddrVFGNode(const AddrStmt* addr) { - AddrVFGNode* sNode = new AddrVFGNode(totalVFGNode++,addr); + AddrVFGNode* sNode = new AddrVFGNode(totalVFGNode++, addr); addStmtVFGNode(sNode, addr); - setDef(addr->getLHSVar(),sNode); + setDef(addr->getLHSVar(), sNode); } /// Add a Copy VFG node inline void addCopyVFGNode(const CopyStmt* copy) { - CopyVFGNode* sNode = new CopyVFGNode(totalVFGNode++,copy); + CopyVFGNode* sNode = new CopyVFGNode(totalVFGNode++, copy); addStmtVFGNode(sNode, copy); - setDef(copy->getLHSVar(),sNode); + setDef(copy->getLHSVar(), sNode); } /// Add a Gep VFG node inline void addGepVFGNode(const GepStmt* gep) { - GepVFGNode* sNode = new GepVFGNode(totalVFGNode++,gep); + GepVFGNode* sNode = new GepVFGNode(totalVFGNode++, gep); addStmtVFGNode(sNode, gep); - setDef(gep->getLHSVar(),sNode); + setDef(gep->getLHSVar(), sNode); } /// Add a Load VFG node void addLoadVFGNode(const LoadStmt* load) { - LoadVFGNode* sNode = new LoadVFGNode(totalVFGNode++,load); + LoadVFGNode* sNode = new LoadVFGNode(totalVFGNode++, load); addStmtVFGNode(sNode, load); - setDef(load->getLHSVar(),sNode); + setDef(load->getLHSVar(), sNode); } /// Add a Store VFG node, /// To be noted store does not create a new pointer, we do not set def for any SVFIR node void addStoreVFGNode(const StoreStmt* store) { - StoreVFGNode* sNode = new StoreVFGNode(totalVFGNode++,store); + StoreVFGNode* sNode = new StoreVFGNode(totalVFGNode++, store); addStmtVFGNode(sNode, store); } @@ -529,37 +524,36 @@ class VFG : public GenericVFGTy /// So we need to make a pair to find the right VFGParmNode inline void addActualParmVFGNode(const PAGNode* aparm, const CallICFGNode* cs) { - ActualParmVFGNode* sNode = new ActualParmVFGNode(totalVFGNode++,aparm,cs); + ActualParmVFGNode* sNode = new ActualParmVFGNode(totalVFGNode++, aparm, cs); addVFGNode(sNode, pag->getICFG()->getCallICFGNode(cs->getCallSite())); - PAGNodeToActualParmMap[std::make_pair(aparm->getId(),cs)] = sNode; + PAGNodeToActualParmMap[std::make_pair(aparm->getId(), cs)] = sNode; /// do not set def here, this node is not a variable definition } /// Add a formal parameter VFG node inline void addFormalParmVFGNode(const PAGNode* fparm, const SVFFunction* fun, CallPESet& callPEs) { - FormalParmVFGNode* sNode = new FormalParmVFGNode(totalVFGNode++,fparm,fun); + FormalParmVFGNode* sNode = new FormalParmVFGNode(totalVFGNode++, fparm, fun); addVFGNode(sNode, pag->getICFG()->getFunEntryICFGNode(fun)); - for(CallPESet::const_iterator it = callPEs.begin(), eit=callPEs.end(); - it!=eit; ++it) + for (CallPESet::const_iterator it = callPEs.begin(), eit = callPEs.end(); it != eit; ++it) sNode->addCallPE(*it); - setDef(fparm,sNode); + setDef(fparm, sNode); PAGNodeToFormalParmMap[fparm] = sNode; } /// Add a callee Return VFG node /// To be noted that here we assume returns of a procedure have already been unified into one - /// Otherwise, we need to handle formalRet using pair to find FormalRetVFG node same as handling actual parameters + /// Otherwise, we need to handle formalRet using pair to find FormalRetVFG node same as + /// handling actual parameters inline void addFormalRetVFGNode(const PAGNode* uniqueFunRet, const SVFFunction* fun, RetPESet& retPEs) { - FormalRetVFGNode *sNode = new FormalRetVFGNode(totalVFGNode++, uniqueFunRet, fun); + FormalRetVFGNode* sNode = new FormalRetVFGNode(totalVFGNode++, uniqueFunRet, fun); addVFGNode(sNode, pag->getICFG()->getFunExitICFGNode(fun)); - for (RetPESet::const_iterator it = retPEs.begin(), eit = retPEs.end(); it != eit; ++it) - sNode->addRetPE(*it); + for (RetPESet::const_iterator it = retPEs.begin(), eit = retPEs.end(); it != eit; ++it) sNode->addRetPE(*it); PAGNodeToFormalRetMap[uniqueFunRet] = sNode; - /// if this uniqueFunRet is a phi node, which means it will receive values from multiple return instructions of fun - /// we will set this phi node's def later - /// Ideally, every function uniqueFunRet should be a PhiNode (SVFIRBuilder.cpp), unless it does not have ret instruction + /// if this uniqueFunRet is a phi node, which means it will receive values from multiple return instructions of + /// fun we will set this phi node's def later Ideally, every function uniqueFunRet should be a PhiNode + /// (SVFIRBuilder.cpp), unless it does not have ret instruction if (!pag->isPhiNode(uniqueFunRet)) { std::string warn = fun->getName(); @@ -568,25 +562,25 @@ class VFG : public GenericVFGTy } } /// Add a callsite Receive VFG node - inline void addActualRetVFGNode(const PAGNode* ret,const CallICFGNode* cs) + inline void addActualRetVFGNode(const PAGNode* ret, const CallICFGNode* cs) { - ActualRetVFGNode* sNode = new ActualRetVFGNode(totalVFGNode++,ret,cs); + ActualRetVFGNode* sNode = new ActualRetVFGNode(totalVFGNode++, ret, cs); addVFGNode(sNode, pag->getICFG()->getRetICFGNode(cs->getCallSite())); - setDef(ret,sNode); + setDef(ret, sNode); PAGNodeToActualRetMap[ret] = sNode; } /// Add an llvm PHI VFG node inline void addIntraPHIVFGNode(const MultiOpndStmt* edge) { - IntraPHIVFGNode* sNode = new IntraPHIVFGNode(totalVFGNode++,edge->getRes()); + IntraPHIVFGNode* sNode = new IntraPHIVFGNode(totalVFGNode++, edge->getRes()); u32_t pos = 0; - for(auto var : edge->getOpndVars()) + for (auto var : edge->getOpndVars()) { sNode->setOpVerAndBB(pos, var, edge->getICFGNode()); pos++; } - addVFGNode(sNode,edge->getICFGNode()); - setDef(edge->getRes(),sNode); + addVFGNode(sNode, edge->getICFGNode()); + setDef(edge->getRes(), sNode); PAGNodeToIntraPHIVFGNodeMap[edge->getRes()] = sNode; } /// Add a Compare VFG node @@ -594,13 +588,13 @@ class VFG : public GenericVFGTy { CmpVFGNode* sNode = new CmpVFGNode(totalVFGNode++, edge->getRes()); u32_t pos = 0; - for(auto var : edge->getOpndVars()) + for (auto var : edge->getOpndVars()) { sNode->setOpVer(pos, var); pos++; } - addVFGNode(sNode,edge->getICFGNode()); - setDef(edge->getRes(),sNode); + addVFGNode(sNode, edge->getICFGNode()); + setDef(edge->getRes(), sNode); PAGNodeToCmpVFGNodeMap[edge->getRes()] = sNode; } /// Add a BinaryOperator VFG node @@ -608,13 +602,13 @@ class VFG : public GenericVFGTy { BinaryOPVFGNode* sNode = new BinaryOPVFGNode(totalVFGNode++, edge->getRes()); u32_t pos = 0; - for(auto var : edge->getOpndVars()) + for (auto var : edge->getOpndVars()) { sNode->setOpVer(pos, var); pos++; } - addVFGNode(sNode,edge->getICFGNode()); - setDef(edge->getRes(),sNode); + addVFGNode(sNode, edge->getICFGNode()); + setDef(edge->getRes(), sNode); PAGNodeToBinaryOPVFGNodeMap[edge->getRes()] = sNode; } /// Add a UnaryOperator VFG node @@ -622,16 +616,16 @@ class VFG : public GenericVFGTy { UnaryOPVFGNode* sNode = new UnaryOPVFGNode(totalVFGNode++, edge->getRes()); sNode->setOpVer(0, edge->getOpVar()); - addVFGNode(sNode,edge->getICFGNode()); - setDef(edge->getRes(),sNode); + addVFGNode(sNode, edge->getICFGNode()); + setDef(edge->getRes(), sNode); PAGNodeToUnaryOPVFGNodeMap[edge->getRes()] = sNode; } /// Add a BranchVFGNode inline void addBranchVFGNode(const BranchStmt* edge) { BranchVFGNode* sNode = new BranchVFGNode(totalVFGNode++, edge); - addVFGNode(sNode,edge->getICFGNode()); - setDef(edge->getBranchInst(),sNode); + addVFGNode(sNode, edge->getICFGNode()); + setDef(edge->getBranchInst(), sNode); PAGNodeToBranchVFGNodeMap[edge->getBranchInst()] = sNode; } }; @@ -644,21 +638,24 @@ namespace SVF * GenericGraphTraits specializations for generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::VFGNode *NodeRef; + typedef SVF::VFGNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* INCLUDE_UTIL_VFG_H_ */ diff --git a/svf/include/Graphs/VFGEdge.h b/svf/include/Graphs/VFGEdge.h index 765a17bd9..7e0ccbc4a 100644 --- a/svf/include/Graphs/VFGEdge.h +++ b/svf/include/Graphs/VFGEdge.h @@ -38,7 +38,8 @@ namespace SVF class VFGNode; /*! - * Interprocedural control-flow and value-flow edge, representing the control- and value-flow dependence between two nodes + * Interprocedural control-flow and value-flow edge, representing the control- and value-flow dependence between two + * nodes */ typedef GenericEdge GenericVFGEdgeTy; class VFGEdge : public GenericVFGEdgeTy @@ -63,13 +64,9 @@ class VFGEdge : public GenericVFGEdgeTy public: /// Constructor - VFGEdge(VFGNode* s, VFGNode* d, GEdgeFlag k) : GenericVFGEdgeTy(s,d,k) - { - } + VFGEdge(VFGNode* s, VFGNode* d, GEdgeFlag k) : GenericVFGEdgeTy(s, d, k) {} /// Destructor - ~VFGEdge() - { - } + ~VFGEdge() {} /// Get methods of the components //@{ @@ -79,7 +76,8 @@ class VFGEdge : public GenericVFGEdgeTy } inline bool isIndirectVFGEdge() const { - return getEdgeKind() == IntraIndirectVF || getEdgeKind() == CallIndVF || getEdgeKind() == RetIndVF || getEdgeKind() == TheadMHPIndirectVF; + return getEdgeKind() == IntraIndirectVF || getEdgeKind() == CallIndVF || getEdgeKind() == RetIndVF || + getEdgeKind() == TheadMHPIndirectVF; } inline bool isCallVFGEdge() const { @@ -114,7 +112,7 @@ class VFGEdge : public GenericVFGEdgeTy return getEdgeKind() == TheadMHPIndirectVF; } //@} - typedef GenericNode::GEdgeSetTy VFGEdgeSetTy; + typedef GenericNode::GEdgeSetTy VFGEdgeSetTy; typedef VFGEdgeSetTy SVFGEdgeSetTy; /// Compute the unique edgeFlag value from edge kind and CallSiteID. static inline GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs) @@ -124,7 +122,7 @@ class VFGEdge : public GenericVFGEdgeTy /// Overloading operator << for dumping ICFG node ID //@{ - friend OutStream& operator<< (OutStream &o, const VFGEdge &edge) + friend OutStream& operator<<(OutStream& o, const VFGEdge& edge) { o << edge.toString(); return o; @@ -134,7 +132,6 @@ class VFGEdge : public GenericVFGEdgeTy virtual const std::string toString() const; }; - /*! * SVFG edge representing direct value-flows */ @@ -143,25 +140,21 @@ class DirectSVFGEdge : public VFGEdge public: /// Constructor - DirectSVFGEdge(VFGNode* s, VFGNode* d, GEdgeFlag k): VFGEdge(s,d,k) - { - } + DirectSVFGEdge(VFGNode* s, VFGNode* d, GEdgeFlag k) : VFGEdge(s, d, k) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const DirectSVFGEdge *) + static inline bool classof(const DirectSVFGEdge*) { return true; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { - return edge->getEdgeKind() == IntraDirectVF || - edge->getEdgeKind() == CallDirVF || + return edge->getEdgeKind() == IntraDirectVF || edge->getEdgeKind() == CallDirVF || edge->getEdgeKind() == RetDirVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { - return edge->getEdgeKind() == IntraDirectVF || - edge->getEdgeKind() == CallDirVF || + return edge->getEdgeKind() == IntraDirectVF || edge->getEdgeKind() == CallDirVF || edge->getEdgeKind() == RetDirVF; } //@} @@ -169,7 +162,6 @@ class DirectSVFGEdge : public VFGEdge virtual const std::string toString() const; }; - /*! * Intra SVFG edge representing direct intra-procedural value-flows */ @@ -178,24 +170,22 @@ class IntraDirSVFGEdge : public DirectSVFGEdge public: /// Constructor - IntraDirSVFGEdge(VFGNode* s, VFGNode* d): DirectSVFGEdge(s,d,IntraDirectVF) - { - } + IntraDirSVFGEdge(VFGNode* s, VFGNode* d) : DirectSVFGEdge(s, d, IntraDirectVF) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ static inline bool classof(const IntraDirSVFGEdge*) { return true; } - static inline bool classof(const DirectSVFGEdge *edge) + static inline bool classof(const DirectSVFGEdge* edge) { return edge->getEdgeKind() == IntraDirectVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { return edge->getEdgeKind() == IntraDirectVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { return edge->getEdgeKind() == IntraDirectVF; } @@ -204,7 +194,6 @@ class IntraDirSVFGEdge : public DirectSVFGEdge virtual const std::string toString() const; }; - /*! * SVFG call edge representing direct value-flows from a caller to its callee at a callsite */ @@ -213,10 +202,11 @@ class CallDirSVFGEdge : public DirectSVFGEdge private: CallSiteID csId; + public: /// Constructor - CallDirSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id): - DirectSVFGEdge(s,d,makeEdgeFlagWithInvokeID(CallDirVF,id)),csId(id) + CallDirSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id) + : DirectSVFGEdge(s, d, makeEdgeFlagWithInvokeID(CallDirVF, id)), csId(id) { } /// Return callsite ID @@ -227,21 +217,21 @@ class CallDirSVFGEdge : public DirectSVFGEdge /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CallDirSVFGEdge *) + static inline bool classof(const CallDirSVFGEdge*) { return true; } - static inline bool classof(const DirectSVFGEdge *edge) + static inline bool classof(const DirectSVFGEdge* edge) { return edge->getEdgeKind() == CallDirVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { - return edge->getEdgeKind() == CallDirVF ; + return edge->getEdgeKind() == CallDirVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { - return edge->getEdgeKind() == CallDirVF ; + return edge->getEdgeKind() == CallDirVF; } //@} @@ -256,10 +246,11 @@ class RetDirSVFGEdge : public DirectSVFGEdge private: CallSiteID csId; + public: /// Constructor - RetDirSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id): - DirectSVFGEdge(s,d,makeEdgeFlagWithInvokeID(RetDirVF,id)),csId(id) + RetDirSVFGEdge(VFGNode* s, VFGNode* d, CallSiteID id) + : DirectSVFGEdge(s, d, makeEdgeFlagWithInvokeID(RetDirVF, id)), csId(id) { } /// Return callsite ID @@ -269,19 +260,19 @@ class RetDirSVFGEdge : public DirectSVFGEdge } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const RetDirSVFGEdge *) + static inline bool classof(const RetDirSVFGEdge*) { return true; } - static inline bool classof(const DirectSVFGEdge *edge) + static inline bool classof(const DirectSVFGEdge* edge) { return edge->getEdgeKind() == RetDirVF; } - static inline bool classof(const VFGEdge *edge) + static inline bool classof(const VFGEdge* edge) { return edge->getEdgeKind() == RetDirVF; } - static inline bool classof(const GenericVFGEdgeTy *edge) + static inline bool classof(const GenericVFGEdgeTy* edge) { return edge->getEdgeKind() == RetDirVF; } diff --git a/svf/include/Graphs/VFGNode.h b/svf/include/Graphs/VFGNode.h index 83d002ae3..f693ce8be 100644 --- a/svf/include/Graphs/VFGNode.h +++ b/svf/include/Graphs/VFGNode.h @@ -42,7 +42,7 @@ namespace SVF * Interprocedural control-flow graph node, representing different kinds of program statements * including top-level pointers (ValVar) and address-taken objects (ObjVar) */ -typedef GenericNode GenericVFGNodeTy; +typedef GenericNode GenericVFGNodeTy; class VFGNode : public GenericVFGNodeTy { @@ -51,9 +51,31 @@ class VFGNode : public GenericVFGNodeTy /// Gep represents offset edge for field sensitivity enum VFGNodeK { - Addr, Copy, Gep, Store, Load, Cmp, BinaryOp, UnaryOp, Branch, TPhi, TIntraPhi, TInterPhi, - MPhi, MIntraPhi, MInterPhi, FRet, ARet, AParm, FParm, - APIN, APOUT, FPIN, FPOUT, NPtr, DummyVProp + Addr, + Copy, + Gep, + Store, + Load, + Cmp, + BinaryOp, + UnaryOp, + Branch, + TPhi, + TIntraPhi, + TInterPhi, + MPhi, + MIntraPhi, + MInterPhi, + FRet, + ARet, + AParm, + FParm, + APIN, + APOUT, + FPIN, + FPOUT, + NPtr, + DummyVProp }; typedef VFGEdge::VFGEdgeSetTy::iterator iterator; @@ -63,10 +85,7 @@ class VFGNode : public GenericVFGNodeTy public: /// Constructor - VFGNode(NodeID i, VFGNodeK k): GenericVFGNodeTy(i,k), icfgNode(nullptr) - { - - } + VFGNode(NodeID i, VFGNodeK k) : GenericVFGNodeTy(i, k), icfgNode(nullptr) {} /// Return corresponding ICFG node virtual const ICFGNode* getICFGNode() const @@ -75,7 +94,7 @@ class VFGNode : public GenericVFGNodeTy } /// Set corresponding ICFG node - virtual void setICFGNode(const ICFGNode* node ) + virtual void setICFGNode(const ICFGNode* node) { icfgNode = node; } @@ -97,7 +116,7 @@ class VFGNode : public GenericVFGNodeTy /// Overloading operator << for dumping ICFG node ID //@{ - friend OutStream& operator<< (OutStream &o, const VFGNode &node) + friend OutStream& operator<<(OutStream& o, const VFGNode& node) { o << node.toString(); return o; @@ -121,9 +140,7 @@ class StmtVFGNode : public VFGNode public: /// Constructor - StmtVFGNode(NodeID id, const PAGEdge* e, VFGNodeK k): VFGNode(id,k), pagEdge(e) - { - } + StmtVFGNode(NodeID id, const PAGEdge* e, VFGNodeK k) : VFGNode(id, k), pagEdge(e) {} /// Whether this node is used for pointer analysis. Both src and dst PAGNodes are of ptr type. inline bool isPTANode() const @@ -161,25 +178,19 @@ class StmtVFGNode : public VFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const StmtVFGNode *) + static inline bool classof(const StmtVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { - return node->getNodeKind() == Addr - || node->getNodeKind() == Copy - || node->getNodeKind() == Gep - || node->getNodeKind() == Store - || node->getNodeKind() == Load; + return node->getNodeKind() == Addr || node->getNodeKind() == Copy || node->getNodeKind() == Gep || + node->getNodeKind() == Store || node->getNodeKind() == Load; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { - return node->getNodeKind() == Addr - || node->getNodeKind() == Copy - || node->getNodeKind() == Gep - || node->getNodeKind() == Store - || node->getNodeKind() == Load; + return node->getNodeKind() == Addr || node->getNodeKind() == Copy || node->getNodeKind() == Gep || + node->getNodeKind() == Store || node->getNodeKind() == Load; } inline const SVFInstruction* getInst() const @@ -196,34 +207,31 @@ class StmtVFGNode : public VFGNode /*! * VFGNode for loads */ -class LoadVFGNode: public StmtVFGNode +class LoadVFGNode : public StmtVFGNode { private: LoadVFGNode(); ///< place holder - LoadVFGNode(const LoadVFGNode &); ///< place holder - void operator=(const LoadVFGNode &); ///< place holder + LoadVFGNode(const LoadVFGNode&); ///< place holder + void operator=(const LoadVFGNode&); ///< place holder public: /// Constructor - LoadVFGNode(NodeID id, const LoadStmt* edge): StmtVFGNode(id, edge,Load) - { - - } + LoadVFGNode(NodeID id, const LoadStmt* edge) : StmtVFGNode(id, edge, Load) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const LoadVFGNode *) + static inline bool classof(const LoadVFGNode*) { return true; } - static inline bool classof(const StmtVFGNode *node) + static inline bool classof(const StmtVFGNode* node) { return node->getNodeKind() == Load; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Load; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Load; } @@ -237,34 +245,31 @@ class LoadVFGNode: public StmtVFGNode /*! * VFGNode for stores */ -class StoreVFGNode: public StmtVFGNode +class StoreVFGNode : public StmtVFGNode { private: StoreVFGNode(); ///< place holder - StoreVFGNode(const StoreVFGNode &); ///< place holder - void operator=(const StoreVFGNode &); ///< place holder + StoreVFGNode(const StoreVFGNode&); ///< place holder + void operator=(const StoreVFGNode&); ///< place holder public: /// Constructor - StoreVFGNode(NodeID id,const StoreStmt* edge): StmtVFGNode(id,edge,Store) - { - - } + StoreVFGNode(NodeID id, const StoreStmt* edge) : StmtVFGNode(id, edge, Store) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const StoreVFGNode *) + static inline bool classof(const StoreVFGNode*) { return true; } - static inline bool classof(const StmtVFGNode *node) + static inline bool classof(const StmtVFGNode* node) { return node->getNodeKind() == Store; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Store; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Store; } @@ -278,34 +283,31 @@ class StoreVFGNode: public StmtVFGNode /*! * VFGNode for copies */ -class CopyVFGNode: public StmtVFGNode +class CopyVFGNode : public StmtVFGNode { private: CopyVFGNode(); ///< place holder - CopyVFGNode(const CopyVFGNode &); ///< place holder - void operator=(const CopyVFGNode &); ///< place holder + CopyVFGNode(const CopyVFGNode&); ///< place holder + void operator=(const CopyVFGNode&); ///< place holder public: /// Constructor - CopyVFGNode(NodeID id,const CopyStmt* copy): StmtVFGNode(id,copy,Copy) - { - - } + CopyVFGNode(NodeID id, const CopyStmt* copy) : StmtVFGNode(id, copy, Copy) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CopyVFGNode *) + static inline bool classof(const CopyVFGNode*) { return true; } - static inline bool classof(const StmtVFGNode *node) + static inline bool classof(const StmtVFGNode* node) { return node->getNodeKind() == Copy; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Copy; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Copy; } @@ -316,38 +318,38 @@ class CopyVFGNode: public StmtVFGNode const std::string toString() const override; }; - /*! * VFGNode for compare instruction, e.g., bool b = (a!=c); */ -class CmpVFGNode: public VFGNode +class CmpVFGNode : public VFGNode { public: - typedef Map OPVers; + typedef Map OPVers; + protected: const PAGNode* res; OPVers opVers; private: CmpVFGNode(); ///< place holder - CmpVFGNode(const CmpVFGNode &); ///< place holder - void operator=(const CmpVFGNode &); ///< place holder + CmpVFGNode(const CmpVFGNode&); ///< place holder + void operator=(const CmpVFGNode&); ///< place holder public: /// Constructor - CmpVFGNode(NodeID id,const PAGNode* r): VFGNode(id,Cmp), res(r) { } + CmpVFGNode(NodeID id, const PAGNode* r) : VFGNode(id, Cmp), res(r) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CmpVFGNode *) + static inline bool classof(const CmpVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Cmp; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Cmp; } @@ -357,7 +359,7 @@ class CmpVFGNode: public VFGNode inline const PAGNode* getOpVer(u32_t pos) const { OPVers::const_iterator it = opVers.find(pos); - assert(it!=opVers.end() && "version is nullptr, did not rename?"); + assert(it != opVers.end() && "version is nullptr, did not rename?"); return it->second; } inline void setOpVer(u32_t pos, const PAGNode* node) @@ -388,37 +390,37 @@ class CmpVFGNode: public VFGNode const std::string toString() const override; }; - /*! * VFGNode for binary operator instructions, e.g., a = b + c; */ -class BinaryOPVFGNode: public VFGNode +class BinaryOPVFGNode : public VFGNode { public: - typedef Map OPVers; + typedef Map OPVers; + protected: const PAGNode* res; OPVers opVers; private: - BinaryOPVFGNode(); ///< place holder - BinaryOPVFGNode(const BinaryOPVFGNode &); ///< place holder - void operator=(const BinaryOPVFGNode &); ///< place holder + BinaryOPVFGNode(); ///< place holder + BinaryOPVFGNode(const BinaryOPVFGNode&); ///< place holder + void operator=(const BinaryOPVFGNode&); ///< place holder public: /// Constructor - BinaryOPVFGNode(NodeID id,const PAGNode* r): VFGNode(id,BinaryOp), res(r) { } + BinaryOPVFGNode(NodeID id, const PAGNode* r) : VFGNode(id, BinaryOp), res(r) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const BinaryOPVFGNode *) + static inline bool classof(const BinaryOPVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == BinaryOp; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == BinaryOp; } @@ -428,7 +430,7 @@ class BinaryOPVFGNode: public VFGNode inline const PAGNode* getOpVer(u32_t pos) const { OPVers::const_iterator it = opVers.find(pos); - assert(it!=opVers.end() && "version is nullptr, did not rename?"); + assert(it != opVers.end() && "version is nullptr, did not rename?"); return it->second; } inline void setOpVer(u32_t pos, const PAGNode* node) @@ -462,33 +464,34 @@ class BinaryOPVFGNode: public VFGNode /*! * VFGNode for unary operator instructions, e.g., a = -b; */ -class UnaryOPVFGNode: public VFGNode +class UnaryOPVFGNode : public VFGNode { public: - typedef Map OPVers; + typedef Map OPVers; + protected: const PAGNode* res; OPVers opVers; private: UnaryOPVFGNode(); ///< place holder - UnaryOPVFGNode(const UnaryOPVFGNode &); ///< place holder - void operator=(const UnaryOPVFGNode &); ///< place holder + UnaryOPVFGNode(const UnaryOPVFGNode&); ///< place holder + void operator=(const UnaryOPVFGNode&); ///< place holder public: /// Constructor - UnaryOPVFGNode(NodeID id, const PAGNode *r) : VFGNode(id, UnaryOp), res(r) { } + UnaryOPVFGNode(NodeID id, const PAGNode* r) : VFGNode(id, UnaryOp), res(r) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const UnaryOPVFGNode *) + static inline bool classof(const UnaryOPVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == UnaryOp; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == UnaryOp; } @@ -498,7 +501,7 @@ class UnaryOPVFGNode: public VFGNode inline const PAGNode* getOpVer(u32_t pos) const { OPVers::const_iterator it = opVers.find(pos); - assert(it!=opVers.end() && "version is nullptr, did not rename?"); + assert(it != opVers.end() && "version is nullptr, did not rename?"); return it->second; } inline void setOpVer(u32_t pos, const PAGNode* node) @@ -511,7 +514,7 @@ class UnaryOPVFGNode: public VFGNode } inline const PAGNode* getOpVar() const { - assert(getOpVerNum()==1 && "UnaryNode can only have one operand!"); + assert(getOpVerNum() == 1 && "UnaryNode can only have one operand!"); return getOpVer(0); } inline u32_t getOpVerNum() const @@ -534,29 +537,30 @@ class UnaryOPVFGNode: public VFGNode }; /* -* Branch VFGNode including if/else and switch statements -*/ -class BranchVFGNode: public VFGNode + * Branch VFGNode including if/else and switch statements + */ +class BranchVFGNode : public VFGNode { private: BranchVFGNode(); ///< place holder - BranchVFGNode(const BranchVFGNode &); ///< place holder - void operator=(const BranchVFGNode &); ///< place holder + BranchVFGNode(const BranchVFGNode&); ///< place holder + void operator=(const BranchVFGNode&); ///< place holder const BranchStmt* brstmt; + public: /// Constructor - BranchVFGNode(NodeID id, const BranchStmt* r) : VFGNode(id, Branch), brstmt(r) { } + BranchVFGNode(NodeID id, const BranchStmt* r) : VFGNode(id, Branch), brstmt(r) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const BranchVFGNode *) + static inline bool classof(const BranchVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Branch; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Branch; } @@ -577,7 +581,7 @@ class BranchVFGNode: public VFGNode { return brstmt->getSuccessors(); } - const ICFGNode* getSuccessor (u32_t i) const + const ICFGNode* getSuccessor(u32_t i) const { return brstmt->getSuccessor(i); } @@ -591,34 +595,31 @@ class BranchVFGNode: public VFGNode /*! * VFGNode for Gep */ -class GepVFGNode: public StmtVFGNode +class GepVFGNode : public StmtVFGNode { private: GepVFGNode(); ///< place holder - GepVFGNode(const GepVFGNode &); ///< place holder - void operator=(const GepVFGNode &); ///< place holder + GepVFGNode(const GepVFGNode&); ///< place holder + void operator=(const GepVFGNode&); ///< place holder public: /// Constructor - GepVFGNode(NodeID id,const GepStmt* edge): StmtVFGNode(id,edge,Gep) - { - - } + GepVFGNode(NodeID id, const GepStmt* edge) : StmtVFGNode(id, edge, Gep) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const GepVFGNode *) + static inline bool classof(const GepVFGNode*) { return true; } - static inline bool classof(const StmtVFGNode *node) + static inline bool classof(const StmtVFGNode* node) { return node->getNodeKind() == Gep; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Gep; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Gep; } @@ -636,14 +637,15 @@ class PHIVFGNode : public VFGNode { public: - typedef Map OPVers; + typedef Map OPVers; + protected: const PAGNode* res; OPVers opVers; public: /// Constructor - PHIVFGNode(NodeID id, const PAGNode* r,VFGNodeK k = TPhi); + PHIVFGNode(NodeID id, const PAGNode* r, VFGNodeK k = TPhi); /// Whether this phi node is of pointer type (used for pointer analysis). inline bool isPTANode() const @@ -656,7 +658,7 @@ class PHIVFGNode : public VFGNode inline const PAGNode* getOpVer(u32_t pos) const { OPVers::const_iterator it = opVers.find(pos); - assert(it!=opVers.end() && "version is nullptr, did not rename?"); + assert(it != opVers.end() && "version is nullptr, did not rename?"); return it->second; } inline void setOpVer(u32_t pos, const PAGNode* node) @@ -683,15 +685,15 @@ class PHIVFGNode : public VFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const PHIVFGNode *) + static inline bool classof(const PHIVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return (node->getNodeKind() == TPhi || node->getNodeKind() == TIntraPhi || node->getNodeKind() == TInterPhi); } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return (node->getNodeKind() == TPhi || node->getNodeKind() == TIntraPhi || node->getNodeKind() == TInterPhi); } @@ -703,7 +705,6 @@ class PHIVFGNode : public VFGNode const std::string toString() const override; }; - /* * Intra LLVM PHI Node */ @@ -711,20 +712,19 @@ class IntraPHIVFGNode : public PHIVFGNode { public: - typedef Map OPIncomingBBs; + typedef Map OPIncomingBBs; private: OPIncomingBBs opIncomingBBs; + public: /// Constructor - IntraPHIVFGNode(NodeID id, const PAGNode* r): PHIVFGNode(id, r, TIntraPhi) - { - } + IntraPHIVFGNode(NodeID id, const PAGNode* r) : PHIVFGNode(id, r, TIntraPhi) {} inline const ICFGNode* getOpIncomingBB(u32_t pos) const { OPIncomingBBs::const_iterator it = opIncomingBBs.find(pos); - assert(it!=opIncomingBBs.end() && "version is nullptr, did not rename?"); + assert(it != opIncomingBBs.end() && "version is nullptr, did not rename?"); return it->second; } inline void setOpVerAndBB(u32_t pos, const PAGNode* node, const ICFGNode* bb) @@ -739,15 +739,15 @@ class IntraPHIVFGNode : public PHIVFGNode { return true; } - static inline bool classof(const PHIVFGNode *node) + static inline bool classof(const PHIVFGNode* node) { return node->getNodeKind() == TIntraPhi; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == TIntraPhi; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == TIntraPhi; } @@ -756,35 +756,31 @@ class IntraPHIVFGNode : public PHIVFGNode const std::string toString() const override; }; - -class AddrVFGNode: public StmtVFGNode +class AddrVFGNode : public StmtVFGNode { private: AddrVFGNode(); ///< place holder - AddrVFGNode(const AddrVFGNode &); ///< place holder - void operator=(const AddrVFGNode &); ///< place holder + AddrVFGNode(const AddrVFGNode&); ///< place holder + void operator=(const AddrVFGNode&); ///< place holder public: /// Constructor - AddrVFGNode(NodeID id, const AddrStmt* edge): StmtVFGNode(id, edge,Addr) - { - - } + AddrVFGNode(NodeID id, const AddrStmt* edge) : StmtVFGNode(id, edge, Addr) {} /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const AddrVFGNode *) + static inline bool classof(const AddrVFGNode*) { return true; } - static inline bool classof(const StmtVFGNode *node) + static inline bool classof(const StmtVFGNode* node) { return node->getNodeKind() == Addr; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == Addr; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == Addr; } @@ -795,7 +791,6 @@ class AddrVFGNode: public StmtVFGNode const std::string toString() const override; }; - class ArgumentVFGNode : public VFGNode { @@ -804,9 +799,7 @@ class ArgumentVFGNode : public VFGNode public: /// Constructor - ArgumentVFGNode(NodeID id, const PAGNode* p, VFGNodeK k): VFGNode(id,k), param(p) - { - } + ArgumentVFGNode(NodeID id, const PAGNode* p, VFGNodeK k) : VFGNode(id, k), param(p) {} /// Whether this argument node is of pointer type (used for pointer analysis). inline bool isPTANode() const @@ -816,23 +809,19 @@ class ArgumentVFGNode : public VFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const ArgumentVFGNode *) + static inline bool classof(const ArgumentVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { - return node->getNodeKind() == FRet - || node->getNodeKind() == ARet - || node->getNodeKind() == AParm - || node->getNodeKind() == FParm; + return node->getNodeKind() == FRet || node->getNodeKind() == ARet || node->getNodeKind() == AParm || + node->getNodeKind() == FParm; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { - return node->getNodeKind() == FRet - || node->getNodeKind() == ARet - || node->getNodeKind() == AParm - || node->getNodeKind() == FParm; + return node->getNodeKind() == FRet || node->getNodeKind() == ARet || node->getNodeKind() == AParm || + node->getNodeKind() == FParm; } //@} @@ -847,12 +836,10 @@ class ActualParmVFGNode : public ArgumentVFGNode { private: const CallICFGNode* cs; + public: /// Constructor - ActualParmVFGNode(NodeID id, const PAGNode* n, const CallICFGNode* c) : - ArgumentVFGNode(id, n, AParm), cs(c) - { - } + ActualParmVFGNode(NodeID id, const PAGNode* n, const CallICFGNode* c) : ArgumentVFGNode(id, n, AParm), cs(c) {} /// Return callsite inline const CallICFGNode* getCallSite() const @@ -868,19 +855,19 @@ class ActualParmVFGNode : public ArgumentVFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const ActualParmVFGNode *) + static inline bool classof(const ActualParmVFGNode*) { return true; } - static inline bool classof(const ArgumentVFGNode *node) + static inline bool classof(const ArgumentVFGNode* node) { return node->getNodeKind() == AParm; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == AParm; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == AParm; } @@ -891,7 +878,6 @@ class ActualParmVFGNode : public ArgumentVFGNode const std::string toString() const override; }; - /* * ICFG Node stands for formal parameter node (top level pointers) */ @@ -903,10 +889,7 @@ class FormalParmVFGNode : public ArgumentVFGNode public: /// Constructor - FormalParmVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f): - ArgumentVFGNode(id, n, FParm), fun(f) - { - } + FormalParmVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f) : ArgumentVFGNode(id, n, FParm), fun(f) {} /// Return parameter inline const PAGNode* getParam() const @@ -938,19 +921,19 @@ class FormalParmVFGNode : public ArgumentVFGNode /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const FormalParmVFGNode *) + static inline bool classof(const FormalParmVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == FParm; } - static inline bool classof(const ArgumentVFGNode *node) + static inline bool classof(const ArgumentVFGNode* node) { return node->getNodeKind() == FParm; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == FParm; } @@ -964,21 +947,18 @@ class FormalParmVFGNode : public ArgumentVFGNode /*! * Callsite receive parameter */ -class ActualRetVFGNode: public ArgumentVFGNode +class ActualRetVFGNode : public ArgumentVFGNode { private: const CallICFGNode* cs; - ActualRetVFGNode(); ///< place holder - ActualRetVFGNode(const ActualRetVFGNode &); ///< place holder - void operator=(const ActualRetVFGNode &); ///< place holder + ActualRetVFGNode(); ///< place holder + ActualRetVFGNode(const ActualRetVFGNode&); ///< place holder + void operator=(const ActualRetVFGNode&); ///< place holder public: /// Constructor - ActualRetVFGNode(NodeID id, const PAGNode* n, const CallICFGNode* c) : - ArgumentVFGNode(id, n, ARet), cs(c) - { - } + ActualRetVFGNode(NodeID id, const PAGNode* n, const CallICFGNode* c) : ArgumentVFGNode(id, n, ARet), cs(c) {} /// Return callsite inline const CallICFGNode* getCallSite() const { @@ -996,19 +976,19 @@ class ActualRetVFGNode: public ArgumentVFGNode } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const ActualRetVFGNode *) + static inline bool classof(const ActualRetVFGNode*) { return true; } - static inline bool classof(const ArgumentVFGNode *node) + static inline bool classof(const ArgumentVFGNode* node) { return node->getNodeKind() == ARet; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == ARet; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == ARet; } @@ -1022,15 +1002,15 @@ class ActualRetVFGNode: public ArgumentVFGNode /*! * Callee return ICFG node */ -class FormalRetVFGNode: public ArgumentVFGNode +class FormalRetVFGNode : public ArgumentVFGNode { private: const SVFFunction* fun; RetPESet retPEs; - FormalRetVFGNode(); ///< place holder - FormalRetVFGNode(const FormalRetVFGNode &); ///< place holder - void operator=(const FormalRetVFGNode &); ///< place holder + FormalRetVFGNode(); ///< place holder + FormalRetVFGNode(const FormalRetVFGNode&); ///< place holder + void operator=(const FormalRetVFGNode&); ///< place holder public: /// Constructor @@ -1060,21 +1040,21 @@ class FormalRetVFGNode: public ArgumentVFGNode { return retPEs.end(); } - ///Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const FormalRetVFGNode ) + static inline bool classof(const FormalRetVFGNode) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == FRet; } - static inline bool classof(const ArgumentVFGNode *node) + static inline bool classof(const ArgumentVFGNode* node) { return node->getNodeKind() == FRet; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == FRet; } @@ -1093,23 +1073,29 @@ class InterPHIVFGNode : public PHIVFGNode public: /// Constructor interPHI for formal parameter - InterPHIVFGNode(NodeID id, const FormalParmVFGNode* fp) : PHIVFGNode(id, fp->getParam(), TInterPhi),fun(fp->getFun()),callInst(nullptr) {} + InterPHIVFGNode(NodeID id, const FormalParmVFGNode* fp) + : PHIVFGNode(id, fp->getParam(), TInterPhi), fun(fp->getFun()), callInst(nullptr) + { + } /// Constructor interPHI for actual return - InterPHIVFGNode(NodeID id, const ActualRetVFGNode* ar) : PHIVFGNode(id, ar->getRev(), TInterPhi), fun(ar->getCaller()),callInst(ar->getCallSite()) {} + InterPHIVFGNode(NodeID id, const ActualRetVFGNode* ar) + : PHIVFGNode(id, ar->getRev(), TInterPhi), fun(ar->getCaller()), callInst(ar->getCallSite()) + { + } inline bool isFormalParmPHI() const { - return (fun!=nullptr) && (callInst == nullptr); + return (fun != nullptr) && (callInst == nullptr); } inline bool isActualRetPHI() const { - return (fun!=nullptr) && (callInst != nullptr); + return (fun != nullptr) && (callInst != nullptr); } inline const SVFFunction* getFun() const override { - assert((isFormalParmPHI() || isActualRetPHI()) && "expect a formal parameter phi"); + assert((isFormalParmPHI() || isActualRetPHI()) && "expect a formal parameter phi"); return fun; } @@ -1125,15 +1111,15 @@ class InterPHIVFGNode : public PHIVFGNode { return true; } - static inline bool classof(const PHIVFGNode *node) + static inline bool classof(const PHIVFGNode* node) { return node->getNodeKind() == TInterPhi; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == TInterPhi; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == TInterPhi; } @@ -1146,8 +1132,6 @@ class InterPHIVFGNode : public PHIVFGNode const CallICFGNode* callInst; }; - - /*! * Dummy Definition for undef and null pointers */ @@ -1155,12 +1139,10 @@ class NullPtrVFGNode : public VFGNode { private: const PAGNode* node; + public: /// Constructor - NullPtrVFGNode(NodeID id, const PAGNode* n) : VFGNode(id,NPtr), node(n) - { - - } + NullPtrVFGNode(NodeID id, const PAGNode* n) : VFGNode(id, NPtr), node(n) {} /// Whether this node is of pointer type (used for pointer analysis). inline bool isPTANode() const { @@ -1173,15 +1155,15 @@ class NullPtrVFGNode : public VFGNode } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const NullPtrVFGNode *) + static inline bool classof(const NullPtrVFGNode*) { return true; } - static inline bool classof(const VFGNode *node) + static inline bool classof(const VFGNode* node) { return node->getNodeKind() == NPtr; } - static inline bool classof(const GenericVFGNodeTy *node) + static inline bool classof(const GenericVFGNodeTy* node) { return node->getNodeKind() == NPtr; } diff --git a/svf/include/Graphs/WTO.h b/svf/include/Graphs/WTO.h index 87ea957c5..ac2a09f7a 100644 --- a/svf/include/Graphs/WTO.h +++ b/svf/include/Graphs/WTO.h @@ -54,8 +54,7 @@ template struct has_nodetype : std::false_type { }; -template -struct has_nodetype> : std::true_type +template struct has_nodetype> : std::true_type { }; @@ -63,8 +62,7 @@ template struct has_edgetype : std::false_type { }; -template -struct has_edgetype> : std::true_type +template struct has_edgetype> : std::true_type { }; @@ -101,8 +99,7 @@ struct has_edgetype> : std::true_type template class WTOCycleDepth { public: - static_assert(has_nodetype::value, - "GraphT must have a nested type named 'NodeType'"); + static_assert(has_nodetype::value, "GraphT must have a nested type named 'NodeType'"); typedef typename GraphT::NodeType NodeT; private: @@ -155,8 +152,8 @@ template class WTOCycleDepth WTOCycleDepth operator^(const WTOCycleDepth& other) const { WTOCycleDepth res; - for (auto this_it = begin(), other_it = other.begin(); - this_it != end() && other_it != other.end(); ++this_it, ++other_it) + for (auto this_it = begin(), other_it = other.begin(); this_it != end() && other_it != other.end(); + ++this_it, ++other_it) { if (*this_it == *other_it) { @@ -254,8 +251,7 @@ template class WTOCycleDepth /// Overloading operator << for dumping ICFG node ID //@{ - friend std::ostream& operator<<(std::ostream& o, - const WTOCycleDepth& wto) + friend std::ostream& operator<<(std::ostream& o, const WTOCycleDepth& wto) { o << wto.toString(); return o; @@ -279,7 +275,7 @@ template class WTOComponent }; /// Default constructor - explicit WTOComponent(WTOCT k) : _type(k) {}; + explicit WTOComponent(WTOCT k) : _type(k){}; /// Copy constructor WTOComponent(const WTOComponent&) noexcept = default; @@ -308,8 +304,7 @@ template class WTOComponent /// Overloading operator << for dumping ICFG node ID //@{ - friend std::ostream& operator<<(std::ostream& o, - const WTOComponent& wto) + friend std::ostream& operator<<(std::ostream& o, const WTOComponent& wto) { o << wto.toString(); return o; @@ -326,8 +321,7 @@ template class WTOComponent template class WTONode final : public WTOComponent { public: - static_assert(has_nodetype::value, - "GraphT must have a nested type named 'NodeType'"); + static_assert(has_nodetype::value, "GraphT must have a nested type named 'NodeType'"); typedef typename GraphT::NodeType NodeT; private: @@ -335,10 +329,7 @@ template class WTONode final : public WTOComponent public: /// Constructor - explicit WTONode(const NodeT* node) - : WTOComponent(WTOComponent::Node), _node(node) - { - } + explicit WTONode(const NodeT* node) : WTOComponent(WTOComponent::Node), _node(node) {} /// Return the graph node const NodeT* getICFGNode() const @@ -380,8 +371,7 @@ template class WTONode final : public WTOComponent template class WTOCycle final : public WTOComponent { public: - static_assert(has_nodetype::value, - "GraphT must have a nested type named 'NodeType'"); + static_assert(has_nodetype::value, "GraphT must have a nested type named 'NodeType'"); typedef typename GraphT::NodeType NodeT; typedef WTOComponent WTOComponentT; @@ -403,8 +393,7 @@ template class WTOCycle final : public WTOComponent public: /// Constructor WTOCycle(const WTONode* head, WTOComponentRefList components) - : WTOComponent(WTOComponent::Cycle), _head(head), - _components(std::move(components)) + : WTOComponent(WTOComponent::Cycle), _head(head), _components(std::move(components)) { } @@ -493,8 +482,7 @@ template class WTOComponentVisitor WTOComponentVisitor(WTOComponentVisitor&&) noexcept = default; /// Copy assignment operator - WTOComponentVisitor& operator=(const WTOComponentVisitor&) noexcept = - default; + WTOComponentVisitor& operator=(const WTOComponentVisitor&) noexcept = default; /// Move assignment operator WTOComponentVisitor& operator=(WTOComponentVisitor&&) noexcept = default; @@ -517,10 +505,8 @@ template class WTO { public: - static_assert(has_nodetype::value, - "GraphT must have a nested type named 'NodeType'"); - static_assert(has_edgetype::value, - "GraphT must have a nested type named 'EdgeType'"); + static_assert(has_nodetype::value, "GraphT must have a nested type named 'NodeType'"); + static_assert(has_edgetype::value, "GraphT must have a nested type named 'EdgeType'"); typedef typename GraphT::NodeType NodeT; typedef typename GraphT::EdgeType EdgeT; typedef WTOCycleDepth GraphTWTOCycleDepth; @@ -558,11 +544,8 @@ template class WTO const NodeT* _entry; public: - /// Compute the weak topological order of the given graph - explicit WTO(GraphT* graph, const NodeT* entry) : _num(0), _graph(graph), _entry(entry) - { - } + explicit WTO(GraphT* graph, const NodeT* entry) : _num(0), _graph(graph), _entry(entry) {} /// No copy constructor WTO(const WTO& other) = default; @@ -680,7 +663,6 @@ template class WTO } protected: - /// Visitor to build the cycle depths of each node class WTOCycleDepthBuilder final : public WTOComponentVisitor { @@ -689,10 +671,8 @@ template class WTO NodeRefToWTOCycleDepthPtr& _nodeToWTOCycleDepth; public: - explicit WTOCycleDepthBuilder( - NodeRefToWTOCycleDepthPtr& nodeToWTOCycleDepth) - : _wtoCycleDepth(std::make_shared()), - _nodeToWTOCycleDepth(nodeToWTOCycleDepth) + explicit WTOCycleDepthBuilder(NodeRefToWTOCycleDepthPtr& nodeToWTOCycleDepth) + : _wtoCycleDepth(std::make_shared()), _nodeToWTOCycleDepth(nodeToWTOCycleDepth) { } @@ -701,8 +681,7 @@ template class WTO const NodeT* head = cycle.head()->getICFGNode(); WTOCycleDepthPtr previous_cycleDepth = _wtoCycleDepth; _nodeToWTOCycleDepth.insert(std::make_pair(head, _wtoCycleDepth)); - _wtoCycleDepth = - std::make_shared(*_wtoCycleDepth); + _wtoCycleDepth = std::make_shared(*_wtoCycleDepth); _wtoCycleDepth->add(head); for (auto it = cycle.begin(), et = cycle.end(); it != et; ++it) { @@ -713,14 +692,12 @@ template class WTO void visit(const WTONodeT& node) override { - _nodeToWTOCycleDepth.insert( - std::make_pair(node.getICFGNode(), _wtoCycleDepth)); + _nodeToWTOCycleDepth.insert(std::make_pair(node.getICFGNode(), _wtoCycleDepth)); } }; // end class WTOCycleDepthBuilder protected: - inline virtual void forEachSuccessor(const NodeT* node, std::function func) const { for (const auto& e : node->getOutEdges()) @@ -776,8 +753,7 @@ template class WTO return ptr; } - const WTOCycleT* newCycle(const WTONodeT* node, - const WTOComponentRefList& partition) + const WTOCycleT* newCycle(const WTONodeT* node, const WTOComponentRefList& partition) { const WTOCycleT* ptr = new WTOCycleT(node, std::move(partition)); _allComponents.insert(ptr); @@ -788,8 +764,7 @@ template class WTO virtual const WTOCycleT* component(const NodeT* node) { WTOComponentRefList partition; - forEachSuccessor(node, [&](const NodeT* succ) - { + forEachSuccessor(node, [&](const NodeT* succ) { if (getCDN(succ) == 0) { visit(succ, partition); @@ -804,8 +779,7 @@ template class WTO /// Visit the given node /// /// Algorithm to build a weak topological order of a graph - virtual CycleDepthNumber visit(const NodeT* node, - WTOComponentRefList& partition) + virtual CycleDepthNumber visit(const NodeT* node, WTOComponentRefList& partition) { CycleDepthNumber head(0); CycleDepthNumber min(0); @@ -816,8 +790,7 @@ template class WTO head = _num; setCDN(node, head); loop = false; - forEachSuccessor(node, [&](const NodeT* succ) - { + forEachSuccessor(node, [&](const NodeT* succ) { CycleDepthNumber succ_dfn = getCDN(succ); if (succ_dfn == CycleDepthNumber(0)) { diff --git a/svf/include/MSSA/MSSAMuChi.h b/svf/include/MSSA/MSSAMuChi.h index 84a82d1d8..16dbe76af 100644 --- a/svf/include/MSSA/MSSAMuChi.h +++ b/svf/include/MSSA/MSSAMuChi.h @@ -45,6 +45,7 @@ class MRVer public: typedef MSSADEF MSSADef; + private: /// ver ID 0 is reserved static u32_t totalVERNum; @@ -52,12 +53,10 @@ class MRVer MRVERSION version; MRVERID vid; MSSADef* def; + public: /// Constructor - MRVer(const MemRegion* m, MRVERSION v, MSSADef* d) : - mr(m), version(v), vid(totalVERNum++),def(d) - { - } + MRVer(const MemRegion* m, MRVERSION v, MSSADef* d) : mr(m), version(v), vid(totalVERNum++), def(d) {} /// Return the memory region inline const MemRegion* getMR() const @@ -84,21 +83,21 @@ class MRVer } }; - /*! * Indirect Memory Read * 1) LoadMU at each store instruction * 2) CallMU at callsite * 3) RetMU at function return */ -template -class MSSAMU +template class MSSAMU { public: enum MUTYPE { - LoadMSSAMU, CallMSSAMU, RetMSSAMU + LoadMSSAMU, + CallMSSAMU, + RetMSSAMU }; protected: @@ -106,15 +105,12 @@ class MSSAMU const MemRegion* mr; MRVer* ver; Cond cond; + public: /// Constructor/Destructor for MU //@{ - MSSAMU(MUTYPE t, const MemRegion* m, Cond c) : type(t), mr(m), ver(nullptr), cond(c) - { - } - virtual ~MSSAMU() - { - } + MSSAMU(MUTYPE t, const MemRegion* m, Cond c) : type(t), mr(m), ver(nullptr), cond(c) {} + virtual ~MSSAMU() {} //@} /// Return MR @@ -136,7 +132,7 @@ class MSSAMU /// Get Ver inline MRVer* getMRVer() const { - assert(ver!=nullptr && "version is nullptr, did not rename?"); + assert(ver != nullptr && "version is nullptr, did not rename?"); return ver; } /// Return condition @@ -146,23 +142,22 @@ class MSSAMU } /// Avoid adding duplicated mus - inline bool operator < (const MSSAMU & rhs) const + inline bool operator<(const MSSAMU& rhs) const { return mr > rhs.getMR(); } /// Print MU virtual void dump() { - SVFUtil::outs() << "MU(MR_" << mr->getMRID() << "V_" << ver->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << "MU(MR_" << mr->getMRID() << "V_" << ver->getSSAVersion() << ") \t" + << this->getMR()->dumpStr() << "\n"; } }; /*! * LoadMU is annotated at each load instruction, representing a memory object is read here */ -template -class LoadMU : public MSSAMU +template class LoadMU : public MSSAMU { private: @@ -172,14 +167,11 @@ class LoadMU : public MSSAMU public: /// Constructor/Destructor for MU //@{ - LoadMU(const SVFBasicBlock* b,const LoadStmt* i, const MemRegion* m, Cond c = true) : - MSSAMU(MSSAMU::LoadMSSAMU,m,c), inst(i), bb(b) + LoadMU(const SVFBasicBlock* b, const LoadStmt* i, const MemRegion* m, Cond c = true) + : MSSAMU(MSSAMU::LoadMSSAMU, m, c), inst(i), bb(b) { } - virtual ~LoadMU() - { - - } + virtual ~LoadMU() {} //@} /// Return load instruction @@ -196,11 +188,11 @@ class LoadMU : public MSSAMU /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const LoadMU *) + static inline bool classof(const LoadMU*) { return true; } - static inline bool classof(const MSSAMU *mu) + static inline bool classof(const MSSAMU* mu) { return mu->getType() == MSSAMU::LoadMSSAMU; } @@ -209,16 +201,15 @@ class LoadMU : public MSSAMU /// Print MU virtual void dump() { - SVFUtil::outs() << "LDMU(MR_" << this->getMR()->getMRID() << "V_" << this->getMRVer()->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << "LDMU(MR_" << this->getMR()->getMRID() << "V_" << this->getMRVer()->getSSAVersion() << ") \t" + << this->getMR()->dumpStr() << "\n"; } }; /*! * CallMU is annotated at callsite, representing a memory object is indirect read by callee */ -template -class CallMU : public MSSAMU +template class CallMU : public MSSAMU { private: @@ -227,14 +218,11 @@ class CallMU : public MSSAMU public: /// Constructor/Destructor for MU //@{ - CallMU(const CallICFGNode* cs, const MemRegion* m, Cond c = true) : - MSSAMU(MSSAMU::CallMSSAMU,m,c), callsite(cs) + CallMU(const CallICFGNode* cs, const MemRegion* m, Cond c = true) + : MSSAMU(MSSAMU::CallMSSAMU, m, c), callsite(cs) { } - virtual ~CallMU() - { - - } + virtual ~CallMU() {} //@} /// Return callsite @@ -251,11 +239,11 @@ class CallMU : public MSSAMU /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CallMU *) + static inline bool classof(const CallMU*) { return true; } - static inline bool classof(const MSSAMU *mu) + static inline bool classof(const MSSAMU* mu) { return mu->getType() == MSSAMU::CallMSSAMU; } @@ -264,25 +252,23 @@ class CallMU : public MSSAMU /// Print MU virtual void dump() { - SVFUtil::outs() << "CALMU(MR_" << this->getMR()->getMRID() << "V_" << this->getMRVer()->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << "CALMU(MR_" << this->getMR()->getMRID() << "V_" << this->getMRVer()->getSSAVersion() + << ") \t" << this->getMR()->dumpStr() << "\n"; } }; - /*! * RetMU is annotated at function return, representing memory objects returns to callers */ -template -class RetMU : public MSSAMU +template class RetMU : public MSSAMU { private: const SVFFunction* fun; + public: /// Constructor/Destructor for MU //@{ - RetMU(const SVFFunction* f, const MemRegion* m, Cond c = true) : - MSSAMU(MSSAMU::RetMSSAMU,m,c), fun(f) + RetMU(const SVFFunction* f, const MemRegion* m, Cond c = true) : MSSAMU(MSSAMU::RetMSSAMU, m, c), fun(f) { } virtual ~RetMU() {} @@ -296,11 +282,11 @@ class RetMU : public MSSAMU /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const RetMU *) + static inline bool classof(const RetMU*) { return true; } - static inline bool classof(const MSSAMU *mu) + static inline bool classof(const MSSAMU* mu) { return mu->getType() == MSSAMU::RetMSSAMU; } @@ -309,12 +295,11 @@ class RetMU : public MSSAMU /// Print MU virtual void dump() { - SVFUtil::outs() << "RETMU(MR_" << this->getMR()->getMRID() << "V_" << this->getMRVer()->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << "RETMU(MR_" << this->getMR()->getMRID() << "V_" << this->getMRVer()->getSSAVersion() + << ") \t" << this->getMR()->dumpStr() << "\n"; } }; - /*! * Indirect Memory Definition * 1) MSSACHI indirect memory object is modified @@ -343,10 +328,7 @@ class MSSADEF public: /// Constructor/Destructor for MSSADEF //@{ - MSSADEF(DEFTYPE t, const MemRegion* m): type(t), mr(m), resVer(nullptr) - { - - } + MSSADEF(DEFTYPE t, const MemRegion* m) : type(t), mr(m), resVer(nullptr) {} virtual ~MSSADEF() {} //@} @@ -372,12 +354,12 @@ class MSSADEF /// Set operand vers inline MRVer* getResVer() const { - assert(resVer!=nullptr && "version is nullptr, did not rename?"); + assert(resVer != nullptr && "version is nullptr, did not rename?"); return resVer; } /// Avoid adding duplicated chis and phis - inline bool operator < (const MSSADEF & rhs) const + inline bool operator<(const MSSADEF& rhs) const { return mr > rhs.getMR(); } @@ -392,21 +374,18 @@ class MSSADEF /*! * Indirect Memory Write */ -template -class MSSACHI : public MSSADEF +template class MSSACHI : public MSSADEF { private: MRVer* opVer; Cond cond; + public: typedef typename MSSADEF::DEFTYPE CHITYPE; /// Constructor/Destructor for MSSACHI //@{ - MSSACHI(CHITYPE t, const MemRegion* m, Cond c): MSSADEF(t,m), opVer(nullptr), cond(c) - { - - } + MSSACHI(CHITYPE t, const MemRegion* m, Cond c) : MSSADEF(t, m), opVer(nullptr), cond(c) {} virtual ~MSSACHI() {} //@} @@ -420,7 +399,7 @@ class MSSACHI : public MSSADEF /// Get operand ver inline MRVer* getOpVer() const { - assert(opVer!=nullptr && "version is nullptr, did not rename?"); + assert(opVer != nullptr && "version is nullptr, did not rename?"); return opVer; } @@ -432,24 +411,23 @@ class MSSACHI : public MSSADEF /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const MSSACHI * chi) + static inline bool classof(const MSSACHI* chi) { return true; } - static inline bool classof(const MSSADEF *chi) + static inline bool classof(const MSSADEF* chi) { - return chi->getType() == MSSADEF::EntryMSSACHI || - chi->getType() == MSSADEF::StoreMSSACHI || - chi->getType() == MSSADEF::SSACHI ; + return chi->getType() == MSSADEF::EntryMSSACHI || chi->getType() == MSSADEF::StoreMSSACHI || + chi->getType() == MSSADEF::SSACHI; } //@} /// Print CHI virtual void dump() { - SVFUtil::outs() << "MR_" << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << - " = CHI(MR_" << this->getMR()->getMRID() << "V_" << opVer->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << "MR_" << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() + << " = CHI(MR_" << this->getMR()->getMRID() << "V_" << opVer->getSSAVersion() << ") \t" + << this->getMR()->dumpStr() << "\n"; } }; @@ -457,22 +435,20 @@ class MSSACHI : public MSSADEF * * StoreCHI is annotated at each store instruction, representing a memory object is modified here */ -template -class StoreCHI : public MSSACHI +template class StoreCHI : public MSSACHI { private: const SVFBasicBlock* bb; const StoreStmt* inst; + public: /// Constructors for StoreCHI //@{ - StoreCHI(const SVFBasicBlock* b, const StoreStmt* i, const MemRegion* m, Cond c = true) : - MSSACHI(MSSADEF::StoreMSSACHI,m,c), bb(b), inst(i) - { - } - virtual ~StoreCHI() + StoreCHI(const SVFBasicBlock* b, const StoreStmt* i, const MemRegion* m, Cond c = true) + : MSSACHI(MSSADEF::StoreMSSACHI, m, c), bb(b), inst(i) { } + virtual ~StoreCHI() {} //@} /// Get basic block @@ -489,15 +465,15 @@ class StoreCHI : public MSSACHI /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const StoreCHI * chi) + static inline bool classof(const StoreCHI* chi) { return true; } - static inline bool classof(const MSSACHI * chi) + static inline bool classof(const MSSACHI* chi) { return chi->getType() == MSSADEF::StoreMSSACHI; } - static inline bool classof(const MSSADEF *chi) + static inline bool classof(const MSSADEF* chi) { return chi->getType() == MSSADEF::StoreMSSACHI; } @@ -506,32 +482,29 @@ class StoreCHI : public MSSACHI /// Print CHI virtual void dump() { - SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << - " = STCHI(MR_" << this->getMR()->getMRID() << "V_" << this->getOpVer()->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << " = STCHI(MR_" + << this->getMR()->getMRID() << "V_" << this->getOpVer()->getSSAVersion() << ") \t" + << this->getMR()->dumpStr() << "\n"; } }; - /*! * * StoreCHI is annotated at each store instruction, representing a memory object is modified here */ -template -class CallCHI : public MSSACHI +template class CallCHI : public MSSACHI { private: const CallICFGNode* callsite; + public: /// Constructors for StoreCHI //@{ - CallCHI(const CallICFGNode* cs, const MemRegion* m, Cond c = true) : - MSSACHI(MSSADEF::CallMSSACHI,m,c), callsite(cs) - { - } - virtual ~CallCHI() + CallCHI(const CallICFGNode* cs, const MemRegion* m, Cond c = true) + : MSSACHI(MSSADEF::CallMSSACHI, m, c), callsite(cs) { } + virtual ~CallCHI() {} //@} /// Return basic block @@ -548,15 +521,15 @@ class CallCHI : public MSSACHI /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const CallCHI * chi) + static inline bool classof(const CallCHI* chi) { return true; } - static inline bool classof(const MSSACHI * chi) + static inline bool classof(const MSSACHI* chi) { return chi->getType() == MSSADEF::CallMSSACHI; } - static inline bool classof(const MSSADEF *chi) + static inline bool classof(const MSSADEF* chi) { return chi->getType() == MSSADEF::CallMSSACHI; } @@ -565,30 +538,28 @@ class CallCHI : public MSSACHI /// Print CHI virtual void dump() { - SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << - " = CALCHI(MR_" << this->getMR()->getMRID() << "V_" << this->getOpVer()->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << " = CALCHI(MR_" + << this->getMR()->getMRID() << "V_" << this->getOpVer()->getSSAVersion() << ") \t" + << this->getMR()->dumpStr() << "\n"; } }; /*! * EntryCHI is annotated at function entry, representing receiving memory objects from callers */ -template -class EntryCHI : public MSSACHI +template class EntryCHI : public MSSACHI { private: const SVFFunction* fun; + public: /// Constructors for EntryCHI //@{ - EntryCHI(const SVFFunction* f, const MemRegion* m, Cond c = true) : - MSSACHI(MSSADEF::EntryMSSACHI,m,c),fun(f) - { - } - virtual ~EntryCHI() + EntryCHI(const SVFFunction* f, const MemRegion* m, Cond c = true) + : MSSACHI(MSSADEF::EntryMSSACHI, m, c), fun(f) { } + virtual ~EntryCHI() {} //@} /// Return function @@ -599,15 +570,15 @@ class EntryCHI : public MSSACHI /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const EntryCHI * chi) + static inline bool classof(const EntryCHI* chi) { return true; } - static inline bool classof(const MSSACHI * chi) + static inline bool classof(const MSSACHI* chi) { return chi->getType() == MSSADEF::EntryMSSACHI; } - static inline bool classof(const MSSADEF *chi) + static inline bool classof(const MSSADEF* chi) { return chi->getType() == MSSADEF::EntryMSSACHI; } @@ -616,35 +587,31 @@ class EntryCHI : public MSSACHI /// Print CHI virtual void dump() { - SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << - " = ENCHI(MR_" << this->getMR()->getMRID() << "V_" << this->getOpVer()->getSSAVersion() << ") \t" << - this->getMR()->dumpStr() << "\n"; + SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << " = ENCHI(MR_" + << this->getMR()->getMRID() << "V_" << this->getOpVer()->getSSAVersion() << ") \t" + << this->getMR()->dumpStr() << "\n"; } }; /* * Memory SSA Select, similar to PHINode */ -template -class MSSAPHI : public MSSADEF +template class MSSAPHI : public MSSADEF { public: - typedef Map OPVers; + typedef Map OPVers; + private: const SVFBasicBlock* bb; OPVers opVers; Cond cond; + public: /// Constructors for PHI //@{ - MSSAPHI(const SVFBasicBlock* b, const MemRegion* m, Cond c = true) : - MSSADEF(MSSADEF::SSAPHI,m), bb(b), cond(c) - { - } - virtual ~MSSAPHI() - { - } + MSSAPHI(const SVFBasicBlock* b, const MemRegion* m, Cond c = true) : MSSADEF(MSSADEF::SSAPHI, m), bb(b), cond(c) {} + virtual ~MSSAPHI() {} //@} /// Set operand ver @@ -658,7 +625,7 @@ class MSSAPHI : public MSSADEF inline const MRVer* getOpVer(u32_t pos) const { OPVers::const_iterator it = opVers.find(pos); - assert(it!=opVers.end() && "version is nullptr, did not rename?"); + assert(it != opVers.end() && "version is nullptr, did not rename?"); return it->second; } @@ -694,29 +661,28 @@ class MSSAPHI : public MSSADEF /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const MSSAPHI * phi) + static inline bool classof(const MSSAPHI* phi) { return true; } - static inline bool classof(const MSSADEF *phi) + static inline bool classof(const MSSADEF* phi) { - return phi->getType() == MSSADEF::SSAPHI ; + return phi->getType() == MSSADEF::SSAPHI; } //@} /// Print PHI virtual void dump() { - SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << - " = PHI("; - for(OPVers::iterator it = opVers.begin(), eit = opVers.end(); it!=eit; ++it) + SVFUtil::outs() << this->getMR()->getMRID() << "V_" << this->getResVer()->getSSAVersion() << " = PHI("; + for (OPVers::iterator it = opVers.begin(), eit = opVers.end(); it != eit; ++it) SVFUtil::outs() << "MR_" << this->getMR()->getMRID() << "V_" << it->second->getSSAVersion() << ", "; SVFUtil::outs() << ")\n"; } }; -std::ostream& operator<<(std::ostream &o, const MRVer& mrver); +std::ostream& operator<<(std::ostream& o, const MRVer& mrver); } // End namespace SVF #endif /* MSSAMUCHI_H_ */ diff --git a/svf/include/MSSA/MemPartition.h b/svf/include/MSSA/MemPartition.h index 3138f7b58..a3f49b16e 100644 --- a/svf/include/MSSA/MemPartition.h +++ b/svf/include/MSSA/MemPartition.h @@ -32,7 +32,6 @@ * */ - #ifndef DISNCTMRGENERATOR_H_ #define DISNCTMRGENERATOR_H_ @@ -47,8 +46,7 @@ namespace SVF class DistinctMRG : public MRGenerator { public: - DistinctMRG(BVDataPTAImpl* p, bool ptrOnly) : MRGenerator(p, ptrOnly) - {} + DistinctMRG(BVDataPTAImpl* p, bool ptrOnly) : MRGenerator(p, ptrOnly) {} ~DistinctMRG() {} @@ -61,10 +59,10 @@ class DistinctMRG : public MRGenerator /// Get memory regions to be inserted at a load statement. virtual void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun); + private: /// Create memory regions for each points-to target. void createDistinctMR(const SVFFunction* func, const NodeBS& cpts); - }; /*! @@ -77,13 +75,11 @@ class IntraDisjointMRG : public MRGenerator typedef Map FunToPtsMap; typedef Map FunToInterMap; - IntraDisjointMRG(BVDataPTAImpl* p, bool ptrOnly) : MRGenerator(p, ptrOnly) - {} + IntraDisjointMRG(BVDataPTAImpl* p, bool ptrOnly) : MRGenerator(p, ptrOnly) {} ~IntraDisjointMRG() {} protected: - /// Partition regions virtual void partitionMRs(); @@ -93,8 +89,7 @@ class IntraDisjointMRG : public MRGenerator * @param fun The function being analyzed. * @param mrs Memory region set contains all possible target memory regions. */ - virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, - const SVFFunction* fun) + virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun) { const PointsToList& inters = getIntersList(fun); getMRsForLoadFromInterList(aliasMRs, cpts, inters); @@ -139,8 +134,7 @@ class IntraDisjointMRG : public MRGenerator class InterDisjointMRG : public IntraDisjointMRG { public: - InterDisjointMRG(BVDataPTAImpl* p, bool ptrOnly) : IntraDisjointMRG(p, ptrOnly) - {} + InterDisjointMRG(BVDataPTAImpl* p, bool ptrOnly) : IntraDisjointMRG(p, ptrOnly) {} ~InterDisjointMRG() {} @@ -154,8 +148,7 @@ class InterDisjointMRG : public IntraDisjointMRG * @param fun The function being analyzed. * @param mrs Memory region set contains all possible target memory regions. */ - virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, - const SVFFunction*) + virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction*) { getMRsForLoadFromInterList(aliasMRs, cpts, inters); } diff --git a/svf/include/MSSA/MemRegion.h b/svf/include/MSSA/MemRegion.h index 42d18e70d..96279c4eb 100644 --- a/svf/include/MSSA/MemRegion.h +++ b/svf/include/MSSA/MemRegion.h @@ -57,6 +57,7 @@ class MemRegion public: typedef bool Condition; + private: /// region ID 0 is reserved static u32_t totalMRNum; @@ -65,14 +66,9 @@ class MemRegion public: /// Constructor - MemRegion(const NodeBS& cp) : - rid(++totalMRNum), cptsSet(cp) - { - } + MemRegion(const NodeBS& cp) : rid(++totalMRNum), cptsSet(cp) {} /// Destructor - ~MemRegion() - { - } + ~MemRegion() {} /// Return memory region ID inline MRID getMRID() const @@ -80,7 +76,7 @@ class MemRegion return rid; } /// Return points-to - inline const NodeBS &getPointsTo() const + inline const NodeBS& getPointsTo() const { return cptsSet; } @@ -94,8 +90,7 @@ class MemRegion { std::string str; str += "pts{"; - for (NodeBS::iterator ii = cptsSet.begin(), ie = cptsSet.end(); - ii != ie; ii++) + for (NodeBS::iterator ii = cptsSet.begin(), ie = cptsSet.end(); ii != ie; ii++) { char int2str[16]; snprintf(int2str, sizeof(int2str), "%d", *ii); @@ -137,7 +132,7 @@ class MRGenerator /// Get typedef from Pointer Analysis //@{ //@} - ///Define mem region set + /// Define mem region set typedef OrderedSet MRSet; typedef Map PAGEdgeToFunMap; typedef OrderedSet PointsToList; @@ -186,14 +181,13 @@ class MRGenerator inline const NodeBS& getRepPointsTo(const NodeBS& cpts) const { PtsToRepPtsSetMap::const_iterator it = cptsToRepCPtsMap.find(cpts); - assert(it!=cptsToRepCPtsMap.end() && "can not find superset of cpts??"); + assert(it != cptsToRepCPtsMap.end() && "can not find superset of cpts??"); return it->second; } /// Get a memory region according to cpts const MemRegion* getMR(const NodeBS& cpts) const; private: - BVDataPTAImpl* pta; SCC* callGraphSCC; CallGraph* callGraph; @@ -212,7 +206,7 @@ class MRGenerator /// Map a load SVFIR Edge to its CPts set map LoadsToPointsToMap loadsToPointsToMap; /// Map a store SVFIR Edge to its CPts set map - StoresToPointsToMap storesToPointsToMap; + StoresToPointsToMap storesToPointsToMap; /// Map a callsite to it refs cpts set CallSiteToPointsToMap callsiteToRefPointsToMap; /// Map a callsite to it mods cpts set @@ -245,10 +239,10 @@ class MRGenerator /// Clean up memory void destroy(); - //Get all objects might pass into callee from a callsite + // Get all objects might pass into callee from a callsite void collectCallSitePts(const CallICFGNode* cs); - //Recursive collect points-to chain + // Recursive collect points-to chain NodeBS& CollectPtsChain(NodeID id); /// Return the pts chain of all callsite arguments @@ -308,10 +302,9 @@ class MRGenerator /// Get all aliased mem regions from function fun according to cpts virtual inline void getAliasMemRegions(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun) { - for(MRSet::const_iterator it = funToMRsMap[fun].begin(), eit = funToMRsMap[fun].end(); it!=eit; ++it) + for (MRSet::const_iterator it = funToMRsMap[fun].begin(), eit = funToMRsMap[fun].end(); it != eit; ++it) { - if(isAliasedMR(cpts,*it)) - aliasMRs.insert(*it); + if (isAliasedMR(cpts, *it)) aliasMRs.insert(*it); } } @@ -335,20 +328,19 @@ class MRGenerator /// Get Mod-Ref of a callee function virtual bool handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const SVFFunction* fun); - /// Add cpts to store/load //@{ - inline void addCPtsToStore(NodeBS& cpts, const StoreStmt *st, const SVFFunction* fun) + inline void addCPtsToStore(NodeBS& cpts, const StoreStmt* st, const SVFFunction* fun) { storesToPointsToMap[st] = cpts; funToPointsToMap[fun].insert(cpts); - addModSideEffectOfFunction(fun,cpts); + addModSideEffectOfFunction(fun, cpts); } - inline void addCPtsToLoad(NodeBS& cpts, const LoadStmt *ld, const SVFFunction* fun) + inline void addCPtsToLoad(NodeBS& cpts, const LoadStmt* ld, const SVFFunction* fun) { loadsToPointsToMap[ld] = cpts; funToPointsToMap[fun].insert(cpts); - addRefSideEffectOfFunction(fun,cpts); + addRefSideEffectOfFunction(fun, cpts); } inline void addCPtsToCallSiteRefs(NodeBS& cpts, const CallICFGNode* cs) { @@ -362,7 +354,7 @@ class MRGenerator } inline bool hasCPtsList(const SVFFunction* fun) const { - return funToPointsToMap.find(fun)!=funToPointsToMap.end(); + return funToPointsToMap.find(fun) != funToPointsToMap.end(); } inline PointsToList& getPointsToList(const SVFFunction* fun) { @@ -435,7 +427,7 @@ class MRGenerator const SVFFunction* getFunction(const PAGEdge* pagEdge) const { PAGEdgeToFunMap::const_iterator it = pagEdgeToFunMap.find(pagEdge); - assert(it!=pagEdgeToFunMap.end() && "can not find its function, it is a global SVFIR edge"); + assert(it != pagEdgeToFunMap.end() && "can not find its function, it is a global SVFIR edge"); return it->second; } /// Get Memory Region set @@ -454,11 +446,11 @@ class MRGenerator } inline bool hasRefMRSet(const CallICFGNode* cs) { - return callsiteToRefMRsMap.find(cs)!=callsiteToRefMRsMap.end(); + return callsiteToRefMRsMap.find(cs) != callsiteToRefMRsMap.end(); } inline bool hasModMRSet(const CallICFGNode* cs) { - return callsiteToModMRsMap.find(cs)!=callsiteToModMRsMap.end(); + return callsiteToModMRsMap.find(cs) != callsiteToModMRsMap.end(); } inline MRSet& getCallSiteRefMRSet(const CallICFGNode* cs) { @@ -483,7 +475,6 @@ class MRGenerator ModRefInfo getModRefInfo(const CallICFGNode* cs, const SVFValue* V); ModRefInfo getModRefInfo(const CallICFGNode* cs1, const CallICFGNode* cs2); //@} - }; } // End namespace SVF diff --git a/svf/include/MSSA/MemSSA.h b/svf/include/MSSA/MemSSA.h index 3424095a6..e6f68e7fc 100644 --- a/svf/include/MSSA/MemSSA.h +++ b/svf/include/MSSA/MemSSA.h @@ -32,7 +32,6 @@ * Journal of Systems and Software (JSS'16), Algorithm 3 in the paper */ - #ifndef MEMORYSSAPASS_H_ #define MEMORYSSAPASS_H_ @@ -53,7 +52,6 @@ class MemSSA { public: - /// define condition here changes needed if we add new type typedef MemRegion::Condition Condition; typedef MSSAMU MU; @@ -71,7 +69,7 @@ class MemSSA typedef Set CHISet; typedef Set PHISet; - ///Define mem region set + /// Define mem region set typedef MRGenerator::MRSet MRSet; typedef std::vector MRVector; /// Map loads/stores to its mem regions, @@ -96,7 +94,7 @@ class MemSSA //@} /// For SSA renaming - typedef Map > MemRegToVerStackMap; + typedef Map> MemRegToVerStackMap; typedef Map MemRegToCounterMap; /// SVFIR edge list @@ -104,10 +102,10 @@ class MemSSA /// Statistics //@{ - static double timeOfGeneratingMemRegions; ///< Time for allocating regions - static double timeOfCreateMUCHI; ///< Time for generating mu/chi for load/store/calls - static double timeOfInsertingPHI; ///< Time for inserting phis - static double timeOfSSARenaming; ///< Time for SSA rename + static double timeOfGeneratingMemRegions; ///< Time for allocating regions + static double timeOfCreateMUCHI; ///< Time for generating mu/chi for load/store/calls + static double timeOfInsertingPHI; ///< Time for inserting phis + static double timeOfSSARenaming; ///< Time for SSA rename //@} enum MemPartition @@ -130,6 +128,7 @@ class MemSSA virtual void SSARename(const SVFFunction& fun); /// SSA rename for a basic block virtual void SSARenameBB(const SVFBasicBlock& bb); + private: LoadToMUSetMap load2MuSetMap; StoreToChiSetMap store2ChiSetMap; @@ -165,7 +164,7 @@ class MemSSA /// Get the last version of the SSA ver of memory region inline MRVer* getTopStackVer(const MemRegion* mr) { - std::vector &stack = mr2VerStackMap[mr]; + std::vector& stack = mr2VerStackMap[mr]; assert(!stack.empty() && "stack is empty!!"); return stack.back(); } @@ -174,8 +173,7 @@ class MemSSA //@{ inline void collectRegUses(const MemRegion* mr) { - if (0 == varKills.count(mr)) - usedRegs.insert(mr); + if (0 == varKills.count(mr)) usedRegs.insert(mr); } inline void collectRegDefs(const SVFBasicBlock* bb, const MemRegion* mr) { @@ -189,40 +187,38 @@ class MemSSA inline void AddLoadMU(const SVFBasicBlock* bb, const LoadStmt* load, const MRSet& mrSet) { for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) - AddLoadMU(bb,load,*iter); + AddLoadMU(bb, load, *iter); } inline void AddStoreCHI(const SVFBasicBlock* bb, const StoreStmt* store, const MRSet& mrSet) { for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) - AddStoreCHI(bb,store,*iter); + AddStoreCHI(bb, store, *iter); } - inline void AddCallSiteMU(const CallICFGNode* cs, const MRSet& mrSet) + inline void AddCallSiteMU(const CallICFGNode* cs, const MRSet& mrSet) { - for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) - AddCallSiteMU(cs,*iter); + for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) AddCallSiteMU(cs, *iter); } - inline void AddCallSiteCHI(const CallICFGNode* cs, const MRSet& mrSet) + inline void AddCallSiteCHI(const CallICFGNode* cs, const MRSet& mrSet) { for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) - AddCallSiteCHI(cs,*iter); + AddCallSiteCHI(cs, *iter); } inline void AddMSSAPHI(const SVFBasicBlock* bb, const MRSet& mrSet) { - for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) - AddMSSAPHI(bb,*iter); + for (MRSet::iterator iter = mrSet.begin(), eiter = mrSet.end(); iter != eiter; ++iter) AddMSSAPHI(bb, *iter); } inline void AddLoadMU(const SVFBasicBlock* bb, const LoadStmt* load, const MemRegion* mr) { - LOADMU* mu = new LOADMU(bb,load, mr); + LOADMU* mu = new LOADMU(bb, load, mr); load2MuSetMap[load].insert(mu); collectRegUses(mr); } inline void AddStoreCHI(const SVFBasicBlock* bb, const StoreStmt* store, const MemRegion* mr) { - STORECHI* chi = new STORECHI(bb,store, mr); + STORECHI* chi = new STORECHI(bb, store, mr); store2ChiSetMap[store].insert(chi); collectRegUses(mr); - collectRegDefs(bb,mr); + collectRegDefs(bb, mr); } inline void AddCallSiteMU(const CallICFGNode* cs, const MemRegion* mr) { @@ -235,7 +231,7 @@ class MemSSA CALLCHI* chi = new CALLCHI(cs, mr); callsiteToChiSetMap[cs].insert(chi); collectRegUses(mr); - collectRegDefs(chi->getBasicBlock(),mr); + collectRegDefs(chi->getBasicBlock(), mr); } inline void AddMSSAPHI(const SVFBasicBlock* bb, const MemRegion* mr) { @@ -248,8 +244,7 @@ class MemSSA /// Rename mu set inline void RenameMuSet(const MUSet& muSet) { - for (MUSet::const_iterator mit = muSet.begin(), emit = muSet.end(); - mit != emit; ++mit) + for (MUSet::const_iterator mit = muSet.begin(), emit = muSet.end(); mit != emit; ++mit) { MU* mu = (*mit); mu->setVer(getTopStackVer(mu->getMR())); @@ -259,12 +254,11 @@ class MemSSA /// Rename chi set inline void RenameChiSet(const CHISet& chiSet, MRVector& memRegs) { - for (CHISet::const_iterator cit = chiSet.begin(), ecit = chiSet.end(); - cit != ecit; ++cit) + for (CHISet::const_iterator cit = chiSet.begin(), ecit = chiSet.end(); cit != ecit; ++cit) { CHI* chi = (*cit); chi->setOpVer(getTopStackVer(chi->getMR())); - chi->setResVer(newSSAName(chi->getMR(),chi)); + chi->setResVer(newSSAName(chi->getMR(), chi)); memRegs.push_back(chi->getMR()); } } @@ -272,11 +266,10 @@ class MemSSA /// Rename result (LHS) of phis inline void RenamePhiRes(const PHISet& phiSet, MRVector& memRegs) { - for (PHISet::const_iterator iter = phiSet.begin(), eiter = phiSet.end(); - iter != eiter; ++iter) + for (PHISet::const_iterator iter = phiSet.begin(), eiter = phiSet.end(); iter != eiter; ++iter) { PHI* phi = *iter; - phi->setResVer(newSSAName(phi->getMR(),phi)); + phi->setResVer(newSSAName(phi->getMR(), phi)); memRegs.push_back(phi->getMR()); } } @@ -284,8 +277,7 @@ class MemSSA /// Rename operands (RHS) of phis inline void RenamePhiOps(const PHISet& phiSet, u32_t pos, MRVector&) { - for (PHISet::const_iterator iter = phiSet.begin(), eiter = phiSet.end(); - iter != eiter; ++iter) + for (PHISet::const_iterator iter = phiSet.begin(), eiter = phiSet.end(); iter != eiter; ++iter) { PHI* phi = *iter; phi->setOpVer(getTopStackVer(phi->getMR()), pos); @@ -335,8 +327,7 @@ class MemSSA } inline bool hasCHI(const PAGEdge* inst) const { - if (const StoreStmt* store = SVFUtil::dyn_cast( - inst)) + if (const StoreStmt* store = SVFUtil::dyn_cast(inst)) { bool has_store = store2ChiSetMap.count(store) != 0; assert(has_store && "not associated with mem region!"); @@ -347,30 +338,30 @@ class MemSSA } inline bool hasMU(const CallICFGNode* cs) const { - return callsiteToMuSetMap.find(cs)!=callsiteToMuSetMap.end(); + return callsiteToMuSetMap.find(cs) != callsiteToMuSetMap.end(); } inline bool hasCHI(const CallICFGNode* cs) const { - return callsiteToChiSetMap.find(cs)!=callsiteToChiSetMap.end(); + return callsiteToChiSetMap.find(cs) != callsiteToChiSetMap.end(); } //@} /// Has function entry chi or return mu //@{ - inline bool hasFuncEntryChi(const SVFFunction * fun) const + inline bool hasFuncEntryChi(const SVFFunction* fun) const { return (funToEntryChiSetMap.find(fun) != funToEntryChiSetMap.end()); } - inline bool hasReturnMu(const SVFFunction * fun) const + inline bool hasReturnMu(const SVFFunction* fun) const { return (funToReturnMuSetMap.find(fun) != funToReturnMuSetMap.end()); } - inline CHISet& getFuncEntryChiSet(const SVFFunction * fun) + inline CHISet& getFuncEntryChiSet(const SVFFunction* fun) { return funToEntryChiSetMap[fun]; } - inline MUSet& getReturnMuSet(const SVFFunction * fun) + inline MUSet& getReturnMuSet(const SVFFunction* fun) { return funToReturnMuSetMap[fun]; } @@ -400,7 +391,7 @@ class MemSSA } inline bool hasPHISet(const SVFBasicBlock* bb) const { - return bb2PhiSetMap.find(bb)!=bb2PhiSetMap.end(); + return bb2PhiSetMap.find(bb) != bb2PhiSetMap.end(); } inline LoadToMUSetMap& getLoadToMUSetMap() { @@ -444,7 +435,7 @@ class MemSSA //@} /// Print Memory SSA - void dumpMSSA(OutStream & Out = SVFUtil::outs()); + void dumpMSSA(OutStream& Out = SVFUtil::outs()); }; } // End namespace SVF diff --git a/svf/include/MSSA/SVFGBuilder.h b/svf/include/MSSA/SVFGBuilder.h index c08825605..4ad3296d3 100644 --- a/svf/include/MSSA/SVFGBuilder.h +++ b/svf/include/MSSA/SVFGBuilder.h @@ -49,7 +49,7 @@ class SVFGBuilder typedef SVFG::SVFGEdgeSetTy SVFGEdgeSet; /// Constructor - explicit SVFGBuilder(bool _SVFGWithIndCall = false): svfg(nullptr), SVFGWithIndCall(_SVFGWithIndCall) {} + explicit SVFGBuilder(bool _SVFGWithIndCall = false) : svfg(nullptr), SVFGWithIndCall(_SVFGWithIndCall) {} /// Destructor virtual ~SVFGBuilder() = default; @@ -66,13 +66,13 @@ class SVFGBuilder /// Mark feasible VF edge by removing it from set vfEdgesAtIndCallSite inline void markValidVFEdge(SVFGEdgeSet& edges) { - for(SVFGEdgeSet::iterator it = edges.begin(), eit = edges.end(); it!=eit; ++it) + for (SVFGEdgeSet::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it) vfEdgesAtIndCallSite.erase(*it); } /// Return true if this is an VF Edge pre-connected by Andersen's analysis inline bool isSpuriousVFEdgeAtIndCallSite(const SVFGEdge* edge) { - return vfEdgesAtIndCallSite.find(const_cast(edge))!=vfEdgesAtIndCallSite.end(); + return vfEdgesAtIndCallSite.find(const_cast(edge)) != vfEdgesAtIndCallSite.end(); } /// Build Memory SSA diff --git a/svf/include/MTA/LockAnalysis.h b/svf/include/MTA/LockAnalysis.h index f106e5f8f..f4e1295f9 100644 --- a/svf/include/MTA/LockAnalysis.h +++ b/svf/include/MTA/LockAnalysis.h @@ -48,9 +48,9 @@ class LockAnalysis /// semilattice Empty==>TDUnlocked==>TDLocked enum ValDomain { - Empty, // initial(dummy) state - TDLocked, // stmt is locked - TDUnlocked, // stmt is unlocked + Empty, // initial(dummy) state + TDLocked, // stmt is locked + TDUnlocked, // stmt is unlocked }; typedef CxtStmt CxtLock; @@ -60,7 +60,7 @@ class LockAnalysis typedef TCT::InstVec InstVec; typedef Set InstSet; typedef InstSet CISpan; - typedef MapCILockToSpan; + typedef Map CILockToSpan; typedef Set FunSet; typedef Map InstToInstSetMap; typedef Map CxtStmtToLockFlagMap; @@ -79,9 +79,7 @@ class LockAnalysis typedef Map InstToCxtStmt; - LockAnalysis(TCT* t) : tct(t), lockTime(0),numOfTotalQueries(0), numOfLockedQueries(0), lockQueriesTime(0) - { - } + LockAnalysis(TCT* t) : tct(t), lockTime(0), numOfTotalQueries(0), numOfLockedQueries(0), lockQueriesTime(0) {} /// context-sensitive forward traversal from each lock site. Generate following results /// (1) context-sensitive lock site, @@ -102,14 +100,14 @@ class LockAnalysis /// Return true if the lock is an intra-procedural lock inline bool isIntraLock(const ICFGNode* lock) const { - assert(locksites.find(lock)!=locksites.end() && "not a lock site?"); - return ciLocktoSpan.find(lock)!=ciLocktoSpan.end(); + assert(locksites.find(lock) != locksites.end() && "not a lock site?"); + return ciLocktoSpan.find(lock) != ciLocktoSpan.end(); } /// Add intra-procedural lock inline void addIntraLock(const ICFGNode* lockSite, const InstSet& stmts) { - for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it) + for (InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it != eit; ++it) { instCILocksMap[*it].insert(lockSite); ciLocktoSpan[lockSite].insert(*it); @@ -119,7 +117,7 @@ class LockAnalysis /// Add intra-procedural lock inline void addCondIntraLock(const ICFGNode* lockSite, const InstSet& stmts) { - for(InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it!=eit; ++it) + for (InstSet::const_iterator it = stmts.begin(), eit = stmts.end(); it != eit; ++it) { instTocondCILocksMap[*it].insert(lockSite); } @@ -128,19 +126,19 @@ class LockAnalysis /// Return true if a statement is inside an intra-procedural lock inline bool isInsideIntraLock(const ICFGNode* stmt) const { - return instCILocksMap.find(stmt)!=instCILocksMap.end() || isInsideCondIntraLock(stmt); + return instCILocksMap.find(stmt) != instCILocksMap.end() || isInsideCondIntraLock(stmt); } /// Return true if a statement is inside a partial lock/unlock pair (conditional lock with unconditional unlock) inline bool isInsideCondIntraLock(const ICFGNode* stmt) const { - return instTocondCILocksMap.find(stmt)!=instTocondCILocksMap.end(); + return instTocondCILocksMap.find(stmt) != instTocondCILocksMap.end(); } inline const InstSet& getIntraLockSet(const ICFGNode* stmt) const { InstToInstSetMap::const_iterator it = instCILocksMap.find(stmt); - assert(it!=instCILocksMap.end() && "intralock not found!"); + assert(it != instCILocksMap.end() && "intralock not found!"); return it->second; } //@} @@ -148,9 +146,9 @@ class LockAnalysis /// Context-sensitive locks //@{ /// Add inter-procedural context-sensitive lock - inline void addCxtLock(const CallStrCxt& cxt,const ICFGNode* inst) + inline void addCxtLock(const CallStrCxt& cxt, const ICFGNode* inst) { - CxtLock cxtlock(cxt,inst); + CxtLock cxtlock(cxt, inst); cxtLockset.insert(cxtlock); DBOUT(DMTA, SVFUtil::outs() << "LockAnalysis Process new lock "; cxtlock.dump()); } @@ -158,33 +156,31 @@ class LockAnalysis /// Get context-sensitive lock inline bool hasCxtLock(const CxtLock& cxtLock) const { - return cxtLockset.find(cxtLock)!=cxtLockset.end(); + return cxtLockset.find(cxtLock) != cxtLockset.end(); } /// Return true if the intersection of two locksets is not empty - inline bool intersects(const CxtLockSet& lockset1,const CxtLockSet& lockset2) const + inline bool intersects(const CxtLockSet& lockset1, const CxtLockSet& lockset2) const { - for(CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it!=eit; ++it) + for (CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it != eit; ++it) { const CxtLock& lock = *it; - for(CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit!=elit; ++lit) + for (CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit != elit; ++lit) { - if(lock==*lit) - return true; + if (lock == *lit) return true; } } return false; } /// Return true if two locksets has at least one alias lock - inline bool alias(const CxtLockSet& lockset1,const CxtLockSet& lockset2) + inline bool alias(const CxtLockSet& lockset1, const CxtLockSet& lockset2) { - for(CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it!=eit; ++it) + for (CxtLockSet::const_iterator it = lockset1.begin(), eit = lockset1.end(); it != eit; ++it) { const CxtLock& lock = *it; - for(CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit!=elit; ++lit) + for (CxtLockSet::const_iterator lit = lockset2.begin(), elit = lockset2.end(); lit != elit; ++lit) { - if(isAliasedLocks(lock,*lit)) - return true; + if (isAliasedLocks(lock, *lit)) return true; } } return false; @@ -194,7 +190,7 @@ class LockAnalysis /// Return true if it is a candidate function inline bool isLockCandidateFun(const SVFFunction* fun) const { - return lockcandidateFuncSet.find(fun)!=lockcandidateFuncSet.end(); + return lockcandidateFuncSet.find(fun) != lockcandidateFuncSet.end(); } /// Context-sensitive statement and lock spans @@ -237,8 +233,8 @@ class LockAnalysis /// Add context-sensitive statement inline bool removeCxtStmtToSpan(CxtStmt& cts, const CxtLock& cl) { - bool find = cxtStmtToCxtLockSet[cts].find(cl)!=cxtStmtToCxtLockSet[cts].end(); - if(find) + bool find = cxtStmtToCxtLockSet[cts].find(cl) != cxtStmtToCxtLockSet[cts].end(); + if (find) { cxtStmtToCxtLockSet[cts].erase(cl); cxtLocktoSpan[cl].erase(cts); @@ -266,17 +262,14 @@ class LockAnalysis } //@} - - /// Check if one instruction's context stmt is in a lock span - inline bool hasOneCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const + inline bool hasOneCxtInLockSpan(const ICFGNode* I, LockSpan lspan) const { - if(!hasCxtStmtfromInst(I)) - return false; + if (!hasCxtStmtfromInst(I)) return false; const LockSpan ctsset = getCxtStmtfromInst(I); for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++) { - if(lspan.find(*cts) != lspan.end()) + if (lspan.find(*cts) != lspan.end()) { return true; } @@ -284,10 +277,9 @@ class LockAnalysis return false; } - inline bool hasAllCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const + inline bool hasAllCxtInLockSpan(const ICFGNode* I, LockSpan lspan) const { - if(!hasCxtStmtfromInst(I)) - return false; + if (!hasCxtStmtfromInst(I)) return false; const LockSpan ctsset = getCxtStmtfromInst(I); for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++) { @@ -299,19 +291,18 @@ class LockAnalysis return true; } - /// Check if two Instructions are protected by common locks /// echo inst may have multiple cxt stmt /// we check whether every cxt stmt of instructions is protected by a common lock. - bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2); - bool isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2); + bool isProtectedByCommonLock(const ICFGNode* i1, const ICFGNode* i2); + bool isProtectedByCommonCxtLock(const ICFGNode* i1, const ICFGNode* i2); bool isProtectedByCommonCxtLock(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2); - bool isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2); + bool isProtectedByCommonCILock(const ICFGNode* i1, const ICFGNode* i2); - bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2); - bool isInSameCSSpan(const ICFGNode *i1, const ICFGNode *i2) const; + bool isInSameSpan(const ICFGNode* I1, const ICFGNode* I2); + bool isInSameCSSpan(const ICFGNode* i1, const ICFGNode* i2) const; bool isInSameCSSpan(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2) const; - bool isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const; + bool isInSameCISpan(const ICFGNode* i1, const ICFGNode* i2) const; inline u32_t getNumOfCxtLocks() { @@ -325,6 +316,7 @@ class LockAnalysis { return tct; } + private: /// Handle fork void handleFork(const CxtStmt& cts); @@ -358,29 +350,27 @@ class LockAnalysis void markCxtStmtFlag(const CxtStmt& tgr, const CxtStmt& src) { const CxtLockSet& srclockset = getCxtLockfromCxtStmt(src); - if(hasCxtLockfromCxtStmt(tgr)== false) + if (hasCxtLockfromCxtStmt(tgr) == false) { - for(CxtLockSet::const_iterator it = srclockset.begin(), eit = srclockset.end(); it!=eit; ++it) + for (CxtLockSet::const_iterator it = srclockset.begin(), eit = srclockset.end(); it != eit; ++it) { - addCxtStmtToSpan(tgr,*it); + addCxtStmtToSpan(tgr, *it); } pushToCTSWorkList(tgr); } else { - if(intersect(getCxtLockfromCxtStmt(tgr),srclockset)) - pushToCTSWorkList(tgr); + if (intersect(getCxtLockfromCxtStmt(tgr), srclockset)) pushToCTSWorkList(tgr); } } bool intersect(CxtLockSet& tgrlockset, const CxtLockSet& srclockset) { CxtLockSet toBeDeleted; - for(CxtLockSet::const_iterator it = tgrlockset.begin(), eit = tgrlockset.end(); it!=eit; ++it) + for (CxtLockSet::const_iterator it = tgrlockset.begin(), eit = tgrlockset.end(); it != eit; ++it) { - if(srclockset.find(*it)==srclockset.end()) - toBeDeleted.insert(*it); + if (srclockset.find(*it) == srclockset.end()) toBeDeleted.insert(*it); } - for(CxtLockSet::const_iterator it = toBeDeleted.begin(), eit = toBeDeleted.end(); it!=eit; ++it) + for (CxtLockSet::const_iterator it = toBeDeleted.begin(), eit = toBeDeleted.end(); it != eit; ++it) { tgrlockset.erase(*it); } @@ -479,7 +469,6 @@ class LockAnalysis /// Map a statement to all its context-sensitive statements InstToCxtStmtSet instToCxtStmtSet; - /// Context-sensitive locks CxtLockSet cxtLockset; @@ -492,7 +481,7 @@ class LockAnalysis /// Following data structures are used for collecting context-sensitive locks //@{ - CxtLockProcVec clpList; /// CxtLockProc List + CxtLockProcVec clpList; /// CxtLockProc List CxtLockProcSet visitedCTPs; /// Record all visited clps //@} @@ -514,7 +503,6 @@ class LockAnalysis InstToInstSetMap instTocondCILocksMap; //@} - public: double lockTime; u32_t numOfTotalQueries; diff --git a/svf/include/MTA/MHP.h b/svf/include/MTA/MHP.h index 55ed243c7..379eac056 100644 --- a/svf/include/MTA/MHP.h +++ b/svf/include/MTA/MHP.h @@ -40,7 +40,8 @@ class LockAnalysis; /*! * This class serves as a base may-happen in parallel analysis for multithreaded program - * Given a statement under an abstract thread, it tells which abstract threads may be alive at the same time (May-happen-in-parallel). + * Given a statement under an abstract thread, it tells which abstract threads may be alive at the same time + * (May-happen-in-parallel). */ class MHP { @@ -49,13 +50,13 @@ class MHP typedef Set FunSet; typedef FIFOWorkList CxtThreadStmtWorkList; typedef Set CxtThreadStmtSet; - typedef Map ThreadStmtToThreadInterleav; - typedef Map InstToThreadStmtSetMap; + typedef Map ThreadStmtToThreadInterleav; + typedef Map InstToThreadStmtSetMap; typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; typedef Set LockSpan; - typedef std::pair FuncPair; + typedef std::pair FuncPair; typedef Map FuncPairToBool; /// Constructor @@ -85,7 +86,7 @@ class MHP /// Whether the function is connected from main function in thread call graph bool isConnectedfromMain(const SVFFunction* fun); -// LockSpan getSpanfromCxtLock(NodeID l); + // LockSpan getSpanfromCxtLock(NodeID l); /// Interface to query whether two instructions may happen-in-parallel virtual bool mayHappenInParallel(const ICFGNode* i1, const ICFGNode* i2); virtual bool mayHappenInParallelCache(const ICFGNode* i1, const ICFGNode* i2); @@ -100,7 +101,7 @@ class MHP } inline bool hasInterleavingThreads(const CxtThreadStmt& cts) const { - return threadStmtToTheadInterLeav.find(cts)!=threadStmtToTheadInterLeav.end(); + return threadStmtToTheadInterLeav.find(cts) != threadStmtToTheadInterLeav.end(); } //@} @@ -109,12 +110,12 @@ class MHP inline const CxtThreadStmtSet& getThreadStmtSet(const ICFGNode* inst) const { InstToThreadStmtSetMap::const_iterator it = instToTSMap.find(inst); - assert(it!=instToTSMap.end() && "no thread access the instruction?"); + assert(it != instToTSMap.end() && "no thread access the instruction?"); return it->second; } inline bool hasThreadStmtSet(const ICFGNode* inst) const { - return instToTSMap.find(inst)!=instToTSMap.end(); + return instToTSMap.find(inst) != instToTSMap.end(); } //@} @@ -122,7 +123,6 @@ class MHP void printInterleaving(); private: - inline const CallGraph::FunctionSet& getCallee(const CallICFGNode* inst, CallGraph::FunctionSet& callees) { tcg->getCallees(inst, callees); @@ -154,7 +154,7 @@ class MHP //@{ inline void addInterleavingThread(const CxtThreadStmt& tgr, NodeID tid) { - if(threadStmtToTheadInterLeav[tgr].test_and_set(tid)) + if (threadStmtToTheadInterLeav[tgr].test_and_set(tid)) { instToTSMap[tgr.getStmt()].insert(tgr); pushToCTSWorkList(tgr); @@ -163,7 +163,7 @@ class MHP inline void addInterleavingThread(const CxtThreadStmt& tgr, const CxtThreadStmt& src) { bool changed = threadStmtToTheadInterLeav[tgr] |= threadStmtToTheadInterLeav[src]; - if(changed) + if (changed) { instToTSMap[tgr.getStmt()].insert(tgr); pushToCTSWorkList(tgr); @@ -172,12 +172,11 @@ class MHP inline void rmInterleavingThread(const CxtThreadStmt& tgr, const NodeBS& tids, const ICFGNode* joinsite) { NodeBS joinedTids; - for(NodeBS::iterator it = tids.begin(), eit = tids.end(); it!=eit; ++it) + for (NodeBS::iterator it = tids.begin(), eit = tids.end(); it != eit; ++it) { - if(isMustJoin(tgr.getTid(),joinsite)) - joinedTids.set(*it); + if (isMustJoin(tgr.getTid(), joinsite)) joinedTids.set(*it); } - if(threadStmtToTheadInterLeav[tgr].intersectWithComplement(joinedTids)) + if (threadStmtToTheadInterLeav[tgr].intersectWithComplement(joinedTids)) { pushToCTSWorkList(tgr); } @@ -204,12 +203,12 @@ class MHP /// Push calling context inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) { - tct->pushCxt(cxt,call,callee); + tct->pushCxt(cxt, call, callee); } /// Match context inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) { - return tct->matchCxt(cxt,call,callee); + return tct->matchCxt(cxt, call, callee); } /// WorkList helper functions @@ -247,24 +246,21 @@ class MHP /// Whether thread t1 happens before t2 based on ForkJoin Analysis bool isHBPair(NodeID tid1, NodeID tid2); - ThreadCallGraph* tcg; ///< TCG - TCT* tct; ///< TCT - ForkJoinAnalysis* fja; ///< ForJoin Analysis - CxtThreadStmtWorkList cxtStmtList; ///< CxtThreadStmt worklist + ThreadCallGraph* tcg; ///< TCG + TCT* tct; ///< TCT + ForkJoinAnalysis* fja; ///< ForJoin Analysis + CxtThreadStmtWorkList cxtStmtList; ///< CxtThreadStmt worklist ThreadStmtToThreadInterleav threadStmtToTheadInterLeav; /// Map a statement to its thread interleavings - InstToThreadStmtSetMap instToTSMap; ///< Map an instruction to its ThreadStmtSet + InstToThreadStmtSetMap instToTSMap; ///< Map an instruction to its ThreadStmtSet FuncPairToBool nonCandidateFuncMHPRelMap; - public: - u32_t numOfTotalQueries; ///< Total number of queries - u32_t numOfMHPQueries; ///< Number of queries are answered as may-happen-in-parallel + u32_t numOfTotalQueries; ///< Total number of queries + u32_t numOfMHPQueries; ///< Number of queries are answered as may-happen-in-parallel double interleavingTime; double interleavingQueriesTime; }; - - /*! * */ @@ -275,15 +271,15 @@ class ForkJoinAnalysis /// semilattice Empty==>TDDead==>TDAlive enum ValDomain { - Empty, // initial(dummy) state - TDAlive, // thread is alive + Empty, // initial(dummy) state + TDAlive, // thread is alive TDDead, // thread is dead }; typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; typedef TCT::InstVec InstVec; - typedef Map CxtStmtToAliveFlagMap; - typedef Map CxtStmtToTIDMap; + typedef Map CxtStmtToAliveFlagMap; + typedef Map CxtStmtToTIDMap; typedef Set ThreadPairSet; typedef Map CxtStmtToLoopMap; typedef FIFOWorkList CxtStmtWorkList; @@ -312,26 +308,26 @@ class ForkJoinAnalysis inline const LoopBBs& getJoinInSymmetricLoop(const CxtStmt& cs) const { CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs); - assert(it!=cxtJoinInLoop.end() && "does not have the loop"); + assert(it != cxtJoinInLoop.end() && "does not have the loop"); return it->second; } inline bool hasJoinInSymmetricLoop(const CxtStmt& cs) const { CxtStmtToLoopMap::const_iterator it = cxtJoinInLoop.find(cs); - return it!=cxtJoinInLoop.end(); + return it != cxtJoinInLoop.end(); } /// Whether thread t1 happens-before thread t2 inline bool isHBPair(NodeID tid1, NodeID tid2) { - bool nonhp = HBPair.find(std::make_pair(tid1,tid2))!=HBPair.end(); - bool hp = HPPair.find(std::make_pair(tid1,tid2))!=HPPair.end(); + bool nonhp = HBPair.find(std::make_pair(tid1, tid2)) != HBPair.end(); + bool hp = HPPair.find(std::make_pair(tid1, tid2)) != HPPair.end(); return nonhp && !hp; } /// Whether t1 fully joins t2 inline bool isFullJoin(NodeID tid1, NodeID tid2) { - bool full = fullJoin.find(std::make_pair(tid1,tid2))!=fullJoin.end(); - bool partial = partialJoin.find(std::make_pair(tid1,tid2))!=partialJoin.end(); + bool full = fullJoin.find(std::make_pair(tid1, tid2)) != fullJoin.end(); + bool partial = partialJoin.find(std::make_pair(tid1, tid2)) != partialJoin.end(); return full && !partial; } @@ -354,16 +350,16 @@ class ForkJoinAnalysis { return tct->hasJoinLoop(inst); } -private: +private: /// Handle fork - void handleFork(const CxtStmt& cts,NodeID rootTid); + void handleFork(const CxtStmt& cts, NodeID rootTid); /// Handle join - void handleJoin(const CxtStmt& cts,NodeID rootTid); + void handleJoin(const CxtStmt& cts, NodeID rootTid); /// Handle call - void handleCall(const CxtStmt& cts,NodeID rootTid); + void handleCall(const CxtStmt& cts, NodeID rootTid); /// Handle return void handleRet(const CxtStmt& cts); @@ -380,7 +376,8 @@ class ForkJoinAnalysis /// Whether it is a matched fork join pair bool isAliasedForkJoin(const ICFGNode* forkSite, const ICFGNode* joinSite) { - return tct->getPTA()->alias(getForkedThread(forkSite), getJoinedThread(joinSite)) && isSameSCEV(forkSite,joinSite); + return tct->getPTA()->alias(getForkedThread(forkSite), getJoinedThread(joinSite)) && + isSameSCEV(forkSite, joinSite); } /// Mark thread flags for cxtStmt //@{ @@ -388,7 +385,7 @@ class ForkJoinAnalysis inline ValDomain getMarkedFlag(const CxtStmt& cs) { CxtStmtToAliveFlagMap::const_iterator it = cxtStmtToAliveFlagMap.find(cs); - if(it==cxtStmtToAliveFlagMap.end()) + if (it == cxtStmtToAliveFlagMap.end()) { cxtStmtToAliveFlagMap[cs] = Empty; return Empty; @@ -401,28 +398,26 @@ class ForkJoinAnalysis { ValDomain flag_tgr = getMarkedFlag(tgr); cxtStmtToAliveFlagMap[tgr] = flag; - if(flag_tgr!=getMarkedFlag(tgr)) - pushToCTSWorkList(tgr); + if (flag_tgr != getMarkedFlag(tgr)) pushToCTSWorkList(tgr); } /// Transfer function for marking context-sensitive statement void markCxtStmtFlag(const CxtStmt& tgr, const CxtStmt& src) { ValDomain flag_tgr = getMarkedFlag(tgr); ValDomain flag_src = getMarkedFlag(src); - if(flag_tgr == Empty) + if (flag_tgr == Empty) { cxtStmtToAliveFlagMap[tgr] = flag_src; } - else if(flag_tgr == TDDead) + else if (flag_tgr == TDDead) { - if(flag_src==TDAlive) - cxtStmtToAliveFlagMap[tgr] = TDAlive; + if (flag_src == TDAlive) cxtStmtToAliveFlagMap[tgr] = TDAlive; } else { /// alive is at the bottom of the semilattice, nothing needs to be done here } - if(flag_tgr!=getMarkedFlag(tgr)) + if (flag_tgr != getMarkedFlag(tgr)) { pushToCTSWorkList(tgr); } @@ -451,12 +446,12 @@ class ForkJoinAnalysis /// Push calling context inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) { - tct->pushCxt(cxt,call,callee); + tct->pushCxt(cxt, call, callee); } /// Match context inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) { - return tct->matchCxt(cxt,call,callee); + return tct->matchCxt(cxt, call, callee); } /// Whether it is a fork site @@ -489,7 +484,7 @@ class ForkJoinAnalysis { return tct->getThreadCallGraph(); } - ///maps a context-sensitive join site to a thread id + /// maps a context-sensitive join site to a thread id inline void addDirectlyJoinTID(const CxtStmt& cs, NodeID tid) { directJoinMap[cs].set(tid); @@ -500,12 +495,12 @@ class ForkJoinAnalysis //@{ inline void addToHPPair(NodeID tid1, NodeID tid2) { - HPPair.insert(std::make_pair(tid1,tid2)); - HPPair.insert(std::make_pair(tid2,tid1)); + HPPair.insert(std::make_pair(tid1, tid2)); + HPPair.insert(std::make_pair(tid2, tid1)); } inline void addToHBPair(NodeID tid1, NodeID tid2) { - HBPair.insert(std::make_pair(tid1,tid2)); + HBPair.insert(std::make_pair(tid1, tid2)); } //@} @@ -513,11 +508,11 @@ class ForkJoinAnalysis //@{ inline void addToFullJoin(NodeID tid1, NodeID tid2) { - fullJoin.insert(std::make_pair(tid1,tid2)); + fullJoin.insert(std::make_pair(tid1, tid2)); } inline void addToPartial(NodeID tid1, NodeID tid2) { - partialJoin.insert(std::make_pair(tid1,tid2)); + partialJoin.insert(std::make_pair(tid1, tid2)); } //@} @@ -527,15 +522,16 @@ class ForkJoinAnalysis cxtJoinInLoop[cs] = lp; } TCT* tct; - CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap; ///< flags for context-sensitive statements - CxtStmtWorkList cxtStmtList; ///< context-sensitive statement worklist - CxtStmtToTIDMap directJoinMap; ///< maps a context-sensitive join site to directly joined thread ids - CxtStmtToTIDMap dirAndIndJoinMap; ///< maps a context-sensitive join site to directly and indirectly joined thread ids - CxtStmtToLoopMap cxtJoinInLoop; ///< a set of context-sensitive join inside loop - ThreadPairSet HBPair; ///< thread happens-before pair - ThreadPairSet HPPair; ///< threads happen-in-parallel - ThreadPairSet fullJoin; ///< t1 fully joins t2 along all program path - ThreadPairSet partialJoin; ///< t1 partially joins t2 along some program path(s) + CxtStmtToAliveFlagMap cxtStmtToAliveFlagMap; ///< flags for context-sensitive statements + CxtStmtWorkList cxtStmtList; ///< context-sensitive statement worklist + CxtStmtToTIDMap directJoinMap; ///< maps a context-sensitive join site to directly joined thread ids + CxtStmtToTIDMap + dirAndIndJoinMap; ///< maps a context-sensitive join site to directly and indirectly joined thread ids + CxtStmtToLoopMap cxtJoinInLoop; ///< a set of context-sensitive join inside loop + ThreadPairSet HBPair; ///< thread happens-before pair + ThreadPairSet HPPair; ///< threads happen-in-parallel + ThreadPairSet fullJoin; ///< t1 fully joins t2 along all program path + ThreadPairSet partialJoin; ///< t1 partially joins t2 along some program path(s) }; } // End namespace SVF diff --git a/svf/include/MTA/MTA.h b/svf/include/MTA/MTA.h index 44242c907..5462211c3 100644 --- a/svf/include/MTA/MTA.h +++ b/svf/include/MTA/MTA.h @@ -63,7 +63,6 @@ class MTA /// Destructor virtual ~MTA(); - /// We start the pass here virtual bool runOnModule(SVFIR* module); /// Compute MHP @@ -85,6 +84,7 @@ class MTA { return lsa; } + private: ThreadCallGraph* tcg; std::unique_ptr tct; diff --git a/svf/include/MTA/MTAStat.h b/svf/include/MTA/MTAStat.h index 6ef8ab597..fb1e71485 100644 --- a/svf/include/MTA/MTAStat.h +++ b/svf/include/MTA/MTAStat.h @@ -51,9 +51,7 @@ class MTAStat : public PTAStat typedef Set InstSet; /// Constructor - MTAStat():PTAStat(nullptr),TCTTime(0),MHPTime(0),AnnotationTime(0) - { - } + MTAStat() : PTAStat(nullptr), TCTTime(0), MHPTime(0), AnnotationTime(0) {} /// Statistics for thread call graph void performThreadCallGraphStat(ThreadCallGraph* tcg); /// Statistics for thread creation tree @@ -61,7 +59,7 @@ class MTAStat : public PTAStat /// Statistics for MHP statement pairs void performMHPPairStat(MHP* mhp, LockAnalysis* lsa); /// Statistics for annotation - //void performAnnotationStat(MTAAnnotator* anno); + // void performAnnotationStat(MTAAnnotator* anno); double TCTTime; double MHPTime; diff --git a/svf/include/MTA/TCT.h b/svf/include/MTA/TCT.h index 6b71db69b..5c0ee837f 100644 --- a/svf/include/MTA/TCT.h +++ b/svf/include/MTA/TCT.h @@ -42,12 +42,11 @@ namespace SVF class TCTNode; - /* * Thread creation edge represents a spawning relation between two context sensitive threads */ typedef GenericEdge GenericTCTEdgeTy; -class TCTEdge: public GenericTCTEdgeTy +class TCTEdge : public GenericTCTEdgeTy { public: enum CEDGEK @@ -55,46 +54,38 @@ class TCTEdge: public GenericTCTEdgeTy ThreadCreateEdge }; /// Constructor - TCTEdge(TCTNode* s, TCTNode* d, CEDGEK kind) : - GenericTCTEdgeTy(s, d, kind) - { - } + TCTEdge(TCTNode* s, TCTNode* d, CEDGEK kind) : GenericTCTEdgeTy(s, d, kind) {} /// Destructor - virtual ~TCTEdge() - { - } + virtual ~TCTEdge() {} /// Classof //@{ static inline bool classof(const TCTEdge*) { return true; } - static inline bool classof(const GenericTCTEdgeTy *edge) + static inline bool classof(const GenericTCTEdgeTy* edge) { return edge->getEdgeKind() == TCTEdge::ThreadCreateEdge; } ///@} typedef GenericNode::GEdgeSetTy ThreadCreateEdgeSet; - }; /* * Each node represents a context-sensitive thread */ typedef GenericNode GenericTCTNodeTy; -class TCTNode: public GenericTCTNodeTy +class TCTNode : public GenericTCTNodeTy { public: /// Constructor - TCTNode(NodeID i, const CxtThread& cctx) : - GenericTCTNodeTy(i, 0), ctx(cctx), multiforked(false) - { - } + TCTNode(NodeID i, const CxtThread& cctx) : GenericTCTNodeTy(i, 0), ctx(cctx), multiforked(false) {} void dump() { - SVFUtil::outs() << "---\ntid: " << this->getId() << " inloop:" << ctx.isInloop() << " incycle:" << ctx.isIncycle() << " multiforked:"<< isMultiforked(); + SVFUtil::outs() << "---\ntid: " << this->getId() << " inloop:" << ctx.isInloop() + << " incycle:" << ctx.isIncycle() << " multiforked:" << isMultiforked(); } /// Get CxtThread @@ -132,7 +123,7 @@ class TCTNode: public GenericTCTNodeTy * Pointer Analysis Call Graph used internally for various pointer analysis */ typedef GenericGraph GenericThreadCreateTreeTy; -class TCT: public GenericThreadCreateTreeTy +class TCT : public GenericThreadCreateTreeTy { public: @@ -143,20 +134,20 @@ class TCT: public GenericThreadCreateTreeTy typedef std::vector InstVec; typedef Set InstSet; typedef Set PTACGNodeSet; - typedef Map CxtThreadToNodeMap; - typedef Map CxtThreadToForkCxt; - typedef Map CxtThreadToFun; + typedef Map CxtThreadToNodeMap; + typedef Map CxtThreadToForkCxt; + typedef Map CxtThreadToFun; typedef Map InstToLoopMap; typedef FIFOWorkList CxtThreadProcVec; typedef Set CxtThreadProcSet; typedef SCCDetection ThreadCallGraphSCC; /// Constructor - TCT(PointerAnalysis* p) :pta(p),TCTNodeNum(0),TCTEdgeNum(0),MaxCxtSize(0) + TCT(PointerAnalysis* p) : pta(p), TCTNodeNum(0), TCTEdgeNum(0), MaxCxtSize(0) { tcg = SVFUtil::cast(pta->getCallGraph()); tcg->updateCallGraph(pta); - //tcg->updateJoinEdge(pta); + // tcg->updateJoinEdge(pta); tcgSCC = pta->getCallGraphSCC(); tcgSCC->find(); build(); @@ -254,7 +245,7 @@ class TCT: public GenericThreadCreateTreeTy /// Whether it is calling an external function inline bool isExtCall(const ICFGNode* inst) { - if(const CallICFGNode* call = SVFUtil::dyn_cast(inst)) + if (const CallICFGNode* call = SVFUtil::dyn_cast(inst)) return SVFUtil::isExtCall(call->getCallSite()); return false; } @@ -268,12 +259,12 @@ class TCT: public GenericThreadCreateTreeTy //@{ inline bool hasTCTNode(const CxtThread& ct) const { - return ctpToNodeMap.find(ct)!=ctpToNodeMap.end(); + return ctpToNodeMap.find(ct) != ctpToNodeMap.end(); } inline TCTNode* getTCTNode(const CxtThread& ct) const { CxtThreadToNodeMap::const_iterator it = ctpToNodeMap.find(ct); - assert(it!=ctpToNodeMap.end() && "TCT node not found??"); + assert(it != ctpToNodeMap.end() && "TCT node not found??"); return it->second; } //@} @@ -281,20 +272,18 @@ class TCT: public GenericThreadCreateTreeTy /// Whether it is a candidate function for indirect call inline bool isCandidateFun(const CallGraph::FunctionSet& callees) const { - for(CallGraph::FunctionSet::const_iterator cit = callees.begin(), - ecit = callees.end(); cit!=ecit; cit++) + for (CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit != ecit; cit++) { - if(candidateFuncSet.find((*cit))!=candidateFuncSet.end()) - return true; + if (candidateFuncSet.find((*cit)) != candidateFuncSet.end()) return true; } return false; } inline bool isCandidateFun(const SVFFunction* fun) const { - return candidateFuncSet.find(fun)!=candidateFuncSet.end(); + return candidateFuncSet.find(fun) != candidateFuncSet.end(); } /// Whether two functions in the same callgraph scc - inline bool inSameCallGraphSCC(const CallGraphNode* src,const CallGraphNode* dst) + inline bool inSameCallGraphSCC(const CallGraphNode* src, const CallGraphNode* dst) { return (tcgSCC->repNode(src->getId()) == tcgSCC->repNode(dst->getId())); } @@ -305,14 +294,14 @@ class TCT: public GenericThreadCreateTreeTy inline bool hasParentThread(NodeID tid) const { const TCTNode* node = getTCTNode(tid); - return node->getInEdges().size()==1; + return node->getInEdges().size() == 1; } /// Get parent thread inline NodeID getParentThread(NodeID tid) const { const TCTNode* node = getTCTNode(tid); - assert(node->getInEdges().size()<=1 && "should have at most one parent thread"); - assert(node->getInEdges().size()==1 && "does not have a parent thread"); + assert(node->getInEdges().size() <= 1 && "should have at most one parent thread"); + assert(node->getInEdges().size() == 1 && "does not have a parent thread"); const TCTEdge* edge = *(node->getInEdges().begin()); return edge->getSrcID(); } @@ -320,19 +309,17 @@ class TCT: public GenericThreadCreateTreeTy const NodeBS getAncestorThread(NodeID tid) const { NodeBS tds; - if(hasParentThread(tid) == false) - return tds; + if (hasParentThread(tid) == false) return tds; FIFOWorkList worklist; worklist.push(getParentThread(tid)); - while(!worklist.empty()) + while (!worklist.empty()) { NodeID t = worklist.pop(); - if(tds.test_and_set(t)) + if (tds.test_and_set(t)) { - if(hasParentThread(t)) - worklist.push(getParentThread(t)); + if (hasParentThread(t)) worklist.push(getParentThread(t)); } } return tds; @@ -341,15 +328,14 @@ class TCT: public GenericThreadCreateTreeTy inline const NodeBS getSiblingThread(NodeID tid) const { NodeBS tds; - if(hasParentThread(tid) == false) - return tds; + if (hasParentThread(tid) == false) return tds; const TCTNode* node = getTCTNode(getParentThread(tid)); - for(ThreadCreateEdgeSet::const_iterator it = getChildrenBegin(node), eit = getChildrenEnd(node); it!=eit; ++it) + for (ThreadCreateEdgeSet::const_iterator it = getChildrenBegin(node), eit = getChildrenEnd(node); it != eit; + ++it) { NodeID child = (*it)->getDstNode()->getId(); - if(child!=tid) - tds.set(child); + if (child != tid) tds.set(child); } return tds; @@ -360,7 +346,7 @@ class TCT: public GenericThreadCreateTreeTy const CallStrCxt& getCxtOfCxtThread(const CxtThread& ct) const { CxtThreadToForkCxt::const_iterator it = ctToForkCxtMap.find(ct); - assert(it!=ctToForkCxtMap.end() && "Cxt Thread not found!!"); + assert(it != ctToForkCxtMap.end() && "Cxt Thread not found!!"); return it->second; } @@ -368,7 +354,7 @@ class TCT: public GenericThreadCreateTreeTy const SVFFunction* getStartRoutineOfCxtThread(const CxtThread& ct) const { CxtThreadToFun::const_iterator it = ctToRoutineFunMap.find(ct); - assert(it!=ctToRoutineFunMap.end() && "Cxt Thread not found!!"); + assert(it != ctToRoutineFunMap.end() && "Cxt Thread not found!!"); return it->second; } @@ -377,7 +363,7 @@ class TCT: public GenericThreadCreateTreeTy { assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site"); InstToLoopMap::iterator it = joinSiteToLoopMap.find(join); - assert(it!=joinSiteToLoopMap.end() && "loop not found"); + assert(it != joinSiteToLoopMap.end() && "loop not found"); return it->second; } @@ -385,7 +371,7 @@ class TCT: public GenericThreadCreateTreeTy { assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site"); InstToLoopMap::const_iterator it = joinSiteToLoopMap.find(join); - return it!=joinSiteToLoopMap.end(); + return it != joinSiteToLoopMap.end(); } bool hasLoop(const SVFBasicBlock* bb) const @@ -398,7 +384,7 @@ class TCT: public GenericThreadCreateTreeTy return hasLoop(inst->getBB()); } /// Return true if a join instruction must be executed inside a loop - bool isJoinMustExecutedInLoop(const LoopBBs& lp,const ICFGNode* join); + bool isJoinMustExecutedInLoop(const LoopBBs& lp, const ICFGNode* join); /// Get loop for an instruction const LoopBBs& getLoop(const ICFGNode* inst); /// Get loop for fork/join site @@ -412,14 +398,13 @@ class TCT: public GenericThreadCreateTreeTy inline void pushCxt(CallStrCxt& cxt, CallSiteID csId) { cxt.push_back(csId); - if (cxt.size() > MaxCxtSize) - MaxCxtSize = cxt.size(); + if (cxt.size() > MaxCxtSize) MaxCxtSize = cxt.size(); } /// Whether a join site is in recursion inline bool isJoinSiteInRecursion(const ICFGNode* join) const { assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site"); - return inRecurJoinSites.find(join)!=inRecurJoinSites.end(); + return inRecurJoinSites.find(join) != inRecurJoinSites.end(); } /// Dump calling context void dumpCxt(CallStrCxt& cxt); @@ -440,7 +425,7 @@ class TCT: public GenericThreadCreateTreeTy /// Add TCT node inline TCTNode* addTCTNode(const CxtThread& ct) { - assert(ctpToNodeMap.find(ct)==ctpToNodeMap.end() && "Already has this node!!"); + assert(ctpToNodeMap.find(ct) == ctpToNodeMap.end() && "Already has this node!!"); NodeID id = TCTNodeNum; TCTNode* node = new TCTNode(id, ct); addGNode(id, node); @@ -501,17 +486,18 @@ class TCT: public GenericThreadCreateTreeTy /// Get or create a tct node based on CxtThread //@{ - inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork,const CallStrCxt& oldCxt, const SVFFunction* routine) + inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork, const CallStrCxt& oldCxt, + const SVFFunction* routine) { - CxtThread ct(cxt,fork); + CxtThread ct(cxt, fork); CxtThreadToNodeMap::const_iterator it = ctpToNodeMap.find(ct); - if(it!=ctpToNodeMap.end()) + if (it != ctpToNodeMap.end()) { return it->second; } - addCxtOfCxtThread(oldCxt,ct); - addStartRoutineOfCxtThread(routine,ct); + addCxtOfCxtThread(oldCxt, ct); + addStartRoutineOfCxtThread(routine, ct); setMultiForkedAttrs(ct); return addTCTNode(ct); @@ -522,7 +508,7 @@ class TCT: public GenericThreadCreateTreeTy void setMultiForkedAttrs(CxtThread& ct) { /// non-main thread - if(ct.getThread() != nullptr) + if (ct.getThread() != nullptr) { const ICFGNode* svfInst = ct.getThread(); ct.setInloop(isInLoopInstruction(svfInst)); @@ -551,7 +537,7 @@ class TCT: public GenericThreadCreateTreeTy //@{ inline bool pushToCTPWorkList(const CxtThreadProc& ctp) { - if(isVisitedCTPs(ctp)==false) + if (isVisitedCTPs(ctp) == false) { visitedCTPs.insert(ctp); return ctpList.push(ctp); @@ -565,27 +551,26 @@ class TCT: public GenericThreadCreateTreeTy } inline bool isVisitedCTPs(const CxtThreadProc& ctp) const { - return visitedCTPs.find(ctp)!=visitedCTPs.end(); + return visitedCTPs.find(ctp) != visitedCTPs.end(); } //@} /// Clean up memory inline void destroy() { - if(tcgSCC) - delete tcgSCC; - tcgSCC=nullptr; + if (tcgSCC) delete tcgSCC; + tcgSCC = nullptr; } - FunSet entryFuncSet; /// Procedures that are neither called by other functions nor extern functions - FunSet candidateFuncSet; /// Procedures we care about during call graph traversing when creating TCT - ThreadCallGraphSCC* tcgSCC; /// Thread call graph SCC - CxtThreadProcVec ctpList; /// CxtThreadProc List - CxtThreadProcSet visitedCTPs; /// Record all visited ctps - CxtThreadToNodeMap ctpToNodeMap; /// Map a ctp to its graph node + FunSet entryFuncSet; /// Procedures that are neither called by other functions nor extern functions + FunSet candidateFuncSet; /// Procedures we care about during call graph traversing when creating TCT + ThreadCallGraphSCC* tcgSCC; /// Thread call graph SCC + CxtThreadProcVec ctpList; /// CxtThreadProc List + CxtThreadProcSet visitedCTPs; /// Record all visited ctps + CxtThreadToNodeMap ctpToNodeMap; /// Map a ctp to its graph node CxtThreadToForkCxt ctToForkCxtMap; /// Map a CxtThread to the context at its spawning site (fork site). - CxtThreadToFun ctToRoutineFunMap; /// Map a CxtThread to its start routine function. - InstToLoopMap joinSiteToLoopMap; ///< map an inloop join to its loop class - Set inRecurJoinSites; ///< Fork or Join sites in recursions + CxtThreadToFun ctToRoutineFunMap; /// Map a CxtThread to its start routine function. + InstToLoopMap joinSiteToLoopMap; ///< map an inloop join to its loop class + Set inRecurJoinSites; ///< Fork or Join sites in recursions }; } // End namespace SVF @@ -597,21 +582,24 @@ namespace SVF * graphs by the generic graph algorithms. * Provide graph traits for traversing from a constraint node using standard graph traversals. */ -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { }; /// Inverse GenericGraphTraits specializations for Value flow node, it is used for inverse traversal. -template<> -struct GenericGraphTraits > : public GenericGraphTraits* > > +template <> +struct GenericGraphTraits> + : public GenericGraphTraits*>> { }; -template<> struct GenericGraphTraits : public GenericGraphTraits* > +template <> +struct GenericGraphTraits : public GenericGraphTraits*> { - typedef SVF::TCTNode *NodeRef; + typedef SVF::TCTNode* NodeRef; }; -} // End namespace llvm +} // namespace SVF #endif /* TCTNodeDetector_H_ */ diff --git a/svf/include/MemoryModel/AbstractPointsToDS.h b/svf/include/MemoryModel/AbstractPointsToDS.h index 6c59acdc4..43718ef5f 100644 --- a/svf/include/MemoryModel/AbstractPointsToDS.h +++ b/svf/include/MemoryModel/AbstractPointsToDS.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /// Contains abstract classes for: /// PTData: basic points-to data structure derived by all others. /// DiffPTData: PTData which only propagates new changes, not entire points-to sets. @@ -39,7 +38,6 @@ /// | /// MutableIncDFPTData - /* * AbstractPointsToDS.h * @@ -70,8 +68,7 @@ namespace SVF /// KeySet: collection of keys. /// Data: elements in points-to sets. /// DataSet: the points-to set; a collection of Data. -template -class PTData +template class PTData { public: /// Types of a points-to data structures. @@ -93,9 +90,9 @@ class PTData PersVersioned, }; - PTData(bool reversePT = true, PTDataTy ty = PTDataTy::Base) : rev(reversePT), ptdTy(ty) { } + PTData(bool reversePT = true, PTDataTy ty = PTDataTy::Base) : rev(reversePT), ptdTy(ty) {} - virtual ~PTData() { } + virtual ~PTData() {} /// Get the type of points-to data structure that this is. inline PTDataTy getPTDTY() const @@ -152,9 +149,9 @@ class DiffPTData : public PTData typedef PTData BasePTData; typedef typename BasePTData::PTDataTy PTDataTy; - DiffPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Diff) : BasePTData(reversePT, ty) { } + DiffPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Diff) : BasePTData(reversePT, ty) {} - virtual ~DiffPTData() { } + virtual ~DiffPTData() {} /// Get diff points to. virtual const DataSet& getDiffPts(Key& var) = 0; @@ -173,15 +170,14 @@ class DiffPTData : public PTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const DiffPTData *) + static inline bool classof(const DiffPTData*) { return true; } static inline bool classof(const PTData* ptd) { - return ptd->getPTDTY() == PTDataTy::Diff - || ptd->getPTDTY() == PTDataTy::MutDiff - || ptd->getPTDTY() == PTDataTy::PersDiff; + return ptd->getPTDTY() == PTDataTy::Diff || ptd->getPTDTY() == PTDataTy::MutDiff || + ptd->getPTDTY() == PTDataTy::PersDiff; } ///@} }; @@ -200,9 +196,9 @@ class DFPTData : public PTData typedef NodeID LocID; /// Constructor - DFPTData(bool reversePT = true, PTDataTy ty = BasePTData::DataFlow) : BasePTData(reversePT, ty) { } + DFPTData(bool reversePT = true, PTDataTy ty = BasePTData::DataFlow) : BasePTData(reversePT, ty) {} - virtual ~DFPTData() { } + virtual ~DFPTData() {} /// Determine whether the DF IN/OUT sets have points-to sets. ///@{ @@ -246,18 +242,16 @@ class DFPTData : public PTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const DFPTData *) + static inline bool classof(const DFPTData*) { return true; } static inline bool classof(const PTData* ptd) { - return ptd->getPTDTY() == BasePTData::DataFlow - || ptd->getPTDTY() == BasePTData::MutDataFlow - || ptd->getPTDTY() == BasePTData::MutIncDataFlow - || ptd->getPTDTY() == BasePTData::PersDataFlow - || ptd->getPTDTY() == BasePTData::PersIncDataFlow; + return ptd->getPTDTY() == BasePTData::DataFlow || ptd->getPTDTY() == BasePTData::MutDataFlow || + ptd->getPTDTY() == BasePTData::MutIncDataFlow || ptd->getPTDTY() == BasePTData::PersDataFlow || + ptd->getPTDTY() == BasePTData::PersIncDataFlow; } ///@} }; @@ -265,16 +259,17 @@ class DFPTData : public PTData /// PTData with normal keys and versioned keys. Replicates the PTData interface for /// versioned keys too. Intended to be used for versioned flow-sensitive PTA--hence the /// name--but can be used anywhere where there are two types of keys at play. -template +template class VersionedPTData : public PTData { public: typedef PTData BasePTData; typedef typename BasePTData::PTDataTy PTDataTy; - VersionedPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Versioned) : BasePTData(reversePT, ty) { } + VersionedPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Versioned) : BasePTData(reversePT, ty) {} - virtual ~VersionedPTData() { } + virtual ~VersionedPTData() {} virtual const DataSet& getPts(const VersionedKey& vk) = 0; virtual const VersionedKeySet& getVersionedKeyRevPts(const Data& datum) = 0; @@ -291,26 +286,26 @@ class VersionedPTData : public PTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const VersionedPTData *) + static inline bool classof(const VersionedPTData*) { return true; } static inline bool classof(const PTData* ptd) { - return ptd->getPTDTY() == PTDataTy::Versioned - || ptd->getPTDTY() == PTDataTy::MutVersioned - || ptd->getPTDTY() == PTDataTy::PersVersioned; + return ptd->getPTDTY() == PTDataTy::Versioned || ptd->getPTDTY() == PTDataTy::MutVersioned || + ptd->getPTDTY() == PTDataTy::PersVersioned; } + private: - using BasePTData::getPts; using BasePTData::addPts; - using BasePTData::unionPts; - using BasePTData::clearPts; using BasePTData::clearFullPts; + using BasePTData::clearPts; + using BasePTData::getPts; + using BasePTData::unionPts; ///@} }; } // End namespace SVF -#endif // ABSTRACT_POINTSTO_H_ +#endif // ABSTRACT_POINTSTO_H_ diff --git a/svf/include/MemoryModel/AccessPath.h b/svf/include/MemoryModel/AccessPath.h index 4a5fb1c03..22154b2b4 100644 --- a/svf/include/MemoryModel/AccessPath.h +++ b/svf/include/MemoryModel/AccessPath.h @@ -29,26 +29,22 @@ * */ - #ifndef AccessPath_H_ #define AccessPath_H_ - #include "SVFIR/SVFValue.h" - namespace SVF { class SVFVar; - /* -* Location set represents a set of locations in a memory block with following offsets: -* { offset + \sum_{i=0}^N (stride_i * j_i) | 0 \leq j_i < M_i } -* where N is the size of number-stride pair vector, M_i (stride_i) is i-th number (stride) -* in the number-stride pair vector. -*/ + * Location set represents a set of locations in a memory block with following offsets: + * { offset + \sum_{i=0}^N (stride_i * j_i) | 0 \leq j_i < M_i } + * where N is the size of number-stride pair vector, M_i (stride_i) is i-th number (stride) + * in the number-stride pair vector. + */ class AccessPath { friend class SymbolTableInfo; @@ -58,7 +54,11 @@ class AccessPath public: enum LSRelation { - NonOverlap, Overlap, Subset, Superset, Same + NonOverlap, + Overlap, + Subset, + Superset, + Same }; typedef std::pair IdxOperandPair; @@ -69,9 +69,7 @@ class AccessPath /// Copy Constructor AccessPath(const AccessPath& ap) - : fldIdx(ap.fldIdx), - idxOperandPairs(ap.getIdxOperandPairVec()), - gepPointeeType(ap.gepSrcPointeeType()) + : fldIdx(ap.fldIdx), idxOperandPairs(ap.getIdxOperandPairVec()), gepPointeeType(ap.gepSrcPointeeType()) { } @@ -90,8 +88,8 @@ class AccessPath } inline bool operator==(const AccessPath& rhs) const { - return this->fldIdx == rhs.fldIdx && - this->idxOperandPairs == rhs.idxOperandPairs && this->gepPointeeType == rhs.gepPointeeType; + return this->fldIdx == rhs.fldIdx && this->idxOperandPairs == rhs.idxOperandPairs && + this->gepPointeeType == rhs.gepPointeeType; } //@} @@ -146,7 +144,6 @@ class AccessPath /// Return element number of a type. u32_t getElementNum(const SVFType* type) const; - bool addOffsetVarAndGepTypePair(const SVFVar* var, const SVFType* gepIterType); /// Return TRUE if this is a constant location set. @@ -165,15 +162,14 @@ class AccessPath std::string dump() const; private: - /// Check relations of two location sets LSRelation checkRelation(const AccessPath& LHS, const AccessPath& RHS); /// Compute all possible locations according to offset and number-stride pairs. NodeBS computeAllLocations() const; - APOffset fldIdx; ///< Accumulated Constant Offsets - IdxOperandPairs idxOperandPairs; ///< a vector of actual offset in the form of + APOffset fldIdx; ///< Accumulated Constant Offsets + IdxOperandPairs idxOperandPairs; ///< a vector of actual offset in the form of const SVFType* gepPointeeType; /// source element type in gep instruction, /// e.g., %f1 = getelementptr inbounds %struct.MyStruct, %struct.MyStruct* %arrayidx, i32 0, i32 0 /// the source element type is %struct.MyStruct @@ -183,12 +179,11 @@ class AccessPath template <> struct std::hash { - size_t operator()(const SVF::AccessPath &ap) const + size_t operator()(const SVF::AccessPath& ap) const { SVF::Hash> h; std::hash v; - return h(std::make_pair(ap.getConstantStructFldIdx(), - v(ap.getIdxOperandPairVec()))); + return h(std::make_pair(ap.getConstantStructFldIdx(), v(ap.getIdxOperandPairVec()))); } }; diff --git a/svf/include/MemoryModel/ConditionalPT.h b/svf/include/MemoryModel/ConditionalPT.h index d82ae5ab4..c21d78704 100644 --- a/svf/include/MemoryModel/ConditionalPT.h +++ b/svf/include/MemoryModel/ConditionalPT.h @@ -42,18 +42,13 @@ namespace SVF * A context/path condition * A variable NodeID */ -template -class CondVar +template class CondVar { public: /// Constructor - CondVar(const Cond& cond, NodeID id) : m_cond(cond),m_id(id) - { - } + CondVar(const Cond& cond, NodeID id) : m_cond(cond), m_id(id) {} /// Copy constructor - CondVar(const CondVar& conVar) : m_cond(conVar.m_cond), m_id(conVar.m_id) - { - } + CondVar(const CondVar& conVar) : m_cond(conVar.m_cond), m_id(conVar.m_id) {} /// Default constructor CondVar() : m_cond(), m_id(0) {} @@ -63,21 +58,20 @@ class CondVar * Comparison between two elements. */ ///@{ - inline bool operator == (const CondVar & rhs) const + inline bool operator==(const CondVar& rhs) const { return (m_id == rhs.get_id() && m_cond == rhs.get_cond()); } - inline bool operator != (const CondVar & rhs) const + inline bool operator!=(const CondVar& rhs) const { return !(*this == rhs); } ///@} - - inline CondVar& operator= (const CondVar& rhs) + inline CondVar& operator=(const CondVar& rhs) { - if(*this!=rhs) + if (*this != rhs) { m_cond = rhs.get_cond(); m_id = rhs.get_id(); @@ -85,14 +79,12 @@ class CondVar return *this; } - /** * Less than implementation. */ - inline bool operator < (const CondVar & rhs) const + inline bool operator<(const CondVar& rhs) const { - if(m_id != rhs.get_id()) - return m_id < rhs.get_id(); + if (m_id != rhs.get_id()) return m_id < rhs.get_id(); else return m_cond < rhs.get_cond(); } @@ -114,21 +106,21 @@ class CondVar return rawstr.str(); } - friend OutStream& operator<< (OutStream &o, const CondVar &cvar) + friend OutStream& operator<<(OutStream& o, const CondVar& cvar) { o << cvar.toString(); return o; } + private: - Cond m_cond; - NodeID m_id; + Cond m_cond; + NodeID m_id; }; /*! * Conditional variable set */ -template -class CondStdSet +template class CondStdSet { typedef OrderedSet ElementSet; @@ -140,9 +132,7 @@ class CondStdSet ~CondStdSet() {} /// Copy constructor - CondStdSet(const CondStdSet& cptsSet) : elements(cptsSet.getElementSet()) - { - } + CondStdSet(const CondStdSet& cptsSet) : elements(cptsSet.getElementSet()) {} /// Return true if the element is added inline bool test_and_set(const Element& var) @@ -212,16 +202,14 @@ class CondStdSet inline bool operator|=(const CondStdSet& rhs) { const ElementSet& rhsElementSet = rhs.getElementSet(); - if(rhsElementSet.empty() || (*this==rhs)) - return false; + if (rhsElementSet.empty() || (*this == rhs)) return false; u32_t oldSize = elements.size(); - elements.insert(rhsElementSet.begin(),rhsElementSet.end()); - return oldSize!=elements.size(); + elements.insert(rhsElementSet.begin(), rhsElementSet.end()); + return oldSize != elements.size(); } inline bool operator&=(const CondStdSet& rhs) { - if(rhs.empty() || (*this == rhs)) - return false; + if (rhs.empty() || (*this == rhs)) return false; bool changed = false; for (const_iterator i = rhs.begin(); i != rhs.end(); ++i) { @@ -235,7 +223,7 @@ class CondStdSet } inline bool operator!=(const CondStdSet& rhs) const { - return elements!=rhs.getElementSet(); + return elements != rhs.getElementSet(); } inline bool operator==(const CondStdSet& rhs) const { @@ -243,7 +231,7 @@ class CondStdSet } inline CondStdSet& operator=(const CondStdSet& rhs) { - if(*this!=rhs) + if (*this != rhs) { elements = rhs.getElementSet(); } @@ -260,13 +248,11 @@ class CondStdSet */ bool intersects(const CondStdSet& rhs) const { - if (empty() && rhs.empty()) - return false; + if (empty() && rhs.empty()) return false; for (const_iterator i = rhs.begin(); i != rhs.end(); ++i) { - if (elements.find(*i) != elements.end()) - return true; + if (elements.find(*i) != elements.end()) return true; } return false; } @@ -290,18 +276,16 @@ class CondStdSet } /// TODO: dummy to use for PointsTo in the various PTData. - void checkAndRemap(void) const { } + void checkAndRemap(void) const {} private: ElementSet elements; }; - /*! * Conditional Points-to set */ -template -class CondPointsToSet +template class CondPointsToSet { public: typedef Map CondPts; @@ -311,9 +295,7 @@ class CondPointsToSet /// Constructor //@{ - CondPointsToSet() - { - } + CondPointsToSet() {} CondPointsToSet(const Cond& cond, const PointsTo& pts) { _condPts[cond] |= pts; @@ -329,25 +311,25 @@ class CondPointsToSet /// Get Conditional PointsTo and standard points-to //@{ - inline CondPts &pointsTo(void) + inline CondPts& pointsTo(void) { return _condPts; } - inline const CondPts &pointsTo(void) const + inline const CondPts& pointsTo(void) const { return _condPts; } - inline const PointsTo &pointsTo(Cond cond) const + inline const PointsTo& pointsTo(Cond cond) const { CondPtsConstIter it = _condPts.find(cond); - assert(it!=_condPts.end() && "do not have pts of such condition!"); + assert(it != _condPts.end() && "do not have pts of such condition!"); return it->second; } inline bool hasPointsTo(Cond cond) const { return (_condPts.find(cond) != _condPts.end()); } - inline PointsTo &pointsTo(Cond cond) + inline PointsTo& pointsTo(Cond cond) { return _condPts[cond]; } @@ -378,11 +360,10 @@ class CondPointsToSet _condPts.clear(); } - ///Get number of points-to targets. + /// Get number of points-to targets. inline unsigned numElement() const { - if (_condPts.empty()) - return 0; + if (_condPts.empty()) return 0; else { unsigned num = 0; @@ -397,14 +378,12 @@ class CondPointsToSet /// Return true if no element in the set inline bool empty() const { - return numElement()==0; + return numElement() == 0; } - /// Overloading operators //@{ - inline CondPointsToSet& operator=( - const CondPointsToSet& other) + inline CondPointsToSet& operator=(const CondPointsToSet& other) { _condPts = other.pointsTo(); return *this; @@ -414,16 +393,14 @@ class CondPointsToSet inline bool operator==(const CondPointsToSet& rhs) const { // Always remember give the typename when define a template variable - if (pointsTo().size() != rhs.pointsTo().size()) - return false; + if (pointsTo().size() != rhs.pointsTo().size()) return false; CondPtsConstIter lit = cptsBegin(), elit = cptsEnd(); CondPtsConstIter rit = rhs.cptsBegin(), erit = rhs.cptsEnd(); for (; lit != elit && rit != erit; ++lit, ++rit) { const Cond& lc = lit->first; const Cond& rc = rit->first; - if (lc != rc || lit->second != rit->second) - return false; + if (lc != rc || lit->second != rit->second) return false; } return true; } @@ -433,8 +410,7 @@ class CondPointsToSet /// location under the same condition inline bool aliased(const CondPointsToSet& rhs) const { - if (pointsTo().empty() || rhs.pointsTo().empty()) - return false; + if (pointsTo().empty() || rhs.pointsTo().empty()) return false; else { CondPtsConstIter lit = cptsBegin(), elit = cptsEnd(); @@ -443,11 +419,10 @@ class CondPointsToSet const Cond& lc = lit->first; const PointsTo& pts = lit->second; CondPtsConstIter rit = rhs.pointsTo().find(lc); - if(rit !=rhs.pointsTo().end()) + if (rit != rhs.pointsTo().end()) { const PointsTo& rpts = rit->second; - if (pts.intersects(rpts)) - return true; + if (pts.intersects(rpts)) return true; } } return false; @@ -457,8 +432,7 @@ class CondPointsToSet /// Check whether this CondPointsToSet is a subset of RHS inline bool isSubset(const CondPointsToSet& rhs) const { - if (pointsTo().size() > rhs.pointsTo().size()) - return false; + if (pointsTo().size() > rhs.pointsTo().size()) return false; else { CondPtsConstIter lit = cptsBegin(), elit = cptsEnd(); @@ -466,14 +440,12 @@ class CondPointsToSet { const Cond& lc = lit->first; CondPtsConstIter rit = rhs.pointsTo().find(lc); - if (rit == rhs.pointsTo().end()) - return false; + if (rit == rhs.pointsTo().end()) return false; else { const PointsTo& pts = lit->second; const PointsTo& rpts = rit->second; - if (!rpts.contains(pts)) - return false; + if (!rpts.contains(pts)) return false; } } } @@ -484,8 +456,7 @@ class CondPointsToSet bool intersects(const CondPointsToSet* rhs) const { /// if either cpts is empty, just return. - if (pointsTo().empty() && rhs->pointsTo().empty()) - return false; + if (pointsTo().empty() && rhs->pointsTo().empty()) return false; CondPtsConstIter it = rhs->cptsBegin(), eit = rhs->cptsEnd(); for (; it != eit; ++it) @@ -493,10 +464,9 @@ class CondPointsToSet const Cond& cond = it->first; if (hasPointsTo(cond)) { - const PointsTo& rhs_pts= it->second; - const PointsTo& pts= pointsTo(cond); - if (pts.intersects(rhs_pts)) - return true; + const PointsTo& rhs_pts = it->second; + const PointsTo& pts = pointsTo(cond); + if (pts.intersects(rhs_pts)) return true; } } @@ -561,7 +531,7 @@ class CondPointsToSet } /// Overloading operator &= - inline bool operator &= (const CondPointsToSet& rhs) + inline bool operator&=(const CondPointsToSet& rhs) { if (empty()) { @@ -581,8 +551,7 @@ class CondPointsToSet PointsTo& pts = it->second; if (rhs.hasPointsTo(cond)) { - if (pts &= rhs.pointsTo(cond)) - changed = true; + if (pts &= rhs.pointsTo(cond)) changed = true; } else { @@ -604,10 +573,9 @@ class CondPointsToSet } //@} - /// Overloading operator |= /// Merge CondPointsToSet of RHS into this one. - inline bool operator |= (const CondPointsToSet& rhs) + inline bool operator|=(const CondPointsToSet& rhs) { bool changed = false; CondPtsConstIter rhsIt = rhs.cptsBegin(); @@ -617,8 +585,7 @@ class CondPointsToSet const Cond& cond = rhsIt->first; const PointsTo& rhsPts = rhsIt->second; PointsTo& pts = pointsTo(cond); - if ((pts |= rhsPts)) - changed = true; + if ((pts |= rhsPts)) changed = true; } return changed; } @@ -631,10 +598,9 @@ class CondPointsToSet * their points-to elements. */ // TODO: try to use an efficient method to compare two conditional points-to set. - inline bool operator< (const CondPointsToSet& rhs) const + inline bool operator<(const CondPointsToSet& rhs) const { - if (pointsTo().size() < rhs.pointsTo().size()) - return true; + if (pointsTo().size() < rhs.pointsTo().size()) return true; else if (pointsTo().size() == rhs.pointsTo().size()) { CondPtsConstIter lit = cptsBegin(), elit = cptsEnd(); @@ -643,14 +609,12 @@ class CondPointsToSet { const Cond& lc = lit->first; const Cond& rc = rit->first; - if (lc < rc) - return true; + if (lc < rc) return true; else if (lc == rc) { const PointsTo& lpts = lit->second; const PointsTo& rpts = rit->second; - if (lpts.count() < rpts.count()) - return true; + if (lpts.count() < rpts.count()) return true; else if (lpts.count() == rpts.count()) { PointsTo::iterator bit = lpts.begin(); @@ -659,8 +623,7 @@ class CondPointsToSet PointsTo::iterator reit = rpts.end(); for (; bit != eit && rbit != reit; bit++, rbit++) { - if (*bit < *rbit) - return true; + if (*bit < *rbit) return true; else if (*bit > *rbit) return false; } @@ -708,7 +671,7 @@ class CondPointsToSet // Print all points-to targets //@{ - inline void dump(OutStream & O) const + inline void dump(OutStream& O) const { CondPtsConstIter it = cptsBegin(); CondPtsConstIter eit = cptsEnd(); @@ -729,8 +692,7 @@ class CondPointsToSet { const PointsTo& pts = it->second; str += "pts{"; - for (PointsTo::iterator ii = pts.begin(), ie = pts.end(); - ii != ie; ii++) + for (PointsTo::iterator ii = pts.begin(), ie = pts.end(); ii != ie; ii++) { char int2str[16]; snprintf(int2str, sizeof(int2str), "%d", *ii); @@ -744,42 +706,41 @@ class CondPointsToSet //@} private: - /// Conditional Points-to Set Iterator class CondPtsSetIterator { public: - CondPtsSetIterator(CondPointsToSet &n, bool ae = false) - : _curIter(n.cptsBegin()), _endIter(n.cptsEnd()), - _ptIter(_curIter->second.begin()), _ptEndIter(_curIter->second.end()), atEnd(ae) {} + CondPtsSetIterator(CondPointsToSet& n, bool ae = false) + : _curIter(n.cptsBegin()), _endIter(n.cptsEnd()), _ptIter(_curIter->second.begin()), + _ptEndIter(_curIter->second.end()), atEnd(ae) + { + } ~CondPtsSetIterator() {} - bool operator != (int val) + bool operator!=(int val) { return _curIter != _endIter; } /// Operator overloading //@{ - bool operator==(const CondPtsSetIterator &RHS) const + bool operator==(const CondPtsSetIterator& RHS) const { // If they are both at the end, ignore the rest of the fields. - if (atEnd && RHS.atEnd) - return true; + if (atEnd && RHS.atEnd) return true; // Otherwise they are the same if they have the same condVar return atEnd == RHS.atEnd && RHS._curIter == _curIter && RHS._ptIter == _ptIter; } - bool operator!=(const CondPtsSetIterator &RHS) const + bool operator!=(const CondPtsSetIterator& RHS) const { return !(*this == RHS); } - void operator ++(void) + void operator++(void) { - if(atEnd == true) - return; + if (atEnd == true) return; - if(_ptIter==_ptEndIter) + if (_ptIter == _ptEndIter) { - if(_curIter == _endIter) + if (_curIter == _endIter) { atEnd = true; return; @@ -791,7 +752,7 @@ class CondPointsToSet else _ptIter++; } - SingleCondVar operator *(void) + SingleCondVar operator*(void) { SingleCondVar temp_var(cond(), *_ptIter); return temp_var; @@ -822,7 +783,7 @@ class CondPointsToSet inline iterator end() { - return iterator(this,true); + return iterator(this, true); } inline iterator begin() const @@ -832,7 +793,7 @@ class CondPointsToSet inline iterator end() const { - return iterator(this,true); + return iterator(this, true); } //@} @@ -843,30 +804,27 @@ class CondPointsToSet } // End namespace SVF /// Specialise hash for CondVar -template -struct std::hash> +template struct std::hash> { - size_t operator()(const SVF::CondVar &cv) const + size_t operator()(const SVF::CondVar& cv) const { std::hash h; return h(cv.get_cond()); } }; -template -struct std::hash> +template struct std::hash> { - size_t operator()(const SVF::CondVar &cv) const + size_t operator()(const SVF::CondVar& cv) const { std::hash h; return h(cv.get_cond()); } }; -template -struct std::hash> +template struct std::hash> { - size_t operator()(const SVF::CondStdSet &css) const + size_t operator()(const SVF::CondStdSet& css) const { // TODO: this is not a very good hash, but we probably won't be // using it for now. Needed for other templates to compile... diff --git a/svf/include/MemoryModel/MutablePointsToDS.h b/svf/include/MemoryModel/MutablePointsToDS.h index 50c029530..2a0e8cd9d 100644 --- a/svf/include/MemoryModel/MutablePointsToDS.h +++ b/svf/include/MemoryModel/MutablePointsToDS.h @@ -36,7 +36,7 @@ #ifndef MUTABLE_POINTSTO_H_ #define MUTABLE_POINTSTO_H_ -#include +#include #include "MemoryModel/AbstractPointsToDS.h" #include "SVFIR/SVFType.h" @@ -45,14 +45,14 @@ namespace SVF { -template -class MutableDFPTData; +template class MutableDFPTData; /// PTData implemented using points-to sets which are created once and updated continuously. template class MutablePTData : public PTData { friend class MutableDFPTData; + public: typedef PTData BasePTData; typedef typename BasePTData::PTDataTy PTDataTy; @@ -64,9 +64,9 @@ class MutablePTData : public PTData typedef typename DataSet::iterator iterator; /// Constructor - MutablePTData(bool reversePT = true, PTDataTy ty = PTDataTy::MutBase) : BasePTData(reversePT, ty) { } + MutablePTData(bool reversePT = true, PTDataTy ty = PTDataTy::MutBase) : BasePTData(reversePT, ty) {} - virtual ~MutablePTData() { } + virtual ~MutablePTData() {} /// Return Points-to map virtual inline const PtsMap& getPtsMap() const @@ -91,7 +91,7 @@ class MutablePTData : public PTData return revPtsMap[datum]; } - virtual inline bool addPts(const Key &dstKey, const Data& element) override + virtual inline bool addPts(const Key& dstKey, const Data& element) override { addSingleRevPts(revPtsMap[element], dstKey); return addPts(ptsMap[dstKey], element); @@ -105,7 +105,7 @@ class MutablePTData : public PTData virtual inline bool unionPts(const Key& dstKey, const DataSet& srcDataSet) override { - addRevPts(srcDataSet,dstKey); + addRevPts(srcDataSet, dstKey); return unionPts(ptsMap[dstKey], srcDataSet); } @@ -122,14 +122,14 @@ class MutablePTData : public PTData virtual void clearFullPts(const Key& var) override { - DataSet &pts = ptsMap[var]; + DataSet& pts = ptsMap[var]; clearRevPts(pts, var); pts.clear(); } virtual void remapAllPts(void) override { - for (typename PtsMap::value_type &ppt : ptsMap) ppt.second.checkAndRemap(); + for (typename PtsMap::value_type& ppt : ptsMap) ppt.second.checkAndRemap(); } virtual inline Map getAllPts(bool liveOnly) const override @@ -137,7 +137,7 @@ class MutablePTData : public PTData Map allPts; for (typename PtsMap::value_type ppt : ptsMap) { - const DataSet &pt = ppt.second; + const DataSet& pt = ppt.second; ++allPts[pt]; } @@ -146,7 +146,7 @@ class MutablePTData : public PTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const MutablePTData *) + static inline bool classof(const MutablePTData*) { return true; } @@ -158,16 +158,15 @@ class MutablePTData : public PTData ///@} protected: - virtual inline void dumpPts(const PtsMap & ptsSet,OutStream & O = SVFUtil::outs()) const + virtual inline void dumpPts(const PtsMap& ptsSet, OutStream& O = SVFUtil::outs()) const { for (PtsMapConstIter nodeIt = ptsSet.begin(); nodeIt != ptsSet.end(); nodeIt++) { const Key& var = nodeIt->first; - const DataSet & pts = nodeIt->second; - if (pts.empty()) - continue; + const DataSet& pts = nodeIt->second; + if (pts.empty()) continue; O << var << " ==> { "; - for(typename DataSet::iterator cit = pts.begin(), ecit=pts.end(); cit!=ecit; ++cit) + for (typename DataSet::iterator cit = pts.begin(), ecit = pts.end(); cit != ecit; ++cit) { O << *cit << " "; } @@ -182,37 +181,37 @@ class MutablePTData : public PTData { return dstDataSet |= srcDataSet; } - inline bool addPts(DataSet &d, const Data& e) + inline bool addPts(DataSet& d, const Data& e) { return d.test_and_set(e); } - inline void addSingleRevPts(KeySet &revData, const Key& tgr) + inline void addSingleRevPts(KeySet& revData, const Key& tgr) { if (this->rev) { SVFUtil::insertKey(tgr, revData); } } - inline void addRevPts(const DataSet &ptsData, const Key& tgr) + inline void addRevPts(const DataSet& ptsData, const Key& tgr) { if (this->rev) { - for(iterator it = ptsData.begin(), eit = ptsData.end(); it!=eit; ++it) + for (iterator it = ptsData.begin(), eit = ptsData.end(); it != eit; ++it) addSingleRevPts(revPtsMap[*it], tgr); } } - inline void clearSingleRevPts(KeySet &revSet, const Key &k) + inline void clearSingleRevPts(KeySet& revSet, const Key& k) { if (this->rev) { SVFUtil::removeKey(k, revSet); } } - inline void clearRevPts(const DataSet &pts, const Key &k) + inline void clearRevPts(const DataSet& pts, const Key& k) { if (this->rev) { - for (const Data &d : pts) clearSingleRevPts(revPtsMap[d], k); + for (const Data& d : pts) clearSingleRevPts(revPtsMap[d], k); } } ///@} @@ -234,7 +233,10 @@ class MutableDiffPTData : public DiffPTData typedef typename MutablePTData::PtsMap PtsMap; /// Constructor - explicit MutableDiffPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Diff) : BaseDiffPTData(reversePT, ty), mutPTData(reversePT) { } + explicit MutableDiffPTData(bool reversePT = true, PTDataTy ty = PTDataTy::Diff) + : BaseDiffPTData(reversePT, ty), mutPTData(reversePT) + { + } ~MutableDiffPTData() override = default; @@ -259,7 +261,7 @@ class MutableDiffPTData : public DiffPTData return mutPTData.getRevPts(datum); } - virtual inline bool addPts(const Key &dstKey, const Data& element) override + virtual inline bool addPts(const Key& dstKey, const Data& element) override { return mutPTData.addPts(dstKey, element); } @@ -287,8 +289,8 @@ class MutableDiffPTData : public DiffPTData virtual void remapAllPts(void) override { mutPTData.remapAllPts(); - for (typename PtsMap::value_type &ppt : diffPtsMap) ppt.second.checkAndRemap(); - for (typename PtsMap::value_type &ppt : propaPtsMap) ppt.second.checkAndRemap(); + for (typename PtsMap::value_type& ppt : diffPtsMap) ppt.second.checkAndRemap(); + for (typename PtsMap::value_type& ppt : propaPtsMap) ppt.second.checkAndRemap(); } virtual inline void dumpPTData() override @@ -296,12 +298,12 @@ class MutableDiffPTData : public DiffPTData mutPTData.dumpPTData(); } - virtual inline const DataSet &getDiffPts(Key &var) override + virtual inline const DataSet& getDiffPts(Key& var) override { return diffPtsMap[var]; } - virtual inline bool computeDiffPts(Key &var, const DataSet &all) override + virtual inline bool computeDiffPts(Key& var, const DataSet& all) override { /// Clear diff pts. DataSet& diff = diffPtsMap[var]; @@ -313,14 +315,14 @@ class MutableDiffPTData : public DiffPTData return !diff.empty(); } - virtual inline void updatePropaPtsMap(Key &src, Key &dst) override + virtual inline void updatePropaPtsMap(Key& src, Key& dst) override { DataSet& srcPropa = getPropaPts(src); DataSet& dstPropa = getPropaPts(dst); dstPropa &= srcPropa; } - virtual inline void clearPropaPts(Key &var) override + virtual inline void clearPropaPts(Key& var) override { getPropaPts(var).clear(); } @@ -332,7 +334,7 @@ class MutableDiffPTData : public DiffPTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const MutableDiffPTData *) + static inline bool classof(const MutableDiffPTData*) { return true; } @@ -345,7 +347,7 @@ class MutableDiffPTData : public DiffPTData protected: /// Get propagated points to. - inline DataSet &getPropaPts(Key &var) + inline DataSet& getPropaPts(Key& var) { return propaPtsMap[var]; } @@ -371,14 +373,17 @@ class MutableDFPTData : public DFPTData typedef typename BaseDFPTData::LocID LocID; typedef typename BaseMutPTData::PtsMap PtsMap; typedef typename BaseMutPTData::PtsMapConstIter PtsMapConstIter; - typedef Map DFPtsMap; ///< Data-flow point-to map + typedef Map DFPtsMap; ///< Data-flow point-to map typedef typename DFPtsMap::iterator DFPtsMapIter; typedef typename DFPtsMap::const_iterator DFPtsMapconstIter; /// Constructor - MutableDFPTData(bool reversePT = true, PTDataTy ty = BaseDFPTData::MutDataFlow) : BaseDFPTData(reversePT, ty), mutPTData(reversePT) { } + MutableDFPTData(bool reversePT = true, PTDataTy ty = BaseDFPTData::MutDataFlow) + : BaseDFPTData(reversePT, ty), mutPTData(reversePT) + { + } - virtual ~MutableDFPTData() { } + virtual ~MutableDFPTData() {} virtual inline const PtsMap& getPtsMap() const { @@ -411,11 +416,10 @@ class MutableDFPTData : public DFPTData return (dfOutPtsMap.find(loc) != dfOutPtsMap.end()); } - virtual inline bool hasDFInSet(LocID loc,const Key& var) const override + virtual inline bool hasDFInSet(LocID loc, const Key& var) const override { DFPtsMapconstIter it = dfInPtsMap.find(loc); - if ( it == dfInPtsMap.end()) - return false; + if (it == dfInPtsMap.end()) return false; const PtsMap& ptsMap = it->second; return (ptsMap.find(var) != ptsMap.end()); } @@ -423,8 +427,7 @@ class MutableDFPTData : public DFPTData virtual inline bool hasDFOutSet(LocID loc, const Key& var) const override { DFPtsMapconstIter it = dfOutPtsMap.find(loc); - if ( it == dfOutPtsMap.end()) - return false; + if (it == dfOutPtsMap.end()) return false; const PtsMap& ptsMap = it->second; return (ptsMap.find(var) != ptsMap.end()); } @@ -463,27 +466,27 @@ class MutableDFPTData : public DFPTData virtual inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - return this->unionPts(getDFInPtsSet(dstLoc,dstVar), getDFInPtsSet(srcLoc,srcVar)); + return this->unionPts(getDFInPtsSet(dstLoc, dstVar), getDFInPtsSet(srcLoc, srcVar)); } virtual inline bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - return this->unionPts(getDFInPtsSet(dstLoc,dstVar), getDFOutPtsSet(srcLoc,srcVar)); + return this->unionPts(getDFInPtsSet(dstLoc, dstVar), getDFOutPtsSet(srcLoc, srcVar)); } virtual inline bool updateDFOutFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - return this->unionPts(getDFOutPtsSet(dstLoc,dstVar), getDFInPtsSet(srcLoc,srcVar)); + return this->unionPts(getDFOutPtsSet(dstLoc, dstVar), getDFInPtsSet(srcLoc, srcVar)); } virtual inline bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - return this->updateDFInFromOut(srcLoc,srcVar,dstLoc,dstVar); + return this->updateDFInFromOut(srcLoc, srcVar, dstLoc, dstVar); } virtual inline bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - return this->updateDFInFromIn(srcLoc,srcVar,dstLoc,dstVar); + return this->updateDFInFromIn(srcLoc, srcVar, dstLoc, dstVar); } virtual inline bool updateAllDFOutFromIn(LocID loc, const Key& singleton, bool strongUpdates) override @@ -492,15 +495,14 @@ class MutableDFPTData : public DFPTData if (this->hasDFInSet(loc)) { /// Only variables has new pts from IN set need to be updated. - const PtsMap & ptsMap = getDFInPtsMap(loc); - for (typename PtsMap::const_iterator ptsIt = ptsMap.begin(), ptsEit = ptsMap.end(); ptsIt != ptsEit; ++ptsIt) + const PtsMap& ptsMap = getDFInPtsMap(loc); + for (typename PtsMap::const_iterator ptsIt = ptsMap.begin(), ptsEit = ptsMap.end(); ptsIt != ptsEit; + ++ptsIt) { const Key var = ptsIt->first; /// Enable strong updates if it is required to do so - if (strongUpdates && var == singleton) - continue; - if (updateDFOutFromIn(loc, var, loc, var)) - changed = true; + if (strongUpdates && var == singleton) continue; + if (updateDFOutFromIn(loc, var, loc, var)) changed = true; } } return changed; @@ -508,7 +510,7 @@ class MutableDFPTData : public DFPTData virtual inline bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override { - return this->unionPts(dstVar, this->getDFInPtsSet(srcLoc,srcVar)); + return this->unionPts(dstVar, this->getDFInPtsSet(srcLoc, srcVar)); } virtual inline bool updateATVPts(const Key& srcVar, LocID dstLoc, const Key& dstVar) override @@ -516,14 +518,12 @@ class MutableDFPTData : public DFPTData return (this->unionPts(this->getDFOutPtsSet(dstLoc, dstVar), this->getPts(srcVar))); } - virtual inline void clearAllDFOutUpdatedVar(LocID) override - { - } + virtual inline void clearAllDFOutUpdatedVar(LocID) override {} /// Override the methods defined in PTData. /// Union/add points-to without adding reverse points-to, used internally ///@{ - virtual inline bool addPts(const Key &dstKey, const Key& srcKey) override + virtual inline bool addPts(const Key& dstKey, const Key& srcKey) override { return addPts(mutPTData.ptsMap[dstKey], srcKey); } @@ -546,14 +546,14 @@ class MutableDFPTData : public DFPTData virtual void remapAllPts(void) override { mutPTData.remapAllPts(); - for (typename DFPtsMap::value_type &lopt : dfInPtsMap) + for (typename DFPtsMap::value_type& lopt : dfInPtsMap) { - for (typename PtsMap::value_type &opt : lopt.second) opt.second.checkAndRemap(); + for (typename PtsMap::value_type& opt : lopt.second) opt.second.checkAndRemap(); } - for (typename DFPtsMap::value_type &lopt : dfOutPtsMap) + for (typename DFPtsMap::value_type& lopt : dfOutPtsMap) { - for (typename PtsMap::value_type &opt : lopt.second) opt.second.checkAndRemap(); + for (typename PtsMap::value_type& opt : lopt.second) opt.second.checkAndRemap(); } } ///@} @@ -582,14 +582,13 @@ class MutableDFPTData : public DFPTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const MutableDFPTData *) + static inline bool classof(const MutableDFPTData*) { return true; } static inline bool classof(const PTData* ptd) { - return ptd->getPTDTY() == BaseDFPTData::MutDataFlow - || ptd->getPTDTY() == BaseDFPTData::MutIncDataFlow; + return ptd->getPTDTY() == BaseDFPTData::MutDataFlow || ptd->getPTDTY() == BaseDFPTData::MutIncDataFlow; } ///@} @@ -600,7 +599,7 @@ class MutableDFPTData : public DFPTData { return dstDataSet |= srcDataSet; } - inline bool addPts(DataSet &d, const Data& e) + inline bool addPts(DataSet& d, const Data& e) { return d.test_and_set(e); } @@ -619,10 +618,10 @@ class MutableDFPTData : public DFPTData if (f.good()) { NodeBS locs; - for(DFPtsMapconstIter it = dfInPtsMap.begin(), eit = dfInPtsMap.end(); it!=eit; ++it) + for (DFPtsMapconstIter it = dfInPtsMap.begin(), eit = dfInPtsMap.end(); it != eit; ++it) locs.set(it->first); - for(DFPtsMapconstIter it = dfOutPtsMap.begin(), eit = dfOutPtsMap.end(); it!=eit; ++it) + for (DFPtsMapconstIter it = dfOutPtsMap.begin(), eit = dfOutPtsMap.end(); it != eit; ++it) locs.set(it->first); for (NodeBS::iterator it = locs.begin(), eit = locs.end(); it != eit; it++) @@ -652,16 +651,15 @@ class MutableDFPTData : public DFPTData SVFUtil::outs() << " error opening file for writing!\n"; } - virtual inline void dumpPts(const PtsMap & ptsSet,OutStream & O = SVFUtil::outs()) const + virtual inline void dumpPts(const PtsMap& ptsSet, OutStream& O = SVFUtil::outs()) const { for (PtsMapConstIter nodeIt = ptsSet.begin(); nodeIt != ptsSet.end(); nodeIt++) { const Key& var = nodeIt->first; - const DataSet & pts = nodeIt->second; - if (pts.empty()) - continue; + const DataSet& pts = nodeIt->second; + if (pts.empty()) continue; O << "<" << var << ",{"; - SVFUtil::dumpSet(pts,O); + SVFUtil::dumpSet(pts, O); O << "}> "; } } @@ -689,7 +687,7 @@ class MutableIncDFPTData : public MutableDFPTData typedef typename BasePTData::PTDataTy PTDataTy; typedef typename BaseDFPTData::LocID LocID; - typedef Map UpdatedVarMap; ///< for propagating only newly added variable in IN/OUT set + typedef Map UpdatedVarMap; ///< for propagating only newly added variable in IN/OUT set typedef typename UpdatedVarMap::iterator UpdatedVarMapIter; typedef typename UpdatedVarMap::const_iterator UpdatedVarconstIter; typedef typename DataSet::iterator DataIter; @@ -700,16 +698,18 @@ class MutableIncDFPTData : public MutableDFPTData public: /// Constructor - MutableIncDFPTData(bool reversePT = true, PTDataTy ty = BasePTData::MutIncDataFlow) : BaseMutDFPTData(reversePT, ty) { } + MutableIncDFPTData(bool reversePT = true, PTDataTy ty = BasePTData::MutIncDataFlow) : BaseMutDFPTData(reversePT, ty) + { + } - virtual ~MutableIncDFPTData() { } + virtual ~MutableIncDFPTData() {} virtual inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - if(varHasNewDFInPts(srcLoc, srcVar) && - this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFInPtsSet(srcLoc,srcVar))) + if (varHasNewDFInPts(srcLoc, srcVar) && + this->unionPts(this->getDFInPtsSet(dstLoc, dstVar), this->getDFInPtsSet(srcLoc, srcVar))) { - setVarDFInSetUpdated(dstLoc,dstVar); + setVarDFInSetUpdated(dstLoc, dstVar); return true; } return false; @@ -717,10 +717,10 @@ class MutableIncDFPTData : public MutableDFPTData virtual inline bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - if(varHasNewDFOutPts(srcLoc, srcVar) && - this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFOutPtsSet(srcLoc,srcVar))) + if (varHasNewDFOutPts(srcLoc, srcVar) && + this->unionPts(this->getDFInPtsSet(dstLoc, dstVar), this->getDFOutPtsSet(srcLoc, srcVar))) { - setVarDFInSetUpdated(dstLoc,dstVar); + setVarDFInSetUpdated(dstLoc, dstVar); return true; } return false; @@ -728,12 +728,12 @@ class MutableIncDFPTData : public MutableDFPTData virtual inline bool updateDFOutFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - if(varHasNewDFInPts(srcLoc,srcVar)) + if (varHasNewDFInPts(srcLoc, srcVar)) { - removeVarFromDFInUpdatedSet(srcLoc,srcVar); - if (this->unionPts(this->getDFOutPtsSet(dstLoc,dstVar), this->getDFInPtsSet(srcLoc,srcVar))) + removeVarFromDFInUpdatedSet(srcLoc, srcVar); + if (this->unionPts(this->getDFOutPtsSet(dstLoc, dstVar), this->getDFInPtsSet(srcLoc, srcVar))) { - setVarDFOutSetUpdated(dstLoc,dstVar); + setVarDFOutSetUpdated(dstLoc, dstVar); return true; } } @@ -742,9 +742,9 @@ class MutableIncDFPTData : public MutableDFPTData virtual inline bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - if(this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFOutPtsSet(srcLoc,srcVar))) + if (this->unionPts(this->getDFInPtsSet(dstLoc, dstVar), this->getDFOutPtsSet(srcLoc, srcVar))) { - setVarDFInSetUpdated(dstLoc,dstVar); + setVarDFInSetUpdated(dstLoc, dstVar); return true; } return false; @@ -752,9 +752,9 @@ class MutableIncDFPTData : public MutableDFPTData virtual inline bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - if(this->unionPts(this->getDFInPtsSet(dstLoc,dstVar), this->getDFInPtsSet(srcLoc,srcVar))) + if (this->unionPts(this->getDFInPtsSet(dstLoc, dstVar), this->getDFInPtsSet(srcLoc, srcVar))) { - setVarDFInSetUpdated(dstLoc,dstVar); + setVarDFInSetUpdated(dstLoc, dstVar); return true; } return false; @@ -771,10 +771,8 @@ class MutableIncDFPTData : public MutableDFPTData { const Key var = *ptsIt; /// Enable strong updates if it is required to do so - if (strongUpdates && var == singleton) - continue; - if (updateDFOutFromIn(loc, var, loc, var)) - changed = true; + if (strongUpdates && var == singleton) continue; + if (updateDFOutFromIn(loc, var, loc, var)) changed = true; } } return changed; @@ -782,10 +780,10 @@ class MutableIncDFPTData : public MutableDFPTData virtual inline bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override { - if(varHasNewDFInPts(srcLoc,srcVar)) + if (varHasNewDFInPts(srcLoc, srcVar)) { - removeVarFromDFInUpdatedSet(srcLoc,srcVar); - return this->mutPTData.unionPts(dstVar, this->getDFInPtsSet(srcLoc,srcVar)); + removeVarFromDFInUpdatedSet(srcLoc, srcVar); + return this->mutPTData.unionPts(dstVar, this->getDFInPtsSet(srcLoc, srcVar)); } return false; } @@ -815,7 +813,7 @@ class MutableIncDFPTData : public MutableDFPTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const MutableIncDFPTData *) + static inline bool classof(const MutableIncDFPTData*) { return true; } @@ -829,23 +827,21 @@ class MutableIncDFPTData : public MutableDFPTData /// Handle address-taken variables whose IN pts changed //@{ /// Add var into loc's IN updated set. Called when var's pts in loc's IN set changed - inline void setVarDFInSetUpdated(LocID loc,const Key& var) + inline void setVarDFInSetUpdated(LocID loc, const Key& var) { inUpdatedVarMap[loc].set(var); } /// Remove var from loc's IN updated set - inline void removeVarFromDFInUpdatedSet(LocID loc,const Key& var) + inline void removeVarFromDFInUpdatedSet(LocID loc, const Key& var) { UpdatedVarMapIter it = inUpdatedVarMap.find(loc); - if (it != inUpdatedVarMap.end()) - it->second.reset(var); + if (it != inUpdatedVarMap.end()) it->second.reset(var); } /// Return TRUE if var has new pts in loc's IN set - inline bool varHasNewDFInPts(LocID loc,const Key& var) + inline bool varHasNewDFInPts(LocID loc, const Key& var) { UpdatedVarMapIter it = inUpdatedVarMap.find(loc); - if (it != inUpdatedVarMap.end()) - return it->second.test(var); + if (it != inUpdatedVarMap.end()) return it->second.test(var); return false; } /// Get all var which have new pts information in loc's IN set @@ -858,23 +854,21 @@ class MutableIncDFPTData : public MutableDFPTData /// Handle address-taken variables whose OUT pts changed //@{ /// Add var into loc's OUT updated set. Called when var's pts in loc's OUT set changed - inline void setVarDFOutSetUpdated(LocID loc,const Key& var) + inline void setVarDFOutSetUpdated(LocID loc, const Key& var) { outUpdatedVarMap[loc].set(var); } /// Remove var from loc's OUT updated set - inline void removeVarFromDFOutUpdatedSet(LocID loc,const Key& var) + inline void removeVarFromDFOutUpdatedSet(LocID loc, const Key& var) { UpdatedVarMapIter it = outUpdatedVarMap.find(loc); - if (it != outUpdatedVarMap.end()) - it->second.reset(var); + if (it != outUpdatedVarMap.end()) it->second.reset(var); } /// Return TRUE if var has new pts in loc's OUT set - inline bool varHasNewDFOutPts(LocID loc,const Key& var) + inline bool varHasNewDFOutPts(LocID loc, const Key& var) { UpdatedVarMapIter it = outUpdatedVarMap.find(loc); - if (it != outUpdatedVarMap.end()) - return it->second.test(var); + if (it != outUpdatedVarMap.end()) return it->second.test(var); return false; } /// Get all var which have new pts information in loc's OUT set @@ -888,7 +882,8 @@ class MutableIncDFPTData : public MutableDFPTData /// VersionedPTData implemented with mutable points-to set (DataSet). /// Implemented as a wrapper around two MutablePTDatas: one for Keys, one /// for VersionedKeys. -template +template class MutableVersionedPTData : public VersionedPTData { public: @@ -897,9 +892,11 @@ class MutableVersionedPTData : public VersionedPTData *) + static inline bool classof(const MutableVersionedPTData*) { return true; } @@ -1022,4 +1019,4 @@ class MutableVersionedPTData : public VersionedPTData -class PersistentPointsToCache +template class PersistentPointsToCache { public: typedef Map PTSToIDMap; - typedef std::function DataOp; + typedef std::function DataOp; // TODO: an unordered pair type may be better. typedef Map, PointsToID> OpCache; @@ -79,7 +78,7 @@ class PersistentPointsToCache /// Remaps all points-to sets stored in the cache to the current mapping. void remapAllPts(void) { - for (auto &d : idToPts) d->checkAndRemap(); + for (auto& d : idToPts) d->checkAndRemap(); // Rebuild ptsToId from idToPts. ptsToId.clear(); @@ -88,7 +87,7 @@ class PersistentPointsToCache /// If pts is not in the PersistentPointsToCache, inserts it, assigns an ID, and returns /// that ID. If it is, then the ID is returned. - PointsToID emplacePts(const Data &pts) + PointsToID emplacePts(const Data& pts) { // Is it already in the cache? typename PTSToIDMap::const_iterator foundId = ptsToId.find(pts); @@ -103,7 +102,7 @@ class PersistentPointsToCache } /// Returns the points-to set which id represents. id must be stored in the cache. - const Data &getActualPts(PointsToID id) const + const Data& getActualPts(PointsToID id) const { // Check if the points-to set for ID has already been stored. assert(idToPts.size() > id && "PPTC::getActualPts: points-to set not stored!"); @@ -113,10 +112,7 @@ class PersistentPointsToCache /// Unions lhs and rhs and returns their union's ID. PointsToID unionPts(PointsToID lhs, PointsToID rhs) { - static const DataOp unionOp = [](const Data &lhs, const Data &rhs) - { - return lhs | rhs; - }; + static const DataOp unionOp = [](const Data& lhs, const Data& rhs) { return lhs | rhs; }; ++totalUnions; @@ -164,7 +160,8 @@ class PersistentPointsToCache ++totalUnions; } } - else ++lookupUnions; + else + ++lookupUnions; return result; } @@ -172,10 +169,7 @@ class PersistentPointsToCache /// Relatively complements lhs and rhs (lhs \ rhs) and returns it's ID. PointsToID complementPts(PointsToID lhs, PointsToID rhs) { - static const DataOp complementOp = [](const Data &lhs, const Data &rhs) - { - return lhs - rhs; - }; + static const DataOp complementOp = [](const Data& lhs, const Data& rhs) { return lhs - rhs; }; ++totalComplements; @@ -227,7 +221,8 @@ class PersistentPointsToCache ++totalComplements; } } - else ++lookupComplements; + else + ++lookupComplements; return result; } @@ -235,10 +230,7 @@ class PersistentPointsToCache /// Intersects lhs and rhs (lhs AND rhs) and returns the intersection's ID. PointsToID intersectPts(PointsToID lhs, PointsToID rhs) { - static const DataOp intersectionOp = [](const Data &lhs, const Data &rhs) - { - return lhs & rhs; - }; + static const DataOp intersectionOp = [](const Data& lhs, const Data& rhs) { return lhs & rhs; }; ++totalIntersections; @@ -304,7 +296,8 @@ class PersistentPointsToCache } } } - else ++lookupIntersections; + else + ++lookupIntersections; return result; } @@ -315,24 +308,24 @@ class PersistentPointsToCache static const unsigned fieldWidth = 25; SVFUtil::outs().flags(std::ios::left); - SVFUtil::outs() << std::setw(fieldWidth) << "UniquePointsToSets" << idToPts.size() << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "UniquePointsToSets" << idToPts.size() << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "TotalUnions" << totalUnions << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "PropertyUnions" << propertyUnions << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "UniqueUnions" << uniqueUnions << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "LookupUnions" << lookupUnions << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveUnions" << preemptiveUnions << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "TotalUnions" << totalUnions << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "PropertyUnions" << propertyUnions << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "UniqueUnions" << uniqueUnions << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "LookupUnions" << lookupUnions << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveUnions" << preemptiveUnions << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "TotalComplements" << totalComplements << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "PropertyComplements" << propertyComplements << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "UniqueComplements" << uniqueComplements << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "LookupComplements" << lookupComplements << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveComplements" << preemptiveComplements << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "TotalComplements" << totalComplements << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "PropertyComplements" << propertyComplements << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "UniqueComplements" << uniqueComplements << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "LookupComplements" << lookupComplements << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveComplements" << preemptiveComplements << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "TotalIntersections" << totalIntersections << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "PropertyIntersections" << propertyIntersections << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "UniqueIntersections" << uniqueIntersections << "\n"; - SVFUtil::outs() << std::setw(fieldWidth) << "LookupIntersections" << lookupIntersections << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "TotalIntersections" << totalIntersections << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "PropertyIntersections" << propertyIntersections << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "UniqueIntersections" << uniqueIntersections << "\n"; + SVFUtil::outs() << std::setw(fieldWidth) << "LookupIntersections" << lookupIntersections << "\n"; SVFUtil::outs() << std::setw(fieldWidth) << "PreemptiveIntersections" << preemptiveIntersections << "\n"; SVFUtil::outs().flush(); @@ -345,7 +338,7 @@ class PersistentPointsToCache Map getAllPts(void) { Map allPts; - for (const auto &d : idToPts) allPts[*d] = 1; + for (const auto& d : idToPts) allPts[*d] = 1; return allPts; } @@ -362,14 +355,15 @@ class PersistentPointsToCache /// Performs dataOp on lhs and rhs, checking the opCache first and updating it afterwards. /// commutative indicates whether the operation in question is commutative or not. /// opPerformed is set to true if the operation was *not* cached and thus performed, false otherwise. - inline PointsToID opPts(PointsToID lhs, PointsToID rhs, const DataOp &dataOp, OpCache &opCache, - bool commutative, bool &opPerformed) + inline PointsToID opPts(PointsToID lhs, PointsToID rhs, const DataOp& dataOp, OpCache& opCache, bool commutative, + bool& opPerformed) { std::pair operands; // If we're commutative, we want to always perform the same operation: x op y. // Performing x op y sometimes and y op x other times is a waste of time. if (commutative) operands = std::minmax(lhs, rhs); - else operands = std::make_pair(lhs, rhs); + else + operands = std::make_pair(lhs, rhs); // Check if we have performed this operation OpCache::const_iterator foundResult = opCache.find(operands); @@ -377,8 +371,8 @@ class PersistentPointsToCache opPerformed = true; - const Data &lhsPts = getActualPts(lhs); - const Data &rhsPts = getActualPts(rhs); + const Data& lhsPts = getActualPts(lhs); + const Data& rhsPts = getActualPts(rhs); Data result = dataOp(lhsPts, rhsPts); @@ -403,21 +397,21 @@ class PersistentPointsToCache inline void initStats(void) { - totalUnions = 0; - uniqueUnions = 0; - propertyUnions = 0; - lookupUnions = 0; - preemptiveUnions = 0; - totalComplements = 0; - uniqueComplements = 0; - propertyComplements = 0; - lookupComplements = 0; - preemptiveComplements = 0; - totalIntersections = 0; - uniqueIntersections = 0; - propertyIntersections = 0; - lookupIntersections = 0; - preemptiveIntersections = 0; + totalUnions = 0; + uniqueUnions = 0; + propertyUnions = 0; + lookupUnions = 0; + preemptiveUnions = 0; + totalComplements = 0; + uniqueComplements = 0; + propertyComplements = 0; + lookupComplements = 0; + preemptiveComplements = 0; + totalIntersections = 0; + uniqueIntersections = 0; + propertyIntersections = 0; + lookupIntersections = 0; + preemptiveIntersections = 0; } private: diff --git a/svf/include/MemoryModel/PersistentPointsToDS.h b/svf/include/MemoryModel/PersistentPointsToDS.h index 016f46f5c..be6092dcf 100644 --- a/svf/include/MemoryModel/PersistentPointsToDS.h +++ b/svf/include/MemoryModel/PersistentPointsToDS.h @@ -22,11 +22,10 @@ namespace SVF { -template -class PersistentDFPTData; -template -class PersistentIncDFPTData; -template +template class PersistentDFPTData; +template class PersistentIncDFPTData; +template class PersistentVersionedPTData; /// PTData backed by a PersistentPointsToCache. @@ -37,6 +36,7 @@ class PersistentPTData : public PTData friend class PersistentVersionedPTData; friend class PersistentDFPTData; friend class PersistentIncDFPTData; + public: typedef PTData BasePTData; typedef typename BasePTData::PTDataTy PTDataTy; @@ -45,8 +45,11 @@ class PersistentPTData : public PTData typedef Map RevPtsMap; /// Constructor - explicit PersistentPTData(PersistentPointsToCache &cache, bool reversePT = true, PTDataTy ty = PTDataTy::PersBase) - : BasePTData(reversePT, ty), ptCache(cache) { } + explicit PersistentPTData(PersistentPointsToCache& cache, bool reversePT = true, + PTDataTy ty = PTDataTy::PersBase) + : BasePTData(reversePT, ty), ptCache(cache) + { + } ~PersistentPTData() override = default; @@ -56,19 +59,19 @@ class PersistentPTData : public PTData revPtsMap.clear(); } - inline const DataSet& getPts(const Key &var) override + inline const DataSet& getPts(const Key& var) override { PointsToID id = ptsMap[var]; return ptCache.getActualPts(id); } - inline const KeySet& getRevPts(const Data &data) override + inline const KeySet& getRevPts(const Data& data) override { assert(this->rev && "PersistentPTData::getRevPts: constructed without reverse PT support!"); return revPtsMap[data]; } - inline bool addPts(const Key &dstKey, const Data &element) override + inline bool addPts(const Key& dstKey, const Data& element) override { DataSet srcPts; srcPts.set(element); @@ -88,11 +91,9 @@ class PersistentPTData : public PTData return unionPtsFromId(dstKey, srcId); } - inline void dumpPTData() override - { - } + inline void dumpPTData() override {} - void clearPts(const Key &var, const Data &element) override + void clearPts(const Key& var, const Data& element) override { DataSet toRemoveData; toRemoveData.set(element); @@ -122,7 +123,7 @@ class PersistentPTData : public PTData Map allPts; if (liveOnly) { - for (const typename KeyToIDMap::value_type &ki : ptsMap) + for (const typename KeyToIDMap::value_type& ki : ptsMap) { ++allPts[ptCache.getActualPts(ki.second)]; } @@ -137,7 +138,7 @@ class PersistentPTData : public PTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const PersistentPTData *) + static inline bool classof(const PersistentPTData*) { return true; } @@ -151,7 +152,7 @@ class PersistentPTData : public PTData private: /// Internal unionPts since other methods follow the same pattern. /// Renamed because PointsToID and Key may be the same type... - inline bool unionPtsFromId(const Key &dstKey, PointsToID srcId) + inline bool unionPtsFromId(const Key& dstKey, PointsToID srcId) { PointsToID dstId = ptsMap[dstKey]; PointsToID newDstId = ptCache.unionPts(dstId, srcId); @@ -165,15 +166,15 @@ class PersistentPTData : public PTData // points-to set has changed (i.e., do it the first time only). if (this->rev) { - const DataSet &srcPts = ptCache.getActualPts(srcId); - for (const Data &d : srcPts) SVFUtil::insertKey(dstKey, revPtsMap[d]); + const DataSet& srcPts = ptCache.getActualPts(srcId); + for (const Data& d : srcPts) SVFUtil::insertKey(dstKey, revPtsMap[d]); } } return changed; } - inline void clearSingleRevPts(KeySet &revSet, const Key &k) + inline void clearSingleRevPts(KeySet& revSet, const Key& k) { if (this->rev) { @@ -181,16 +182,16 @@ class PersistentPTData : public PTData } } - inline void clearRevPts(const DataSet &pts, const Key &k) + inline void clearRevPts(const DataSet& pts, const Key& k) { if (this->rev) { - for (const Data &d : pts) clearSingleRevPts(revPtsMap[d], k); + for (const Data& d : pts) clearSingleRevPts(revPtsMap[d], k); } } protected: - PersistentPointsToCache &ptCache; + PersistentPointsToCache& ptCache; KeyToIDMap ptsMap; RevPtsMap revPtsMap; }; @@ -209,8 +210,11 @@ class PersistentDiffPTData : public DiffPTData typedef typename BasePersPTData::RevPtsMap RevPtsMap; /// Constructor - explicit PersistentDiffPTData(PersistentPointsToCache &cache, bool reversePT = true, PTDataTy ty = PTDataTy::PersDiff) - : BaseDiffPTData(reversePT, ty), ptCache(cache), persPTData(cache, reversePT) { } + explicit PersistentDiffPTData(PersistentPointsToCache& cache, bool reversePT = true, + PTDataTy ty = PTDataTy::PersDiff) + : BaseDiffPTData(reversePT, ty), ptCache(cache), persPTData(cache, reversePT) + { + } ~PersistentDiffPTData() override = default; @@ -221,18 +225,18 @@ class PersistentDiffPTData : public DiffPTData propaPtsMap.clear(); } - inline const DataSet &getPts(const Key& var) override + inline const DataSet& getPts(const Key& var) override { return persPTData.getPts(var); } - inline const KeySet& getRevPts(const Data &data) override + inline const KeySet& getRevPts(const Data& data) override { assert(this->rev && "PersistentDiffPTData::getRevPts: constructed without reverse PT support!"); return persPTData.getRevPts(data); } - inline bool addPts(const Key &dstKey, const Data &element) override + inline bool addPts(const Key& dstKey, const Data& element) override { return persPTData.addPts(dstKey, element); } @@ -242,17 +246,17 @@ class PersistentDiffPTData : public DiffPTData return persPTData.unionPts(dstKey, srcKey); } - inline bool unionPts(const Key &dstKey, const DataSet &srcDataSet) override + inline bool unionPts(const Key& dstKey, const DataSet& srcDataSet) override { return persPTData.unionPts(dstKey, srcDataSet); } - void clearPts(const Key &var, const Data &element) override + void clearPts(const Key& var, const Data& element) override { return persPTData.clearPts(var, element); } - void clearFullPts(const Key &var) override + void clearFullPts(const Key& var) override { return persPTData.clearFullPts(var); } @@ -267,13 +271,13 @@ class PersistentDiffPTData : public DiffPTData // TODO. } - inline const DataSet &getDiffPts(Key &var) override + inline const DataSet& getDiffPts(Key& var) override { PointsToID id = diffPtsMap[var]; return ptCache.getActualPts(id); } - inline bool computeDiffPts(Key &var, const DataSet &all) override + inline bool computeDiffPts(Key& var, const DataSet& all) override { PointsToID propaId = propaPtsMap[var]; PointsToID allId = ptCache.emplacePts(all); @@ -289,14 +293,14 @@ class PersistentDiffPTData : public DiffPTData return diffId != ptCache.emptyPointsToId(); } - inline void updatePropaPtsMap(Key &src, Key &dst) override + inline void updatePropaPtsMap(Key& src, Key& dst) override { PointsToID dstId = propaPtsMap[dst]; PointsToID srcId = propaPtsMap[src]; propaPtsMap[dst] = ptCache.intersectPts(dstId, srcId); } - inline void clearPropaPts(Key &var) override + inline void clearPropaPts(Key& var) override { propaPtsMap[var] = ptCache.emptyPointsToId(); } @@ -308,7 +312,7 @@ class PersistentDiffPTData : public DiffPTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const PersistentDiffPTData *) + static inline bool classof(const PersistentDiffPTData*) { return true; } @@ -320,7 +324,7 @@ class PersistentDiffPTData : public DiffPTData ///@} private: - PersistentPointsToCache &ptCache; + PersistentPointsToCache& ptCache; /// Backing to implement basic PTData methods. Allows us to avoid multiple inheritance. PersistentPTData persPTData; /// Diff points-to to be propagated. @@ -343,8 +347,11 @@ class PersistentDFPTData : public DFPTData typedef typename BasePersPTData::KeyToIDMap KeyToIDMap; typedef Map DFKeyToIDMap; - explicit PersistentDFPTData(PersistentPointsToCache &cache, bool reversePT = true, PTDataTy ty = PTDataTy::PersDataFlow) - : BaseDFPTData(reversePT, ty), ptCache(cache), persPTData(cache, reversePT) { } + explicit PersistentDFPTData(PersistentPointsToCache& cache, bool reversePT = true, + PTDataTy ty = PTDataTy::PersDataFlow) + : BaseDFPTData(reversePT, ty), ptCache(cache), persPTData(cache, reversePT) + { + } ~PersistentDFPTData() override = default; @@ -355,7 +362,7 @@ class PersistentDFPTData : public DFPTData persPTData.clear(); } - inline const DataSet &getPts(const Key& var) override + inline const DataSet& getPts(const Key& var) override { return persPTData.getPts(var); } @@ -371,17 +378,17 @@ class PersistentDFPTData : public DFPTData return persPTData.unionPts(dstKey, srcKey); } - inline bool unionPts(const Key& dstKey, const DataSet &srcDataSet) override + inline bool unionPts(const Key& dstKey, const DataSet& srcDataSet) override { return persPTData.unionPts(dstKey, srcDataSet); } - inline bool addPts(const Key &dstKey, const Data &element) override + inline bool addPts(const Key& dstKey, const Data& element) override { return persPTData.addPts(dstKey, element); } - void clearPts(const Key& var, const Data &element) override + void clearPts(const Key& var, const Data& element) override { persPTData.clearPts(var, element); } @@ -415,7 +422,7 @@ class PersistentDFPTData : public DFPTData { typename DFKeyToIDMap::const_iterator foundInKeyToId = dfInPtsMap.find(loc); if (foundInKeyToId == dfInPtsMap.end()) return false; - const KeyToIDMap &inKeyToId = foundInKeyToId->second; + const KeyToIDMap& inKeyToId = foundInKeyToId->second; return (inKeyToId.find(var) != inKeyToId.end()); } @@ -423,38 +430,38 @@ class PersistentDFPTData : public DFPTData { typename DFKeyToIDMap::const_iterator foundOutKeyToId = dfOutPtsMap.find(loc); if (foundOutKeyToId == dfOutPtsMap.end()) return false; - const KeyToIDMap &outKeyToId = foundOutKeyToId->second; + const KeyToIDMap& outKeyToId = foundOutKeyToId->second; return (outKeyToId.find(var) != outKeyToId.end()); } - const DataSet &getDFInPtsSet(LocID loc, const Key& var) override + const DataSet& getDFInPtsSet(LocID loc, const Key& var) override { PointsToID id = dfInPtsMap[loc][var]; return ptCache.getActualPts(id); } - const DataSet &getDFOutPtsSet(LocID loc, const Key& var) override + const DataSet& getDFOutPtsSet(LocID loc, const Key& var) override { PointsToID id = dfOutPtsMap[loc][var]; return ptCache.getActualPts(id); } - bool updateDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override + bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { return unionPtsThroughIds(getDFInPtIdRef(dstLoc, dstVar), getDFInPtIdRef(srcLoc, srcVar)); } - bool updateAllDFInFromIn(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override + bool updateAllDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { return updateDFInFromIn(srcLoc, srcVar, dstLoc, dstVar); } - bool updateDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override + bool updateDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { return unionPtsThroughIds(getDFInPtIdRef(dstLoc, dstVar), getDFOutPtIdRef(srcLoc, srcVar)); } - bool updateAllDFInFromOut(LocID srcLoc, const Key &srcVar, LocID dstLoc, const Key &dstVar) override + bool updateAllDFInFromOut(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { return updateDFInFromOut(srcLoc, srcVar, dstLoc, dstVar); } @@ -464,13 +471,13 @@ class PersistentDFPTData : public DFPTData return unionPtsThroughIds(getDFOutPtIdRef(dstLoc, dstVar), getDFInPtIdRef(srcLoc, srcVar)); } - bool updateAllDFOutFromIn(LocID loc, const Key &singleton, bool strongUpdates) override + bool updateAllDFOutFromIn(LocID loc, const Key& singleton, bool strongUpdates) override { bool changed = false; if (this->hasDFInSet(loc)) { - const KeyToIDMap &inKeyToId = dfInPtsMap[loc]; - for (const typename KeyToIDMap::value_type &ki : inKeyToId) + const KeyToIDMap& inKeyToId = dfInPtsMap[loc]; + for (const typename KeyToIDMap::value_type& ki : inKeyToId) { const Key var = ki.first; /// Enable strong updates if required. @@ -483,12 +490,10 @@ class PersistentDFPTData : public DFPTData return changed; } - void clearAllDFOutUpdatedVar(LocID) override - { - } + void clearAllDFOutUpdatedVar(LocID) override {} /// Update points-to set of top-level pointers with IN[srcLoc:srcVar]. - bool updateTLVPts(LocID srcLoc, const Key &srcVar, const Key &dstVar) override + bool updateTLVPts(LocID srcLoc, const Key& srcVar, const Key& dstVar) override { return unionPtsThroughIds(persPTData.ptsMap[dstVar], getDFInPtIdRef(srcLoc, srcVar)); } @@ -501,17 +506,17 @@ class PersistentDFPTData : public DFPTData Map getAllPts(bool liveOnly) const override { Map allPts = persPTData.getAllPts(liveOnly); - for (const typename DFKeyToIDMap::value_type &lki : dfInPtsMap) + for (const typename DFKeyToIDMap::value_type& lki : dfInPtsMap) { - for (const typename KeyToIDMap::value_type &ki : lki.second) + for (const typename KeyToIDMap::value_type& ki : lki.second) { ++allPts[ptCache.getActualPts(ki.second)]; } } - for (const typename DFKeyToIDMap::value_type &lki : dfOutPtsMap) + for (const typename DFKeyToIDMap::value_type& lki : dfOutPtsMap) { - for (const typename KeyToIDMap::value_type &ki : lki.second) + for (const typename KeyToIDMap::value_type& ki : lki.second) { ++allPts[ptCache.getActualPts(ki.second)]; } @@ -533,38 +538,37 @@ class PersistentDFPTData : public DFPTData /// Methods to support type inquiry through isa, cast, and dyn_cast: ///@{ - static inline bool classof(const PersistentDFPTData *) + static inline bool classof(const PersistentDFPTData*) { return true; } - static inline bool classof(const PTData *ptd) + static inline bool classof(const PTData* ptd) { - return ptd->getPTDTY() == PTDataTy::PersDataFlow - || ptd->getPTDTY() == PTDataTy::PersIncDataFlow; + return ptd->getPTDTY() == PTDataTy::PersDataFlow || ptd->getPTDTY() == PTDataTy::PersIncDataFlow; } ///@} protected: - inline bool unionPtsThroughIds(PointsToID &dst, PointsToID &src) + inline bool unionPtsThroughIds(PointsToID& dst, PointsToID& src) { PointsToID oldDst = dst; dst = ptCache.unionPts(dst, src); return oldDst != dst; } - PointsToID &getDFInPtIdRef(LocID loc, const Key &var) + PointsToID& getDFInPtIdRef(LocID loc, const Key& var) { return dfInPtsMap[loc][var]; } - PointsToID &getDFOutPtIdRef(LocID loc, const Key &var) + PointsToID& getDFOutPtIdRef(LocID loc, const Key& var) { return dfOutPtsMap[loc][var]; } protected: - PersistentPointsToCache &ptCache; + PersistentPointsToCache& ptCache; /// PTData for top-level pointers. We will also use its cache for address-taken pointers. PersistentPTData persPTData; @@ -591,15 +595,18 @@ class PersistentIncDFPTData : public PersistentDFPTData &cache, bool reversePT = true, PTDataTy ty = BasePTData::PersIncDataFlow) - : BasePersDFPTData(cache, reversePT, ty) { } + explicit PersistentIncDFPTData(PersistentPointsToCache& cache, bool reversePT = true, + PTDataTy ty = BasePTData::PersIncDataFlow) + : BasePersDFPTData(cache, reversePT, ty) + { + } ~PersistentIncDFPTData() override = default; inline bool updateDFInFromIn(LocID srcLoc, const Key& srcVar, LocID dstLoc, const Key& dstVar) override { - if (varHasNewDFInPts(srcLoc, srcVar) - && this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar))) + if (varHasNewDFInPts(srcLoc, srcVar) && + this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFInPtIdRef(srcLoc, srcVar))) { setVarDFInSetUpdated(dstLoc, dstVar); return true; @@ -610,8 +617,8 @@ class PersistentIncDFPTData : public PersistentDFPTDataunionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFOutPtIdRef(srcLoc, srcVar))) + if (varHasNewDFOutPts(srcLoc, srcVar) && + this->unionPtsThroughIds(this->getDFInPtIdRef(dstLoc, dstVar), this->getDFOutPtIdRef(srcLoc, srcVar))) { setVarDFInSetUpdated(dstLoc, dstVar); return true; @@ -664,7 +671,7 @@ class PersistentIncDFPTData : public PersistentDFPTDatahasDFOutSet(loc)) { const KeySet vars = getDFOutUpdatedVar(loc); - for (const Key &var : vars) + for (const Key& var : vars) { removeVarFromDFOutUpdatedSet(loc, var); } @@ -718,19 +725,18 @@ class PersistentIncDFPTData : public PersistentDFPTData *) + static inline bool classof(const PersistentIncDFPTData*) { return true; } - static inline bool classof(const PTData *ptd) + static inline bool classof(const PTData* ptd) { return ptd->getPTDTY() == BasePTData::PersIncDataFlow; } ///@} private: - /// Handle address-taken variables whose IN pts changed //@{ /// Add var into loc's IN updated set. Called when var's pts in loc's IN set is changed. @@ -791,7 +797,6 @@ class PersistentIncDFPTData : public PersistentDFPTData +template class PersistentVersionedPTData : public VersionedPTData { public: @@ -812,8 +818,11 @@ class PersistentVersionedPTData : public VersionedPTData::KeyToIDMap KeyToIDMap; typedef typename PersistentPTData::KeyToIDMap VersionedKeyToIDMap; - explicit PersistentVersionedPTData(PersistentPointsToCache &cache, bool reversePT = true, PTDataTy ty = PTDataTy::PersVersioned) - : BaseVersionedPTData(reversePT, ty), tlPTData(cache, reversePT), atPTData(cache, reversePT) { } + explicit PersistentVersionedPTData(PersistentPointsToCache& cache, bool reversePT = true, + PTDataTy ty = PTDataTy::PersVersioned) + : BaseVersionedPTData(reversePT, ty), tlPTData(cache, reversePT), atPTData(cache, reversePT) + { + } ~PersistentVersionedPTData() override = default; @@ -823,31 +832,32 @@ class PersistentVersionedPTData : public VersionedPTDatarev && "PersistentVersionedPTData::getRevPts: constructed without reverse PT support!"); return tlPTData.getRevPts(data); } - const VersionedKeySet& getVersionedKeyRevPts(const Data &data) override + const VersionedKeySet& getVersionedKeyRevPts(const Data& data) override { - assert(this->rev && "PersistentVersionedPTData::getVersionedKeyRevPts: constructed without reverse PT support!"); + assert(this->rev && + "PersistentVersionedPTData::getVersionedKeyRevPts: constructed without reverse PT support!"); return atPTData.getRevPts(data); } - bool addPts(const Key& k, const Data &element) override + bool addPts(const Key& k, const Data& element) override { return tlPTData.addPts(k, element); } - bool addPts(const VersionedKey& vk, const Data &element) override + bool addPts(const VersionedKey& vk, const Data& element) override { return atPTData.addPts(vk, element); } @@ -868,20 +878,20 @@ class PersistentVersionedPTData : public VersionedPTData::value_type &pto : allPts) pto.second -= 1; + for (typename Map::value_type& pto : allPts) pto.second -= 1; SVFUtil::mergePtsOccMaps(allPts, tlPTData.ptCache.getAllPts()); } @@ -933,7 +943,8 @@ class PersistentVersionedPTData : public VersionedPTData *) + static inline bool classof( + const PersistentVersionedPTData*) { return true; } @@ -952,4 +963,4 @@ class PersistentVersionedPTData : public VersionedPTData(pag->getBaseObj(id)); + MemObj* mem = const_cast(pag->getBaseObj(id)); mem->setFieldInsensitive(); } inline bool isFieldInsensitive(NodeID id) const { - const MemObj* mem = pag->getBaseObj(id); + const MemObj* mem = pag->getBaseObj(id); return mem->isFieldInsensitive(); } ///@} @@ -387,8 +384,7 @@ class PointerAnalysis /// CallGraph SCC detection inline void callGraphSCCDetection() { - if(callGraphSCC==nullptr) - callGraphSCC = new CallGraphSCC(callgraph); + if (callGraphSCC == nullptr) callGraphSCC = new CallGraphSCC(callgraph); callGraphSCC->find(); } @@ -398,7 +394,7 @@ class PointerAnalysis return callGraphSCC->repNode(id); } /// Return TRUE if this edge is inside a CallGraph SCC, i.e., src node and dst node are in the same SCC on the SVFG. - inline bool inSameCallGraphSCC(const SVFFunction* fun1,const SVFFunction* fun2) + inline bool inSameCallGraphSCC(const SVFFunction* fun1, const SVFFunction* fun2) { const CallGraphNode* src = callgraph->getCallGraphNode(fun1); const CallGraphNode* dst = callgraph->getCallGraphNode(fun2); @@ -419,17 +415,15 @@ class PointerAnalysis } /// get CHGraph - CommonCHGraph *getCHGraph() const + CommonCHGraph* getCHGraph() const { return chgraph; } - void getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns); - void getVFnsFromPts(const CallICFGNode* cs, const PointsTo &target, VFunSet &vfns); - void connectVCallToVFns(const CallICFGNode* cs, const VFunSet &vfns, CallEdgeMap& newEdges); - virtual void resolveCPPIndCalls(const CallICFGNode* cs, - const PointsTo& target, - CallEdgeMap& newEdges); + void getVFnsFromCHA(const CallICFGNode* cs, VFunSet& vfns); + void getVFnsFromPts(const CallICFGNode* cs, const PointsTo& target, VFunSet& vfns); + void connectVCallToVFns(const CallICFGNode* cs, const VFunSet& vfns, CallEdgeMap& newEdges); + virtual void resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& target, CallEdgeMap& newEdges); }; } // End namespace SVF diff --git a/svf/include/MemoryModel/PointerAnalysisImpl.h b/svf/include/MemoryModel/PointerAnalysisImpl.h index 00d1a0b5c..ed297754b 100644 --- a/svf/include/MemoryModel/PointerAnalysisImpl.h +++ b/svf/include/MemoryModel/PointerAnalysisImpl.h @@ -52,13 +52,15 @@ class BVDataPTAImpl : public PointerAnalysis typedef MutableDiffPTData MutDiffPTDataTy; typedef MutableDFPTData MutDFPTDataTy; typedef MutableIncDFPTData MutIncDFPTDataTy; - typedef MutableVersionedPTData> MutVersionedPTDataTy; + typedef MutableVersionedPTData> + MutVersionedPTDataTy; typedef PersistentPTData PersPTDataTy; typedef PersistentDiffPTData PersDiffPTDataTy; typedef PersistentDFPTData PersDFPTDataTy; typedef PersistentIncDFPTData PersIncDFPTDataTy; - typedef PersistentVersionedPTData> PersVersionedPTDataTy; + typedef PersistentVersionedPTData> + PersVersionedPTDataTy; /// How the PTData used is implemented. enum PTBackingType @@ -73,12 +75,12 @@ class BVDataPTAImpl : public PointerAnalysis /// Destructor ~BVDataPTAImpl() override = default; - inline PersistentPointsToCache &getPtCache() + inline PersistentPointsToCache& getPtCache() { return ptCache; } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { return pta->getImplTy() == BVDataImpl; } @@ -116,11 +118,11 @@ class BVDataPTAImpl : public PointerAnalysis } virtual inline bool unionPts(NodeID id, NodeID ptd) { - return ptD->unionPts(id,ptd); + return ptD->unionPts(id, ptd); } virtual inline bool addPts(NodeID id, NodeID ptd) { - return ptD->addPts(id,ptd); + return ptD->addPts(id, ptd); } //@} @@ -157,7 +159,6 @@ class BVDataPTAImpl : public PointerAnalysis return ptD.get(); } - /// Finalization of pointer analysis, and normalize points-to information to Bit Vector representation void finalize() override; @@ -211,8 +212,7 @@ class BVDataPTAImpl : public PointerAnalysis public: /// Interface expose to users of our pointer analysis, given Value infos - AliasResult alias(const SVFValue* V1, - const SVFValue* V2) override; + AliasResult alias(const SVFValue* V1, const SVFValue* V2) override; /// Interface expose to users of our pointer analysis, given PAGNodeID AliasResult alias(NodeID node1, NodeID node2) override; @@ -236,24 +236,22 @@ class BVDataPTAImpl : public PointerAnalysis /*! * Pointer analysis implementation which uses conditional points-to map data structure (context/path sensitive analysis) */ -template -class CondPTAImpl : public PointerAnalysis +template class CondPTAImpl : public PointerAnalysis { public: typedef CondVar CVar; - typedef CondStdSet CPtSet; + typedef CondStdSet CPtSet; typedef PTData, CVar, CPtSet> PTDataTy; typedef MutablePTData, CVar, CPtSet> MutPTDataTy; - typedef Map PtrToBVPtsMap; /// map a pointer to its BitVector points-to representation + typedef Map PtrToBVPtsMap; /// map a pointer to its BitVector points-to representation typedef Map PtrToNSMap; - typedef Map PtrToCPtsMap; /// map a pointer to its conditional points-to set + typedef Map PtrToCPtsMap; /// map a pointer to its conditional points-to set /// Constructor CondPTAImpl(SVFIR* pag, PointerAnalysis::PTATY type) : PointerAnalysis(pag, type), normalized(false) { - if (type == PathS_DDA || type == Cxt_DDA) - ptD = new MutPTDataTy(); + if (type == PathS_DDA || type == Cxt_DDA) ptD = new MutPTDataTy(); else assert(false && "no points-to data available"); @@ -266,7 +264,7 @@ class CondPTAImpl : public PointerAnalysis destroy(); } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { return pta->getImplTy() == CondImpl; } @@ -298,7 +296,7 @@ class CondPTAImpl : public PointerAnalysis inline const typename MutPTDataTy::PtsMap& getPtsMap() const { - if (MutPTDataTy *m = SVFUtil::dyn_cast(ptD)) return m->getPtsMap(); + if (MutPTDataTy* m = SVFUtil::dyn_cast(ptD)) return m->getPtsMap(); assert(false && "CondPTAImpl::getPtsMap: not a PTData with a PtsMap!"); exit(1); } @@ -328,8 +326,7 @@ class CondPTAImpl : public PointerAnalysis { for (typename CPtSet::const_iterator it2 = cpts2.begin(); it2 != cpts2.end(); ++it2) { - if(isSameVar(*it1,*it2)) - return true; + if (isSameVar(*it1, *it2)) return true; } } return false; @@ -338,15 +335,16 @@ class CondPTAImpl : public PointerAnalysis /// Expand all fields of an aggregate in all points-to sets void expandFIObjs(const CPtSet& cpts, CPtSet& expandedCpts) { - expandedCpts = cpts;; - for(typename CPtSet::const_iterator cit = cpts.begin(), ecit=cpts.end(); cit!=ecit; ++cit) + expandedCpts = cpts; + ; + for (typename CPtSet::const_iterator cit = cpts.begin(), ecit = cpts.end(); cit != ecit; ++cit) { - if(pag->getBaseObjVar(cit->get_id())==cit->get_id()) + if (pag->getBaseObjVar(cit->get_id()) == cit->get_id()) { NodeBS& fields = pag->getAllFieldsObjVars(cit->get_id()); - for(NodeBS::iterator it = fields.begin(), eit = fields.end(); it!=eit; ++it) + for (NodeBS::iterator it = fields.begin(), eit = fields.end(); it != eit; ++it) { - CVar cvar(cit->get_cond(),*it); + CVar cvar(cit->get_cond(), *it); expandedCpts.set(cvar); } } @@ -354,7 +352,6 @@ class CondPTAImpl : public PointerAnalysis } protected: - /// Finalization of pointer analysis, and normalize points-to information to Bit Vector representation virtual void finalize() { @@ -371,12 +368,12 @@ class CondPTAImpl : public PointerAnalysis virtual inline bool unionPts(CVar id, CVar ptd) { - return ptD->unionPts(id,ptd); + return ptD->unionPts(id, ptd); } virtual inline bool addPts(CVar id, CVar ptd) { - return ptD->addPts(id,ptd); + return ptD->addPts(id, ptd); } //@} @@ -384,37 +381,33 @@ class CondPTAImpl : public PointerAnalysis //@{ inline bool mustAlias(const CVar& var1, const CVar& var2) { - if(isSameVar(var1,var2)) - return true; + if (isSameVar(var1, var2)) return true; bool singleton = !(isHeapMemObj(var1.get_id()) || isLocalVarInRecursiveFun(var1.get_id())); - if(isCondCompatible(var1.get_cond(),var2.get_cond(),singleton) == false) - return false; + if (isCondCompatible(var1.get_cond(), var2.get_cond(), singleton) == false) return false; const CPtSet& cpts1 = getPts(var1); const CPtSet& cpts2 = getPts(var2); - return (contains(cpts1,cpts2) && contains(cpts2,cpts1)); + return (contains(cpts1, cpts2) && contains(cpts2, cpts1)); } // Whether cpts1 contains all points-to targets of pts2 bool contains(const CPtSet& cpts1, const CPtSet& cpts2) { - if (cpts1.empty() || cpts2.empty()) - return false; + if (cpts1.empty() || cpts2.empty()) return false; for (typename CPtSet::const_iterator it2 = cpts2.begin(); it2 != cpts2.end(); ++it2) { bool hasObj = false; for (typename CPtSet::const_iterator it1 = cpts1.begin(); it1 != cpts1.end(); ++it1) { - if(isSameVar(*it1,*it2)) + if (isSameVar(*it1, *it2)) { hasObj = true; break; } } - if(hasObj == false) - return false; + if (hasObj == false) return false; } return true; } @@ -422,12 +415,11 @@ class CondPTAImpl : public PointerAnalysis /// Whether two pointers/objects are the same one by considering their conditions bool isSameVar(const CVar& var1, const CVar& var2) const { - if(var1.get_id() != var2.get_id()) - return false; + if (var1.get_id() != var2.get_id()) return false; /// we distinguish context sensitive memory allocation here bool singleton = !(isHeapMemObj(var1.get_id()) || isLocalVarInRecursiveFun(var1.get_id())); - return isCondCompatible(var1.get_cond(),var2.get_cond(),singleton); + return isCondCompatible(var1.get_cond(), var2.get_cond(), singleton); } //@} @@ -438,9 +430,10 @@ class CondPTAImpl : public PointerAnalysis if (hasPtsMap()) { const typename MutPTDataTy::PtsMap& ptsMap = getPtsMap(); - for(typename MutPTDataTy::PtsMap::const_iterator it = ptsMap.begin(), eit=ptsMap.end(); it!=eit; ++it) + for (typename MutPTDataTy::PtsMap::const_iterator it = ptsMap.begin(), eit = ptsMap.end(); it != eit; ++it) { - for(typename CPtSet::const_iterator cit = it->second.begin(), ecit=it->second.end(); cit!=ecit; ++cit) + for (typename CPtSet::const_iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; + ++cit) { ptrToBVPtsMap[(it->first).get_id()].set(cit->get_id()); objToNSRevPtsMap[cit->get_id()].insert((it->first).get_id()); @@ -463,6 +456,7 @@ class CondPTAImpl : public PointerAnalysis PtrToNSMap objToNSRevPtsMap; /// Conditional points-to representation (with conditions) PtrToCPtsMap ptrToCPtsMap; + public: /// Print out conditional pts virtual void dumpCPts() @@ -473,7 +467,7 @@ class CondPTAImpl : public PointerAnalysis virtual inline PointsTo getBVPointsTo(const CPtSet& cpts) const { PointsTo pts; - for(typename CPtSet::const_iterator cit = cpts.begin(), ecit=cpts.end(); cit!=ecit; ++cit) + for (typename CPtSet::const_iterator cit = cpts.begin(), ecit = cpts.end(); cit != ecit; ++cit) pts.set(cit->get_id()); return pts; } @@ -499,32 +493,31 @@ class CondPTAImpl : public PointerAnalysis /// Interface expose to users of our pointer analysis, given Value infos virtual inline AliasResult alias(const SVFValue* V1, const SVFValue* V2) { - return alias(pag->getValueNode(V1),pag->getValueNode(V2)); + return alias(pag->getValueNode(V1), pag->getValueNode(V2)); } /// Interface expose to users of our pointer analysis, given two pointers virtual inline AliasResult alias(NodeID node1, NodeID node2) { - return alias(getCondPointsTo(node1),getCondPointsTo(node2)); + return alias(getCondPointsTo(node1), getCondPointsTo(node2)); } /// Interface expose to users of our pointer analysis, given conditional variables virtual AliasResult alias(const CVar& var1, const CVar& var2) { - return alias(getPts(var1),getPts(var2)); + return alias(getPts(var1), getPts(var2)); } /// Interface expose to users of our pointer analysis, given two conditional points-to sets virtual inline AliasResult alias(const CPtSet& pts1, const CPtSet& pts2) { CPtSet cpts1; - expandFIObjs(pts1,cpts1); + expandFIObjs(pts1, cpts1); CPtSet cpts2; - expandFIObjs(pts2,cpts2); - if (containBlackHoleNode(cpts1) || containBlackHoleNode(cpts2)) - return AliasResult::MayAlias; - else if(this->getAnalysisTy()==PathS_DDA && contains(cpts1,cpts2) && contains(cpts2,cpts1)) + expandFIObjs(pts2, cpts2); + if (containBlackHoleNode(cpts1) || containBlackHoleNode(cpts2)) return AliasResult::MayAlias; + else if (this->getAnalysisTy() == PathS_DDA && contains(cpts1, cpts2) && contains(cpts2, cpts1)) { return AliasResult::MustAlias; } - else if(overlap(cpts1,cpts2)) + else if (overlap(cpts1, cpts2)) return AliasResult::MayAlias; else return AliasResult::NoAlias; @@ -532,20 +525,18 @@ class CondPTAImpl : public PointerAnalysis /// Test blk node for cpts inline bool containBlackHoleNode(const CPtSet& cpts) { - for(typename CPtSet::const_iterator cit = cpts.begin(), ecit=cpts.end(); cit!=ecit; ++cit) + for (typename CPtSet::const_iterator cit = cpts.begin(), ecit = cpts.end(); cit != ecit; ++cit) { - if(cit->get_id() == pag->getBlackHoleNode()) - return true; + if (cit->get_id() == pag->getBlackHoleNode()) return true; } return false; } /// Test constant node for cpts inline bool containConstantNode(const CPtSet& cpts) { - for(typename CPtSet::const_iterator cit = cpts.begin(), ecit=cpts.end(); cit!=ecit; ++cit) + for (typename CPtSet::const_iterator cit = cpts.begin(), ecit = cpts.end(); cit != ecit; ++cit) { - if(cit->get_id() == pag->getConstantNode()) - return true; + if (cit->get_id() == pag->getConstantNode()) return true; } return false; } @@ -555,7 +546,8 @@ class CondPTAImpl : public PointerAnalysis /// Dump points-to information of top-level pointers void dumpTopLevelPtsTo() { - for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); nIter != this->getAllValidPtrs().end(); ++nIter) + for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); nIter != this->getAllValidPtrs().end(); + ++nIter) { const PAGNode* node = this->getPAG()->getGNode(*nIter); if (this->getPAG()->isValidTopLevelPtr(node)) @@ -567,7 +559,7 @@ class CondPTAImpl : public PointerAnalysis else if (!SVFUtil::isa(node)) { SVFUtil::outs() << "##<" << node->getValue()->getName() << "> "; - //SVFUtil::outs() << "Source Loc: " << SVFUtil::getSourceLoc(node->getValue()); + // SVFUtil::outs() << "Source Loc: " << SVFUtil::getSourceLoc(node->getValue()); } const PointsTo& pts = getPts(node->getId()); diff --git a/svf/include/MemoryModel/PointsTo.h b/svf/include/MemoryModel/PointsTo.h index 97038fe7b..e39f30aa4 100644 --- a/svf/include/MemoryModel/PointsTo.h +++ b/svf/include/MemoryModel/PointsTo.h @@ -45,17 +45,17 @@ class PointsTo /// Construct empty points-to set. PointsTo(); /// Copy constructor. - PointsTo(const PointsTo &pt); + PointsTo(const PointsTo& pt); /// Move constructor. - PointsTo(PointsTo &&pt) noexcept ; + PointsTo(PointsTo&& pt) noexcept; ~PointsTo(); /// Copy assignment. - PointsTo &operator=(const PointsTo &rhs); + PointsTo& operator=(const PointsTo& rhs); /// Move assignment. - PointsTo &operator=(PointsTo &&rhs) noexcept ; + PointsTo& operator=(PointsTo&& rhs) noexcept; /// Returns true if set is empty. bool empty() const; @@ -80,40 +80,40 @@ class PointsTo void reset(u32_t n); /// Returns true if this set is a superset of rhs. - bool contains(const PointsTo &rhs) const; + bool contains(const PointsTo& rhs) const; /// Returns true if this set and rhs share any elements. - bool intersects(const PointsTo &rhs) const; + bool intersects(const PointsTo& rhs) const; /// Returns the first element the set. Returns -1 when the set is empty. /// TODO: should we diverge from LLVM about the int return? int find_first(); /// Returns true if this set and rhs contain exactly the same elements. - bool operator==(const PointsTo &rhs) const; + bool operator==(const PointsTo& rhs) const; /// Returns true if either this set or rhs has an element not in the other. - bool operator!=(const PointsTo &rhs) const; + bool operator!=(const PointsTo& rhs) const; /// Put union of this set and rhs into this set. /// Returns true if this set changed. - bool operator|=(const PointsTo &rhs); - bool operator|=(const NodeBS &rhs); + bool operator|=(const PointsTo& rhs); + bool operator|=(const NodeBS& rhs); /// Put intersection of this set and rhs into this set. /// Returns true if this set changed. - bool operator&=(const PointsTo &rhs); + bool operator&=(const PointsTo& rhs); /// Remove elements in rhs from this set. /// Returns true if this set changed. - bool operator-=(const PointsTo &rhs); + bool operator-=(const PointsTo& rhs); /// Put intersection of this set with complement of rhs into this set. /// Returns true if this set changed. - bool intersectWithComplement(const PointsTo &rhs); + bool intersectWithComplement(const PointsTo& rhs); /// Put intersection of lhs with complement of rhs into this set (overwrites). - void intersectWithComplement(const PointsTo &lhs, const PointsTo &rhs); + void intersectWithComplement(const PointsTo& lhs, const PointsTo& rhs); /// Returns this points-to set as a NodeBS. NodeBS toNodeBS() const; @@ -150,7 +150,7 @@ class PointsTo /// Returns true if this points-to set and pt have the same type, nodeMapping, /// and reverseNodeMapping - bool metaSame(const PointsTo &pt) const; + bool metaSame(const PointsTo& pt) const; private: /// Best node mapping we know of the for the analyses at hand. @@ -160,8 +160,7 @@ class PointsTo /// Holds backing data structure. /// TODO: std::variant when we move to C++17. - union - { + union { /// Sparse bit vector backing. SparseBitVector<> sbv; /// Core bit vector backing. @@ -184,23 +183,23 @@ class PointsTo using iterator_category = std::forward_iterator_tag; using value_type = u32_t; using difference_type = std::ptrdiff_t; - using pointer = u32_t *; - using reference = u32_t &; + using pointer = u32_t*; + using reference = u32_t&; /// Deleted because we don't want iterators with null pt. PointsToIterator() = delete; - PointsToIterator(const PointsToIterator &pt); - PointsToIterator(PointsToIterator &&pt) noexcept ; + PointsToIterator(const PointsToIterator& pt); + PointsToIterator(PointsToIterator&& pt) noexcept; /// Returns an iterator to the beginning of pt if end is false, and to /// the end of pt if end is true. - explicit PointsToIterator(const PointsTo *pt, bool end=false); + explicit PointsToIterator(const PointsTo* pt, bool end = false); - PointsToIterator &operator=(const PointsToIterator &rhs); - PointsToIterator &operator=(PointsToIterator &&rhs) noexcept ; + PointsToIterator& operator=(const PointsToIterator& rhs); + PointsToIterator& operator=(PointsToIterator&& rhs) noexcept; /// Pre-increment: ++it. - const PointsToIterator &operator++(); + const PointsToIterator& operator++(); /// Post-increment: it++. const PointsToIterator operator++(int); @@ -209,21 +208,20 @@ class PointsTo u32_t operator*() const; /// Equality: *this == rhs. - bool operator==(const PointsToIterator &rhs) const; + bool operator==(const PointsToIterator& rhs) const; /// Inequality: *this != rhs. - bool operator!=(const PointsToIterator &rhs) const; + bool operator!=(const PointsToIterator& rhs) const; private: bool atEnd() const; private: /// PointsTo we are iterating over. - const PointsTo *pt; + const PointsTo* pt; /// Iterator into the backing data structure. Discriminated by pt->type. /// TODO: std::variant when we move to C++17. - union - { + union { SparseBitVector<>::iterator sbvIt; CoreBitVector::iterator cbvIt; BitVector::iterator bvIt; @@ -232,24 +230,22 @@ class PointsTo }; /// Returns a new lhs | rhs. -PointsTo operator|(const PointsTo &lhs, const PointsTo &rhs); +PointsTo operator|(const PointsTo& lhs, const PointsTo& rhs); /// Returns a new lhs & rhs. -PointsTo operator&(const PointsTo &lhs, const PointsTo &rhs); +PointsTo operator&(const PointsTo& lhs, const PointsTo& rhs); /// Returns a new lhs - rhs. -PointsTo operator-(const PointsTo &lhs, const PointsTo &rhs); +PointsTo operator-(const PointsTo& lhs, const PointsTo& rhs); } // End namespace SVF -template <> -struct std::hash +template <> struct std::hash { - size_t operator()(const SVF::PointsTo &pt) const + size_t operator()(const SVF::PointsTo& pt) const { return pt.hash(); } }; - -#endif // POINTSTO_H_ +#endif // POINTSTO_H_ diff --git a/svf/include/MemoryModel/SVFLoop.h b/svf/include/MemoryModel/SVFLoop.h index cb4d67227..d591189ca 100644 --- a/svf/include/MemoryModel/SVFLoop.h +++ b/svf/include/MemoryModel/SVFLoop.h @@ -40,19 +40,16 @@ class SVFLoop friend class SVFIRWriter; friend class SVFIRReader; - typedef Set ICFGEdgeSet; - typedef Set ICFGNodeSet; + typedef Set ICFGEdgeSet; + typedef Set ICFGNodeSet; + private: ICFGEdgeSet entryICFGEdges, backICFGEdges, inICFGEdges, outICFGEdges; ICFGNodeSet icfgNodes; u32_t loopBound; public: - SVFLoop(const ICFGNodeSet &_nodes, u32_t _bound) : - icfgNodes(_nodes), loopBound(_bound) - { - - } + SVFLoop(const ICFGNodeSet& _nodes, u32_t _bound) : icfgNodes(_nodes), loopBound(_bound) {} virtual ~SVFLoop() = default; @@ -66,32 +63,32 @@ class SVFLoop return icfgNodes.end(); } - inline bool isInLoop(const ICFGNode *icfgNode) const + inline bool isInLoop(const ICFGNode* icfgNode) const { return icfgNodes.find(icfgNode) != icfgNodes.end(); } - inline bool isEntryICFGEdge(const ICFGEdge *edge) const + inline bool isEntryICFGEdge(const ICFGEdge* edge) const { return entryICFGEdges.find(edge) != entryICFGEdges.end(); } - inline bool isBackICFGEdge(const ICFGEdge *edge) const + inline bool isBackICFGEdge(const ICFGEdge* edge) const { return backICFGEdges.find(edge) != backICFGEdges.end(); } - inline bool isInICFGEdge(const ICFGEdge *edge) const + inline bool isInICFGEdge(const ICFGEdge* edge) const { return inICFGEdges.find(edge) != inICFGEdges.end(); } - inline bool isOutICFGEdge(const ICFGEdge *edge) const + inline bool isOutICFGEdge(const ICFGEdge* edge) const { return outICFGEdges.find(edge) != outICFGEdges.end(); } - inline void addEntryICFGEdge(const ICFGEdge *edge) + inline void addEntryICFGEdge(const ICFGEdge* edge) { entryICFGEdges.insert(edge); } @@ -106,7 +103,7 @@ class SVFLoop return entryICFGEdges.end(); } - inline void addOutICFGEdge(const ICFGEdge *edge) + inline void addOutICFGEdge(const ICFGEdge* edge) { outICFGEdges.insert(edge); } @@ -121,7 +118,7 @@ class SVFLoop return outICFGEdges.end(); } - inline void addBackICFGEdge(const ICFGEdge *edge) + inline void addBackICFGEdge(const ICFGEdge* edge) { backICFGEdges.insert(edge); } @@ -136,7 +133,7 @@ class SVFLoop return backICFGEdges.end(); } - inline void addInICFGEdge(const ICFGEdge *edge) + inline void addInICFGEdge(const ICFGEdge* edge) { inICFGEdges.insert(edge); } @@ -164,4 +161,4 @@ class SVFLoop } // End namespace SVF -#endif //SVF_SVFLOOP_H +#endif // SVF_SVFLOOP_H diff --git a/svf/include/SABER/DoubleFreeChecker.h b/svf/include/SABER/DoubleFreeChecker.h index 786a49db8..96a365d17 100644 --- a/svf/include/SABER/DoubleFreeChecker.h +++ b/svf/include/SABER/DoubleFreeChecker.h @@ -44,14 +44,10 @@ class DoubleFreeChecker : public LeakChecker public: /// Constructor - DoubleFreeChecker(): LeakChecker() - { - } + DoubleFreeChecker() : LeakChecker() {} /// Destructor - virtual ~DoubleFreeChecker() - { - } + virtual ~DoubleFreeChecker() {} /// We start from here virtual bool runOnModule(SVFIR* pag) override @@ -64,7 +60,6 @@ class DoubleFreeChecker : public LeakChecker /// Report file/close bugs void reportBug(ProgSlice* slice) override; - /// Validate test cases for regression test purpose void testsValidation(ProgSlice* slice); void validateSuccessTests(ProgSlice* slice, const SVFFunction* fun); diff --git a/svf/include/SABER/FileChecker.h b/svf/include/SABER/FileChecker.h index ddcc1d4e2..752670cab 100644 --- a/svf/include/SABER/FileChecker.h +++ b/svf/include/SABER/FileChecker.h @@ -43,16 +43,11 @@ class FileChecker : public LeakChecker { public: - /// Constructor - FileChecker(): LeakChecker() - { - } + FileChecker() : LeakChecker() {} /// Destructor - virtual ~FileChecker() - { - } + virtual ~FileChecker() {} /// We start from here virtual bool runOnModule(SVFIR* pag) diff --git a/svf/include/SABER/LeakChecker.h b/svf/include/SABER/LeakChecker.h index 2328adaa6..bc7aa49d7 100644 --- a/svf/include/SABER/LeakChecker.h +++ b/svf/include/SABER/LeakChecker.h @@ -43,7 +43,7 @@ class LeakChecker : public SrcSnkDDA { public: - typedef Map SVFGNodeToCSIDMap; + typedef Map SVFGNodeToCSIDMap; typedef FIFOWorkList CSWorkList; typedef ProgSlice::VFWorkList WorkList; typedef NodeBS SVFGNodeBS; @@ -56,13 +56,9 @@ class LeakChecker : public SrcSnkDDA }; /// Constructor - LeakChecker() - { - } + LeakChecker() {} /// Destructor - virtual ~LeakChecker() - { - } + virtual ~LeakChecker() {} /// We start from here virtual bool runOnModule(SVFIR* pag) @@ -108,8 +104,8 @@ class LeakChecker : public SrcSnkDDA } inline const CallICFGNode* getSrcCSID(const SVFGNode* src) { - SVFGNodeToCSIDMap::iterator it =srcToCSIDMap.find(src); - assert(it!=srcToCSIDMap.end() && "source node not at a callsite??"); + SVFGNodeToCSIDMap::iterator it = srcToCSIDMap.find(src); + assert(it != srcToCSIDMap.end() && "source node not at a callsite??"); return it->second; } //@} diff --git a/svf/include/SABER/ProgSlice.h b/svf/include/SABER/ProgSlice.h index a69ee703c..62ea47052 100644 --- a/svf/include/SABER/ProgSlice.h +++ b/svf/include/SABER/ProgSlice.h @@ -53,18 +53,18 @@ class ProgSlice typedef Set SVFGNodeSet; typedef SVFGNodeSet::const_iterator SVFGNodeSetIter; typedef SaberCondAllocator::Condition Condition; - typedef Map SVFGNodeToCondMap; ///< map a SVFGNode to its condition during value-flow guard computation + typedef Map + SVFGNodeToCondMap; ///< map a SVFGNode to its condition during value-flow guard computation - typedef FIFOWorkList VFWorkList; ///< worklist for value-flow guard computation - typedef FIFOWorkList CFWorkList; ///< worklist for control-flow guard computation + typedef FIFOWorkList VFWorkList; ///< worklist for value-flow guard computation + typedef FIFOWorkList CFWorkList; ///< worklist for control-flow guard computation typedef SaberCondAllocator::SVFGNodeToSVFGNodeSetMap SVFGNodeToSVFGNodeSetMap; - /// Constructor - ProgSlice(const SVFGNode* src, SaberCondAllocator* pa, const SVFG* graph): - root(src), partialReachable(false), fullReachable(false), reachGlob(false), - pathAllocator(pa), _curSVFGNode(nullptr), finalCond(pa->getFalseCond()), svfg(graph) + ProgSlice(const SVFGNode* src, SaberCondAllocator* pa, const SVFG* graph) + : root(src), partialReachable(false), fullReachable(false), reachGlob(false), pathAllocator(pa), + _curSVFGNode(nullptr), finalCond(pa->getFalseCond()), svfg(graph) { } @@ -94,11 +94,11 @@ class ProgSlice } inline bool inForwardSlice(const SVFGNode* node) { - return forwardslice.find(node)!=forwardslice.end(); + return forwardslice.find(node) != forwardslice.end(); } inline bool inBackwardSlice(const SVFGNode* node) { - return backwardslice.find(node)!=backwardslice.end(); + return backwardslice.find(node) != backwardslice.end(); } inline SVFGNodeSetIter forwardSliceBegin() const { @@ -179,15 +179,15 @@ class ProgSlice /// Condition operations //@{ - inline Condition condAnd(const Condition &lhs, const Condition &rhs) + inline Condition condAnd(const Condition& lhs, const Condition& rhs) { - return pathAllocator->condAnd(lhs,rhs); + return pathAllocator->condAnd(lhs, rhs); } - inline Condition condOr(const Condition &lhs, const Condition &rhs) + inline Condition condOr(const Condition& lhs, const Condition& rhs) { - return pathAllocator->condOr(lhs,rhs); + return pathAllocator->condOr(lhs, rhs); } - inline Condition condNeg(const Condition &cond) + inline Condition condNeg(const Condition& cond) { return pathAllocator->condNeg(cond); } @@ -206,7 +206,7 @@ class ProgSlice /// Evaluate final condition std::string evalFinalCond() const; /// Add final condition to eventStack - void evalFinalCond2Event(GenericBug::EventStack &eventStack) const; + void evalFinalCond2Event(GenericBug::EventStack& eventStack) const; //@} protected: @@ -229,18 +229,17 @@ class ProgSlice inline Condition getVFCond(const SVFGNode* node) const { SVFGNodeToCondMap::const_iterator it = svfgNodeToCondMap.find(node); - if(it==svfgNodeToCondMap.end()) + if (it == svfgNodeToCondMap.end()) { return getFalseCond(); } return it->second; } - inline bool setVFCond(const SVFGNode* node, const Condition &cond) + inline bool setVFCond(const SVFGNode* node, const Condition& cond) { SVFGNodeToCondMap::iterator it = svfgNodeToCondMap.find(node); // until a fixed-point is reached (condition is not changed) - if(it!=svfgNodeToCondMap.end() && isEquivalentBranchCond(it->second, cond)) - return false; + if (it != svfgNodeToCondMap.end() && isEquivalentBranchCond(it->second, cond)) return false; svfgNodeToCondMap[node] = cond; return true; @@ -251,19 +250,21 @@ class ProgSlice //@{ inline Condition ComputeIntraVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst) { - return pathAllocator->ComputeIntraVFGGuard(src,dst); + return pathAllocator->ComputeIntraVFGGuard(src, dst); } - inline Condition ComputeInterCallVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, const SVFBasicBlock* callBB) + inline Condition ComputeInterCallVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, + const SVFBasicBlock* callBB) { - return pathAllocator->ComputeInterCallVFGGuard(src,dst,callBB); + return pathAllocator->ComputeInterCallVFGGuard(src, dst, callBB); } - inline Condition ComputeInterRetVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, const SVFBasicBlock* retBB) + inline Condition ComputeInterRetVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, + const SVFBasicBlock* retBB) { - return pathAllocator->ComputeInterRetVFGGuard(src,dst,retBB); + return pathAllocator->ComputeInterRetVFGGuard(src, dst, retBB); } //@} - inline bool isEquivalentBranchCond(const Condition &lhs, const Condition &rhs) const + inline bool isEquivalentBranchCond(const Condition& lhs, const Condition& rhs) const { return pathAllocator->isEquivalentBranchCond(lhs, rhs); }; @@ -274,7 +275,7 @@ class ProgSlice inline const SVFBasicBlock* getSVFGNodeBB(const SVFGNode* node) const { const ICFGNode* icfgNode = node->getICFGNode(); - if(SVFUtil::isa(node) == false) + if (SVFUtil::isa(node) == false) { return icfgNode->getBB(); } @@ -294,13 +295,13 @@ class ProgSlice } //@} /// Set final condition after all path reachability analysis - inline void setFinalCond(const Condition &cond) + inline void setFinalCond(const Condition& cond) { finalCond = cond; } /// Compute invalid branch condition stemming from removed strong update value-flow edges - Condition computeInvalidCondFromRemovedSUVFEdge(const SVFGNode * cur); + Condition computeInvalidCondFromRemovedSUVFEdge(const SVFGNode* cur); const SVFGNodeToSVFGNodeSetMap& getRemovedSUVFEdges() const { @@ -308,18 +309,18 @@ class ProgSlice } private: - SVFGNodeSet forwardslice; ///< the forward slice - SVFGNodeSet backwardslice; ///< the backward slice - SVFGNodeSet sinks; ///< a set of sink nodes - const SVFGNode* root; ///< root node on the slice - SVFGNodeToCondMap svfgNodeToCondMap; ///< map a SVFGNode to its path condition starting from root - bool partialReachable; ///< reachable from some paths - bool fullReachable; ///< reachable from all paths - bool reachGlob; ///< Whether slice reach a global - SaberCondAllocator* pathAllocator; ///< path condition allocator - const SVFGNode* _curSVFGNode; ///< current svfg node during guard computation - Condition finalCond; ///< final condition - const SVFG* svfg; ///< SVFG + SVFGNodeSet forwardslice; ///< the forward slice + SVFGNodeSet backwardslice; ///< the backward slice + SVFGNodeSet sinks; ///< a set of sink nodes + const SVFGNode* root; ///< root node on the slice + SVFGNodeToCondMap svfgNodeToCondMap; ///< map a SVFGNode to its path condition starting from root + bool partialReachable; ///< reachable from some paths + bool fullReachable; ///< reachable from all paths + bool reachGlob; ///< Whether slice reach a global + SaberCondAllocator* pathAllocator; ///< path condition allocator + const SVFGNode* _curSVFGNode; ///< current svfg node during guard computation + Condition finalCond; ///< final condition + const SVFG* svfg; ///< SVFG }; } // End namespace SVF diff --git a/svf/include/SABER/SaberCheckerAPI.h b/svf/include/SABER/SaberCheckerAPI.h index df11b9bb5..8c9233845 100644 --- a/svf/include/SABER/SaberCheckerAPI.h +++ b/svf/include/SABER/SaberCheckerAPI.h @@ -47,11 +47,11 @@ class SaberCheckerAPI public: enum CHECKER_TYPE { - CK_DUMMY = 0, /// dummy type - CK_ALLOC, /// memory allocation + CK_DUMMY = 0, /// dummy type + CK_ALLOC, /// memory allocation CK_FREE, /// memory deallocation - CK_FOPEN, /// File open - CK_FCLOSE /// File close + CK_FOPEN, /// File open + CK_FCLOSE /// File close }; typedef Map TDAPIMap; @@ -61,7 +61,7 @@ class SaberCheckerAPI TDAPIMap tdAPIMap; /// Constructor - SaberCheckerAPI () + SaberCheckerAPI() { init(); } @@ -75,11 +75,10 @@ class SaberCheckerAPI /// Get the function type of a function inline CHECKER_TYPE getType(const SVFFunction* F) const { - if(F) + if (F) { - TDAPIMap::const_iterator it= tdAPIMap.find(F->getName()); - if(it != tdAPIMap.end()) - return it->second; + TDAPIMap::const_iterator it = tdAPIMap.find(F->getName()); + if (it != tdAPIMap.end()) return it->second; } return CK_DUMMY; } @@ -88,7 +87,7 @@ class SaberCheckerAPI /// Return a static reference static SaberCheckerAPI* getCheckerAPI() { - if(ckAPI == nullptr) + if (ckAPI == nullptr) { ckAPI = new SaberCheckerAPI(); } @@ -142,7 +141,6 @@ class SaberCheckerAPI return isFClose(SVFUtil::getCallee(cs->getCallSite())); } //@} - }; } // End namespace SVF diff --git a/svf/include/SABER/SaberCondAllocator.h b/svf/include/SABER/SaberCondAllocator.h index b4e1571ce..6d096e81b 100644 --- a/svf/include/SABER/SaberCondAllocator.h +++ b/svf/include/SABER/SaberCondAllocator.h @@ -36,7 +36,6 @@ #include "Graphs/SVFG.h" #include "Util/Z3Expr.h" - namespace SVF { @@ -47,32 +46,29 @@ class SaberCondAllocator { public: - - typedef Z3Expr Condition; /// z3 condition - typedef Map IndexToTermInstMap; /// id to instruction map for z3 - typedef Map CondPosMap; ///< map a branch to its Condition - typedef Map BBCondMap; /// map bb to a Condition + typedef Z3Expr Condition; /// z3 condition + typedef Map IndexToTermInstMap; /// id to instruction map for z3 + typedef Map CondPosMap; ///< map a branch to its Condition + typedef Map BBCondMap; /// map bb to a Condition typedef Set BasicBlockSet; - typedef Map FunToExitBBsMap; ///< map a function to all its basic blocks calling program exit - typedef Map BBToCondMap; ///< map a basic block to its condition during control-flow guard computation - typedef FIFOWorkList CFWorkList; ///< worklist for control-flow guard computation + typedef Map + FunToExitBBsMap; ///< map a function to all its basic blocks calling program exit + typedef Map + BBToCondMap; ///< map a basic block to its condition during control-flow guard computation + typedef FIFOWorkList CFWorkList; ///< worklist for control-flow guard computation typedef Map> SVFGNodeToSVFGNodeSetMap; - /// Constructor SaberCondAllocator(); /// Destructor - virtual ~SaberCondAllocator() - { - } + virtual ~SaberCondAllocator() {} /// Statistics //@{ inline std::string getMemUsage() { u32_t vmrss, vmsize; - if (SVFUtil::getMemoryUsageKB(&vmrss, &vmsize)) - return std::to_string(vmsize) + "KB"; + if (SVFUtil::getMemoryUsageKB(&vmrss, &vmsize)) return std::to_string(vmsize) + "KB"; else return "cannot read memory usage"; } @@ -86,11 +82,11 @@ class SaberCondAllocator //@{ inline Condition condAnd(const Condition& lhs, const Condition& rhs) { - return Condition::AND(lhs,rhs); + return Condition::AND(lhs, rhs); } inline Condition condOr(const Condition& lhs, const Condition& rhs) { - return Condition::OR(lhs,rhs); + return Condition::OR(lhs, rhs); } inline Condition condNeg(const Condition& cond) { @@ -132,7 +128,7 @@ class SaberCondAllocator return it->second; } - inline void setCondInst(const Condition &condition, const SVFInstruction* inst) + inline void setCondInst(const Condition& condition, const SVFInstruction* inst) { assert(idToTermInstMap.find(condition.id()) == idToTermInstMap.end() && "this should be a fresh condition"); idToTermInstMap[condition.id()] = inst; @@ -146,33 +142,36 @@ class SaberCondAllocator inline bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - const SVFFunction* keyFunc = bbKey->getParent(); - const SVFFunction* valueFunc = bbValue->getParent(); + const SVFFunction* keyFunc = bbKey->getParent(); + const SVFFunction* valueFunc = bbValue->getParent(); bool funcEq = (keyFunc == valueFunc); (void)funcEq; // Suppress warning of unused variable under release build assert(funcEq && "two basicblocks should be in the same function!"); - return keyFunc->postDominate(bbKey,bbValue); + return keyFunc->postDominate(bbKey, bbValue); } inline bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - const SVFFunction* keyFunc = bbKey->getParent(); - const SVFFunction* valueFunc = bbValue->getParent(); + const SVFFunction* keyFunc = bbKey->getParent(); + const SVFFunction* valueFunc = bbValue->getParent(); bool funcEq = (keyFunc == valueFunc); (void)funcEq; // Suppress warning of unused variable under release build assert(funcEq && "two basicblocks should be in the same function!"); - return keyFunc->dominate(bbKey,bbValue); + return keyFunc->dominate(bbKey, bbValue); } /// Guard Computation for a value-flow (between two basic blocks) //@{ virtual Condition ComputeIntraVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst); - virtual Condition ComputeInterCallVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, const SVFBasicBlock* callBB); - virtual Condition ComputeInterRetVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, const SVFBasicBlock* retBB); + virtual Condition ComputeInterCallVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, + const SVFBasicBlock* callBB); + virtual Condition ComputeInterRetVFGGuard(const SVFBasicBlock* src, const SVFBasicBlock* dst, + const SVFBasicBlock* retBB); /// Get complement condition (from B1 to B0) according to a complementBB (BB2) at a phi /// e.g., B0: dstBB; B1:incomingBB; B2:complementBB - virtual Condition getPHIComplementCond(const SVFBasicBlock* BB1, const SVFBasicBlock* BB2, const SVFBasicBlock* BB0); + virtual Condition getPHIComplementCond(const SVFBasicBlock* BB1, const SVFBasicBlock* BB2, + const SVFBasicBlock* BB0); inline void clearCFCond() { @@ -203,7 +202,7 @@ class SaberCondAllocator } /// Whether lhs and rhs are equivalent branch conditions - bool isEquivalentBranchCond(const Condition &lhs, const Condition &rhs) const; + bool isEquivalentBranchCond(const Condition& lhs, const Condition& rhs) const; inline ICFG* getICFG() const { @@ -216,8 +215,7 @@ class SaberCondAllocator { BBToCondMap::iterator it = bbToCondMap.find(bb); // until a fixed-point is reached (condition is not changed) - if(it!=bbToCondMap.end() && isEquivalentBranchCond(it->second, cond)) - return false; + if (it != bbToCondMap.end() && isEquivalentBranchCond(it->second, cond)) return false; bbToCondMap[bb] = cond; return true; @@ -225,7 +223,7 @@ class SaberCondAllocator inline Condition getCFCond(const SVFBasicBlock* bb) const { BBToCondMap::const_iterator it = bbToCondMap.find(bb); - if(it==bbToCondMap.end()) + if (it == bbToCondMap.end()) { return getFalseCond(); } @@ -233,21 +231,19 @@ class SaberCondAllocator } //@} - /// mark neg Z3 expression - inline void setNegCondInst(const Condition &condition, const SVFInstruction* inst) + inline void setNegCondInst(const Condition& condition, const SVFInstruction* inst) { setCondInst(condition, inst); negConds.set(condition.id()); } - SVFGNodeToSVFGNodeSetMap & getRemovedSUVFEdges() + SVFGNodeToSVFGNodeSetMap& getRemovedSUVFEdges() { return removedSUVFEdges; } private: - /// Allocate path condition for every basic block virtual void allocateForBB(const SVFBasicBlock& bb); @@ -256,16 +252,16 @@ class SaberCondAllocator /// Set branch condition void setBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ, const Condition& cond); /// Get branch condition - Condition getBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ) const; - ///Get a condition, evaluate the value for conditions if necessary (e.g., testNull like express) - Condition getEvalBrCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ); + Condition getBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ) const; + /// Get a condition, evaluate the value for conditions if necessary (e.g., testNull like express) + Condition getEvalBrCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ); //@} /// Evaluate branch conditions //@{ /// Evaluate the branch condition - Condition evaluateBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ) ; + Condition evaluateBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ); /// Evaluate loop exit branch - Condition evaluateLoopExitBranch(const SVFBasicBlock* bb, const SVFBasicBlock* succ); + Condition evaluateLoopExitBranch(const SVFBasicBlock* bb, const SVFBasicBlock* succ); /// Return branch condition after evaluating test null like expression Condition evaluateTestNullLikeExpr(const BranchStmt* branchStmt, const SVFBasicBlock* succ); /// Return condition when there is a branch calls program exit @@ -290,27 +286,22 @@ class SaberCondAllocator //@} /// Release memory - void destroy() - { - - } + void destroy() {} /// extract subexpression from a Z3 expression - void extractSubConds(const Condition &condition, NodeBS &support) const; - - - FunToExitBBsMap funToExitBBsMap; ///< map a function to all its basic blocks calling program exit - BBToCondMap bbToCondMap; ///< map a basic block to its path condition starting from root - const SVFGNode* curEvalSVFGNode{}; ///< current llvm value to evaluate branch condition when computing guards - IndexToTermInstMap idToTermInstMap; ///key: z3 expression id, value: instruction - NodeBS negConds; ///bit vector for distinguish neg - std::vector conditionVec; /// vector storing z3expression - static u32_t totalCondNum; /// a counter for fresh condition + void extractSubConds(const Condition& condition, NodeBS& support) const; + + FunToExitBBsMap funToExitBBsMap; ///< map a function to all its basic blocks calling program exit + BBToCondMap bbToCondMap; ///< map a basic block to its path condition starting from root + const SVFGNode* curEvalSVFGNode{}; ///< current llvm value to evaluate branch condition when computing guards + IndexToTermInstMap idToTermInstMap; /// key: z3 expression id, value: instruction + NodeBS negConds; /// bit vector for distinguish neg + std::vector conditionVec; /// vector storing z3expression + static u32_t totalCondNum; /// a counter for fresh condition SVFGNodeToSVFGNodeSetMap removedSUVFEdges; protected: - BBCondMap bbConds; ///< map basic block to its successors/predecessors branch conditions - + BBCondMap bbConds; ///< map basic block to its successors/predecessors branch conditions }; } // End namespace SVF diff --git a/svf/include/SABER/SaberSVFGBuilder.h b/svf/include/SABER/SaberSVFGBuilder.h index 2f47c2dc2..a294c9c11 100644 --- a/svf/include/SABER/SaberSVFGBuilder.h +++ b/svf/include/SABER/SaberSVFGBuilder.h @@ -34,7 +34,6 @@ #include "SVFIR/SVFValue.h" #include "Util/WorkList.h" - namespace SVF { @@ -49,14 +48,14 @@ class SaberSVFGBuilder : public SVFGBuilder typedef FIFOWorkList WorkList; /// Constructor - SaberSVFGBuilder(): SVFGBuilder(true) {} + SaberSVFGBuilder() : SVFGBuilder(true) {} /// Destructor virtual ~SaberSVFGBuilder() {} inline bool isGlobalSVFGNode(const SVFGNode* node) const { - return globSVFGNodes.find(node)!=globSVFGNodes.end(); + return globSVFGNodes.find(node) != globSVFGNodes.end(); } /// Add ActualParmVFGNode @@ -80,7 +79,8 @@ class SaberSVFGBuilder : public SVFGBuilder protected: /// Remove direct value-flow edge to a dereference point for Saber source-sink memory error detection /// for example, given two statements: p = alloc; q = *p, the direct SVFG edge between them is deleted - /// Because those edges only stand for values used at the dereference points but they can not pass the value to other definitions + /// Because those edges only stand for values used at the dereference points but they can not pass the value to + /// other definitions void rmDerefDirSVFGEdges(BVDataPTAImpl* pta); /// Remove Incoming Edge for strong-update (SU) store instruction @@ -97,10 +97,10 @@ class SaberSVFGBuilder : public SVFGBuilder void collectGlobals(BVDataPTAImpl* pta); /// Whether points-to of a PAGNode points-to global variable - bool accessGlobal(BVDataPTAImpl* pta,const PAGNode* pagNode); + bool accessGlobal(BVDataPTAImpl* pta, const PAGNode* pagNode); /// Collect objects along points-to chains - PointsTo& CollectPtsChain(BVDataPTAImpl* pta,NodeID id, NodeToPTSSMap& cachedPtsMap); + PointsTo& CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeToPTSSMap& cachedPtsMap); PointsTo globs; /// Store all global SVFG nodes diff --git a/svf/include/SABER/SrcSnkDDA.h b/svf/include/SABER/SrcSnkDDA.h index 9bbf578af..15eab1175 100644 --- a/svf/include/SABER/SrcSnkDDA.h +++ b/svf/include/SABER/SrcSnkDDA.h @@ -46,7 +46,7 @@ namespace SVF { -typedef GraphReachSolver CFLSrcSnkSolver; +typedef GraphReachSolver CFLSrcSnkSolver; /*! * General source-sink analysis, which serves as a base analysis to be extended for various clients @@ -56,22 +56,22 @@ class SrcSnkDDA : public CFLSrcSnkSolver public: typedef ProgSlice::SVFGNodeSet SVFGNodeSet; - typedef Map SVFGNodeToSliceMap; + typedef Map SVFGNodeToSliceMap; typedef SVFGNodeSet::const_iterator SVFGNodeSetIter; typedef CxtDPItem DPIm; - typedef Set DPImSet; ///< dpitem set - typedef Map SVFGNodeToDPItemsMap; ///< map a SVFGNode to its visited dpitems + typedef Set DPImSet; ///< dpitem set + typedef Map SVFGNodeToDPItemsMap; ///< map a SVFGNode to its visited dpitems typedef Set CallSiteSet; typedef NodeBS SVFGNodeBS; typedef ProgSlice::VFWorkList WorkList; private: - ProgSlice* _curSlice; /// current program slice - SVFGNodeSet sources; /// source nodes - SVFGNodeSet sinks; /// source nodes + ProgSlice* _curSlice; /// current program slice + SVFGNodeSet sources; /// source nodes + SVFGNodeSet sinks; /// source nodes std::unique_ptr saberCondAllocator; - SVFGNodeToDPItemsMap nodeToDPItemsMap; ///< record forward visited dpitems - SVFGNodeSet visitedSet; ///< record backward visited nodes + SVFGNodeToDPItemsMap nodeToDPItemsMap; ///< record forward visited dpitems + SVFGNodeSet visitedSet; ///< record backward visited nodes protected: SaberSVFGBuilder memSSA; @@ -80,7 +80,6 @@ class SrcSnkDDA : public CFLSrcSnkSolver SVFBugReport report; /// Bug Reporter public: - /// Constructor SrcSnkDDA() : _curSlice(nullptr), svfg(nullptr), callgraph(nullptr) { @@ -95,13 +94,13 @@ class SrcSnkDDA : public CFLSrcSnkSolver _curSlice = nullptr; /// the following shared by multiple checkers, thus can not be released. - //if (callgraph != nullptr) - // delete callgraph; - //callgraph = nullptr; + // if (callgraph != nullptr) + // delete callgraph; + // callgraph = nullptr; - //if(pathCondAllocator) - // delete pathCondAllocator; - //pathCondAllocator = nullptr; + // if(pathCondAllocator) + // delete pathCondAllocator; + // pathCondAllocator = nullptr; } /// Start analysis here @@ -186,12 +185,12 @@ class SrcSnkDDA : public CFLSrcSnkSolver bool isSource(const SVFGNode* node) const { - return getSources().find(node)!=getSources().end(); + return getSources().find(node) != getSources().end(); } bool isSink(const SVFGNode* node) const { - return getSinks().find(node)!=getSinks().end(); + return getSinks().find(node) != getSinks().end(); } ///@} @@ -253,7 +252,7 @@ class SrcSnkDDA : public CFLSrcSnkSolver inline void FWProcessCurNode(const DPIm& item) override { const SVFGNode* node = getNode(item.getCurNodeID()); - if(isSink(node)) + if (isSink(node)) { addSinkToCurSlice(node); _curSlice->setPartialReachable(); @@ -265,7 +264,7 @@ class SrcSnkDDA : public CFLSrcSnkSolver inline void BWProcessCurNode(const DPIm& item) override { const SVFGNode* node = getNode(item.getCurNodeID()); - if(isInCurForwardSlice(node)) + if (isInCurForwardSlice(node)) { addToCurBackwardSlice(node); } @@ -279,8 +278,7 @@ class SrcSnkDDA : public CFLSrcSnkSolver inline bool forwardVisited(const SVFGNode* node, const DPIm& item) { SVFGNodeToDPItemsMap::const_iterator it = nodeToDPItemsMap.find(node); - if(it!=nodeToDPItemsMap.end()) - return it->second.find(item)!=it->second.end(); + if (it != nodeToDPItemsMap.end()) return it->second.find(item) != it->second.end(); else return false; } @@ -290,7 +288,7 @@ class SrcSnkDDA : public CFLSrcSnkSolver } inline bool backwardVisited(const SVFGNode* node) { - return visitedSet.find(node)!=visitedSet.end(); + return visitedSet.find(node) != visitedSet.end(); } inline void addBackwardVisited(const SVFGNode* node) { @@ -319,7 +317,6 @@ class SrcSnkDDA : public CFLSrcSnkSolver void annotateSlice(ProgSlice* slice); void printZ3Stat(); //@} - }; } // End namespace SVF diff --git a/svf/include/SABER/SrcSnkSolver.h b/svf/include/SABER/SrcSnkSolver.h index 6a044e8d3..168924d22 100644 --- a/svf/include/SABER/SrcSnkSolver.h +++ b/svf/include/SABER/SrcSnkSolver.h @@ -40,35 +40,29 @@ namespace SVF * Generic CFL solver for demand-driven analysis based on different graphs (e.g. SVFIR, VFG, ThreadVFG) * Extend this class for sophisticated CFL-reachability resolution (e.g. field, flow, path) */ -template -class SrcSnkSolver +template class SrcSnkSolver { public: - ///Define the GTraits and node iterator + /// Define the GTraits and node iterator typedef SVF::GenericGraphTraits GTraits; - typedef typename GTraits::NodeType GNODE; - typedef typename GTraits::EdgeType GEDGE; + typedef typename GTraits::NodeType GNODE; + typedef typename GTraits::EdgeType GEDGE; typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::ChildIteratorType child_iterator; /// Define inverse GTraits and note iterator - typedef SVF::GenericGraphTraits > InvGTraits; + typedef SVF::GenericGraphTraits> InvGTraits; typedef typename InvGTraits::ChildIteratorType inv_child_iterator; /// Define worklist typedef FIFOWorkList WorkList; protected: - /// Constructor - SrcSnkSolver(): _graph(nullptr) - { - } + SrcSnkSolver() : _graph(nullptr) {} /// Destructor - virtual ~SrcSnkSolver() - { - } + virtual ~SrcSnkSolver() {} /// Get/Set graph methods //@{ const inline GraphType graph() const @@ -104,7 +98,7 @@ class SrcSnkSolver child_iterator EE = GTraits::child_end(v); for (; EI != EE; ++EI) { - FWProcessOutgoingEdge(item,*(EI.getCurrent()) ); + FWProcessOutgoingEdge(item, *(EI.getCurrent())); } } } @@ -123,18 +117,14 @@ class SrcSnkSolver inv_child_iterator EE = InvGTraits::child_end(v); for (; EI != EE; ++EI) { - BWProcessIncomingEdge(item,*(EI.getCurrent()) ); + BWProcessIncomingEdge(item, *(EI.getCurrent())); } } } /// Process the DP item //@{ - virtual void FWProcessCurNode(const DPIm&) - { - } - virtual void BWProcessCurNode(const DPIm&) - { - } + virtual void FWProcessCurNode(const DPIm&) {} + virtual void BWProcessCurNode(const DPIm&) {} //@} /// Propagation for the solving, to be implemented in the child class //@{ @@ -172,13 +162,11 @@ class SrcSnkSolver //@} private: - /// Graph GraphType _graph; /// Worklist for resolution WorkList worklist; - }; } // End namespace SVF diff --git a/svf/include/SVFIR/PAGBuilderFromFile.h b/svf/include/SVFIR/PAGBuilderFromFile.h index 8a65608a3..acc7029d6 100644 --- a/svf/include/SVFIR/PAGBuilderFromFile.h +++ b/svf/include/SVFIR/PAGBuilderFromFile.h @@ -44,16 +44,12 @@ class PAGBuilderFromFile private: SVFIR* pag; std::string file; + public: /// Constructor - PAGBuilderFromFile(std::string f) : - pag(SVFIR::getPAG(true)), file(f) - { - } + PAGBuilderFromFile(std::string f) : pag(SVFIR::getPAG(true)), file(f) {} /// Destructor - ~PAGBuilderFromFile() - { - } + ~PAGBuilderFromFile() {} /// Return SVFIR SVFIR* getPAG() const @@ -71,8 +67,7 @@ class PAGBuilderFromFile SVFIR* build(); // Add edges - void addEdge(NodeID nodeSrc, NodeID nodeDst, APOffset offset, - std::string edge); + void addEdge(NodeID nodeSrc, NodeID nodeDst, APOffset offset, std::string edge); }; } // End namespace SVF diff --git a/svf/include/SVFIR/SVFFileSystem.h b/svf/include/SVFIR/SVFFileSystem.h index 6d1e4f0a1..759740500 100644 --- a/svf/include/SVFIR/SVFFileSystem.h +++ b/svf/include/SVFIR/SVFFileSystem.h @@ -29,33 +29,31 @@ #include "Util/cJSON.h" #include -#define ABORT_MSG(reason) \ - do \ - { \ - SVFUtil::errs() << __FILE__ << ':' << __LINE__ << ": " << reason \ - << '\n'; \ - abort(); \ +#define ABORT_MSG(reason) \ + do \ + { \ + SVFUtil::errs() << __FILE__ << ':' << __LINE__ << ": " << reason << '\n'; \ + abort(); \ } while (0) -#define ABORT_IFNOT(condition, reason) \ - do \ - { \ - if (!(condition)) \ - ABORT_MSG(reason); \ +#define ABORT_IFNOT(condition, reason) \ + do \ + { \ + if (!(condition)) ABORT_MSG(reason); \ } while (0) #define SVFIR_DEBUG 1 /* Turn this on if you're debugging SVFWriter */ #if SVFIR_DEBUG -# define ENSURE_NOT_VISITED(graph) \ - do \ - { \ - static std::set visited; \ - bool inserted = visited.insert(graph).second; \ - ABORT_IFNOT(inserted, #graph << " already visited!"); \ +# define ENSURE_NOT_VISITED(graph) \ + do \ + { \ + static std::set visited; \ + bool inserted = visited.insert(graph).second; \ + ABORT_IFNOT(inserted, #graph << " already visited!"); \ } while (0) #else -# define ENSURE_NOT_VISITED(graph) \ - do \ - { \ +# define ENSURE_NOT_VISITED(graph) \ + do \ + { \ } while (0) #endif #define FIELD_NAME_ITEM(field) #field, (field) @@ -64,35 +62,30 @@ #define JSON_KEY(json) JSON_FIELD_OR(json, string, "NULL") #define JSON_CHILD(json) JSON_FIELD_OR(json, child, nullptr) -#define JSON_WRITE_FIELD(root, objptr, field) \ - jsonAddJsonableToObject(root, #field, (objptr)->field) +#define JSON_WRITE_FIELD(root, objptr, field) jsonAddJsonableToObject(root, #field, (objptr)->field) -#define JSON_READ_OBJ_WITH_NAME(json, obj, name) \ - do \ - { \ - ABORT_IFNOT(jsonKeyEquals(json, name), \ - "Expect name '" << name << "', got " << JSON_KEY(json)); \ - SVFIRReader::readJson(json, obj); \ +#define JSON_READ_OBJ_WITH_NAME(json, obj, name) \ + do \ + { \ + ABORT_IFNOT(jsonKeyEquals(json, name), "Expect name '" << name << "', got " << JSON_KEY(json)); \ + SVFIRReader::readJson(json, obj); \ } while (0) -#define JSON_READ_OBJ_WITH_NAME_FWD(json, obj, name) \ - do \ - { \ - JSON_READ_OBJ_WITH_NAME(json, obj, name); \ - json = (json)->next; \ +#define JSON_READ_OBJ_WITH_NAME_FWD(json, obj, name) \ + do \ + { \ + JSON_READ_OBJ_WITH_NAME(json, obj, name); \ + json = (json)->next; \ } while (0) #define JSON_READ_OBJ(json, obj) JSON_READ_OBJ_WITH_NAME(json, obj, #obj) -#define JSON_READ_OBJ_FWD(json, obj) \ - JSON_READ_OBJ_WITH_NAME_FWD(json, obj, #obj) -#define JSON_DEF_READ_FWD(json, type, obj, ...) \ - type obj __VA_ARGS__; \ +#define JSON_READ_OBJ_FWD(json, obj) JSON_READ_OBJ_WITH_NAME_FWD(json, obj, #obj) +#define JSON_DEF_READ_FWD(json, type, obj, ...) \ + type obj __VA_ARGS__; \ JSON_READ_OBJ_FWD(json, obj) -#define JSON_READ_FIELD_FWD(json, objptr, field) \ - JSON_READ_OBJ_WITH_NAME_FWD(json, (objptr)->field, #field) -#define CHECK_JSON_KEY_EQUALS(obj, key) \ - ABORT_IFNOT(jsonKeyEquals(obj, key), \ - "Expect json key: " << key << ", but get " << JSON_KEY(obj)); +#define JSON_READ_FIELD_FWD(json, objptr, field) JSON_READ_OBJ_WITH_NAME_FWD(json, (objptr)->field, #field) +#define CHECK_JSON_KEY_EQUALS(obj, key) \ + ABORT_IFNOT(jsonKeyEquals(obj, key), "Expect json key: " << key << ", but get " << JSON_KEY(obj)); #define CHECK_JSON_KEY(obj) CHECK_JSON_KEY_EQUALS(obj, #obj) namespace SVF @@ -223,8 +216,7 @@ bool jsonAddItemToArray(cJSON* array, cJSON* item); bool jsonAddNumberToObject(cJSON* obj, const char* name, double number); bool jsonAddStringToObject(cJSON* obj, const char* name, const char* str); bool jsonAddStringToObject(cJSON* obj, const char* name, const std::string& s); -#define jsonForEach(field, array) \ - for (const cJSON* field = JSON_CHILD(array); field; field = field->next) +#define jsonForEach(field, array) for (const cJSON* field = JSON_CHILD(array); field; field = field->next) /// @brief Bookkeeping class to keep track of the IDs of objects that doesn't /// have any ID. E.g., SVFValue, XXXEdge. @@ -238,14 +230,12 @@ template class WriterPtrPool public: inline size_t getID(const T* ptr) { - if (!ptr) - return 0; + if (!ptr) return 0; typename decltype(ptrToId)::iterator it; bool inserted; std::tie(it, inserted) = ptrToId.emplace(ptr, 1 + ptrPool.size()); - if (inserted) - ptrPool.push_back(ptr); + if (inserted) ptrPool.push_back(ptr); return it->second; } @@ -535,8 +525,7 @@ class SVFIRWriter cJSON* contentToJson(const StInfo* stInfo); ///@} - template - cJSON* genericNodeToJson(const GenericNode* node) + template cJSON* genericNodeToJson(const GenericNode* node) { cJSON* root = jsonCreateObject(); JSON_WRITE_FIELD(root, node, id); @@ -546,8 +535,7 @@ class SVFIRWriter return root; } - template - cJSON* genericEdgeToJson(const GenericEdge* edge) + template cJSON* genericEdgeToJson(const GenericEdge* edge) { cJSON* root = jsonCreateObject(); JSON_WRITE_FIELD(root, edge, edgeFlag); @@ -557,8 +545,7 @@ class SVFIRWriter } template - cJSON* genericGraphToJson(const GenericGraph* graph, - const std::vector& edgePool) + cJSON* genericGraphToJson(const GenericGraph* graph, const std::vector& edgePool) { cJSON* root = jsonCreateObject(); @@ -619,9 +606,7 @@ class SVFIRWriter return obj; } - template >> - cJSON* toJson(const T& container) + template >> cJSON* toJson(const T& container) { cJSON* array = jsonCreateArray(); for (const auto& item : container) @@ -632,15 +617,13 @@ class SVFIRWriter return array; } - template - bool jsonAddJsonableToObject(cJSON* obj, const char* name, const T& item) + template bool jsonAddJsonableToObject(cJSON* obj, const char* name, const T& item) { cJSON* itemObj = toJson(item); return jsonAddItemToObject(obj, name, itemObj); } - template - bool jsonAddContentToObject(cJSON* obj, const char* name, const T& item) + template bool jsonAddContentToObject(cJSON* obj, const char* name, const T& item) { cJSON* itemObj = contentToJson(item); return jsonAddItemToObject(obj, name, itemObj); @@ -657,15 +640,14 @@ class SVFIRWriter template struct KindBaseHelper { }; -#define KIND_BASE(B, KindGetter) \ - template \ - struct KindBaseHelper::value>> \ - { \ - using type = B; \ - static inline s64_t getKind(T* p) \ - { \ - return {p->KindGetter()}; \ - } \ +#define KIND_BASE(B, KindGetter) \ + template struct KindBaseHelper::value>> \ + { \ + using type = B; \ + static inline s64_t getKind(T* p) \ + { \ + return {p->KindGetter()}; \ + } \ } KIND_BASE(SVFType, getKind); KIND_BASE(SVFValue, getKind); @@ -693,8 +675,7 @@ template class ReaderIDToObjMap /// idObjcreator : (const cJSON*) -> (id, T*) with id set void createObjs(const cJSON* idObjArrayJson, IdObjCreator idObjCreator) { - assert(idMap.empty() && - "idToObjMap should be empty when creating objects"); + assert(idMap.empty() && "idToObjMap should be empty when creating objects"); ABORT_IFNOT(jsonIsArray(idObjArrayJson), "expects an array"); jsonForEach(objJson, idObjArrayJson) @@ -705,8 +686,7 @@ template class ReaderIDToObjMap auto idObj = idObjCreator(objFieldJson); auto pair = std::pair(objFieldJson, idObj.second); bool inserted = idMap.emplace(idObj.first, pair).second; - ABORT_IFNOT(inserted, "ID " << idObj.first << " duplicated in " - << idObjArrayJson->string); + ABORT_IFNOT(inserted, "ID " << idObj.first << " duplicated in " << idObjArrayJson->string); } } @@ -725,8 +705,7 @@ template class ReaderIDToObjMap T* obj = pair.second.second; fillFunc(objFieldJson, obj); - ABORT_IFNOT(!objFieldJson, "json should be consumed by filler, but " - << objFieldJson->string << " left"); + ABORT_IFNOT(!objFieldJson, "json should be consumed by filler, but " << objFieldJson->string << " left"); } } @@ -766,11 +745,9 @@ template class ReaderPtrPool /// @tparam Creator /// @param objArrayJson /// @param creator - template - void createObjs(const cJSON* objArrayJson, Creator creator) + template void createObjs(const cJSON* objArrayJson, Creator creator) { - assert(jsonArray.empty() && - "jsonArray should be empty when creating objects"); + assert(jsonArray.empty() && "jsonArray should be empty when creating objects"); ABORT_IFNOT(jsonIsArray(objArrayJson), "expects an array"); jsonForEach(objJson, objArrayJson) @@ -785,21 +762,18 @@ template class ReaderPtrPool T* getPtr(size_t id) const { - ABORT_IFNOT(id <= ptrPool.size(), - "Invalid ID " << id << ". Max ID = " << ptrPool.size()); + ABORT_IFNOT(id <= ptrPool.size(), "Invalid ID " << id << ". Max ID = " << ptrPool.size()); return id ? ptrPool[id - 1] : nullptr; } template void fillObjs(FillFunc fillFunc) { - assert(jsonArray.size() == ptrPool.size() && - "jsonArray and ptrPool should have same size"); + assert(jsonArray.size() == ptrPool.size() && "jsonArray and ptrPool should have same size"); for (size_t i = 0; i < jsonArray.size(); ++i) { const cJSON*& objFieldJson = jsonArray[i]; fillFunc(objFieldJson, ptrPool[i]); - ABORT_IFNOT(!objFieldJson, "json should be consumed by filler, but " - << objFieldJson->string << " left"); + ABORT_IFNOT(!objFieldJson, "json should be consumed by filler, but " << objFieldJson->string << " left"); } jsonArray.clear(); jsonArray.shrink_to_fit(); @@ -830,8 +804,7 @@ template class GenericGraphReader public: template - void createObjs(const cJSON* graphJson, NodeCreator nodeCreator, - EdgeCreator edgeCreator) + void createObjs(const cJSON* graphJson, NodeCreator nodeCreator, EdgeCreator edgeCreator) { // Read nodeNum const cJSON* nodeNum = graphJson->child; @@ -872,8 +845,7 @@ template class GenericGraphReader return edgePool.getPtr(id); } - template - void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller) + template void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller) { // GenericNode<> contains field `InEdges` and `OutEdges`, which are // ordered set of edges with comparator `GenericEdge::equalGEdge()`, @@ -910,8 +882,7 @@ class SymbolTableInfoReader return memObjMap.getPtr(id); } - template - void createObjs(const cJSON* symTabJson, MemObjCreator memObjCreator) + template void createObjs(const cJSON* symTabJson, MemObjCreator memObjCreator) { assert(!symTabFieldJson && "symTabFieldJson should be empty"); ABORT_IFNOT(jsonIsObject(symTabJson), "symTableJson is not an object?"); @@ -942,8 +913,8 @@ class ICFGReader : public GenericICFGReader public: template - void createObjs(const cJSON* icfgJson, NodeCreator nodeCreator, - EdgeCreator edgeCreator, SVFLoopCreator svfLoopCreator) + void createObjs(const cJSON* icfgJson, NodeCreator nodeCreator, EdgeCreator edgeCreator, + SVFLoopCreator svfLoopCreator) { GenericICFGReader::createObjs(icfgJson, nodeCreator, edgeCreator); @@ -959,8 +930,7 @@ class ICFGReader : public GenericICFGReader } template - void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller, - LoopFiller loopFiller) + void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller, LoopFiller loopFiller) { GenericICFGReader::fillObjs(nodeFiller, edgeFiller); svfLoopPool.fillObjs(loopFiller); @@ -978,16 +948,13 @@ class SVFModuleReader ReaderPtrPool svfValuePool; public: - template - void createObjs(const cJSON* svfModuleJson, SVFTypeCreator typeCreator, - SVFTypeFiller typeFiller, SVFValueCreator valueCreator, - SVFValueFiller valueFiller, StInfoCreator stInfoCreator) + void createObjs(const cJSON* svfModuleJson, SVFTypeCreator typeCreator, SVFTypeFiller typeFiller, + SVFValueCreator valueCreator, SVFValueFiller valueFiller, StInfoCreator stInfoCreator) { assert(!svfModuleFieldJson && "SVFModule Already created?"); - ABORT_IFNOT(jsonIsObject(svfModuleJson), - "svfModuleJson not an JSON object?"); + ABORT_IFNOT(jsonIsObject(svfModuleJson), "svfModuleJson not an JSON object?"); const cJSON* const allSVFType = svfModuleJson->child; CHECK_JSON_KEY(allSVFType); @@ -1058,8 +1025,7 @@ class SVFIRReader return edgeFlag & GenericEdge::EdgeKindMask; } template - static inline void setEdgeFlag(GenericEdge* edge, - typename GenericEdge::GEdgeFlag edgeFlag) + static inline void setEdgeFlag(GenericEdge* edge, typename GenericEdge::GEdgeFlag edgeFlag) { edge->edgeFlag = edgeFlag; } @@ -1075,8 +1041,7 @@ class SVFIRReader static SVFVar* createPAGNode(NodeID id, GNodeK kind); static SVFStmt* createPAGEdge(GEdgeKind kind); - template - static inline auto createEdgeWithFlag(GEdgeFlag flag, EdgeCreator creator) + template static inline auto createEdgeWithFlag(GEdgeFlag flag, EdgeCreator creator) { auto kind = SVFIRReader::applyEdgeMask(flag); auto edge = creator(kind); @@ -1102,9 +1067,9 @@ class SVFIRReader void readJson(const cJSON* obj, SVFStmt*& stmt); // IRGraph Edge void readJson(const cJSON* obj, ICFGNode*& node); // ICFG Node void readJson(const cJSON* obj, ICFGEdge*& edge); // ICFG Edge - void readJson(const cJSON* obj, CHNode*& node); // CHGraph Node - void readJson(const cJSON* obj, CHEdge*& edge); // CHGraph Edge - void readJson(const cJSON* obj, CallSite& cs); // CHGraph's csToClassMap + void readJson(const cJSON* obj, CHNode*& node); // CHGraph Node + void readJson(const cJSON* obj, CHEdge*& edge); // CHGraph Edge + void readJson(const cJSON* obj, CallSite& cs); // CHGraph's csToClassMap void readJson(const cJSON* obj, AccessPath& ap); void readJson(const cJSON* obj, SVFLoop*& loop); @@ -1114,8 +1079,7 @@ class SVFIRReader void readJson(const cJSON* obj, SVFLoopAndDomInfo*& ldInfo); // Only owned by SVFFunction - template - inline void readJson(const cJSON* obj, SparseBitVector& bv) + template inline void readJson(const cJSON* obj, SparseBitVector& bv) { ABORT_IFNOT(jsonIsArray(obj), "SparseBitVector should be an array"); jsonForEach(nObj, obj) @@ -1138,17 +1102,14 @@ class SVFIRReader /// @brief Read a pointer of some child class of /// SVFType/SVFValue/SVFVar/SVFStmt/ICFGNode/ICFGEdge/CHNode/CHEdge - template - inline SVFUtil::void_t> readJson(const cJSON* obj, T*& ptr) + template inline SVFUtil::void_t> readJson(const cJSON* obj, T*& ptr) { // TODO: Can be optimized? KindBaseT* basePtr = ptr; readJson(obj, basePtr); - if (!basePtr) - return; // ptr is nullptr when read + if (!basePtr) return; // ptr is nullptr when read ptr = SVFUtil::dyn_cast(basePtr); - ABORT_IFNOT(ptr, "Cast: " << obj->string << " shouldn't have kind " - << KindBaseHelper::getKind(ptr)); + ABORT_IFNOT(ptr, "Cast: " << obj->string << " shouldn't have kind " << KindBaseHelper::getKind(ptr)); } /// Read a const pointer @@ -1160,16 +1121,14 @@ class SVFIRReader cptr = ptr; } - template - void readJson(const cJSON* obj, std::pair& pair) + template void readJson(const cJSON* obj, std::pair& pair) { auto jpair = jsonUnpackPair(obj); readJson(jpair.first, pair.first); readJson(jpair.second, pair.second); } - template - void readJson(const cJSON* obj, T (&array)[N]) + template void readJson(const cJSON* obj, T (&array)[N]) { static_assert(N > 0, "array size should be greater than 0"); ABORT_IFNOT(jsonIsArray(obj), "array expects an array"); @@ -1177,15 +1136,12 @@ class SVFIRReader jsonForEach(elemJson, obj) { readJson(elemJson, array[i]); - if (++i >= N) - break; + if (++i >= N) break; } ABORT_IFNOT(i == N, "expect array of size " << N); } - template - std::enable_if_t> readJson( - const cJSON* obj, C& container) + template std::enable_if_t> readJson(const cJSON* obj, C& container) { using T = typename C::value_type; assert(container.empty() && "container should be empty"); @@ -1197,8 +1153,7 @@ class SVFIRReader } } - template - std::enable_if_t> readJson(const cJSON* obj, C& map) + template std::enable_if_t> readJson(const cJSON* obj, C& map) { assert(map.empty() && "map should be empty"); ABORT_IFNOT(jsonIsMap(obj), "expects an map (represented by array)"); @@ -1213,8 +1168,7 @@ class SVFIRReader } } - template - std::enable_if_t> readJson(const cJSON* obj, C& set) + template std::enable_if_t> readJson(const cJSON* obj, C& set) { using T = typename C::value_type; assert(set.empty() && "set should be empty"); @@ -1313,16 +1267,14 @@ class SVFIRReader void fill(const cJSON*& fieldJson, SVFArrayType* type); void fill(const cJSON*& fieldJson, SVFOtherType* type); - template - void fill(const cJSON*& fieldJson, GenericNode* node) + template void fill(const cJSON*& fieldJson, GenericNode* node) { // id and nodeKind have already been read. JSON_READ_FIELD_FWD(fieldJson, node, InEdges); JSON_READ_FIELD_FWD(fieldJson, node, OutEdges); } - template - void fill(const cJSON*& fieldJson, GenericEdge* edge) + template void fill(const cJSON*& fieldJson, GenericEdge* edge) { // edgeFlag has already been read. JSON_READ_FIELD_FWD(fieldJson, edge, src); diff --git a/svf/include/SVFIR/SVFIR.h b/svf/include/SVFIR/SVFIR.h index 5f07321d2..7396f767a 100644 --- a/svf/include/SVFIR/SVFIR.h +++ b/svf/include/SVFIR/SVFIR.h @@ -52,54 +52,54 @@ class SVFIR : public IRGraph public: typedef Set CallSiteSet; - typedef OrderedMap CallSiteToFunPtrMap; - typedef Map FunPtrToCallSitesMap; - typedef Map MemObjToFieldsMap; + typedef OrderedMap CallSiteToFunPtrMap; + typedef Map FunPtrToCallSitesMap; + typedef Map MemObjToFieldsMap; typedef std::vector SVFStmtList; typedef std::vector SVFVarList; - typedef Map PHINodeMap; - typedef Map FunToArgsListMap; - typedef Map CSToArgsListMap; - typedef Map CSToRetMap; - typedef Map FunToRetMap; - typedef Map FunToPAGEdgeSetMap; - typedef Map ICFGNode2SVFStmtsMap; + typedef Map PHINodeMap; + typedef Map FunToArgsListMap; + typedef Map CSToArgsListMap; + typedef Map CSToRetMap; + typedef Map FunToRetMap; + typedef Map FunToPAGEdgeSetMap; + typedef Map ICFGNode2SVFStmtsMap; typedef Map NodeToNodeMap; typedef std::pair NodeOffset; typedef std::pair NodeAccessPath; - typedef Map NodeOffsetMap; - typedef Map NodeAccessPathMap; + typedef Map NodeOffsetMap; + typedef Map NodeAccessPathMap; typedef Map GepValueVarMap; typedef std::pair> SVFTypeLocSetsPair; typedef Map TypeLocSetsMap; - typedef Map NodePairSetMap; + typedef Map NodePairSetMap; private: /// ValueNodes - This map indicates the Node that a particular SVFValue* is /// represented by. This contains entries for all pointers. - ICFGNode2SVFStmtsMap icfgNode2SVFStmtsMap; ///< Map an ICFGNode to its SVFStmts - ICFGNode2SVFStmtsMap icfgNode2PTASVFStmtsMap; ///< Map an ICFGNode to its PointerAnalysis related SVFStmts - GepValueVarMap GepValObjMap; ///< Map a pair to a gep value node id - TypeLocSetsMap typeLocSetsMap; ///< Map an arg to its base SVFType* and all its field location sets - NodeOffsetMap GepObjVarMap; ///< Map a pair to a gep obj node id - MemObjToFieldsMap memToFieldsMap; ///< Map a mem object id to all its fields - SVFStmtSet globSVFStmtSet; ///< Global PAGEdges without control flow information - PHINodeMap phiNodeMap; ///< A set of phi copy edges - FunToArgsListMap funArgsListMap; ///< Map a function to a list of all its formal parameters - CSToArgsListMap callSiteArgsListMap; ///< Map a callsite to a list of all its actual parameters - CSToRetMap callSiteRetMap; ///< Map a callsite to its callsite returns PAGNodes - FunToRetMap funRetMap; ///< Map a function to its unique function return PAGNodes - CallSiteToFunPtrMap indCallSiteToFunPtrMap; ///< Map an indirect callsite to its function pointer - FunPtrToCallSitesMap funPtrToCallSitesMap; ///< Map a function pointer to the callsites where it is used + ICFGNode2SVFStmtsMap icfgNode2SVFStmtsMap; ///< Map an ICFGNode to its SVFStmts + ICFGNode2SVFStmtsMap icfgNode2PTASVFStmtsMap; ///< Map an ICFGNode to its PointerAnalysis related SVFStmts + GepValueVarMap GepValObjMap; ///< Map a pair to a gep value node id + TypeLocSetsMap typeLocSetsMap; ///< Map an arg to its base SVFType* and all its field location sets + NodeOffsetMap GepObjVarMap; ///< Map a pair to a gep obj node id + MemObjToFieldsMap memToFieldsMap; ///< Map a mem object id to all its fields + SVFStmtSet globSVFStmtSet; ///< Global PAGEdges without control flow information + PHINodeMap phiNodeMap; ///< A set of phi copy edges + FunToArgsListMap funArgsListMap; ///< Map a function to a list of all its formal parameters + CSToArgsListMap callSiteArgsListMap; ///< Map a callsite to a list of all its actual parameters + CSToRetMap callSiteRetMap; ///< Map a callsite to its callsite returns PAGNodes + FunToRetMap funRetMap; ///< Map a function to its unique function return PAGNodes + CallSiteToFunPtrMap indCallSiteToFunPtrMap; ///< Map an indirect callsite to its function pointer + FunPtrToCallSitesMap funPtrToCallSitesMap; ///< Map a function pointer to the callsites where it is used /// Valid pointers for pointer analysis resolution connected by SVFIR edges (constraints) /// this set of candidate pointers can change during pointer resolution (e.g. adding new object nodes) OrderedNodeSet candidatePointers; - SVFModule* svfModule; /// SVF Module - ICFG* icfg; // ICFG - CommonCHGraph* chgraph; // class hierarchy graph + SVFModule* svfModule; /// SVF Module + ICFG* icfg; // ICFG + CommonCHGraph* chgraph; // class hierarchy graph CallSiteSet callSiteSet; /// all the callsites of a program - static std::unique_ptr pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once. + static std::unique_ptr pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once. /// Constructor SVFIR(bool buildFromFile); @@ -108,7 +108,6 @@ class SVFIR : public IRGraph void destroy(); public: - /// Singleton design here to make sure we only have one instance during any analysis //@{ static inline SVFIR* getPAG(bool buildFromFile = false) @@ -169,7 +168,7 @@ class SVFIR : public IRGraph } inline ICFG* getICFG() const { - assert(icfg->totalICFGNode>0 && "empty ICFG! Build SVF IR first!"); + assert(icfg->totalICFGNode > 0 && "empty ICFG! Build SVF IR first!"); return icfg; } /// Set/Get CHG @@ -201,8 +200,7 @@ class SVFIR : public IRGraph } inline bool hasPTASVFStmtList(const ICFGNode* inst) const { - return icfgNode2PTASVFStmtsMap.find(inst) != - icfgNode2PTASVFStmtsMap.end(); + return icfgNode2PTASVFStmtsMap.find(inst) != icfgNode2PTASVFStmtsMap.end(); } /// Given an instruction, get all its PAGEdges inline SVFStmtList& getSVFStmtList(const ICFGNode* inst) @@ -219,13 +217,12 @@ class SVFIR : public IRGraph { edge->setICFGNode(inst); icfgNode2SVFStmtsMap[inst].push_back(edge); - if (edge->isPTAEdge()) - icfgNode2PTASVFStmtsMap[inst].push_back(edge); + if (edge->isPTAEdge()) icfgNode2PTASVFStmtsMap[inst].push_back(edge); } /// Add a base SVFType* and all its field location sets to an arg NodeId inline void addToTypeLocSetsMap(NodeID argId, SVFTypeLocSetsPair& locSets) { - typeLocSetsMap[argId]=locSets; + typeLocSetsMap[argId] = locSets; } /// Given an arg NodeId, get its base SVFType* and all its field location sets inline SVFTypeLocSetsPair& getTypeLocSetsMap(NodeID argId) @@ -259,7 +256,7 @@ class SVFIR : public IRGraph return funArgsListMap; } /// Get function arguments list - inline const SVFVarList& getFunArgsList(const SVFFunction* func) const + inline const SVFVarList& getFunArgsList(const SVFFunction* func) const { FunToArgsListMap::const_iterator it = funArgsListMap.find(func); assert(it != funArgsListMap.end() && "this function doesn't have arguments"); @@ -304,7 +301,7 @@ class SVFIR : public IRGraph return funRetMap; } /// Get function return list - inline const SVFVar* getFunRet(const SVFFunction* func) const + inline const SVFVar* getFunRet(const SVFFunction* func) const { FunToRetMap::const_iterator it = funRetMap.find(func); assert(it != funRetMap.end() && "this function doesn't have return"); @@ -328,9 +325,9 @@ class SVFIR : public IRGraph } //@} - /// Due to constraint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when creating GepValVar. - NodeID getGepValVar(const SVFValue* curInst, NodeID base, - const AccessPath& ap) const; + /// Due to constraint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when + /// creating GepValVar. + NodeID getGepValVar(const SVFValue* curInst, NodeID base, const AccessPath& ap) const; /// Add/get indirect callsites //@{ @@ -341,13 +338,13 @@ class SVFIR : public IRGraph inline NodeID getFunPtr(const CallICFGNode* cs) const { CallSiteToFunPtrMap::const_iterator it = indCallSiteToFunPtrMap.find(cs); - assert(it!=indCallSiteToFunPtrMap.end() && "indirect callsite not have a function pointer?"); + assert(it != indCallSiteToFunPtrMap.end() && "indirect callsite not have a function pointer?"); return it->second; } inline const CallSiteSet& getIndCallSites(NodeID funPtr) const { FunPtrToCallSitesMap::const_iterator it = funPtrToCallSitesMap.find(funPtr); - assert(it!=funPtrToCallSitesMap.end() && "function pointer not used at any indirect callsite?"); + assert(it != funPtrToCallSitesMap.end() && "function pointer not used at any indirect callsite?"); return it->second; } inline bool isIndirectCallSites(const CallICFGNode* cs) const @@ -382,12 +379,11 @@ class SVFIR : public IRGraph inline const MemObj* getObject(NodeID id) const { const SVFVar* node = getGNode(id); - if (const ObjVar* objPN = SVFUtil::dyn_cast(node)) - return getObject(objPN); + if (const ObjVar* objPN = SVFUtil::dyn_cast(node)) return getObject(objPN); else return nullptr; } - inline const MemObj*getObject(const ObjVar* node) const + inline const MemObj* getObject(const ObjVar* node) const { return node->getMemObj(); } @@ -396,7 +392,7 @@ class SVFIR : public IRGraph /// Get a field SVFIR Object node according to base mem obj and offset NodeID getGepObjVar(const MemObj* obj, const APOffset& ap); /// Get a field obj SVFIR node according to a mem obj and a given offset - NodeID getGepObjVar(NodeID id, const APOffset& ap) ; + NodeID getGepObjVar(NodeID id, const APOffset& ap); /// Get a field-insensitive obj SVFIR node according to a mem obj //@{ inline NodeID getFIObjVar(const MemObj* obj) const @@ -431,8 +427,7 @@ class SVFIR : public IRGraph { const MemObj* obj = getObject(id); assert(obj && "not an object node?"); - return SymbolTableInfo::isConstantObj(id) || - obj->isConstDataOrConstGlobal(); + return SymbolTableInfo::isConstantObj(id) || obj->isConstDataOrConstGlobal(); } //@} @@ -477,14 +472,14 @@ class SVFIR : public IRGraph void print(); private: - /// Map a SVFStatement type to a set of corresponding SVF statements inline void addToStmt2TypeMap(SVFStmt* edge) { bool added = KindToSVFStmtSetMap[edge->getEdgeKind()].insert(edge).second; (void)added; // Suppress warning of unused variable under release build assert(added && "duplicated edge, not added!!!"); - /// this is a pointer-related SVFStmt if (1) both RHS and LHS are pointers or (2) this an int2ptr statment, i.e., LHS = int2ptr RHS + /// this is a pointer-related SVFStmt if (1) both RHS and LHS are pointers or (2) this an int2ptr statment, + /// i.e., LHS = int2ptr RHS if (edge->isPTAEdge() || (SVFUtil::isa(edge) && SVFUtil::cast(edge)->isInt2Ptr())) { totalPTAPAGEdge++; @@ -508,22 +503,22 @@ class SVFIR : public IRGraph funRetMap[fun] = ret; } /// Add callsite arguments - inline void addCallSiteArgs(CallICFGNode* callBlockNode,const SVFVar* arg) + inline void addCallSiteArgs(CallICFGNode* callBlockNode, const SVFVar* arg) { callBlockNode->addActualParms(arg); callSiteArgsListMap[callBlockNode].push_back(arg); } /// Add callsite returns - inline void addCallSiteRets(RetICFGNode* retBlockNode,const SVFVar* arg) + inline void addCallSiteRets(RetICFGNode* retBlockNode, const SVFVar* arg) { retBlockNode->addActualRet(arg); - callSiteRetMap[retBlockNode]= arg; + callSiteRetMap[retBlockNode] = arg; } /// Add indirect callsites - inline void addIndirectCallsites(const CallICFGNode* cs,NodeID funPtr) + inline void addIndirectCallsites(const CallICFGNode* cs, NodeID funPtr) { bool added = indCallSiteToFunPtrMap.emplace(cs, funPtr).second; - (void) added; + (void)added; funPtrToCallSitesMap[funPtr].insert(cs); assert(added && "adding the same indirect callsite twice?"); } @@ -533,7 +528,7 @@ class SVFIR : public IRGraph /// Add a value (pointer) node inline NodeID addValNode(const SVFValue* val, NodeID i) { - SVFVar *node = new ValVar(val,i); + SVFVar* node = new ValVar(val, i); return addValNode(val, node, i); } /// Add a memory obj node @@ -546,18 +541,19 @@ class SVFIR : public IRGraph /// Add a unique return node for a procedure inline NodeID addRetNode(const SVFFunction* val, NodeID i) { - SVFVar *node = new RetPN(val,i); + SVFVar* node = new RetPN(val, i); return addRetNode(val, node, i); } /// Add a unique vararg node for a procedure inline NodeID addVarargNode(const SVFFunction* val, NodeID i) { - SVFVar *node = new VarArgPN(val,i); - return addNode(node,i); + SVFVar* node = new VarArgPN(val, i); + return addNode(node, i); } /// Add a temp field value node, this method can only invoked by getGepValVar - NodeID addGepValNode(const SVFValue* curInst,const SVFValue* val, const AccessPath& ap, NodeID i, const SVFType* type); + NodeID addGepValNode(const SVFValue* curInst, const SVFValue* val, const AccessPath& ap, NodeID i, + const SVFType* type); /// Add a field obj node, this method can only invoked by getGepObjVar NodeID addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId); /// Add a field-insensitive node, this method can only invoked by getFIGepObjNode @@ -573,23 +569,19 @@ class SVFIR : public IRGraph inline NodeID addDummyObjNode(NodeID i, const SVFType* type) { const MemObj* mem = addDummyMemObj(i, type); - return addObjNode(nullptr, new DummyObjVar(i,mem), i); + return addObjNode(nullptr, new DummyObjVar(i, mem), i); } inline const MemObj* addDummyMemObj(NodeID i, const SVFType* type) { - return getSymbolInfo()->createDummyObj(i,type); + return getSymbolInfo()->createDummyObj(i, type); } inline NodeID addBlackholeObjNode() { - return addObjNode( - nullptr, new DummyObjVar(getBlackHoleNode(), getBlackHoleObj()), - getBlackHoleNode()); + return addObjNode(nullptr, new DummyObjVar(getBlackHoleNode(), getBlackHoleObj()), getBlackHoleNode()); } inline NodeID addConstantObjNode() { - return addObjNode(nullptr, - new DummyObjVar(getConstantNode(), getConstantObj()), - getConstantNode()); + return addObjNode(nullptr, new DummyObjVar(getConstantNode(), getConstantObj()), getConstantNode()); } inline NodeID addBlackholePtrNode() { @@ -598,30 +590,28 @@ class SVFIR : public IRGraph //@} /// Add a value (pointer) node - inline NodeID addValNode(const SVFValue*, SVFVar *node, NodeID i) + inline NodeID addValNode(const SVFValue*, SVFVar* node, NodeID i) { - assert(hasGNode(i) == false && - "This NodeID clashes here. Please check NodeIDAllocator. Switch " - "Strategy::DBUG to SEQ or DENSE"); + assert(hasGNode(i) == false && "This NodeID clashes here. Please check NodeIDAllocator. Switch " + "Strategy::DBUG to SEQ or DENSE"); return addNode(node, i); } /// Add a memory obj node - inline NodeID addObjNode(const SVFValue*, SVFVar *node, NodeID i) + inline NodeID addObjNode(const SVFValue*, SVFVar* node, NodeID i) { - assert(hasGNode(i) == false && - "This NodeID clashes here. Please check NodeIDAllocator. Switch " - "Strategy::DBUG to SEQ or DENSE"); + assert(hasGNode(i) == false && "This NodeID clashes here. Please check NodeIDAllocator. Switch " + "Strategy::DBUG to SEQ or DENSE"); return addNode(node, i); } /// Add a unique return node for a procedure - inline NodeID addRetNode(const SVFFunction*, SVFVar *node, NodeID i) + inline NodeID addRetNode(const SVFFunction*, SVFVar* node, NodeID i) { - return addNode(node,i); + return addNode(node, i); } /// Add a unique vararg node for a procedure - inline NodeID addVarargNode(const SVFFunction*, SVFVar *node, NodeID i) + inline NodeID addVarargNode(const SVFFunction*, SVFVar* node, NodeID i) { - return addNode(node,i); + return addNode(node, i); } /// Add global PAGEdges (not in a procedure) @@ -642,42 +632,35 @@ class SVFIR : public IRGraph CopyStmt* addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type); /// Add phi node information - PhiStmt* addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred); + PhiStmt* addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred); /// Add SelectStmt - SelectStmt* addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond); + SelectStmt* addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond); /// Add Copy edge CmpStmt* addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predict); /// Add Copy edge - BinaryOPStmt* addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, - u32_t opcode); + BinaryOPStmt* addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, u32_t opcode); /// Add Unary edge UnaryOPStmt* addUnaryOPStmt(NodeID src, NodeID dst, u32_t opcode); /// Add BranchStmt - BranchStmt* addBranchStmt(NodeID br, NodeID cond, - const BranchStmt::SuccAndCondPairVec& succs); + BranchStmt* addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec& succs); /// Add Load edge LoadStmt* addLoadStmt(NodeID src, NodeID dst); /// Add Store edge StoreStmt* addStoreStmt(NodeID src, NodeID dst, const IntraICFGNode* val); /// Add Call edge - CallPE* addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs, - const FunEntryICFGNode* entry); + CallPE* addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry); /// Add Return edge - RetPE* addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs, - const FunExitICFGNode* exit); + RetPE* addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit); /// Add Gep edge - GepStmt* addGepStmt(NodeID src, NodeID dst, const AccessPath& ap, - bool constGep); + GepStmt* addGepStmt(NodeID src, NodeID dst, const AccessPath& ap, bool constGep); /// Add Offset(Gep) edge GepStmt* addNormalGepStmt(NodeID src, NodeID dst, const AccessPath& ap); /// Add Variant(Gep) edge GepStmt* addVariantGepStmt(NodeID src, NodeID dst, const AccessPath& ap); /// Add Thread fork edge for parameter passing - TDForkPE* addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs, - const FunEntryICFGNode* entry); + TDForkPE* addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunEntryICFGNode* entry); /// Add Thread join edge for parameter passing - TDJoinPE* addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs, - const FunExitICFGNode* exit); + TDJoinPE* addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs, const FunExitICFGNode* exit); //@} /// Set a pointer points-to black hole (e.g. int2ptr) @@ -688,6 +671,4 @@ typedef SVFIR PAG; } // End namespace SVF - - #endif /* INCLUDE_SVFIR_H_ */ diff --git a/svf/include/SVFIR/SVFModule.h b/svf/include/SVFIR/SVFModule.h index 60827032f..771477a68 100644 --- a/svf/include/SVFIR/SVFModule.h +++ b/svf/include/SVFIR/SVFModule.h @@ -203,8 +203,7 @@ class SVFModule { if (pagReadFromTxt.empty()) { - assert(!moduleIdentifier.empty() && - "No module found! Reading from a file other than LLVM-IR?"); + assert(!moduleIdentifier.empty() && "No module found! Reading from a file other than LLVM-IR?"); return moduleIdentifier; } else diff --git a/svf/include/SVFIR/SVFStatements.h b/svf/include/SVFIR/SVFStatements.h index 247e0f280..fee8326ce 100644 --- a/svf/include/SVFIR/SVFStatements.h +++ b/svf/include/SVFIR/SVFStatements.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * SVFStatements.h * @@ -85,10 +84,7 @@ class SVFStmt : public GenericPAGEdgeTy protected: /// Private constructor for reading SVFIR from file without side-effect - SVFStmt(GEdgeFlag k) - : GenericPAGEdgeTy({}, {}, k), value{}, basicBlock{}, icfgNode{} - { - } + SVFStmt(GEdgeFlag k) : GenericPAGEdgeTy({}, {}, k), value{}, basicBlock{}, icfgNode{} {} public: static u32_t totalEdgeNum; ///< Total edge number @@ -106,20 +102,13 @@ class SVFStmt : public GenericPAGEdgeTy } static inline bool classof(const GenericPAGEdgeTy* edge) { - return edge->getEdgeKind() == SVFStmt::Addr || - edge->getEdgeKind() == SVFStmt::Copy || - edge->getEdgeKind() == SVFStmt::Store || - edge->getEdgeKind() == SVFStmt::Load || - edge->getEdgeKind() == SVFStmt::Call || - edge->getEdgeKind() == SVFStmt::Ret || - edge->getEdgeKind() == SVFStmt::Gep || - edge->getEdgeKind() == SVFStmt::Phi || - edge->getEdgeKind() == SVFStmt::Select || - edge->getEdgeKind() == SVFStmt::Cmp || - edge->getEdgeKind() == SVFStmt::BinaryOp || - edge->getEdgeKind() == SVFStmt::UnaryOp || - edge->getEdgeKind() == SVFStmt::Branch || - edge->getEdgeKind() == SVFStmt::ThreadFork || + return edge->getEdgeKind() == SVFStmt::Addr || edge->getEdgeKind() == SVFStmt::Copy || + edge->getEdgeKind() == SVFStmt::Store || edge->getEdgeKind() == SVFStmt::Load || + edge->getEdgeKind() == SVFStmt::Call || edge->getEdgeKind() == SVFStmt::Ret || + edge->getEdgeKind() == SVFStmt::Gep || edge->getEdgeKind() == SVFStmt::Phi || + edge->getEdgeKind() == SVFStmt::Select || edge->getEdgeKind() == SVFStmt::Cmp || + edge->getEdgeKind() == SVFStmt::BinaryOp || edge->getEdgeKind() == SVFStmt::UnaryOp || + edge->getEdgeKind() == SVFStmt::Branch || edge->getEdgeKind() == SVFStmt::ThreadFork || edge->getEdgeKind() == SVFStmt::ThreadJoin; } ///@} @@ -136,8 +125,7 @@ class SVFStmt : public GenericPAGEdgeTy //@{ inline const SVFInstruction* getInst() const { - if (const SVFInstruction* i = SVFUtil::dyn_cast(value)) - return i; + if (const SVFInstruction* i = SVFUtil::dyn_cast(value)) return i; return nullptr; } inline void setValue(const SVFValue* val) @@ -168,36 +156,30 @@ class SVFStmt : public GenericPAGEdgeTy /// Compute the unique edgeFlag value from edge kind and second variable /// operand for MultiOpndStmt. - static inline GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, - const SVFVar* var) + static inline GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, const SVFVar* var) { auto it_inserted = var2LabelMap.emplace(var, multiOpndLabelCounter); - if (it_inserted.second) - ++multiOpndLabelCounter; + if (it_inserted.second) ++multiOpndLabelCounter; u64_t label = it_inserted.first->second; return (label << EdgeKindMaskBits) | k; } /// Compute the unique edgeFlag value from edge kind and call site /// Instruction. - static inline GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, - const ICFGNode* cs) + static inline GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode* cs) { auto it_inserted = inst2LabelMap.emplace(cs, callEdgeLabelCounter); - if (it_inserted.second) - ++callEdgeLabelCounter; + if (it_inserted.second) ++callEdgeLabelCounter; u64_t label = it_inserted.first->second; return (label << EdgeKindMaskBits) | k; } /// Compute the unique edgeFlag value from edge kind and store Instruction. /// Two store instructions may share the same StorePAGEdge - static inline GEdgeFlag makeEdgeFlagWithStoreInst(GEdgeKind k, - const ICFGNode* store) + static inline GEdgeFlag makeEdgeFlagWithStoreInst(GEdgeKind k, const ICFGNode* store) { auto it_inserted = inst2LabelMap.emplace(store, storeEdgeLabelCounter); - if (it_inserted.second) - ++storeEdgeLabelCounter; + if (it_inserted.second) ++storeEdgeLabelCounter; u64_t label = it_inserted.first->second; return (label << EdgeKindMaskBits) | k; } @@ -214,7 +196,7 @@ class SVFStmt : public GenericPAGEdgeTy } //@} - typedef GenericNode::GEdgeSetTy SVFStmtSetTy; + typedef GenericNode::GEdgeSetTy SVFStmtSetTy; typedef Map PAGEdgeToSetMapTy; typedef PAGEdgeToSetMapTy KindToSVFStmtMapTy; typedef SVFStmtSetTy PAGEdgeSetTy; @@ -223,10 +205,10 @@ class SVFStmt : public GenericPAGEdgeTy typedef Map Inst2LabelMap; typedef Map Var2LabelMap; static Inst2LabelMap inst2LabelMap; ///< Call site Instruction to label map - static Var2LabelMap var2LabelMap; ///< Second operand of MultiOpndStmt to label map + static Var2LabelMap var2LabelMap; ///< Second operand of MultiOpndStmt to label map static u64_t callEdgeLabelCounter; ///< Call site Instruction counter - static u64_t storeEdgeLabelCounter; ///< Store Instruction counter - static u64_t multiOpndLabelCounter; ///< MultiOpndStmt counter + static u64_t storeEdgeLabelCounter; ///< Store Instruction counter + static u64_t multiOpndLabelCounter; ///< MultiOpndStmt counter }; /* @@ -241,12 +223,12 @@ class AssignStmt : public SVFStmt private: AssignStmt(); ///< place holder - AssignStmt(const AssignStmt &); ///< place holder - void operator=(const AssignStmt &); ///< place holder - SVFVar* getSrcNode(); ///< not allowed, use getRHSVar() instead - SVFVar* getDstNode(); ///< not allowed, use getLHSVar() instead - NodeID getSrcID(); ///< not allowed, use getRHSVarID() instead - NodeID getDstID(); ///< not allowed, use getLHSVarID() instead + AssignStmt(const AssignStmt&); ///< place holder + void operator=(const AssignStmt&); ///< place holder + SVFVar* getSrcNode(); ///< not allowed, use getRHSVar() instead + SVFVar* getDstNode(); ///< not allowed, use getLHSVar() instead + NodeID getSrcID(); ///< not allowed, use getRHSVarID() instead + NodeID getDstID(); ///< not allowed, use getLHSVarID() instead protected: /// constructor @@ -263,26 +245,18 @@ class AssignStmt : public SVFStmt } static inline bool classof(const SVFStmt* edge) { - return edge->getEdgeKind() == SVFStmt::Addr || - edge->getEdgeKind() == SVFStmt::Copy || - edge->getEdgeKind() == SVFStmt::Store || - edge->getEdgeKind() == SVFStmt::Load || - edge->getEdgeKind() == SVFStmt::Call || - edge->getEdgeKind() == SVFStmt::Ret || - edge->getEdgeKind() == SVFStmt::Gep || - edge->getEdgeKind() == SVFStmt::ThreadFork || + return edge->getEdgeKind() == SVFStmt::Addr || edge->getEdgeKind() == SVFStmt::Copy || + edge->getEdgeKind() == SVFStmt::Store || edge->getEdgeKind() == SVFStmt::Load || + edge->getEdgeKind() == SVFStmt::Call || edge->getEdgeKind() == SVFStmt::Ret || + edge->getEdgeKind() == SVFStmt::Gep || edge->getEdgeKind() == SVFStmt::ThreadFork || edge->getEdgeKind() == SVFStmt::ThreadJoin; } static inline bool classof(const GenericPAGEdgeTy* edge) { - return edge->getEdgeKind() == SVFStmt::Addr || - edge->getEdgeKind() == SVFStmt::Copy || - edge->getEdgeKind() == SVFStmt::Store || - edge->getEdgeKind() == SVFStmt::Load || - edge->getEdgeKind() == SVFStmt::Call || - edge->getEdgeKind() == SVFStmt::Ret || - edge->getEdgeKind() == SVFStmt::Gep || - edge->getEdgeKind() == SVFStmt::ThreadFork || + return edge->getEdgeKind() == SVFStmt::Addr || edge->getEdgeKind() == SVFStmt::Copy || + edge->getEdgeKind() == SVFStmt::Store || edge->getEdgeKind() == SVFStmt::Load || + edge->getEdgeKind() == SVFStmt::Call || edge->getEdgeKind() == SVFStmt::Ret || + edge->getEdgeKind() == SVFStmt::Gep || edge->getEdgeKind() == SVFStmt::ThreadFork || edge->getEdgeKind() == SVFStmt::ThreadJoin; } //@} @@ -310,7 +284,7 @@ class AssignStmt : public SVFStmt /*! * Address statement (memory allocations) */ -class AddrStmt: public AssignStmt +class AddrStmt : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -321,7 +295,7 @@ class AddrStmt: public AssignStmt AddrStmt(const AddrStmt&); ///< place holder void operator=(const AddrStmt&); ///< place holder - std::vector arrSize; ///< Array size of the allocated memory + std::vector arrSize; ///< Array size of the allocated memory public: /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -345,26 +319,26 @@ class AddrStmt: public AssignStmt virtual const std::string toString() const override; - inline void addArrSize(SVFValue* size) //TODO:addSizeVar + inline void addArrSize(SVFValue* size) // TODO:addSizeVar { arrSize.push_back(size); } ///< get array size of the allocated memory - inline const std::vector& getArrSize() const //TODO:getSizeVars + inline const std::vector& getArrSize() const // TODO:getSizeVars { return arrSize; } - }; /*! * Copy statements (simple assignment and casting) */ -class CopyStmt: public AssignStmt +class CopyStmt : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; + private: /// Constructs empty CopyStmt (for SVFIRReader/serialization) CopyStmt() : AssignStmt(SVFStmt::Copy) {} @@ -373,18 +347,18 @@ class CopyStmt: public AssignStmt public: enum CopyKind { - COPYVAL, // Value copies (default one) - ZEXT, // Zero extend integers - SEXT, // Sign extend integers - BITCAST, // Type cast - TRUNC, // Truncate integers - FPTRUNC, // Truncate floating point - FPTOUI, // floating point -> UInt - FPTOSI, // floating point -> SInt - UITOFP, // UInt -> floating point - SITOFP, // SInt -> floating point - INTTOPTR, // Integer -> Pointer - PTRTOINT // Pointer -> Integer + COPYVAL, // Value copies (default one) + ZEXT, // Zero extend integers + SEXT, // Sign extend integers + BITCAST, // Type cast + TRUNC, // Truncate integers + FPTRUNC, // Truncate floating point + FPTOUI, // floating point -> UInt + FPTOSI, // floating point -> SInt + UITOFP, // UInt -> floating point + SITOFP, // SInt -> floating point + INTTOPTR, // Integer -> Pointer + PTRTOINT // Pointer -> Integer }; /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ @@ -442,6 +416,7 @@ class CopyStmt: public AssignStmt CopyStmt(SVFVar* s, SVFVar* d, CopyKind k) : AssignStmt(s, d, SVFStmt::Copy), copyKind(k) {} virtual const std::string toString() const override; + private: u32_t copyKind; }; @@ -449,7 +424,7 @@ class CopyStmt: public AssignStmt /*! * Store statement */ -class StoreStmt: public AssignStmt +class StoreStmt : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -486,14 +461,14 @@ class StoreStmt: public AssignStmt /*! * Load statement */ -class LoadStmt: public AssignStmt +class LoadStmt : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; private: /// Constructs empty LoadStmt (for SVFIRReader/serialization) - LoadStmt(): AssignStmt(SVFStmt::Load) {} + LoadStmt() : AssignStmt(SVFStmt::Load) {} LoadStmt(const LoadStmt&); ///< place holder void operator=(const LoadStmt&); ///< place holder @@ -523,7 +498,7 @@ class LoadStmt: public AssignStmt /*! * Gep statement for struct field access, array access and pointer arithmetic */ -class GepStmt: public AssignStmt +class GepStmt : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -531,11 +506,12 @@ class GepStmt: public AssignStmt private: /// Constructs empty GepStmt (for SVFIRReader/serialization) GepStmt() : AssignStmt(SVFStmt::Gep) {} - GepStmt(const GepStmt &); ///< place holder - void operator=(const GepStmt &); ///< place holder + GepStmt(const GepStmt&); ///< place holder + void operator=(const GepStmt&); ///< place holder - AccessPath ap; ///< Access path of the GEP edge - bool variantField; ///< Gep statement with a variant field index (pointer arithmetic) for struct field access (e.g., p = &(q + f), where f is a variable) + AccessPath ap; ///< Access path of the GEP edge + bool variantField; ///< Gep statement with a variant field index (pointer arithmetic) for struct field access (e.g., + ///< p = &(q + f), where f is a variable) public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ @@ -545,11 +521,11 @@ class GepStmt: public AssignStmt } static inline bool classof(const SVFStmt* edge) { - return edge->getEdgeKind() == SVFStmt::Gep; + return edge->getEdgeKind() == SVFStmt::Gep; } static inline bool classof(const GenericPAGEdgeTy* edge) { - return edge->getEdgeKind() == SVFStmt::Gep; + return edge->getEdgeKind() == SVFStmt::Gep; } //@} @@ -585,7 +561,8 @@ class GepStmt: public AssignStmt /// Field index of the gep statement if it access the field of a struct inline APOffset getConstantStructFldIdx() const { - assert(isVariantFieldGep()==false && "Can't retrieve the AccessPath if using a variable field index (pointer arithmetic) for struct field access "); + assert(isVariantFieldGep() == false && "Can't retrieve the AccessPath if using a variable field index (pointer " + "arithmetic) for struct field access "); return getAccessPath().getConstantStructFldIdx(); } /// Gep statement with a variant field index (pointer arithmetic) for struct field access @@ -601,14 +578,12 @@ class GepStmt: public AssignStmt } virtual const std::string toString() const; - }; - /*! * Call */ -class CallPE: public AssignStmt +class CallPE : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -632,19 +607,16 @@ class CallPE: public AssignStmt } static inline bool classof(const SVFStmt* edge) { - return edge->getEdgeKind() == SVFStmt::Call || - edge->getEdgeKind() == SVFStmt::ThreadFork; + return edge->getEdgeKind() == SVFStmt::Call || edge->getEdgeKind() == SVFStmt::ThreadFork; } static inline bool classof(const GenericPAGEdgeTy* edge) { - return edge->getEdgeKind() == SVFStmt::Call || - edge->getEdgeKind() == SVFStmt::ThreadFork; + return edge->getEdgeKind() == SVFStmt::Call || edge->getEdgeKind() == SVFStmt::ThreadFork; } //@} /// constructor - CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, - const FunEntryICFGNode* e, GEdgeKind k = SVFStmt::Call); + CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunEntryICFGNode* e, GEdgeKind k = SVFStmt::Call); /// Get method for the call instruction //@{ @@ -668,7 +640,7 @@ class CallPE: public AssignStmt /*! * Return */ -class RetPE: public AssignStmt +class RetPE : public AssignStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -693,19 +665,16 @@ class RetPE: public AssignStmt } static inline bool classof(const SVFStmt* edge) { - return edge->getEdgeKind() == SVFStmt::Ret || - edge->getEdgeKind() == SVFStmt::ThreadJoin; + return edge->getEdgeKind() == SVFStmt::Ret || edge->getEdgeKind() == SVFStmt::ThreadJoin; } static inline bool classof(const GenericPAGEdgeTy* edge) { - return edge->getEdgeKind() == SVFStmt::Ret || - edge->getEdgeKind() == SVFStmt::ThreadJoin; + return edge->getEdgeKind() == SVFStmt::Ret || edge->getEdgeKind() == SVFStmt::ThreadJoin; } //@} /// constructor - RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e, - GEdgeKind k = SVFStmt::Ret); + RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e, GEdgeKind k = SVFStmt::Ret); /// Get method for call instruction at caller //@{ @@ -727,8 +696,8 @@ class RetPE: public AssignStmt }; /* -* Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt -*/ + * Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt + */ class MultiOpndStmt : public SVFStmt { friend class SVFIRWriter; @@ -741,10 +710,10 @@ class MultiOpndStmt : public SVFStmt MultiOpndStmt(); ///< place holder MultiOpndStmt(const MultiOpndStmt&); ///< place holder void operator=(const MultiOpndStmt&); ///< place holder - SVFVar* getSrcNode(); ///< not allowed, use getOpVar(idx) instead - SVFVar* getDstNode(); ///< not allowed, use getRes() instead - NodeID getSrcID(); ///< not allowed, use getOpVarID(idx) instead - NodeID getDstID(); ///< not allowed, use getResID() instead + SVFVar* getSrcNode(); ///< not allowed, use getOpVar(idx) instead + SVFVar* getDstNode(); ///< not allowed, use getRes() instead + NodeID getSrcID(); ///< not allowed, use getOpVarID(idx) instead + NodeID getDstID(); ///< not allowed, use getResID() instead protected: OPVars opVars; @@ -762,13 +731,13 @@ class MultiOpndStmt : public SVFStmt } static inline bool classof(const SVFStmt* node) { - return node->getEdgeKind() == Phi || node->getEdgeKind() == Select || - node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp; + return node->getEdgeKind() == Phi || node->getEdgeKind() == Select || node->getEdgeKind() == BinaryOp || + node->getEdgeKind() == Cmp; } static inline bool classof(const GenericPAGEdgeTy* node) { - return node->getEdgeKind() == Phi || node->getEdgeKind() == Select || - node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp; + return node->getEdgeKind() == Phi || node->getEdgeKind() == Select || node->getEdgeKind() == BinaryOp || + node->getEdgeKind() == Cmp; } //@} /// Operands and result at a BinaryNode e.g., p = q + r, `p` is resVar and @@ -811,7 +780,7 @@ class MultiOpndStmt : public SVFStmt * Phi statement (e.g., p = phi(q,r) which receives values from variables q and r from different paths) * it is typically at a joint point of the control-flow graph */ -class PhiStmt: public MultiOpndStmt +class PhiStmt : public MultiOpndStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -852,15 +821,13 @@ class PhiStmt: public MultiOpndStmt PhiStmt(SVFVar* s, const OPVars& opnds, const OpICFGNodeVec& icfgNodes) : MultiOpndStmt(s, opnds, SVFStmt::Phi), opICFGNodes(icfgNodes) { - assert(opnds.size() == icfgNodes.size() && - "Numbers of operands and their ICFGNodes are not consistent?"); + assert(opnds.size() == icfgNodes.size() && "Numbers of operands and their ICFGNodes are not consistent?"); } void addOpVar(SVFVar* op, const ICFGNode* inode) { opVars.push_back(op); opICFGNodes.push_back(inode); - assert(opVars.size() == opICFGNodes.size() && - "Numbers of operands and their ICFGNodes are not consistent?"); + assert(opVars.size() == opICFGNodes.size() && "Numbers of operands and their ICFGNodes are not consistent?"); } /// Return the corresponding ICFGNode of this operand @@ -879,7 +846,7 @@ class PhiStmt: public MultiOpndStmt /*! * Select statement (e.g., p ? q: r which receives values from variables q and r based on condition p) */ -class SelectStmt: public MultiOpndStmt +class SelectStmt : public MultiOpndStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -934,7 +901,7 @@ class SelectStmt: public MultiOpndStmt /*! * Comparison statement */ -class CmpStmt: public MultiOpndStmt +class CmpStmt : public MultiOpndStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -1020,7 +987,7 @@ class CmpStmt: public MultiOpndStmt /*! * Binary statement */ -class BinaryOPStmt: public MultiOpndStmt +class BinaryOPStmt : public MultiOpndStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -1036,24 +1003,24 @@ class BinaryOPStmt: public MultiOpndStmt /// OpCode for BinaryOPStmt, enum value is same to llvm BinaryOperator (llvm/IR/Instruction.def) enum OpCode : unsigned { - Add = 13, // Sum of integers - FAdd = 14, // Sum of floats - Sub = 15, // Subtraction of integers - FSub = 16, // Subtraction of floats - Mul = 17, // Product of integers. - FMul = 18, // Product of floats. - UDiv = 19, // Unsigned division. - SDiv = 20, // Signed division. - FDiv = 21, // Float division. - URem = 22, // Unsigned remainder - SRem = 23, // Signed remainder - FRem = 24, // Float remainder - Shl = 25, // Shift left (logical) - LShr = 26, // Shift right (logical) - AShr = 27, // Shift right (arithmetic) - And = 28, // Logical and - Or = 29, // Logical or - Xor = 30 // Logical xor + Add = 13, // Sum of integers + FAdd = 14, // Sum of floats + Sub = 15, // Subtraction of integers + FSub = 16, // Subtraction of floats + Mul = 17, // Product of integers. + FMul = 18, // Product of floats. + UDiv = 19, // Unsigned division. + SDiv = 20, // Signed division. + FDiv = 21, // Float division. + URem = 22, // Unsigned remainder + SRem = 23, // Signed remainder + FRem = 24, // Float remainder + Shl = 25, // Shift left (logical) + LShr = 26, // Shift right (logical) + AShr = 27, // Shift right (arithmetic) + And = 28, // Logical and + Or = 29, // Logical or + Xor = 30 // Logical xor }; /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -1090,7 +1057,7 @@ class BinaryOPStmt: public MultiOpndStmt /*! * Unary statement */ -class UnaryOPStmt: public SVFStmt +class UnaryOPStmt : public SVFStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -1100,10 +1067,10 @@ class UnaryOPStmt: public SVFStmt UnaryOPStmt() : SVFStmt(SVFStmt::UnaryOp) {} UnaryOPStmt(const UnaryOPStmt&); ///< place holder void operator=(const UnaryOPStmt&); ///< place holder - SVFVar* getSrcNode(); ///< place holder, use getOpVar() instead - SVFVar* getDstNode(); ///< place holder, use getRes() instead - NodeID getSrcID(); ///< place holder, use getOpVarID(pos) instead - NodeID getDstID(); ///< place holder, use getResID() instead + SVFVar* getSrcNode(); ///< place holder, use getOpVar() instead + SVFVar* getDstNode(); ///< place holder, use getRes() instead + NodeID getSrcID(); ///< place holder, use getOpVarID(pos) instead + NodeID getDstID(); ///< place holder, use getResID() instead u32_t opcode; @@ -1131,10 +1098,7 @@ class UnaryOPStmt: public SVFStmt //@} /// constructor - UnaryOPStmt(SVFVar* s, SVFVar* d, u32_t oc) - : SVFStmt(s, d, SVFStmt::UnaryOp), opcode(oc) - { - } + UnaryOPStmt(SVFVar* s, SVFVar* d, u32_t oc) : SVFStmt(s, d, SVFStmt::UnaryOp), opcode(oc) {} u32_t getOpcode() const { @@ -1157,7 +1121,7 @@ class UnaryOPStmt: public SVFStmt /*! * Branch statements including if/else and switch */ -class BranchStmt: public SVFStmt +class BranchStmt : public SVFStmt { friend class SVFIRWriter; friend class SVFIRReader; @@ -1172,8 +1136,8 @@ class BranchStmt: public SVFStmt void operator=(const BranchStmt&); ///< place holder SVFVar* getSrcNode(); ///< place holder, not allowed SVFVar* getDstNode(); ///< place holder, not allowed - NodeID getSrcID(); ///< place holder, use getOpVarID(pos) instead - NodeID getDstID(); ///< place holder, use getResID() instead + NodeID getSrcID(); ///< place holder, use getOpVarID(pos) instead + NodeID getDstID(); ///< place holder, use getResID() instead SuccAndCondPairVec successors; const SVFVar* cond; @@ -1198,8 +1162,7 @@ class BranchStmt: public SVFStmt /// constructor BranchStmt(SVFVar* inst, SVFVar* c, const SuccAndCondPairVec& succs) - : SVFStmt(c, inst, SVFStmt::Branch), successors(succs), cond(c), - brInst(inst) + : SVFStmt(c, inst, SVFStmt::Branch), successors(succs), cond(c), brInst(inst) { } @@ -1247,7 +1210,7 @@ class BranchStmt: public SVFStmt /*! * Thread Fork */ -class TDForkPE: public CallPE +class TDForkPE : public CallPE { friend class SVFIRWriter; friend class SVFIRReader; @@ -1276,8 +1239,7 @@ class TDForkPE: public CallPE //@} /// constructor - TDForkPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, - const FunEntryICFGNode* entry) + TDForkPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunEntryICFGNode* entry) : CallPE(s, d, i, entry, SVFStmt::ThreadFork) { } @@ -1288,7 +1250,7 @@ class TDForkPE: public CallPE /*! * Thread Join */ -class TDJoinPE: public RetPE +class TDJoinPE : public RetPE { friend class SVFIRWriter; friend class SVFIRReader; @@ -1317,8 +1279,7 @@ class TDJoinPE: public RetPE //@} /// Constructor - TDJoinPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, - const FunExitICFGNode* e) + TDJoinPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e) : RetPE(s, d, i, e, SVFStmt::ThreadJoin) { } diff --git a/svf/include/SVFIR/SVFType.h b/svf/include/SVFIR/SVFType.h index 8ed64aced..b86ff74e3 100644 --- a/svf/include/SVFIR/SVFType.h +++ b/svf/include/SVFIR/SVFType.h @@ -33,13 +33,11 @@ #include "Util/SparseBitVector.h" #include "Util/GeneralType.h" - namespace SVF { class SVFType; class SVFPointerType; - /*! * Flattened type information of StructType, ArrayType and SingleValueType */ @@ -75,10 +73,7 @@ class StInfo void operator=(const StInfo&) = delete; /// Constructor - explicit StInfo(u32_t s) - : stride(s), numOfFlattenElements(s), numOfFlattenFields(s) - { - } + explicit StInfo(u32_t s) : stride(s), numOfFlattenElements(s), numOfFlattenFields(s) {} /// Destructor ~StInfo() = default; @@ -174,7 +169,6 @@ class SVFType }; public: - inline static SVFType* getSVFPtrType() { assert(svfPtrTy && "ptr type not set?"); @@ -188,23 +182,18 @@ class SVFType } private: - static SVFType* svfPtrTy; ///< ptr type - static SVFType* svfI8Ty; ///< 8-bit int type + static SVFType* svfI8Ty; ///< 8-bit int type private: - GNodeK kind; ///< used for classof + GNodeK kind; ///< used for classof StInfo* typeinfo; ///< SVF's TypeInfo bool isSingleValTy; ///< The type represents a single value, not struct or - u32_t byteSize; ///< LLVM Byte Size + u32_t byteSize; ///< LLVM Byte Size ///< array protected: - SVFType(bool svt, SVFTyKind k, u32_t Sz = 1) - : kind(k), typeinfo(nullptr), - isSingleValTy(svt), byteSize(Sz) - { - } + SVFType(bool svt, SVFTyKind k, u32_t Sz = 1) : kind(k), typeinfo(nullptr), isSingleValTy(svt), byteSize(Sz) {} public: SVFType(void) = delete; @@ -221,7 +210,6 @@ class SVFType virtual void print(std::ostream& os) const = 0; - inline void setTypeInfo(StInfo* ti) { typeinfo = ti; @@ -275,10 +263,7 @@ class SVFPointerType : public SVFType friend class SVFIRReader; public: - SVFPointerType(u32_t byteSize = 1) - : SVFType(true, SVFPointerTy, byteSize) - { - } + SVFPointerType(u32_t byteSize = 1) : SVFType(true, SVFPointerTy, byteSize) {} static inline bool classof(const SVFType* node) { @@ -325,10 +310,7 @@ class SVFFunctionType : public SVFType const SVFType* retTy; public: - SVFFunctionType(const SVFType* rt) - : SVFType(false, SVFFunctionTy, 1), retTy(rt) - { - } + SVFFunctionType(const SVFType* rt) : SVFType(false, SVFFunctionTy, 1), retTy(rt) {} static inline bool classof(const SVFType* node) { return node->getKind() == SVFFunctionTy; @@ -380,14 +362,11 @@ class SVFArrayType : public SVFType friend class SVFIRReader; private: - unsigned numOfElement; /// For printing & debugging + unsigned numOfElement; /// For printing & debugging const SVFType* typeOfElement; /// For printing & debugging public: - SVFArrayType(u32_t byteSize = 1) - : SVFType(false, SVFArrayTy, byteSize), numOfElement(0), typeOfElement(nullptr) - { - } + SVFArrayType(u32_t byteSize = 1) : SVFType(false, SVFArrayTy, byteSize), numOfElement(0), typeOfElement(nullptr) {} static inline bool classof(const SVFType* node) { @@ -410,8 +389,6 @@ class SVFArrayType : public SVFType { numOfElement = elemNum; } - - }; class SVFOtherType : public SVFType @@ -468,15 +445,15 @@ template <> struct Hash // https://github.com/llvm/llvm-project/blob/75e33f71c2dae584b13a7d1186ae0a038ba98838/llvm/include/llvm/Support/Debug.h#L64 // The original LLVM implementation makes use of type. But we can get that info, // so we can't simulate the full behaviour for now. -# define SVF_DEBUG_WITH_TYPE(TYPE, X) \ - do \ - { \ - X; \ +# define SVF_DEBUG_WITH_TYPE(TYPE, X) \ + do \ + { \ + X; \ } while (false) #else -# define SVF_DEBUG_WITH_TYPE(TYPE, X) \ - do \ - { \ +# define SVF_DEBUG_WITH_TYPE(TYPE, X) \ + do \ + { \ } while (false) #endif @@ -553,8 +530,7 @@ template struct std::hash> size_t operator()(const SVF::SparseBitVector& sbv) const { SVF::Hash, size_t>> h; - return h(std::make_pair(std::make_pair(sbv.count(), sbv.find_first()), - sbv.find_last())); + return h(std::make_pair(std::make_pair(sbv.count(), sbv.find_first()), sbv.find_last())); } }; diff --git a/svf/include/SVFIR/SVFValue.h b/svf/include/SVFIR/SVFValue.h index eac8a16cd..166f64c79 100644 --- a/svf/include/SVFIR/SVFValue.h +++ b/svf/include/SVFIR/SVFValue.h @@ -40,7 +40,6 @@ namespace SVF /// LLVM Aliases and constants typedef SVF::GraphPrinter GraphPrinter; - class SVFInstruction; class SVFBasicBlock; class SVFArgument; @@ -51,33 +50,35 @@ class SVFLoopAndDomInfo { friend class SVFIRWriter; friend class SVFIRReader; + public: typedef Set BBSet; typedef std::vector BBList; typedef BBList LoopBBs; private: - BBList reachableBBs; ///< reachable BasicBlocks from the function entry. - Map dtBBsMap; ///< map a BasicBlock to BasicBlocks it Dominates - Map pdtBBsMap; ///< map a BasicBlock to BasicBlocks it PostDominates - Map dfBBsMap; ///< map a BasicBlock to its Dominate Frontier BasicBlocks - Map bb2LoopMap; ///< map a BasicBlock (if it is in a loop) to all the BasicBlocks in this loop - Map bb2PdomLevel; ///< map a BasicBlock to its level in pdom tree, used in findNearestCommonPDominator - Map bb2PIdom; ///< map a BasicBlock to its immediate dominator in pdom tree, used in findNearestCommonPDominator + BBList reachableBBs; ///< reachable BasicBlocks from the function entry. + Map dtBBsMap; ///< map a BasicBlock to BasicBlocks it Dominates + Map pdtBBsMap; ///< map a BasicBlock to BasicBlocks it PostDominates + Map dfBBsMap; ///< map a BasicBlock to its Dominate Frontier BasicBlocks + Map + bb2LoopMap; ///< map a BasicBlock (if it is in a loop) to all the BasicBlocks in this loop + Map + bb2PdomLevel; ///< map a BasicBlock to its level in pdom tree, used in findNearestCommonPDominator + Map + bb2PIdom; ///< map a BasicBlock to its immediate dominator in pdom tree, used in findNearestCommonPDominator public: - SVFLoopAndDomInfo() - { - } + SVFLoopAndDomInfo() {} virtual ~SVFLoopAndDomInfo() {} - inline const Map& getDomFrontierMap() const + inline const Map& getDomFrontierMap() const { return dfBBsMap; } - inline Map& getDomFrontierMap() + inline Map& getDomFrontierMap() { return dfBBsMap; } @@ -105,51 +106,49 @@ class SVFLoopAndDomInfo bb2LoopMap[bb].push_back(loopBB); } - inline const Map& getPostDomTreeMap() const + inline const Map& getPostDomTreeMap() const { return pdtBBsMap; } - inline Map& getPostDomTreeMap() + inline Map& getPostDomTreeMap() { return pdtBBsMap; } - inline const Map& getBBPDomLevel() const + inline const Map& getBBPDomLevel() const { return bb2PdomLevel; } - inline Map& getBBPDomLevel() + inline Map& getBBPDomLevel() { return bb2PdomLevel; } - inline const Map& getBB2PIdom() const + inline const Map& getBB2PIdom() const { return bb2PIdom; } - inline Map& getBB2PIdom() + inline Map& getBB2PIdom() { return bb2PIdom; } - - inline Map& getDomTreeMap() + inline Map& getDomTreeMap() { return dtBBsMap; } - inline const Map& getDomTreeMap() const + inline const Map& getDomTreeMap() const { return dtBBsMap; } inline bool isUnreachable(const SVFBasicBlock* bb) const { - return std::find(reachableBBs.begin(), reachableBBs.end(), bb) == - reachableBBs.end(); + return std::find(reachableBBs.begin(), reachableBBs.end(), bb) == reachableBBs.end(); } inline const BBList& getReachableBBs() const @@ -171,7 +170,7 @@ class SVFLoopAndDomInfo bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const; /// find nearest common post dominator of two basic blocks - const SVFBasicBlock *findNearestCommonPDominator(const SVFBasicBlock *A, const SVFBasicBlock *B) const; + const SVFBasicBlock* findNearestCommonPDominator(const SVFBasicBlock* A, const SVFBasicBlock* B) const; }; class SVFValue @@ -204,18 +203,18 @@ class SVFValue }; private: - GNodeK kind; ///< used for classof - bool ptrInUncalledFun; ///< true if this pointer is in an uncalled function - bool constDataOrAggData; ///< true if this value is a ConstantData (e.g., numbers, string, floats) or a constantAggregate + GNodeK kind; ///< used for classof + bool ptrInUncalledFun; ///< true if this pointer is in an uncalled function + bool constDataOrAggData; ///< true if this value is a ConstantData (e.g., numbers, string, floats) or a + ///< constantAggregate protected: const SVFType* type; ///< Type of this SVFValue - std::string name; ///< Short name of value for printing & debugging - std::string sourceLoc; ///< Source code information of this value + std::string name; ///< Short name of value for printing & debugging + std::string sourceLoc; ///< Source code information of this value /// Constructor without name SVFValue(const SVFType* ty, SVFValKind k) - : kind(k), ptrInUncalledFun(false), - constDataOrAggData(SVFConstData == k), type(ty), sourceLoc("NoLoc") + : kind(k), ptrInUncalledFun(false), constDataOrAggData(SVFConstData == k), type(ty), sourceLoc("NoLoc") { } @@ -240,7 +239,7 @@ class SVFValue return kind; } - inline const std::string &getName() const + inline const std::string& getName() const { return name; } @@ -267,7 +266,8 @@ class SVFValue } inline bool isblackHole() const { - return getKind() == SVFBlackHole;; + return getKind() == SVFBlackHole; + ; } inline bool isNullPtr() const { @@ -287,7 +287,7 @@ class SVFValue /// Overloading operator << for dumping ICFG node ID //@{ - friend OutStream& operator<<(OutStream &os, const SVFValue &value) + friend OutStream& operator<<(OutStream& os, const SVFValue& value) { return os << value.toString(); } @@ -308,19 +308,22 @@ class SVFFunction : public SVFValue typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; private: - bool isDecl; /// return true if this function does not have a body - bool intrinsic; /// return true if this function is an intrinsic function (e.g., llvm.dbg), which does not reside in the application code + bool isDecl; /// return true if this function does not have a body + bool intrinsic; /// return true if this function is an intrinsic function (e.g., llvm.dbg), which does not reside in + /// the application code bool addrTaken; /// return true if this function is address-taken (for indirect call purposes) - bool isUncalled; /// return true if this function is never called + bool isUncalled; /// return true if this function is never called bool isNotRet; /// return true if this function never returns - bool varArg; /// return true if this function supports variable arguments - const SVFFunctionType* funcType; /// FunctionType, which is different from the type (PointerType) of this SVFFunction - SVFLoopAndDomInfo* loopAndDom; /// the loop and dominate information - const SVFFunction* realDefFun; /// the definition of a function across multiple modules - std::vector allBBs; /// all BasicBlocks of this function - std::vector allArgs; /// all formal arguments of this function - std::vector annotations; /// annotations of this function - SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function + bool varArg; /// return true if this function supports variable arguments + const SVFFunctionType* + funcType; /// FunctionType, which is different from the type (PointerType) of this SVFFunction + SVFLoopAndDomInfo* loopAndDom; /// the loop and dominate information + const SVFFunction* realDefFun; /// the definition of a function across multiple modules + std::vector allBBs; /// all BasicBlocks of this function + std::vector allArgs; /// all formal arguments of this function + std::vector annotations; /// annotations of this function + SVFBasicBlock* + exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function protected: ///@{ attributes to be set only through Module builders e.g., LLVMModule @@ -351,11 +354,12 @@ class SVFFunction : public SVFValue /// @} public: - SVFFunction(const SVFType* ty,const SVFFunctionType* ft, bool declare, bool intrinsic, bool addrTaken, bool varg, SVFLoopAndDomInfo* ld); + SVFFunction(const SVFType* ty, const SVFFunctionType* ft, bool declare, bool intrinsic, bool addrTaken, bool varg, + SVFLoopAndDomInfo* ld); SVFFunction(void) = delete; virtual ~SVFFunction(); - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFFunc; } @@ -393,8 +397,7 @@ class SVFFunction : public SVFValue inline const SVFFunction* getDefFunForMultipleModule() const { - if(realDefFun==nullptr) - return this; + if (realDefFun == nullptr) return this; return realDefFun; } @@ -417,7 +420,7 @@ class SVFFunction : public SVFValue /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 const SVFBasicBlock* getExitBB() const; - void setExitBlock(SVFBasicBlock *bb); + void setExitBlock(SVFBasicBlock* bb); inline const SVFBasicBlock* front() const { @@ -460,7 +463,7 @@ class SVFFunction : public SVFValue inline bool hasReturn() const { - return !isNotRet; + return !isNotRet; } inline const std::vector& getAnnotations() const @@ -475,7 +478,7 @@ class SVFFunction : public SVFValue inline void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const { - return loopAndDom->getExitBlocksOfLoop(bb,exitbbs); + return loopAndDom->getExitBlocksOfLoop(bb, exitbbs); } inline bool hasLoopInfo(const SVFBasicBlock* bb) const @@ -495,15 +498,15 @@ class SVFFunction : public SVFValue inline bool loopContainsBB(const BBList& lp, const SVFBasicBlock* bb) const { - return loopAndDom->loopContainsBB(lp,bb); + return loopAndDom->loopContainsBB(lp, bb); } - inline const Map& getDomTreeMap() const + inline const Map& getDomTreeMap() const { return loopAndDom->getDomTreeMap(); } - inline const Map& getDomFrontierMap() const + inline const Map& getDomFrontierMap() const { return loopAndDom->getDomFrontierMap(); } @@ -515,12 +518,12 @@ class SVFFunction : public SVFValue inline bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - return loopAndDom->dominate(bbKey,bbValue); + return loopAndDom->dominate(bbKey, bbValue); } inline bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - return loopAndDom->postDominate(bbKey,bbValue); + return loopAndDom->postDominate(bbKey, bbValue); } }; @@ -536,10 +539,10 @@ class SVFBasicBlock : public SVFValue typedef std::vector::const_iterator const_iterator; private: - std::vector allInsts; ///< all Instructions in this BasicBlock - std::vector succBBs; ///< all successor BasicBlocks of this BasicBlock - std::vector predBBs; ///< all predecessor BasicBlocks of this BasicBlock - const SVFFunction* fun; /// Function where this BasicBlock is + std::vector allInsts; ///< all Instructions in this BasicBlock + std::vector succBBs; ///< all successor BasicBlocks of this BasicBlock + std::vector predBBs; ///< all predecessor BasicBlocks of this BasicBlock + const SVFFunction* fun; /// Function where this BasicBlock is protected: ///@{ attributes to be set only through Module builders e.g., LLVMModule @@ -565,7 +568,7 @@ class SVFBasicBlock : public SVFValue SVFBasicBlock() = delete; ~SVFBasicBlock() override; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFBB; } @@ -632,27 +635,25 @@ class SVFInstruction : public SVFValue { friend class SVFIRWriter; friend class SVFIRReader; + public: typedef std::vector InstVec; private: - const SVFBasicBlock* bb; /// The BasicBlock where this Instruction resides - bool terminator; /// return true if this is a terminator instruction - bool ret; /// return true if this is an return instruction of a function - InstVec succInsts; /// successor Instructions - InstVec predInsts; /// predecessor Instructions + const SVFBasicBlock* bb; /// The BasicBlock where this Instruction resides + bool terminator; /// return true if this is a terminator instruction + bool ret; /// return true if this is an return instruction of a function + InstVec succInsts; /// successor Instructions + InstVec predInsts; /// predecessor Instructions public: /// Constructor without name, set name with setName() - SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, bool tm, - bool isRet, SVFValKind k = SVFInst); + SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, bool tm, bool isRet, SVFValKind k = SVFInst); SVFInstruction(void) = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { - return node->getKind() == SVFInst || - node->getKind() == SVFCall || - node->getKind() == SVFVCall; + return node->getKind() == SVFInst || node->getKind() == SVFCall || node->getKind() == SVFVCall; } inline const SVFBasicBlock* getParent() const @@ -721,17 +722,17 @@ class SVFCallInst : public SVFInstruction /// @} public: - SVFCallInst(const SVFType* ty, const SVFBasicBlock* b, bool va, bool tm, SVFValKind k = SVFCall) : - SVFInstruction(ty, b, tm, false, k), varArg(va), calledVal(nullptr) + SVFCallInst(const SVFType* ty, const SVFBasicBlock* b, bool va, bool tm, SVFValKind k = SVFCall) + : SVFInstruction(ty, b, tm, false, k), varArg(va), calledVal(nullptr) { } SVFCallInst(void) = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFCall || node->getKind() == SVFVCall; } - static inline bool classof(const SVFInstruction *node) + static inline bool classof(const SVFInstruction* node) { return node->getKind() == SVFCall || node->getKind() == SVFVCall; } @@ -764,7 +765,7 @@ class SVFCallInst : public SVFInstruction { return SVFUtil::dyn_cast(calledVal); } - inline const SVFFunction* getCaller() const + inline const SVFFunction* getCaller() const { return getFunction(); } @@ -777,9 +778,9 @@ class SVFVirtualCallInst : public SVFCallInst friend class LLVMModuleSet; private: - const SVFValue* vCallVtblPtr; /// virtual table pointer - s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call - std::string funNameOfVcall; /// the function name of this virtual call + const SVFValue* vCallVtblPtr; /// virtual table pointer + s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call + std::string funNameOfVcall; /// the function name of this virtual call protected: inline void setFunIdxInVtable(s32_t idx) @@ -796,10 +797,8 @@ class SVFVirtualCallInst : public SVFCallInst } public: - SVFVirtualCallInst(const SVFType* ty, const SVFBasicBlock* b, bool vararg, - bool tm) - : SVFCallInst(ty, b, vararg, tm, SVFVCall), vCallVtblPtr(nullptr), - virtualFunIdx(-1), funNameOfVcall() + SVFVirtualCallInst(const SVFType* ty, const SVFBasicBlock* b, bool vararg, bool tm) + : SVFCallInst(ty, b, vararg, tm, SVFVCall), vCallVtblPtr(nullptr), virtualFunIdx(-1), funNameOfVcall() { } inline const SVFValue* getVtablePtr() const @@ -809,22 +808,22 @@ class SVFVirtualCallInst : public SVFCallInst } inline s32_t getFunIdxInVtable() const { - assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?"); + assert(virtualFunIdx >= 0 && "virtual function idx is less than 0? not set yet?"); return virtualFunIdx; } inline const std::string& getFunNameOfVirtualCall() const { return funNameOfVcall; } - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFVCall; } - static inline bool classof(const SVFInstruction *node) + static inline bool classof(const SVFInstruction* node) { return node->getKind() == SVFVCall; } - static inline bool classof(const SVFCallInst *node) + static inline bool classof(const SVFCallInst* node) { return node->getKind() == SVFVCall; } @@ -834,23 +833,17 @@ class SVFConstant : public SVFValue { friend class SVFIRWriter; friend class SVFIRReader; + public: - SVFConstant(const SVFType* ty, SVFValKind k = SVFConst): SVFValue(ty, k) - { - } + SVFConstant(const SVFType* ty, SVFValKind k = SVFConst) : SVFValue(ty, k) {} SVFConstant() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { - return node->getKind() == SVFConst || - node->getKind() == SVFGlob || - node->getKind() == SVFConstData || - node->getKind() == SVFConstInt || - node->getKind() == SVFConstFP || - node->getKind() == SVFNullPtr || + return node->getKind() == SVFConst || node->getKind() == SVFGlob || node->getKind() == SVFConstData || + node->getKind() == SVFConstInt || node->getKind() == SVFConstFP || node->getKind() == SVFNullPtr || node->getKind() == SVFBlackHole; } - }; class SVFGlobalValue : public SVFConstant @@ -860,7 +853,7 @@ class SVFGlobalValue : public SVFConstant friend class LLVMModuleSet; private: - const SVFValue* realDefGlobal; /// the definition of a function across multiple modules + const SVFValue* realDefGlobal; /// the definition of a function across multiple modules protected: inline void setDefGlobalForMultipleModule(const SVFValue* defg) @@ -869,9 +862,7 @@ class SVFGlobalValue : public SVFConstant } public: - SVFGlobalValue(const SVFType* ty): SVFConstant(ty, SVFValue::SVFGlob), realDefGlobal(nullptr) - { - } + SVFGlobalValue(const SVFType* ty) : SVFConstant(ty, SVFValue::SVFGlob), realDefGlobal(nullptr) {} SVFGlobalValue(std::string&& name, const SVFType* ty) : SVFGlobalValue(ty) { setName(std::move(name)); @@ -880,15 +871,14 @@ class SVFGlobalValue : public SVFConstant inline const SVFValue* getDefGlobalForMultipleModule() const { - if(realDefGlobal==nullptr) - return this; + if (realDefGlobal == nullptr) return this; return realDefGlobal; } - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFGlob; } - static inline bool classof(const SVFConstant *node) + static inline bool classof(const SVFConstant* node) { return node->getKind() == SVFGlob; } @@ -898,15 +888,15 @@ class SVFArgument : public SVFValue { friend class SVFIRWriter; friend class SVFIRReader; + private: const SVFFunction* fun; u32_t argNo; bool uncalled; + public: - SVFArgument(const SVFType* ty, const SVFFunction* fun, u32_t argNo, - bool uncalled) - : SVFValue(ty, SVFValue::SVFArg), fun(fun), argNo(argNo), - uncalled(uncalled) + SVFArgument(const SVFType* ty, const SVFFunction* fun, u32_t argNo, bool uncalled) + : SVFValue(ty, SVFValue::SVFArg), fun(fun), argNo(argNo), uncalled(uncalled) { } SVFArgument() = delete; @@ -928,7 +918,7 @@ class SVFArgument : public SVFValue return uncalled; } - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFArg; } @@ -938,28 +928,20 @@ class SVFConstantData : public SVFConstant { friend class SVFIRWriter; friend class SVFIRReader; + public: - SVFConstantData(const SVFType* ty, SVFValKind k = SVFConstData) - : SVFConstant(ty, k) - { - } + SVFConstantData(const SVFType* ty, SVFValKind k = SVFConstData) : SVFConstant(ty, k) {} SVFConstantData() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { - return node->getKind() == SVFConstData || - node->getKind() == SVFConstInt || - node->getKind() == SVFConstFP || - node->getKind() == SVFNullPtr || - node->getKind() == SVFBlackHole; + return node->getKind() == SVFConstData || node->getKind() == SVFConstInt || node->getKind() == SVFConstFP || + node->getKind() == SVFNullPtr || node->getKind() == SVFBlackHole; } - static inline bool classof(const SVFConstantData *node) + static inline bool classof(const SVFConstantData* node) { - return node->getKind() == SVFConstData || - node->getKind() == SVFConstInt || - node->getKind() == SVFConstFP || - node->getKind() == SVFNullPtr || - node->getKind() == SVFBlackHole; + return node->getKind() == SVFConstData || node->getKind() == SVFConstInt || node->getKind() == SVFConstFP || + node->getKind() == SVFNullPtr || node->getKind() == SVFBlackHole; } }; @@ -967,31 +949,34 @@ class SVFConstantInt : public SVFConstantData { friend class SVFIRWriter; friend class SVFIRReader; + private: u64_t zval; s64_t sval; + public: - SVFConstantInt(const SVFType* ty, u64_t z, s64_t s) - : SVFConstantData(ty, SVFValue::SVFConstInt), zval(z), sval(s) + SVFConstantInt(const SVFType* ty, u64_t z, s64_t s) : SVFConstantData(ty, SVFValue::SVFConstInt), zval(z), sval(s) { } SVFConstantInt() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFConstInt; } - static inline bool classof(const SVFConstantData *node) + static inline bool classof(const SVFConstantData* node) { return node->getKind() == SVFConstInt; } - // Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate for the type of this constant. - inline u64_t getZExtValue () const + // Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate for the + // type of this constant. + inline u64_t getZExtValue() const { return zval; } - // Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the type of this constant - inline s64_t getSExtValue () const + // Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the type of this + // constant + inline s64_t getSExtValue() const { return sval; } @@ -1001,24 +986,23 @@ class SVFConstantFP : public SVFConstantData { friend class SVFIRWriter; friend class SVFIRReader; + private: float dval; + public: - SVFConstantFP(const SVFType* ty, double d) - : SVFConstantData(ty, SVFValue::SVFConstFP), dval(d) - { - } + SVFConstantFP(const SVFType* ty, double d) : SVFConstantData(ty, SVFValue::SVFConstFP), dval(d) {} SVFConstantFP() = delete; - inline double getFPValue () const + inline double getFPValue() const { return dval; } - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFConstFP; } - static inline bool classof(const SVFConstantData *node) + static inline bool classof(const SVFConstantData* node) { return node->getKind() == SVFConstFP; } @@ -1030,17 +1014,14 @@ class SVFConstantNullPtr : public SVFConstantData friend class SVFIRReader; public: - SVFConstantNullPtr(const SVFType* ty) - : SVFConstantData(ty, SVFValue::SVFNullPtr) - { - } + SVFConstantNullPtr(const SVFType* ty) : SVFConstantData(ty, SVFValue::SVFNullPtr) {} SVFConstantNullPtr() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFNullPtr; } - static inline bool classof(const SVFConstantData *node) + static inline bool classof(const SVFConstantData* node) { return node->getKind() == SVFNullPtr; } @@ -1052,17 +1033,14 @@ class SVFBlackHoleValue : public SVFConstantData friend class SVFIRReader; public: - SVFBlackHoleValue(const SVFType* ty) - : SVFConstantData(ty, SVFValue::SVFBlackHole) - { - } + SVFBlackHoleValue(const SVFType* ty) : SVFConstantData(ty, SVFValue::SVFBlackHole) {} SVFBlackHoleValue() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFBlackHole; } - static inline bool classof(const SVFConstantData *node) + static inline bool classof(const SVFConstantData* node) { return node->getKind() == SVFBlackHole; } @@ -1072,14 +1050,12 @@ class SVFOtherValue : public SVFValue { friend class SVFIRWriter; friend class SVFIRReader; + public: - SVFOtherValue(const SVFType* ty, SVFValKind k = SVFValue::SVFOther) - : SVFValue(ty, k) - { - } + SVFOtherValue(const SVFType* ty, SVFValKind k = SVFValue::SVFOther) : SVFValue(ty, k) {} SVFOtherValue() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFOther || node->getKind() == SVFMetaAsValue; } @@ -1087,29 +1063,26 @@ class SVFOtherValue : public SVFValue /* * This class is only for LLVM's MetadataAsValue -*/ + */ class SVFMetadataAsValue : public SVFOtherValue { friend class SVFIRWriter; friend class SVFIRReader; + public: - SVFMetadataAsValue(const SVFType* ty) - : SVFOtherValue(ty, SVFValue::SVFMetaAsValue) - { - } + SVFMetadataAsValue(const SVFType* ty) : SVFOtherValue(ty, SVFValue::SVFMetaAsValue) {} SVFMetadataAsValue() = delete; - static inline bool classof(const SVFValue *node) + static inline bool classof(const SVFValue* node) { return node->getKind() == SVFMetaAsValue; } - static inline bool classof(const SVFOtherValue *node) + static inline bool classof(const SVFOtherValue* node) { return node->getKind() == SVFMetaAsValue; } }; - class CallSite { friend class SVFIRReader; @@ -1208,8 +1181,7 @@ class CallSite /// it in any SVF algorithm because it relies on information stored in LLVM bc. std::string dumpLLVMValue(const SVFValue* svfValue); -template -OutStream& operator<< (OutStream &o, const std::pair &var) +template OutStream& operator<<(OutStream& o, const std::pair& var) { o << "<" << var.first << ", " << var.second << ">"; return o; @@ -1220,9 +1192,9 @@ OutStream& operator<< (OutStream &o, const std::pair &var) /// Specialise hash for CallSites. template <> struct std::hash { - size_t operator()(const SVF::CallSite &cs) const + size_t operator()(const SVF::CallSite& cs) const { - std::hash h; + std::hash h; return h(cs.getInstruction()); } }; diff --git a/svf/include/SVFIR/SVFVariables.h b/svf/include/SVFIR/SVFVariables.h index d209e5a6a..77be29af1 100644 --- a/svf/include/SVFIR/SVFVariables.h +++ b/svf/include/SVFIR/SVFVariables.h @@ -73,12 +73,11 @@ class SVFVar : public GenericPAGNodeTy DummyObjNode, }; - protected: const SVFValue* value; ///< value of this SVFIR node SVFStmt::KindToSVFStmtMapTy InEdgeKindToSetMap; SVFStmt::KindToSVFStmtMapTy OutEdgeKindToSetMap; - bool isPtr; /// whether it is a pointer (top-level or address-taken) + bool isPtr; /// whether it is a pointer (top-level or address-taken) /// Constructor to create an empty object (for deserialization) SVFVar(NodeID i, PNODEK k) : GenericPAGNodeTy(i, k), value{} {} @@ -93,13 +92,11 @@ class SVFVar : public GenericPAGNodeTy //@{ inline const SVFValue* getValue() const { - assert(this->getNodeKind() != DummyValNode && - this->getNodeKind() != DummyObjNode && + assert(this->getNodeKind() != DummyValNode && this->getNodeKind() != DummyObjNode && "dummy node do not have value!"); assert(!SymbolTableInfo::isBlkObjOrConstantObj(this->getId()) && "blackhole and constant obj do not have value"); - assert(value && - "value is null (GepObjNode whose basenode is a DummyObj?)"); + assert(value && "value is null (GepObjNode whose basenode is a DummyObj?)"); return value; } @@ -134,8 +131,7 @@ class SVFVar : public GenericPAGNodeTy { if (value) { - if (auto inst = SVFUtil::dyn_cast(value)) - return inst->getParent()->getParent(); + if (auto inst = SVFUtil::dyn_cast(value)) return inst->getParent()->getParent(); else if (auto arg = SVFUtil::dyn_cast(value)) return arg->getParent(); else if (auto fun = SVFUtil::dyn_cast(value)) @@ -158,8 +154,7 @@ class SVFVar : public GenericPAGNodeTy inline bool hasIncomingEdges(SVFStmt::PEDGEK kind) const { SVFStmt::KindToSVFStmtMapTy::const_iterator it = InEdgeKindToSetMap.find(kind); - if (it != InEdgeKindToSetMap.end()) - return (!it->second.empty()); + if (it != InEdgeKindToSetMap.end()) return (!it->second.empty()); else return false; } @@ -167,8 +162,7 @@ class SVFVar : public GenericPAGNodeTy inline bool hasOutgoingEdges(SVFStmt::PEDGEK kind) const { SVFStmt::KindToSVFStmtMapTy::const_iterator it = OutEdgeKindToSetMap.find(kind); - if (it != OutEdgeKindToSetMap.end()) - return (!it->second.empty()); + if (it != OutEdgeKindToSetMap.end()) return (!it->second.empty()); else return false; } @@ -177,7 +171,7 @@ class SVFVar : public GenericPAGNodeTy inline SVFStmt::SVFStmtSetTy::iterator getIncomingEdgesBegin(SVFStmt::PEDGEK kind) const { SVFStmt::KindToSVFStmtMapTy::const_iterator it = InEdgeKindToSetMap.find(kind); - assert(it!=InEdgeKindToSetMap.end() && "The node does not have such kind of edge"); + assert(it != InEdgeKindToSetMap.end() && "The node does not have such kind of edge"); return it->second.begin(); } @@ -185,7 +179,7 @@ class SVFVar : public GenericPAGNodeTy inline SVFStmt::SVFStmtSetTy::iterator getIncomingEdgesEnd(SVFStmt::PEDGEK kind) const { SVFStmt::KindToSVFStmtMapTy::const_iterator it = InEdgeKindToSetMap.find(kind); - assert(it!=InEdgeKindToSetMap.end() && "The node does not have such kind of edge"); + assert(it != InEdgeKindToSetMap.end() && "The node does not have such kind of edge"); return it->second.end(); } @@ -193,7 +187,7 @@ class SVFVar : public GenericPAGNodeTy inline SVFStmt::SVFStmtSetTy::iterator getOutgoingEdgesBegin(SVFStmt::PEDGEK kind) const { SVFStmt::KindToSVFStmtMapTy::const_iterator it = OutEdgeKindToSetMap.find(kind); - assert(it!=OutEdgeKindToSetMap.end() && "The node does not have such kind of edge"); + assert(it != OutEdgeKindToSetMap.end() && "The node does not have such kind of edge"); return it->second.begin(); } @@ -201,7 +195,7 @@ class SVFVar : public GenericPAGNodeTy inline SVFStmt::SVFStmtSetTy::iterator getOutgoingEdgesEnd(SVFStmt::PEDGEK kind) const { SVFStmt::KindToSVFStmtMapTy::const_iterator it = OutEdgeKindToSetMap.find(kind); - assert(it!=OutEdgeKindToSetMap.end() && "The node does not have such kind of edge"); + assert(it != OutEdgeKindToSetMap.end() && "The node does not have such kind of edge"); return it->second.end(); } //@} @@ -228,10 +222,9 @@ class SVFVar : public GenericPAGNodeTy SVFStmt::KindToSVFStmtMapTy::const_iterator it = InEdgeKindToSetMap.find(SVFStmt::Gep); if (it != InEdgeKindToSetMap.end()) { - for(auto gep : it->second) + for (auto gep : it->second) { - if(SVFUtil::cast(gep)->isVariantFieldGep()) - return true; + if (SVFUtil::cast(gep)->isVariantFieldGep()) return true; } } return false; @@ -246,7 +239,7 @@ class SVFVar : public GenericPAGNodeTy //@} /// Overloading operator << for dumping SVFVar value //@{ - friend OutStream& operator<< (OutStream &o, const SVFVar &node) + friend OutStream& operator<<(OutStream& o, const SVFVar& node) { o << node.toString(); return o; @@ -254,12 +247,10 @@ class SVFVar : public GenericPAGNodeTy //@} }; - - /* * Value (Pointer) variable */ -class ValVar: public SVFVar +class ValVar : public SVFVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -277,32 +268,24 @@ class ValVar: public SVFVar } static inline bool classof(const SVFVar* node) { - return node->getNodeKind() == SVFVar::ValNode || - node->getNodeKind() == SVFVar::GepValNode || - node->getNodeKind() == SVFVar::RetNode || - node->getNodeKind() == SVFVar::VarargNode || + return node->getNodeKind() == SVFVar::ValNode || node->getNodeKind() == SVFVar::GepValNode || + node->getNodeKind() == SVFVar::RetNode || node->getNodeKind() == SVFVar::VarargNode || node->getNodeKind() == SVFVar::DummyValNode; } static inline bool classof(const GenericPAGNodeTy* node) { - return node->getNodeKind() == SVFVar::ValNode || - node->getNodeKind() == SVFVar::GepValNode || - node->getNodeKind() == SVFVar::RetNode || - node->getNodeKind() == SVFVar::VarargNode || + return node->getNodeKind() == SVFVar::ValNode || node->getNodeKind() == SVFVar::GepValNode || + node->getNodeKind() == SVFVar::RetNode || node->getNodeKind() == SVFVar::VarargNode || node->getNodeKind() == SVFVar::DummyValNode; } //@} /// Constructor - ValVar(const SVFValue* val, NodeID i, PNODEK ty = ValNode) - : SVFVar(val, i, ty) - { - } + ValVar(const SVFValue* val, NodeID i, PNODEK ty = ValNode) : SVFVar(val, i, ty) {} /// Return name of a LLVM value inline const std::string getValueName() const { - if (value) - return value->getName(); + if (value) return value->getName(); return ""; } @@ -312,20 +295,18 @@ class ValVar: public SVFVar /* * Memory Object variable */ -class ObjVar: public SVFVar +class ObjVar : public SVFVar { friend class SVFIRWriter; friend class SVFIRReader; protected: - const MemObj* mem; ///< memory object + const MemObj* mem; ///< memory object /// Constructor to create an empty ObjVar (for SVFIRReader/deserialization) ObjVar(NodeID i, PNODEK ty = ObjNode) : SVFVar(i, ty), mem{} {} /// Constructor - ObjVar(const SVFValue* val, NodeID i, const MemObj* m, PNODEK ty = ObjNode) : - SVFVar(val, i, ty), mem(m) - { - } + ObjVar(const SVFValue* val, NodeID i, const MemObj* m, PNODEK ty = ObjNode) : SVFVar(val, i, ty), mem(m) {} + public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ @@ -335,17 +316,13 @@ class ObjVar: public SVFVar } static inline bool classof(const SVFVar* node) { - return node->getNodeKind() == SVFVar::ObjNode || - node->getNodeKind() == SVFVar::GepObjNode || - node->getNodeKind() == SVFVar::FIObjNode || - node->getNodeKind() == SVFVar::DummyObjNode; + return node->getNodeKind() == SVFVar::ObjNode || node->getNodeKind() == SVFVar::GepObjNode || + node->getNodeKind() == SVFVar::FIObjNode || node->getNodeKind() == SVFVar::DummyObjNode; } static inline bool classof(const GenericPAGNodeTy* node) { - return node->getNodeKind() == SVFVar::ObjNode || - node->getNodeKind() == SVFVar::GepObjNode || - node->getNodeKind() == SVFVar::FIObjNode || - node->getNodeKind() == SVFVar::DummyObjNode; + return node->getNodeKind() == SVFVar::ObjNode || node->getNodeKind() == SVFVar::GepObjNode || + node->getNodeKind() == SVFVar::FIObjNode || node->getNodeKind() == SVFVar::DummyObjNode; } //@} @@ -358,8 +335,7 @@ class ObjVar: public SVFVar /// Return name of a LLVM value virtual const std::string getValueName() const { - if (value) - return value->getName(); + if (value) return value->getName(); return ""; } /// Return type of the value @@ -371,19 +347,18 @@ class ObjVar: public SVFVar virtual const std::string toString() const; }; - /* * Gep Value (Pointer) variable, this variable can be dynamic generated for field sensitive analysis * e.g. memcpy, temp gep value variable needs to be created * Each Gep Value variable is connected to base value variable via gep edge */ -class GepValVar: public ValVar +class GepValVar : public ValVar { friend class SVFIRWriter; friend class SVFIRReader; private: - AccessPath ap; // AccessPath + AccessPath ap; // AccessPath const SVFType* gepValType; /// Constructor to create empty GeValVar (for SVFIRReader/deserialization) @@ -392,27 +367,26 @@ class GepValVar: public ValVar public: /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const GepValVar *) + static inline bool classof(const GepValVar*) { return true; } - static inline bool classof(const ValVar * node) + static inline bool classof(const ValVar* node) { return node->getNodeKind() == SVFVar::GepValNode; } - static inline bool classof(const SVFVar *node) + static inline bool classof(const SVFVar* node) { return node->getNodeKind() == SVFVar::GepValNode; } - static inline bool classof(const GenericPAGNodeTy *node) + static inline bool classof(const GenericPAGNodeTy* node) { return node->getNodeKind() == SVFVar::GepValNode; } //@} /// Constructor - GepValVar(const SVFValue* val, NodeID i, const AccessPath& ap, - const SVFType* ty) + GepValVar(const SVFValue* val, NodeID i, const AccessPath& ap, const SVFType* ty) : ValVar(val, i, GepValNode), ap(ap), gepValType(ty) { } @@ -426,9 +400,7 @@ class GepValVar: public ValVar /// Return name of a LLVM value inline const std::string getValueName() const { - if (value) - return value->getName() + "_" + - std::to_string(getConstantFieldIdx()); + if (value) return value->getName() + "_" + std::to_string(getConstantFieldIdx()); return "offset_" + std::to_string(getConstantFieldIdx()); } @@ -440,12 +412,11 @@ class GepValVar: public ValVar virtual const std::string toString() const; }; - /* * Gep Obj variable, this is dynamic generated for field sensitive analysis * Each gep obj variable is one field of a MemObj (base) */ -class GepObjVar: public ObjVar +class GepObjVar : public ObjVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -480,8 +451,7 @@ class GepObjVar: public ObjVar //@} /// Constructor - GepObjVar(const MemObj* mem, NodeID i, const APOffset& apOffset, - PNODEK ty = GepObjNode) + GepObjVar(const MemObj* mem, NodeID i, const APOffset& apOffset, PNODEK ty = GepObjNode) : ObjVar(mem->getValue(), i, mem, ty), apOffset(apOffset) { base = mem->getId(); @@ -514,8 +484,7 @@ class GepObjVar: public ObjVar /// Return name of a LLVM value inline const std::string getValueName() const { - if (value) - return value->getName() + "_" + std::to_string(apOffset); + if (value) return value->getName() + "_" + std::to_string(apOffset); return "offset_" + std::to_string(apOffset); } @@ -526,7 +495,7 @@ class GepObjVar: public ObjVar * Field-insensitive Gep Obj variable, this is dynamic generated for field sensitive analysis * Each field-insensitive gep obj node represents all fields of a MemObj (base) */ -class FIObjVar: public ObjVar +class FIObjVar : public ObjVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -557,17 +526,12 @@ class FIObjVar: public ObjVar //@} /// Constructor - FIObjVar(const SVFValue* val, NodeID i, const MemObj* mem, - PNODEK ty = FIObjNode) - : ObjVar(val, i, mem, ty) - { - } + FIObjVar(const SVFValue* val, NodeID i, const MemObj* mem, PNODEK ty = FIObjNode) : ObjVar(val, i, mem, ty) {} /// Return name of a LLVM value inline const std::string getValueName() const { - if (value) - return value->getName() + " (base object)"; + if (value) return value->getName() + " (base object)"; return " (base object)"; } @@ -577,7 +541,7 @@ class FIObjVar: public ObjVar /* * Unique Return node of a procedure */ -class RetPN: public ValVar +class RetPN : public ValVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -621,7 +585,7 @@ class RetPN: public ValVar /* * Unique vararg node of a procedure */ -class VarArgPN: public ValVar +class VarArgPN : public ValVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -665,7 +629,7 @@ class VarArgPN: public ValVar /* * Dummy variable without any LLVM value */ -class DummyValVar: public ValVar +class DummyValVar : public ValVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -705,7 +669,7 @@ class DummyValVar: public ValVar /* * Dummy object variable */ -class DummyObjVar: public ObjVar +class DummyObjVar : public ObjVar { friend class SVFIRWriter; friend class SVFIRReader; @@ -735,10 +699,7 @@ class DummyObjVar: public ObjVar //@} /// Constructor - DummyObjVar(NodeID i, const MemObj* m, PNODEK ty = DummyObjNode) - : ObjVar(nullptr, i, m, ty) - { - } + DummyObjVar(NodeID i, const MemObj* m, PNODEK ty = DummyObjNode) : ObjVar(nullptr, i, m, ty) {} /// Return name of this node inline const std::string getValueName() const diff --git a/svf/include/SVFIR/SymbolTableInfo.h b/svf/include/SVFIR/SymbolTableInfo.h index b856409c9..704f2d8c8 100644 --- a/svf/include/SVFIR/SymbolTableInfo.h +++ b/svf/include/SVFIR/SymbolTableInfo.h @@ -30,7 +30,6 @@ #ifndef INCLUDE_SVFIR_SYMBOLTABLEINFO_H_ #define INCLUDE_SVFIR_SYMBOLTABLEINFO_H_ - #include "Util/SVFUtil.h" #include "MemoryModel/AccessPath.h" #include "SVFIR/SVFModule.h" @@ -51,7 +50,6 @@ class SymbolTableInfo friend class SVFIRReader; public: - /// Symbol types enum SYMTYPE { @@ -102,14 +100,9 @@ class SymbolTableInfo protected: /// Constructor - SymbolTableInfo(void) - : mod(nullptr), modelConstants(false), totalSymNum(0), - maxStruct(nullptr), maxStSize(0) - { - } + SymbolTableInfo(void) : mod(nullptr), modelConstants(false), totalSymNum(0), maxStruct(nullptr), maxStSize(0) {} public: - /// Singleton design here to make sure we only have one instance during any analysis //@{ static SymbolTableInfo* SymbolInfo(); @@ -213,36 +206,35 @@ class SymbolTableInfo inline SymID getObjSym(const SVFValue* val) const { const SVFValue* svfVal = val; - if(const SVFGlobalValue* g = SVFUtil::dyn_cast(val)) + if (const SVFGlobalValue* g = SVFUtil::dyn_cast(val)) svfVal = g->getDefGlobalForMultipleModule(); ValueToIDMapTy::const_iterator iter = objSymMap.find(svfVal); - assert(iter!=objSymMap.end() && "obj sym not found"); + assert(iter != objSymMap.end() && "obj sym not found"); return iter->second; } inline MemObj* getObj(SymID id) const { IDToMemMapTy::const_iterator iter = objMap.find(id); - assert(iter!=objMap.end() && "obj not found"); + assert(iter != objMap.end() && "obj not found"); return iter->second; } inline SymID getRetSym(const SVFFunction* val) const { - FunToIDMapTy::const_iterator iter = returnSymMap.find(val); - assert(iter!=returnSymMap.end() && "ret sym not found"); + FunToIDMapTy::const_iterator iter = returnSymMap.find(val); + assert(iter != returnSymMap.end() && "ret sym not found"); return iter->second; } inline SymID getVarargSym(const SVFFunction* val) const { - FunToIDMapTy::const_iterator iter = varargSymMap.find(val); - assert(iter!=varargSymMap.end() && "vararg sym not found"); + FunToIDMapTy::const_iterator iter = varargSymMap.find(val); + assert(iter != varargSymMap.end() && "vararg sym not found"); return iter->second; } //@} - /// Statistics //@{ inline u32_t getTotalSymNum() const @@ -304,15 +296,15 @@ class SymbolTableInfo /// Get struct info //@{ - ///Get a reference to StructInfo. + /// Get a reference to StructInfo. const StInfo* getTypeInfo(const SVFType* T) const; inline bool hasSVFTypeInfo(const SVFType* T) { return svfTypes.find(T) != svfTypes.end(); } - ///Get a reference to the components of struct_info. - /// Number of flattened elements of an array or struct + /// Get a reference to the components of struct_info. + /// Number of flattened elements of an array or struct u32_t getNumOfFlattenElements(const SVFType* T); /// Flattened element idx of an array or struct by considering stride u32_t getFlattenedElemIdx(const SVFType* T, u32_t origId); @@ -333,20 +325,18 @@ class SymbolTableInfo virtual void dump(); /// Given an offset from a Gep Instruction, return it modulus offset by considering memory layout - virtual APOffset getModulusOffset(const MemObj* obj, - const APOffset& apOffset); + virtual APOffset getModulusOffset(const MemObj* obj, const APOffset& apOffset); - ///The struct type with the most fields + /// The struct type with the most fields const SVFType* maxStruct; - ///The number of fields in max_struct + /// The number of fields in max_struct u32_t maxStSize; inline void addTypeInfo(const SVFType* ty) { bool inserted = svfTypes.insert(ty).second; - if(!inserted) - assert(false && "this type info has been added before"); + if (!inserted) assert(false && "this type info has been added before"); } inline void addStInfo(StInfo* stInfo) @@ -355,9 +345,8 @@ class SymbolTableInfo } protected: - /// Return the flattened field type for struct type only - const std::vector& getFlattenFieldTypes(const SVFStructType *T); + const std::vector& getFlattenFieldTypes(const SVFStructType* T); /// Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy object) ObjTypeInfo* createObjTypeInfo(const SVFType* type); @@ -373,7 +362,6 @@ class SymbolTableInfo Set stInfos; }; - /*! * Memory object symbols or MemObj (address-taken variables in LLVM-based languages) */ @@ -444,7 +432,6 @@ class MemObj /// Check if byte size is a const value bool isConstantByteSize() const; - /// object attributes methods //@{ bool isFunction() const; @@ -484,17 +471,17 @@ class ObjTypeInfo public: typedef enum { - FUNCTION_OBJ = 0x1, // object is a function - GLOBVAR_OBJ = 0x2, // object is a global variable - STATIC_OBJ = 0x4, // object is a static variable allocated before main - STACK_OBJ = 0x8, // object is a stack variable - HEAP_OBJ = 0x10, // object is a heap variable - VAR_STRUCT_OBJ = 0x20, // object contains struct - VAR_ARRAY_OBJ = 0x40, // object contains array + FUNCTION_OBJ = 0x1, // object is a function + GLOBVAR_OBJ = 0x2, // object is a global variable + STATIC_OBJ = 0x4, // object is a static variable allocated before main + STACK_OBJ = 0x8, // object is a stack variable + HEAP_OBJ = 0x10, // object is a heap variable + VAR_STRUCT_OBJ = 0x20, // object contains struct + VAR_ARRAY_OBJ = 0x40, // object contains array CONST_STRUCT_OBJ = 0x80, // constant struct CONST_ARRAY_OBJ = 0x100, // constant array - CONST_GLOBAL_OBJ = 0x200, // global constant object - CONST_DATA = 0x400, // constant object str e.g. 5, 10, 1.0 + CONST_GLOBAL_OBJ = 0x200, // global constant object + CONST_DATA = 0x400, // constant object str e.g. 5, 10, 1.0 } MEMTYPE; private: @@ -513,15 +500,13 @@ class ObjTypeInfo u32_t byteSize; void resetTypeForHeapStaticObj(const SVFType* type); -public: +public: /// Constructors ObjTypeInfo(const SVFType* t, u32_t max); /// Destructor - virtual ~ObjTypeInfo() - { - } + virtual ~ObjTypeInfo() {} /// Get LLVM type inline const SVFType* getType() const @@ -630,7 +615,7 @@ class ObjTypeInfo } inline bool isConstantArray() { - return hasFlag(CONST_ARRAY_OBJ); + return hasFlag(CONST_ARRAY_OBJ); } inline bool isArray() { @@ -647,7 +632,6 @@ class ObjTypeInfo //@} }; - } // End namespace SVF #endif /* INCLUDE_SVFIR_SYMBOLTABLEINFO_H_ */ diff --git a/svf/include/Util/Annotator.h b/svf/include/Util/Annotator.h index aa2157919..771fbce36 100644 --- a/svf/include/Util/Annotator.h +++ b/svf/include/Util/Annotator.h @@ -35,21 +35,19 @@ class Annotator } /// Destructor - virtual ~Annotator() - { - } + virtual ~Annotator() {} /// SB Has flag methods //@{ inline bool hasSBSourceFlag(Instruction* inst) const { - std::vector values; + std::vector values; return evalMDTag(inst, inst, SB_SLICESOURCE, values); } inline bool hasSBSinkFlag(Instruction* inst) const { - std::vector values; + std::vector values; return evalMDTag(inst, inst, SB_SLICESINK, values); } //@} @@ -58,29 +56,29 @@ class Annotator //@{ inline bool hasDRNotCheckFlag(Instruction* inst) const { - //std::vector values; - //return evalMDTag(inst, inst, DR_NOT_CHECK, values); + // std::vector values; + // return evalMDTag(inst, inst, DR_NOT_CHECK, values); return inst->getMetadata(DR_NOT_CHECK); } inline bool hasDRNotCheckFlag(const Instruction* inst) const { - //std::vector values; - //return evalMDTag(inst, inst, DR_NOT_CHECK, values); + // std::vector values; + // return evalMDTag(inst, inst, DR_NOT_CHECK, values); return inst->getMetadata(DR_NOT_CHECK); } inline bool hasDRCheckFlag(Instruction* inst) const { - //std::vector values; - //return evalMDTag(inst, inst, DR_CHECK, values); + // std::vector values; + // return evalMDTag(inst, inst, DR_CHECK, values); return inst->getMetadata(DR_CHECK); } inline bool hasDRCheckFlag(const Instruction* inst) const { - //std::vector values; - //return evalMDTag(inst, inst, DR_CHECK, values); + // std::vector values; + // return evalMDTag(inst, inst, DR_CHECK, values); return inst->getMetadata(DR_CHECK); } //@} @@ -103,17 +101,17 @@ class Annotator inline void addMDTag(Instruction* inst, Value* val, std::string str) { assert(!val->getType()->isVoidTy() && "expecting non-void value for MD!"); - std::vector values; - //std::vector metavalues; - // add the flag if we did not see it before + std::vector values; + // std::vector metavalues; + // add the flag if we did not see it before if (evalMDTag(inst, val, str, values) == false) { values.push_back(val); - //llvm::ArrayRef ar(metavalues); - // FIXME: delete the old MDNode + // llvm::ArrayRef ar(metavalues); + // FIXME: delete the old MDNode inst->setMetadata(str, MDNode::get(inst->getContext(), nullptr)); - //inst->setMetadata(str, llvm::MDNode::get(inst->getContext(), ar)); + // inst->setMetadata(str, llvm::MDNode::get(inst->getContext(), ar)); } } @@ -121,45 +119,42 @@ class Annotator inline void removeMDTag(Instruction* inst, Value* val, std::string str) { assert(!val->getType()->isVoidTy() && "expecting non-void value for MD!"); - std::vector values; + std::vector values; // remove the flag if it is there if (evalMDTag(inst, val, str, values) == true) { - llvm::ArrayRef ar(values); + llvm::ArrayRef ar(values); // FIXME: delete the old MDNode - //inst->setMetadata(str, llvm::MDNode::get(inst->getContext(), ar)); + // inst->setMetadata(str, llvm::MDNode::get(inst->getContext(), ar)); } } //@} private: - /// evaluate llvm metadata - inline bool evalMDTag(const Instruction* inst, const Value* val, std::string str, - std::vector&) const + inline bool evalMDTag(const Instruction* inst, const Value* val, std::string str, std::vector&) const { assert(val && "value should not be null"); bool hasFlag = false; - if (MDNode *mdNode = inst->getMetadata(str)) + if (MDNode* mdNode = inst->getMetadata(str)) { /// When mdNode has operands and value is not null for (unsigned k = 0; k < mdNode->getNumOperands(); ++k) { - //Value* v = mdNode->getOperand(k); - // if (v == val) - // hasFlag = true; - //else - // values.push_back(v); + // Value* v = mdNode->getOperand(k); + // if (v == val) + // hasFlag = true; + // else + // values.push_back(v); } } return hasFlag; } protected: - /// Saber annotations //@{ const char* SB_SLICESOURCE; diff --git a/svf/include/Util/BitVector.h b/svf/include/Util/BitVector.h index c2198c005..c4d9552d0 100644 --- a/svf/include/Util/BitVector.h +++ b/svf/include/Util/BitVector.h @@ -38,18 +38,18 @@ class BitVector : public CoreBitVector BitVector(size_t n); /// Copy constructor. - BitVector(const BitVector &bv); + BitVector(const BitVector& bv); /// Move constructor. - BitVector(BitVector &&bv); + BitVector(BitVector&& bv); /// Copy assignment. - BitVector &operator=(const BitVector &rhs); + BitVector& operator=(const BitVector& rhs); /// Move assignment. - BitVector &operator=(BitVector &&rhs); + BitVector& operator=(BitVector&& rhs); }; -}; // namespace SVF +}; // namespace SVF -#endif // BITVECTOR_H_ +#endif // BITVECTOR_H_ diff --git a/svf/include/Util/CDGBuilder.h b/svf/include/Util/CDGBuilder.h index d7135f175..c6ad0ef26 100644 --- a/svf/include/Util/CDGBuilder.h +++ b/svf/include/Util/CDGBuilder.h @@ -38,70 +38,53 @@ namespace SVF class CDGBuilder { public: - /// constructor - CDGBuilder() : _controlDG(CDG::getCDG()) - { - - } + CDGBuilder() : _controlDG(CDG::getCDG()) {} /// destructor - ~CDGBuilder() - { - - } + ~CDGBuilder() {} /// start here void build(); /// build control dependence for each function - void buildControlDependence(const SVFModule *svfgModule); + void buildControlDependence(const SVFModule* svfgModule); /// build map at icfg node level void buildICFGNodeControlMap(); - - private: - - /// extract basic block edges to be processed - static void - extractBBS(const SVFFunction *func, - Map> &res); + static void extractBBS(const SVFFunction* func, Map>& res); /// extract nodes between two nodes in pdom tree - void - extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBasicBlock *LCA, - std::vector &tgtNodes); - + void extractNodesBetweenPdomNodes(const SVFBasicBlock* succ, const SVFBasicBlock* LCA, + std::vector& tgtNodes); - void dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur, - const SVFBasicBlock *tgt, - std::vector &path, - std::vector &tgtNodes, - SVFLoopAndDomInfo *ld); - - - s64_t getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasicBlock *Succ); + void dfsNodesBetweenPdomNodes(const SVFBasicBlock* cur, const SVFBasicBlock* tgt, + std::vector& path, std::vector& tgtNodes, + SVFLoopAndDomInfo* ld); + s64_t getBBSuccessorBranchID(const SVFBasicBlock* BB, const SVFBasicBlock* Succ); /// update map - inline void updateMap(const SVFBasicBlock *pred, const SVFBasicBlock *bb, s32_t pos) + inline void updateMap(const SVFBasicBlock* pred, const SVFBasicBlock* bb, s32_t pos) { _svfcontrolMap[pred][bb].insert(pos); _svfdependentOnMap[bb][pred].insert(pos); } - private: - CDG *_controlDG; - Map>> _svfcontrolMap; ///< map a basicblock to its controlling BBs (position, set of BBs) - Map>> _svfdependentOnMap; ///< map a basicblock to its dependent on BBs (position, set of BBs) - Map>> _nodeControlMap; ///< map an ICFG node to its controlling ICFG nodes (position, set of Nodes) - Map>> _nodeDependentOnMap; ///< map an ICFG node to its dependent on ICFG nodes (position, set of Nodes) + CDG* _controlDG; + Map>> + _svfcontrolMap; ///< map a basicblock to its controlling BBs (position, set of BBs) + Map>> + _svfdependentOnMap; ///< map a basicblock to its dependent on BBs (position, set of BBs) + Map>> + _nodeControlMap; ///< map an ICFG node to its controlling ICFG nodes (position, set of Nodes) + Map>> + _nodeDependentOnMap; ///< map an ICFG node to its dependent on ICFG nodes (position, set of Nodes) }; -} - +} // namespace SVF -#endif //SVF_CDGBUILDER_H \ No newline at end of file +#endif // SVF_CDGBUILDER_H \ No newline at end of file diff --git a/svf/include/Util/CallGraphBuilder.h b/svf/include/Util/CallGraphBuilder.h index 39afafd65..ab303d3cd 100644 --- a/svf/include/Util/CallGraphBuilder.h +++ b/svf/include/Util/CallGraphBuilder.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * CallGraphBuilder.h * @@ -45,30 +44,24 @@ class CallGraphBuilder protected: CallGraph* callgraph; ICFG* icfg; + public: - CallGraphBuilder(CallGraph* cg, ICFG* i): callgraph(cg),icfg(i) - { - } + CallGraphBuilder(CallGraph* cg, ICFG* i) : callgraph(cg), icfg(i) {} /// Build normal callgraph CallGraph* buildCallGraph(SVFModule* svfModule); - }; class ThreadCallGraphBuilder : public CallGraphBuilder { public: - ThreadCallGraphBuilder(ThreadCallGraph* cg, ICFG* i): CallGraphBuilder(cg,i) - { - } + ThreadCallGraphBuilder(ThreadCallGraph* cg, ICFG* i) : CallGraphBuilder(cg, i) {} /// Build thread-aware callgraph CallGraph* buildThreadCallGraph(SVFModule* svfModule); - }; } // End namespace SVF - #endif /* INCLUDE_UTIL_CALLGRAPHBUILDER_H_ */ diff --git a/svf/include/Util/Casting.h b/svf/include/Util/Casting.h index fed46a073..2065d55d7 100644 --- a/svf/include/Util/Casting.h +++ b/svf/include/Util/Casting.h @@ -8,7 +8,6 @@ #ifndef INCLUDE_UTIL_CASTING_H_ #define INCLUDE_UTIL_CASTING_H_ - //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===// // // The LLVM Compiler Infrastructure @@ -32,28 +31,28 @@ // Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in // C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid. #ifndef LLVM_HAS_CPP_ATTRIBUTE -#if defined(__cplusplus) && defined(__has_cpp_attribute) -# define LLVM_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -# define LLVM_HAS_CPP_ATTRIBUTE(x) 0 -#endif +# if defined(__cplusplus) && defined(__has_cpp_attribute) +# define LLVM_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +# else +# define LLVM_HAS_CPP_ATTRIBUTE(x) 0 +# endif #endif /// LLVM_NODISCARD - Warn if a type or return value is discarded. // Use the 'nodiscard' attribute in C++17 or newer mode. #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) -#define LLVM_NODISCARD [[nodiscard]] +# define LLVM_NODISCARD [[nodiscard]] #elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result) -#define LLVM_NODISCARD [[clang::warn_unused_result]] +# define LLVM_NODISCARD [[clang::warn_unused_result]] // Clang in C++14 mode claims that it has the 'nodiscard' attribute, but also // warns in the pedantic mode that 'nodiscard' is a C++17 extension (PR33518). // Use the 'nodiscard' attribute in C++14 mode only with GCC. // TODO: remove this workaround when PR33518 is resolved. #elif defined(__GNUC__) && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) -#define LLVM_NODISCARD [[nodiscard]] +# define LLVM_NODISCARD [[nodiscard]] #else -#define LLVM_NODISCARD +# define LLVM_NODISCARD #endif namespace SVF @@ -66,28 +65,23 @@ namespace SVFUtil /// If T is a pointer to X, return a pointer to const X. If it is not, /// return const T. -template -struct add_const_past_pointer +template struct add_const_past_pointer { using type = const T; }; -template -struct add_const_past_pointer::value>> +template struct add_const_past_pointer::value>> { - using type = const std::remove_pointer_t *; + using type = const std::remove_pointer_t*; }; /// If T is a pointer, just return it. If it is not, return T&. -template -struct add_lvalue_reference_if_not_pointer +template struct add_lvalue_reference_if_not_pointer { - using type = T &; + using type = T&; }; -template -struct add_lvalue_reference_if_not_pointer< - T, std::enable_if_t::value>> +template struct add_lvalue_reference_if_not_pointer::value>> { using type = T; }; @@ -100,24 +94,22 @@ struct add_lvalue_reference_if_not_pointer< // fact that they are automatically dereferenced, and are not involved with the // template selection process... the default implementation is a noop. // -template struct simplify_type +template struct simplify_type { using SimpleType = From; // The real type this represents... // An accessor to get the real value... - static SimpleType &getSimplifiedValue(From &Val) + static SimpleType& getSimplifiedValue(From& Val) { return Val; } }; -template struct simplify_type +template struct simplify_type { using NonConstSimpleType = typename simplify_type::SimpleType; - using SimpleType = - typename SVFUtil::add_const_past_pointer::type; - using RetType = - typename SVFUtil::add_lvalue_reference_if_not_pointer::type; + using SimpleType = typename SVFUtil::add_const_past_pointer::type; + using RetType = typename SVFUtil::add_lvalue_reference_if_not_pointer::type; static RetType getSimplifiedValue(const From& Val) { @@ -128,20 +120,18 @@ template struct simplify_type // The core of the implementation of SVFUtil::isa is here; To and From should be // the names of classes. This template can be specialized to customize the // implementation of SVFUtil::isa<> without rewriting it from scratch. -template -struct isa_impl +template struct isa_impl { - static inline bool doit(const From &Val) + static inline bool doit(const From& Val) { return To::classof(&Val); } }; /// \brief Always allow upcasts, and perform no dynamic check for them. -template -struct isa_impl::value>> +template struct isa_impl::value>> { - static inline bool doit(const From &) + static inline bool doit(const From&) { return true; } @@ -149,7 +139,7 @@ struct isa_impl::value>> template struct isa_impl_cl { - static inline bool doit(const From &Val) + static inline bool doit(const From& Val) { return isa_impl::doit(Val); } @@ -157,16 +147,15 @@ template struct isa_impl_cl template struct isa_impl_cl { - static inline bool doit(const From &Val) + static inline bool doit(const From& Val) { return isa_impl::doit(Val); } }; -template -struct isa_impl_cl> +template struct isa_impl_cl> { - static inline bool doit(const std::unique_ptr &Val) + static inline bool doit(const std::unique_ptr& Val) { assert(Val && "SVFUtil::isa<> used on a null pointer"); return isa_impl_cl::doit(*Val); @@ -175,16 +164,16 @@ struct isa_impl_cl> template struct isa_impl_cl { - static inline bool doit(const From *Val) + static inline bool doit(const From* Val) { assert(Val && "SVFUtil::isa<> used on a null pointer"); return isa_impl::doit(*Val); } }; -template struct isa_impl_cl +template struct isa_impl_cl { - static inline bool doit(const From *Val) + static inline bool doit(const From* Val) { assert(Val && "SVFUtil::isa<> used on a null pointer"); return isa_impl::doit(*Val); @@ -193,42 +182,39 @@ template struct isa_impl_cl template struct isa_impl_cl { - static inline bool doit(const From *Val) + static inline bool doit(const From* Val) { assert(Val && "SVFUtil::isa<> used on a null pointer"); return isa_impl::doit(*Val); } }; -template struct isa_impl_cl +template struct isa_impl_cl { - static inline bool doit(const From *Val) + static inline bool doit(const From* Val) { assert(Val && "SVFUtil::isa<> used on a null pointer"); return isa_impl::doit(*Val); } }; -template -struct isa_impl_wrap +template struct isa_impl_wrap { // When From != SimplifiedType, we can simplify the type some more by using // the simplify_type template. - static bool doit(const From &Val) + static bool doit(const From& Val) { - return isa_impl_wrap::SimpleType>::doit( - simplify_type::getSimplifiedValue(Val)); + return isa_impl_wrap::SimpleType>::doit( + simplify_type::getSimplifiedValue(Val)); } }; -template -struct isa_impl_wrap +template struct isa_impl_wrap { // When From == SimpleType, we are as simple as we are going to get. - static bool doit(const FromTy &Val) + static bool doit(const FromTy& Val) { - return isa_impl_cl::doit(Val); + return isa_impl_cl::doit(Val); } }; @@ -238,14 +224,12 @@ struct isa_impl_wrap // if (SVFUtil::isa(myVal)) { ... } // if (SVFUtil::isa(myVal)) { ... } // -template LLVM_NODISCARD inline bool isa(const Y &Val) +template LLVM_NODISCARD inline bool isa(const Y& Val) { - return isa_impl_wrap::SimpleType>::doit(Val); + return isa_impl_wrap::SimpleType>::doit(Val); } -template -LLVM_NODISCARD inline bool isa(const Y &Val) +template LLVM_NODISCARD inline bool isa(const Y& Val) { return SVFUtil::isa(Val) || SVFUtil::isa(Val); } @@ -254,47 +238,45 @@ LLVM_NODISCARD inline bool isa(const Y &Val) // cast Support Templates //===----------------------------------------------------------------------===// -template struct cast_retty; +template struct cast_retty; // Calculate what type the 'cast' function should return, based on a requested // type of To and a source type of From. -template struct cast_retty_impl +template struct cast_retty_impl { - using ret_type = To &; // Normal case, return Ty& + using ret_type = To&; // Normal case, return Ty& }; -template struct cast_retty_impl +template struct cast_retty_impl { - using ret_type = const To &; // Normal case, return Ty& + using ret_type = const To&; // Normal case, return Ty& }; -template struct cast_retty_impl +template struct cast_retty_impl { - using ret_type = To *; // Pointer arg case, return Ty* + using ret_type = To*; // Pointer arg case, return Ty* }; -template struct cast_retty_impl +template struct cast_retty_impl { - using ret_type = const To *; // Constant pointer arg case, return const Ty* + using ret_type = const To*; // Constant pointer arg case, return const Ty* }; -template struct cast_retty_impl +template struct cast_retty_impl { - using ret_type = const To *; // Constant pointer arg case, return const Ty* + using ret_type = const To*; // Constant pointer arg case, return const Ty* }; -template -struct cast_retty_impl> +template struct cast_retty_impl> { private: - using PointerType = typename cast_retty_impl::ret_type; + using PointerType = typename cast_retty_impl::ret_type; using ResultType = typename std::remove_pointer::type; public: using ret_type = std::unique_ptr; }; -template -struct cast_retty_wrap +template struct cast_retty_wrap { // When the simplified type and the from type are not the same, use the type // simplifier to reduce the type, then reuse cast_retty_impl to get the @@ -302,49 +284,44 @@ struct cast_retty_wrap using ret_type = typename cast_retty::ret_type; }; -template -struct cast_retty_wrap +template struct cast_retty_wrap { // When the simplified type is equal to the from type, use it directly. - using ret_type = typename cast_retty_impl::ret_type; + using ret_type = typename cast_retty_impl::ret_type; }; -template -struct cast_retty +template struct cast_retty { - using ret_type = typename cast_retty_wrap< - To, From, typename simplify_type::SimpleType>::ret_type; + using ret_type = typename cast_retty_wrap::SimpleType>::ret_type; }; // Ensure the non-simple values are converted using the simplify_type template // that may be specialized by smart pointers... // -template struct cast_convert_val +template struct cast_convert_val { // This is not a simple type, use the template to simplify it... - static typename cast_retty::ret_type doit(From &Val) + static typename cast_retty::ret_type doit(From& Val) { - return cast_convert_val::SimpleType>::doit( - simplify_type::getSimplifiedValue(Val)); + return cast_convert_val::SimpleType>::doit( + simplify_type::getSimplifiedValue(Val)); } }; -template struct cast_convert_val +template struct cast_convert_val { // This _is_ a simple type, just cast it. - static typename cast_retty::ret_type doit(const FromTy &Val) + static typename cast_retty::ret_type doit(const FromTy& Val) { - typename cast_retty::ret_type Res2 - = (typename cast_retty::ret_type)const_cast(Val); + typename cast_retty::ret_type Res2 = + (typename cast_retty::ret_type) const_cast(Val); return Res2; } }; template struct is_simple_type { - static const bool value = - std::is_same::SimpleType>::value; + static const bool value = std::is_same::SimpleType>::value; }; // cast - Return the argument parameter cast to the specified type. This @@ -355,40 +332,29 @@ template struct is_simple_type // cast(myVal)->getParent() // template -inline std::enable_if_t::value, - typename cast_retty::ret_type> - cast(const Y &Val) +inline std::enable_if_t::value, typename cast_retty::ret_type> cast(const Y& Val) { assert(SVFUtil::isa(Val) && "cast() argument of incompatible type!"); - return cast_convert_val< - X, const Y, typename simplify_type::SimpleType>::doit(Val); + return cast_convert_val::SimpleType>::doit(Val); } -template -inline typename cast_retty::ret_type cast(Y &Val) +template inline typename cast_retty::ret_type cast(Y& Val) { assert(SVFUtil::isa(Val) && "cast() argument of incompatible type!"); - return cast_convert_val::SimpleType>::doit(Val); + return cast_convert_val::SimpleType>::doit(Val); } -template -inline typename cast_retty::ret_type cast(Y *Val) +template inline typename cast_retty::ret_type cast(Y* Val) { assert(SVFUtil::isa(Val) && "cast() argument of incompatible type!"); - return cast_convert_val::SimpleType>::doit(Val); + return cast_convert_val::SimpleType>::doit(Val); } -template -inline typename cast_retty>::ret_type - cast(std::unique_ptr &&Val) +template inline typename cast_retty>::ret_type cast(std::unique_ptr&& Val) { assert(SVFUtil::isa(Val.get()) && "cast() argument of incompatible type!"); using ret_type = typename cast_retty>::ret_type; - return ret_type( - cast_convert_val::SimpleType>::doit( - Val.release())); + return ret_type(cast_convert_val::SimpleType>::doit(Val.release())); } // dyn_cast - Return the argument parameter cast to the specified type. This @@ -400,21 +366,18 @@ inline typename cast_retty>::ret_type // template -LLVM_NODISCARD inline std::enable_if_t< -!is_simple_type::value, typename cast_retty::ret_type> -dyn_cast(const Y &Val) +LLVM_NODISCARD inline std::enable_if_t::value, typename cast_retty::ret_type> dyn_cast( + const Y& Val) { return SVFUtil::isa(Val) ? SVFUtil::cast(Val) : nullptr; } -template -LLVM_NODISCARD inline typename cast_retty::ret_type dyn_cast(Y &Val) +template LLVM_NODISCARD inline typename cast_retty::ret_type dyn_cast(Y& Val) { return SVFUtil::isa(Val) ? SVFUtil::cast(Val) : nullptr; } -template -LLVM_NODISCARD inline typename cast_retty::ret_type dyn_cast(Y *Val) +template LLVM_NODISCARD inline typename cast_retty::ret_type dyn_cast(Y* Val) { return SVFUtil::isa(Val) ? SVFUtil::cast(Val) : nullptr; } diff --git a/svf/include/Util/CommandLine.h b/svf/include/Util/CommandLine.h index 4614c44de..e8bff3c1a 100644 --- a/svf/include/Util/CommandLine.h +++ b/svf/include/Util/CommandLine.h @@ -26,14 +26,10 @@ class OptionBase /// Value/name/description tuples. If [1] is the value on the commandline for an option, we'd /// set the value for the associated Option to [0]. - template - using OptionPossibility = std::tuple; + template using OptionPossibility = std::tuple; protected: - OptionBase(std::string name, std::string description) - : OptionBase(name, description, {}) - { - } + OptionBase(std::string name, std::string description) : OptionBase(name, description, {}) {} OptionBase(std::string name, std::string description, PossibilityDescriptions possibilityDescriptions) : name(name), description(description), possibilityDescriptions(possibilityDescriptions) @@ -72,7 +68,8 @@ class OptionBase public: /// Parse all constructed OptionBase children, returning positional arguments /// in the order they appeared. - static std::vector parseOptions(int argc, char *argv[], std::string description, std::string callFormat) + static std::vector parseOptions(int argc, char* argv[], std::string description, + std::string callFormat) { const std::string usage = buildUsage(description, std::string(argv[0]), callFormat); @@ -95,7 +92,7 @@ class OptionBase std::string argName; std::string argValue; - OptionBase *opt = nullptr; + OptionBase* opt = nullptr; size_t equalsSign = arg.find('='); if (equalsSign != std::string::npos) @@ -171,16 +168,14 @@ class OptionBase /// Sets the usage member to a usage string, built from the static list of options. /// argv0 is argv[0] and callFormat is how the command should be used, minus the command /// name (e.g. "[options] ". - static std::string buildUsage( - const std::string description, const std::string argv0, const std::string callFormat - ) + static std::string buildUsage(const std::string description, const std::string argv0, const std::string callFormat) { // Determine longest option to split into two columns: options and descriptions. unsigned longest = 0; - for (const std::pair nopt : getOptionsMap()) + for (const std::pair nopt : getOptionsMap()) { const std::string name = std::get<0>(nopt); - const OptionBase *option = std::get<1>(nopt); + const OptionBase* option = std::get<1>(nopt); if (option->isMultiple()) { // For Multiple, description goes in left column. @@ -191,7 +186,7 @@ class OptionBase if (name.length() > longest) longest = name.length(); } - for (const PossibilityDescription &pd : option->possibilityDescriptions) + for (const PossibilityDescription& pd : option->possibilityDescriptions) { const std::string possibility = std::get<0>(pd); if (possibility.length() + 3 > longest) longest = possibility.length() + 3; @@ -209,11 +204,11 @@ class OptionBase ss << "OPTIONS:" << std::endl; // Required as we have OptionMultiples doing a many-to-one in options. - std::unordered_set handled; - for (const std::pair nopt : getOptionsMap()) + std::unordered_set handled; + for (const std::pair nopt : getOptionsMap()) { const std::string name = std::get<0>(nopt); - const OptionBase *option = std::get<1>(nopt); + const OptionBase* option = std::get<1>(nopt); if (handled.find(option) != handled.end()) continue; handled.insert(option); @@ -224,7 +219,7 @@ class OptionBase // -name2 - description // ... ss << " " << option->description << std::endl; - for (const PossibilityDescription &pd : option->possibilityDescriptions) + for (const PossibilityDescription& pd : option->possibilityDescriptions) { const std::string possibility = std::get<0>(pd); const std::string description = std::get<1>(pd); @@ -242,7 +237,7 @@ class OptionBase // ... ss << " -" << name << std::string(longest - name.length() + 2, ' '); ss << "- " << option->description << std::endl; - for (const PossibilityDescription &pd : option->possibilityDescriptions) + for (const PossibilityDescription& pd : option->possibilityDescriptions) { const std::string possibility = std::get<0>(pd); const std::string description = std::get<1>(pd); @@ -266,18 +261,20 @@ class OptionBase } /// Find option based on name in options map. Returns nullptr if not found. - static OptionBase *getOption(const std::string optName) + static OptionBase* getOption(const std::string optName) { auto optIt = getOptionsMap().find(optName); if (optIt == getOptionsMap().end()) return nullptr; - else return optIt->second; + else + return optIt->second; } /// Print usage and exit. If error is set, print to stderr and exits with code 1. static void usageAndExit(const std::string usage, bool error) { if (error) std::cerr << usage; - else std::cout << usage; + else + std::cout << usage; std::exit(error ? 1 : 0); } @@ -290,11 +287,11 @@ class OptionBase protected: // Return the name/description part of OptionsPossibilities (second and third fields). - template + template static PossibilityDescriptions extractPossibilityDescriptions(const std::vector> possibilities) { PossibilityDescriptions possibilityDescriptions; - for (const OptionPossibility &op : possibilities) + for (const OptionPossibility& op : possibilities) { possibilityDescriptions.push_back(std::make_pair(std::get<1>(op), std::get<2>(op))); } @@ -304,14 +301,13 @@ class OptionBase /// Not unordered map so we can have sorted names when building the usage string. /// Map of option names to their object. - static std::map &getOptionsMap(void) + static std::map& getOptionsMap(void) { // Not static member to avoid initialisation order problems. - static std::map options; + static std::map options; return options; } - protected: std::string name; std::string description; @@ -321,8 +317,7 @@ class OptionBase /// General -name=value options. /// Retrieve value by Opt(). -template -class Option : public OptionBase +template class Option : public OptionBase { public: Option(const std::string& name, const std::string& description, T init) @@ -362,8 +357,7 @@ class Option : public OptionBase // Convert string to boolean, returning whether we succeeded. static bool fromString(const std::string& s, bool& value) { - if (s == "true") - value = true; + if (s == "true") value = true; else if (s == "false") value = false; else @@ -372,14 +366,14 @@ class Option : public OptionBase } // Convert string to string, always succeeds. - static bool fromString(const std::string s, std::string &value) + static bool fromString(const std::string s, std::string& value) { value = s; return true; } // Convert string to u32_t, returning whether we succeeded. - static bool fromString(const std::string s, u32_t &value) + static bool fromString(const std::string s, u32_t& value) { // We won't allow anything except [0-9]+. if (s.empty()) return false; @@ -405,15 +399,14 @@ class Option : public OptionBase /// Option allowing a limited range of values, probably corresponding to an enum. /// Opt() gives the value. -template -class OptionMap : public OptionBase +template class OptionMap : public OptionBase { public: typedef std::vector> OptionPossibilities; OptionMap(std::string name, std::string description, T init, OptionPossibilities possibilities) - : OptionBase(name, description, extractPossibilityDescriptions(possibilities)), - isExplicitlySet(false), value(init), possibilities(possibilities) + : OptionBase(name, description, extractPossibilityDescriptions(possibilities)), isExplicitlySet(false), + value(init), possibilities(possibilities) { assert(!name.empty() && "OptionMap: empty option name given"); } @@ -425,7 +418,7 @@ class OptionMap : public OptionBase virtual bool parseAndSetValue(const std::string s) override { - for (const OptionPossibility &op : possibilities) + for (const OptionPossibility& op : possibilities) { // Check if the given string is a valid one. if (s == std::get<1>(op)) @@ -453,8 +446,7 @@ class OptionMap : public OptionBase /// Options which form a kind of bit set. There are multiple names and n of them can be set. /// Opt(v) tests whether v had been set, aborting if v is invalid. -template -class OptionMultiple : public OptionBase +template class OptionMultiple : public OptionBase { public: typedef std::vector> OptionPossibilities; @@ -462,12 +454,12 @@ class OptionMultiple : public OptionBase OptionMultiple(std::string description, OptionPossibilities possibilities) : OptionBase("", description, extractPossibilityDescriptions(possibilities)), possibilities(possibilities) { - for (const OptionPossibility &op : possibilities) + for (const OptionPossibility& op : possibilities) { optionValues[std::get<0>(op)] = false; } - for (const OptionPossibility &op : possibilities) + for (const OptionPossibility& op : possibilities) { std::string possibilityName = std::get<1>(op); getOptionsMap()[possibilityName] = this; @@ -482,7 +474,7 @@ class OptionMultiple : public OptionBase virtual bool parseAndSetValue(const std::string s) override { // Like in OptionMap basically, except we can have many values. - for (const OptionPossibility &op : possibilities) + for (const OptionPossibility& op : possibilities) { if (s == std::get<1>(op)) { @@ -527,4 +519,4 @@ class OptionMultiple : public OptionBase OptionPossibilities possibilities; }; -#endif /* COMMANDLINE_H_ */ +#endif /* COMMANDLINE_H_ */ diff --git a/svf/include/Util/CoreBitVector.h b/svf/include/Util/CoreBitVector.h index 4e7f7d284..923834288 100644 --- a/svf/include/Util/CoreBitVector.h +++ b/svf/include/Util/CoreBitVector.h @@ -45,16 +45,16 @@ class CoreBitVector CoreBitVector(size_t n); /// Copy constructor. - CoreBitVector(const CoreBitVector &cbv); + CoreBitVector(const CoreBitVector& cbv); /// Move constructor. - CoreBitVector(CoreBitVector &&cbv); + CoreBitVector(CoreBitVector&& cbv); /// Copy assignment. - CoreBitVector &operator=(const CoreBitVector &rhs); + CoreBitVector& operator=(const CoreBitVector& rhs); /// Move assignment. - CoreBitVector &operator=(CoreBitVector &&rhs); + CoreBitVector& operator=(CoreBitVector&& rhs); /// Returns true if no bits are set. bool empty(void) const; @@ -79,35 +79,35 @@ class CoreBitVector void reset(u32_t bit); /// Returns true if this CBV is a superset of rhs. - bool contains(const CoreBitVector &rhs) const; + bool contains(const CoreBitVector& rhs) const; /// Returns true if this CBV and rhs share any set bits. - bool intersects(const CoreBitVector &rhs) const; + bool intersects(const CoreBitVector& rhs) const; /// Returns true if this CBV and rhs have the same bits set. - bool operator==(const CoreBitVector &rhs) const; + bool operator==(const CoreBitVector& rhs) const; /// Returns true if either this CBV or rhs has a bit set unique to the other. - bool operator!=(const CoreBitVector &rhs) const; + bool operator!=(const CoreBitVector& rhs) const; /// Put union of this CBV and rhs into this CBV. /// Returns true if CBV changed. - bool operator|=(const CoreBitVector &rhs); + bool operator|=(const CoreBitVector& rhs); /// Put intersection of this CBV and rhs into this CBV. /// Returns true if CBV changed. - bool operator&=(const CoreBitVector &rhs); + bool operator&=(const CoreBitVector& rhs); /// Remove set bits in rhs from this CBV. /// Returns true if CBV changed. - bool operator-=(const CoreBitVector &rhs); + bool operator-=(const CoreBitVector& rhs); /// Put intersection of this CBV with complement of rhs into this CBV. /// Returns true if this CBV changed. - bool intersectWithComplement(const CoreBitVector &rhs); + bool intersectWithComplement(const CoreBitVector& rhs); /// Put intersection of lhs with complement of rhs into this CBV. - void intersectWithComplement(const CoreBitVector &lhs, const CoreBitVector &rhs); + void intersectWithComplement(const CoreBitVector& lhs, const CoreBitVector& rhs); /// Hash for this CBV. size_t hash(void) const; @@ -135,7 +135,7 @@ class CoreBitVector u32_t finalBit(void) const; /// Returns the first bit position that both this CBV and rhs *can* hold. - u32_t firstCommonBit(const CoreBitVector &rhs) const; + u32_t firstCommonBit(const CoreBitVector& rhs) const; /// Returns the next index in the words array at or after start which contains /// set bits. This index and start are indices into the words array not @@ -150,23 +150,23 @@ class CoreBitVector using iterator_category = std::forward_iterator_tag; using value_type = u32_t; using difference_type = std::ptrdiff_t; - using pointer = u32_t *; - using reference = u32_t &; + using pointer = u32_t*; + using reference = u32_t&; CoreBitVectorIterator(void) = delete; /// Returns an iterator to the beginning of cbv if end is false, and to /// the end of cbv if end is true. - CoreBitVectorIterator(const CoreBitVector *cbv, bool end=false); + CoreBitVectorIterator(const CoreBitVector* cbv, bool end = false); - CoreBitVectorIterator(const CoreBitVectorIterator &cbv) = default; - CoreBitVectorIterator(CoreBitVectorIterator &&cbv) = default; + CoreBitVectorIterator(const CoreBitVectorIterator& cbv) = default; + CoreBitVectorIterator(CoreBitVectorIterator&& cbv) = default; - CoreBitVectorIterator &operator=(const CoreBitVectorIterator &cbv) = default; - CoreBitVectorIterator &operator=(CoreBitVectorIterator &&cbv) = default; + CoreBitVectorIterator& operator=(const CoreBitVectorIterator& cbv) = default; + CoreBitVectorIterator& operator=(CoreBitVectorIterator&& cbv) = default; /// Pre-increment: ++it. - const CoreBitVectorIterator &operator++(void); + const CoreBitVectorIterator& operator++(void); /// Post-increment: it++. const CoreBitVectorIterator operator++(int); @@ -175,17 +175,17 @@ class CoreBitVector u32_t operator*(void) const; /// Equality: *this == rhs. - bool operator==(const CoreBitVectorIterator &rhs) const; + bool operator==(const CoreBitVectorIterator& rhs) const; /// Inequality: *this != rhs. - bool operator!=(const CoreBitVectorIterator &rhs) const; + bool operator!=(const CoreBitVectorIterator& rhs) const; private: bool atEnd(void) const; private: /// CoreBitVector we are iterating over. - const CoreBitVector *cbv; + const CoreBitVector* cbv; /// Word in words we are looking at. std::vector::const_iterator wordIt; /// Current bit in wordIt we are looking at @@ -200,10 +200,9 @@ class CoreBitVector std::vector words; }; -template <> -struct Hash +template <> struct Hash { - size_t operator()(const CoreBitVector &cbv) const + size_t operator()(const CoreBitVector& cbv) const { return cbv.hash(); } @@ -211,4 +210,4 @@ struct Hash } // End namespace SVF -#endif // COREBITVECTOR_H_ +#endif // COREBITVECTOR_H_ diff --git a/svf/include/Util/CxtStmt.h b/svf/include/Util/CxtStmt.h index edcf7811c..1a4902435 100644 --- a/svf/include/Util/CxtStmt.h +++ b/svf/include/Util/CxtStmt.h @@ -43,17 +43,11 @@ class CxtStmt { public: /// Constructor - CxtStmt(const CallStrCxt& c, const ICFGNode* f) :cxt(c), inst(f) - { - } + CxtStmt(const CallStrCxt& c, const ICFGNode* f) : cxt(c), inst(f) {} /// Copy constructor - CxtStmt(const CxtStmt& ctm) : cxt(ctm.getContext()),inst(ctm.getStmt()) - { - } + CxtStmt(const CxtStmt& ctm) : cxt(ctm.getContext()), inst(ctm.getStmt()) {} /// Destructor - virtual ~CxtStmt() - { - } + virtual ~CxtStmt() {} /// Return current context inline const CallStrCxt& getContext() const { @@ -66,17 +60,16 @@ class CxtStmt } /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const CxtStmt& rhs) const + inline bool operator<(const CxtStmt& rhs) const { - if(inst!=rhs.getStmt()) - return inst < rhs.getStmt(); + if (inst != rhs.getStmt()) return inst < rhs.getStmt(); else return cxt < rhs.getContext(); } /// Overloading operator= - inline CxtStmt& operator= (const CxtStmt& rhs) + inline CxtStmt& operator=(const CxtStmt& rhs) { - if(*this!=rhs) + if (*this != rhs) { inst = rhs.getStmt(); cxt = rhs.getContext(); @@ -84,14 +77,14 @@ class CxtStmt return *this; } /// Overloading operator== - inline bool operator== (const CxtStmt& rhs) const + inline bool operator==(const CxtStmt& rhs) const { return (inst == rhs.getStmt() && cxt == rhs.getContext()); } /// Overloading operator== - inline bool operator!= (const CxtStmt& rhs) const + inline bool operator!=(const CxtStmt& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } /// Return context in string format inline std::string cxtToStr() const @@ -99,7 +92,7 @@ class CxtStmt std::string str; std::stringstream rawstr(str); rawstr << "[:"; - for(CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it!=eit; ++it) + for (CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it != eit; ++it) { rawstr << *it << " "; } @@ -117,7 +110,6 @@ class CxtStmt const ICFGNode* inst; }; - /*! * Context-sensitive thread statement */ @@ -125,17 +117,11 @@ class CxtThreadStmt : public CxtStmt { public: /// Constructor - CxtThreadStmt(NodeID t, const CallStrCxt& c, const ICFGNode* f) :CxtStmt(c,f), tid(t) - { - } + CxtThreadStmt(NodeID t, const CallStrCxt& c, const ICFGNode* f) : CxtStmt(c, f), tid(t) {} /// Copy constructor - CxtThreadStmt(const CxtThreadStmt& ctm) :CxtStmt(ctm), tid(ctm.getTid()) - { - } + CxtThreadStmt(const CxtThreadStmt& ctm) : CxtStmt(ctm), tid(ctm.getTid()) {} /// Destructor - virtual ~CxtThreadStmt() - { - } + virtual ~CxtThreadStmt() {} /// Return current context inline NodeID getTid() const { @@ -143,19 +129,18 @@ class CxtThreadStmt : public CxtStmt } /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const CxtThreadStmt& rhs) const + inline bool operator<(const CxtThreadStmt& rhs) const { - if (tid != rhs.getTid()) - return tid < rhs.getTid(); - else if(inst!=rhs.getStmt()) + if (tid != rhs.getTid()) return tid < rhs.getTid(); + else if (inst != rhs.getStmt()) return inst < rhs.getStmt(); else return cxt < rhs.getContext(); } /// Overloading operator= - inline CxtThreadStmt& operator= (const CxtThreadStmt& rhs) + inline CxtThreadStmt& operator=(const CxtThreadStmt& rhs) { - if(*this!=rhs) + if (*this != rhs) { CxtStmt::operator=(rhs); tid = rhs.getTid(); @@ -163,26 +148,26 @@ class CxtThreadStmt : public CxtStmt return *this; } /// Overloading operator== - inline bool operator== (const CxtThreadStmt& rhs) const + inline bool operator==(const CxtThreadStmt& rhs) const { return (tid == rhs.getTid() && inst == rhs.getStmt() && cxt == rhs.getContext()); } /// Overloading operator== - inline bool operator!= (const CxtThreadStmt& rhs) const + inline bool operator!=(const CxtThreadStmt& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } /// Dump CxtThreadStmt inline void dump() const { - SVFUtil::outs() << "[ Current Thread id: " << tid << " Stmt: " << inst->toString() << "\t Contexts: " << cxtToStr() << " ]\n"; + SVFUtil::outs() << "[ Current Thread id: " << tid << " Stmt: " << inst->toString() + << "\t Contexts: " << cxtToStr() << " ]\n"; } private: NodeID tid; }; - /*! * Context-sensitive thread */ @@ -190,18 +175,14 @@ class CxtThread { public: /// Constructor - CxtThread(const CallStrCxt& c, const ICFGNode* fork) : cxt(c), forksite(fork), inloop(false), incycle(false) - { - } + CxtThread(const CallStrCxt& c, const ICFGNode* fork) : cxt(c), forksite(fork), inloop(false), incycle(false) {} /// Copy constructor - CxtThread(const CxtThread& ct) : - cxt(ct.getContext()), forksite(ct.getThread()), inloop(ct.isInloop()), incycle(ct.isIncycle()) + CxtThread(const CxtThread& ct) + : cxt(ct.getContext()), forksite(ct.getThread()), inloop(ct.isInloop()), incycle(ct.isIncycle()) { } /// Destructor - virtual ~CxtThread() - { - } + virtual ~CxtThread() {} /// Return context of the thread inline const CallStrCxt& getContext() const { @@ -214,17 +195,16 @@ class CxtThread } /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const CxtThread& rhs) const + inline bool operator<(const CxtThread& rhs) const { - if (forksite != rhs.getThread()) - return forksite < rhs.getThread(); + if (forksite != rhs.getThread()) return forksite < rhs.getThread(); else return cxt < rhs.getContext(); } /// Overloading operator= - inline CxtThread& operator= (const CxtThread& rhs) + inline CxtThread& operator=(const CxtThread& rhs) { - if(*this!=rhs) + if (*this != rhs) { forksite = rhs.getThread(); cxt = rhs.getContext(); @@ -232,14 +212,14 @@ class CxtThread return *this; } /// Overloading operator== - inline bool operator== (const CxtThread& rhs) const + inline bool operator==(const CxtThread& rhs) const { return (forksite == rhs.getThread() && cxt == rhs.getContext()); } /// Overloading operator== - inline bool operator!= (const CxtThread& rhs) const + inline bool operator!=(const CxtThread& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } /// Return context in string format inline std::string cxtToStr() const @@ -247,7 +227,7 @@ class CxtThread std::string str; std::stringstream rawstr(str); rawstr << "[:"; - for(CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it!=eit; ++it) + for (CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it != eit; ++it) { rawstr << *it << " "; } @@ -278,21 +258,22 @@ class CxtThread /// Dump CxtThread inline void dump() const { - std::string loop = inloop?", inloop":""; - std::string cycle = incycle?", incycle":""; + std::string loop = inloop ? ", inloop" : ""; + std::string cycle = incycle ? ", incycle" : ""; - if(forksite) + if (forksite) { - SVFUtil::outs() << "[ Thread: " - << forksite->toString() << "\t Contexts: " << cxtToStr() - << loop << cycle <<" ]\n"; + SVFUtil::outs() << "[ Thread: " << forksite->toString() << "\t Contexts: " << cxtToStr() << loop << cycle + << " ]\n"; } else { - SVFUtil::outs() << "[ Thread: " << "main " << "\t Contexts: " << cxtToStr() - << loop << cycle <<" ]\n"; + SVFUtil::outs() << "[ Thread: " + << "main " + << "\t Contexts: " << cxtToStr() << loop << cycle << " ]\n"; } } + protected: CallStrCxt cxt; const ICFGNode* forksite; @@ -300,7 +281,6 @@ class CxtThread bool incycle; }; - /*! * Context-sensitive procedure * c represent current context @@ -310,19 +290,11 @@ class CxtProc { public: /// Constructor - CxtProc(const CallStrCxt& c, const SVFFunction* f) : - cxt(c), fun(f) - { - } + CxtProc(const CallStrCxt& c, const SVFFunction* f) : cxt(c), fun(f) {} /// Copy constructor - CxtProc(const CxtProc& ctm) : - cxt(ctm.getContext()), fun(ctm.getProc()) - { - } + CxtProc(const CxtProc& ctm) : cxt(ctm.getContext()), fun(ctm.getProc()) {} /// Destructor - virtual ~CxtProc() - { - } + virtual ~CxtProc() {} /// Return current procedure inline const SVFFunction* getProc() const { @@ -337,8 +309,7 @@ class CxtProc /// to be noted that two vectors can also overload operator() inline bool operator<(const CxtProc& rhs) const { - if (fun != rhs.getProc()) - return fun < rhs.getProc(); + if (fun != rhs.getProc()) return fun < rhs.getProc(); else return cxt < rhs.getContext(); } @@ -386,7 +357,6 @@ class CxtProc const SVFFunction* fun; }; - /*! * Context-sensitive procedure * t represent current thread during traversing @@ -397,17 +367,11 @@ class CxtThreadProc : public CxtProc { public: /// Constructor - CxtThreadProc(NodeID t, const CallStrCxt& c, const SVFFunction* f) :CxtProc(c,f),tid(t) - { - } + CxtThreadProc(NodeID t, const CallStrCxt& c, const SVFFunction* f) : CxtProc(c, f), tid(t) {} /// Copy constructor - CxtThreadProc(const CxtThreadProc& ctm) : CxtProc(ctm.getContext(),ctm.getProc()), tid(ctm.getTid()) - { - } + CxtThreadProc(const CxtThreadProc& ctm) : CxtProc(ctm.getContext(), ctm.getProc()), tid(ctm.getTid()) {} /// Destructor - virtual ~CxtThreadProc() - { - } + virtual ~CxtThreadProc() {} /// Return current thread id inline NodeID getTid() const { @@ -415,19 +379,18 @@ class CxtThreadProc : public CxtProc } /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const CxtThreadProc& rhs) const + inline bool operator<(const CxtThreadProc& rhs) const { - if (tid != rhs.getTid()) - return tid < rhs.getTid(); - else if(fun!=rhs.getProc()) + if (tid != rhs.getTid()) return tid < rhs.getTid(); + else if (fun != rhs.getProc()) return fun < rhs.getProc(); else return cxt < rhs.getContext(); } /// Overloading operator= - inline CxtThreadProc& operator= (const CxtThreadProc& rhs) + inline CxtThreadProc& operator=(const CxtThreadProc& rhs) { - if(*this!=rhs) + if (*this != rhs) { tid = rhs.getTid(); fun = rhs.getProc(); @@ -436,19 +399,20 @@ class CxtThreadProc : public CxtProc return *this; } /// Overloading operator== - inline bool operator== (const CxtThreadProc& rhs) const + inline bool operator==(const CxtThreadProc& rhs) const { return (tid == rhs.getTid() && fun == rhs.getProc() && cxt == rhs.getContext()); } /// Overloading operator== - inline bool operator!= (const CxtThreadProc& rhs) const + inline bool operator!=(const CxtThreadProc& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } /// Dump CxtThreadProc inline void dump() const { - SVFUtil::outs() << "[ Current Thread id: " << tid << " Proc: " << fun->getName() << "\t Contexts: " << cxtToStr() << " ]\n"; + SVFUtil::outs() << "[ Current Thread id: " << tid << " Proc: " << fun->getName() + << "\t Contexts: " << cxtToStr() << " ]\n"; } private: @@ -486,7 +450,7 @@ template <> struct std::hash size_t operator()(const SVF::CxtStmt& cs) const { std::hash h; - SVF::ICFGNode* inst = const_cast (cs.getStmt()); + SVF::ICFGNode* inst = const_cast(cs.getStmt()); return h(inst); } }; @@ -495,7 +459,7 @@ template <> struct std::hash size_t operator()(const SVF::CxtProc& cs) const { std::hash h; - SVF::SVFFunction* fun = const_cast (cs.getProc()); + SVF::SVFFunction* fun = const_cast(cs.getProc()); return h(fun); } }; diff --git a/svf/include/Util/DPItem.h b/svf/include/Util/DPItem.h index 867edfd4b..e8bc5d243 100644 --- a/svf/include/Util/DPItem.h +++ b/svf/include/Util/DPItem.h @@ -31,7 +31,7 @@ #define DPITEM_H_ #include "MemoryModel/ConditionalPT.h" -#include // std::sort +#include // std::sort namespace SVF { @@ -49,20 +49,13 @@ class DPItem public: /// Constructor - DPItem(NodeID c) : cur(c) - { - } + DPItem(NodeID c) : cur(c) {} /// Copy constructor - DPItem(const DPItem& dps) : cur(dps.cur) - { - } + DPItem(const DPItem& dps) : cur(dps.cur) {} /// Move constructor - DPItem(DPItem&& dps) noexcept : cur(dps.cur) - { - - } + DPItem(DPItem&& dps) noexcept : cur(dps.cur) {} /// Move operator= - DPItem &operator=(DPItem &&rhs) noexcept + DPItem& operator=(DPItem&& rhs) noexcept { if (this != &rhs) { @@ -71,9 +64,7 @@ class DPItem return *this; } /// Destructor - virtual ~DPItem() - { - } + virtual ~DPItem() {} inline NodeID getCurNodeID() const { return cur; @@ -93,26 +84,26 @@ class DPItem } /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const DPItem& rhs) const + inline bool operator<(const DPItem& rhs) const { return cur < rhs.cur; } /// Overloading Operator= - inline DPItem& operator= (const DPItem& rhs) + inline DPItem& operator=(const DPItem& rhs) { - if(*this!=rhs) + if (*this != rhs) { cur = rhs.cur; } return *this; } /// Overloading Operator== - inline bool operator== (const DPItem& rhs) const + inline bool operator==(const DPItem& rhs) const { return (cur == rhs.cur); } /// Overloading Operator!= - inline bool operator!= (const DPItem& rhs) const + inline bool operator!=(const DPItem& rhs) const { return !(*this == rhs); } @@ -123,32 +114,22 @@ class DPItem } }; - /*! * FlowSensitive DPItem */ -template -class StmtDPItem : public DPItem +template class StmtDPItem : public DPItem { - protected: const LocCond* curloc; public: /// Constructor - StmtDPItem(NodeID c, const LocCond* locCond) : DPItem(c), curloc(locCond) - { - } + StmtDPItem(NodeID c, const LocCond* locCond) : DPItem(c), curloc(locCond) {} /// Copy constructor - StmtDPItem(const StmtDPItem& dps) : - DPItem(dps), curloc(dps.curloc) - { - } + StmtDPItem(const StmtDPItem& dps) : DPItem(dps), curloc(dps.curloc) {} /// Destructor - virtual ~StmtDPItem() - { - } + virtual ~StmtDPItem() {} /// Get context inline const LocCond* getLoc() const { @@ -160,24 +141,23 @@ class StmtDPItem : public DPItem this->curloc = l; } /// Set location and pointer id - inline void setLocVar(const LocCond* l,NodeID v) + inline void setLocVar(const LocCond* l, NodeID v) { this->curloc = l; this->cur = v; } /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const StmtDPItem& rhs) const + inline bool operator<(const StmtDPItem& rhs) const { - if (this->cur != rhs.cur) - return this->cur < rhs.cur; + if (this->cur != rhs.cur) return this->cur < rhs.cur; else return this->curloc < rhs.curloc; } /// Overloading operator== - inline StmtDPItem& operator= (const StmtDPItem& rhs) + inline StmtDPItem& operator=(const StmtDPItem& rhs) { - if(*this!=rhs) + if (*this != rhs) { DPItem::operator=(rhs); this->curloc = rhs.getLoc(); @@ -185,18 +165,18 @@ class StmtDPItem : public DPItem return *this; } /// Overloading operator== - inline bool operator== (const StmtDPItem& rhs) const + inline bool operator==(const StmtDPItem& rhs) const { return (this->cur == rhs.cur && this->curloc == rhs.getLoc()); } /// Overloading operator!= - inline bool operator!= (const StmtDPItem& rhs) const + inline bool operator!=(const StmtDPItem& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } inline void dump() const { - SVFUtil::outs() << "statement " << *(this->curloc) << ", var " << this->cur << "\n"; + SVFUtil::outs() << "statement " << *(this->curloc) << ", var " << this->cur << "\n"; } }; @@ -208,19 +188,15 @@ class ContextCond public: typedef CallStrCxt::const_iterator const_iterator; /// Constructor - ContextCond():concreteCxt(true) - { - } + ContextCond() : concreteCxt(true) {} /// Copy Constructor - ContextCond(const ContextCond& cond): context(cond.getContexts()), concreteCxt(cond.isConcreteCxt()) - { - } + ContextCond(const ContextCond& cond) : context(cond.getContexts()), concreteCxt(cond.isConcreteCxt()) {} /// Move Constructor - ContextCond(ContextCond &&cond) noexcept: context(std::move(cond.context)), concreteCxt(cond.concreteCxt) {} + ContextCond(ContextCond&& cond) noexcept : context(std::move(cond.context)), concreteCxt(cond.concreteCxt) {} /// Move operator= - ContextCond& operator=(ContextCond&&cond) noexcept + ContextCond& operator=(ContextCond&& cond) noexcept { - if(this!=&cond) + if (this != &cond) { context = std::move(cond.context); concreteCxt = cond.concreteCxt; @@ -228,9 +204,7 @@ class ContextCond return *this; } /// Destructor - virtual ~ContextCond() - { - } + virtual ~ContextCond() {} /// Get context inline const CallStrCxt& getContexts() const { @@ -254,7 +228,7 @@ class ContextCond /// Whether contains callstring cxt inline bool containCallStr(NodeID cxt) const { - return std::find(context.begin(),context.end(),cxt) != context.end(); + return std::find(context.begin(), context.end(), cxt) != context.end(); } /// Get context size inline u32_t cxtSize() const @@ -279,17 +253,16 @@ class ContextCond inline virtual bool pushContext(NodeID ctx) { - if(context.size() < maximumCxtLen) + if (context.size() < maximumCxtLen) { context.push_back(ctx); - if(context.size() > maximumCxt) - maximumCxt = context.size(); + if (context.size() > maximumCxt) maximumCxt = context.size(); return true; } - else /// handle out of context limit case + else /// handle out of context limit case { - if(!context.empty()) + if (!context.empty()) { setNonConcreteCxt(); context.erase(context.begin()); @@ -303,10 +276,9 @@ class ContextCond inline virtual bool matchContext(NodeID ctx) { /// if context is empty, then it is the unbalanced parentheses match - if(context.empty()) - return true; + if (context.empty()) return true; /// otherwise, we perform balanced parentheses matching - else if(context.back() == ctx) + else if (context.back() == ctx) { context.pop_back(); return true; @@ -316,20 +288,20 @@ class ContextCond /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const ContextCond& rhs) const + inline bool operator<(const ContextCond& rhs) const { return context < rhs.context; } /// Overloading operator[] - inline NodeID operator[] (const u32_t index) const + inline NodeID operator[](const u32_t index) const { assert(index < context.size()); return context[index]; } /// Overloading operator= - inline ContextCond& operator= (const ContextCond& rhs) + inline ContextCond& operator=(const ContextCond& rhs) { - if(*this!=rhs) + if (*this != rhs) { context = rhs.getContexts(); concreteCxt = rhs.isConcreteCxt(); @@ -337,14 +309,14 @@ class ContextCond return *this; } /// Overloading operator== - inline bool operator== (const ContextCond& rhs) const + inline bool operator==(const ContextCond& rhs) const { return (context == rhs.getContexts()); } /// Overloading operator!= - inline bool operator!= (const ContextCond& rhs) const + inline bool operator!=(const ContextCond& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } /// Begin iterators inline const_iterator begin() const @@ -362,18 +334,20 @@ class ContextCond std::string str; std::stringstream rawstr(str); rawstr << "[:"; - for(CallStrCxt::const_iterator it = context.begin(), eit = context.end(); it!=eit; ++it) + for (CallStrCxt::const_iterator it = context.begin(), eit = context.end(); it != eit; ++it) { rawstr << *it << " "; } rawstr << " ]"; return rawstr.str(); } + protected: CallStrCxt context; static u32_t maximumCxtLen; static u32_t maximumPathLen; bool concreteCxt; + public: static u32_t maximumCxt; static u32_t maximumPath; @@ -385,29 +359,25 @@ class ContextCond typedef CondVar CxtVar; typedef CondStdSet CxtPtSet; -template -class CxtStmtDPItem : public StmtDPItem +template class CxtStmtDPItem : public StmtDPItem { private: ContextCond context; + public: /// Constructor - CxtStmtDPItem(const CxtVar& var, const LocCond* locCond) : StmtDPItem(var.get_id(),locCond), context(var.get_cond()) + CxtStmtDPItem(const CxtVar& var, const LocCond* locCond) + : StmtDPItem(var.get_id(), locCond), context(var.get_cond()) { } /// Copy constructor - CxtStmtDPItem(const CxtStmtDPItem& dps) : - StmtDPItem(dps), context(dps.context) - { - } + CxtStmtDPItem(const CxtStmtDPItem& dps) : StmtDPItem(dps), context(dps.context) {} /// Destructor - virtual ~CxtStmtDPItem() - { - } + virtual ~CxtStmtDPItem() {} /// Get context var inline CxtVar getCondVar() const { - CxtVar var(this->context,this->cur); + CxtVar var(this->context, this->cur); return var; } /// Get context @@ -434,19 +404,18 @@ class CxtStmtDPItem : public StmtDPItem /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const CxtStmtDPItem& rhs) const + inline bool operator<(const CxtStmtDPItem& rhs) const { - if (this->cur != rhs.cur) - return this->cur < rhs.cur; - else if(this->curloc != rhs.getLoc()) + if (this->cur != rhs.cur) return this->cur < rhs.cur; + else if (this->curloc != rhs.getLoc()) return this->curloc < rhs.getLoc(); else return this->context < rhs.context; } /// Overloading operator= - inline CxtStmtDPItem& operator= (const CxtStmtDPItem& rhs) + inline CxtStmtDPItem& operator=(const CxtStmtDPItem& rhs) { - if(*this!=rhs) + if (*this != rhs) { StmtDPItem::operator=(rhs); this->context = rhs.getCond(); @@ -454,19 +423,19 @@ class CxtStmtDPItem : public StmtDPItem return *this; } /// Overloading operator== - inline bool operator== (const CxtStmtDPItem& rhs) const + inline bool operator==(const CxtStmtDPItem& rhs) const { return (this->cur == rhs.cur && this->curloc == rhs.getLoc() && this->context == rhs.context); } /// Overloading operator== - inline bool operator!= (const CxtStmtDPItem& rhs) const + inline bool operator!=(const CxtStmtDPItem& rhs) const { - return !(*this==rhs); + return !(*this == rhs); } inline void dump() const { - SVFUtil::outs() << "statement " << *(this->curloc) << ", var " << this->cur << " "; - SVFUtil::outs() << this->context.toString() <<"\n"; + SVFUtil::outs() << "statement " << *(this->curloc) << ", var " << this->cur << " "; + SVFUtil::outs() << this->context.toString() << "\n"; } }; @@ -481,23 +450,14 @@ class CxtDPItem : public DPItem public: /// Constructor - CxtDPItem(NodeID c, const ContextCond& cxt) : DPItem(c),context(cxt) - { - } - CxtDPItem(const CxtVar& var) : DPItem(var.get_id()),context(var.get_cond()) - { - } + CxtDPItem(NodeID c, const ContextCond& cxt) : DPItem(c), context(cxt) {} + CxtDPItem(const CxtVar& var) : DPItem(var.get_id()), context(var.get_cond()) {} /// Copy constructor - CxtDPItem(const CxtDPItem& dps) : - DPItem(dps.getCurNodeID()), context(dps.context) - { - } + CxtDPItem(const CxtDPItem& dps) : DPItem(dps.getCurNodeID()), context(dps.context) {} /// Move constructor - CxtDPItem(CxtDPItem &&dps) noexcept: DPItem(dps), context(std::move(dps.context)) - { - } + CxtDPItem(CxtDPItem&& dps) noexcept : DPItem(dps), context(std::move(dps.context)) {} /// Move operator= - CxtDPItem &operator=(CxtDPItem &&dps) noexcept + CxtDPItem& operator=(CxtDPItem&& dps) noexcept { if (this != &dps) { @@ -507,9 +467,7 @@ class CxtDPItem : public DPItem return *this; } /// Destructor - virtual ~CxtDPItem() - { - } + virtual ~CxtDPItem() {} /// Get context inline const ContextCond& getContexts() const @@ -530,17 +488,16 @@ class CxtDPItem : public DPItem /// Enable compare operator to avoid duplicated item insertion in map or set /// to be noted that two vectors can also overload operator() - inline bool operator< (const CxtDPItem& rhs) const + inline bool operator<(const CxtDPItem& rhs) const { - if (cur != rhs.cur) - return cur < rhs.cur; + if (cur != rhs.cur) return cur < rhs.cur; else return context < rhs.context; } /// Overloading Operator= - inline CxtDPItem& operator= (const CxtDPItem& rhs) + inline CxtDPItem& operator=(const CxtDPItem& rhs) { - if(*this!=rhs) + if (*this != rhs) { cur = rhs.cur; context = rhs.context; @@ -548,24 +505,22 @@ class CxtDPItem : public DPItem return *this; } /// Overloading Operator== - inline bool operator== (const CxtDPItem& rhs) const + inline bool operator==(const CxtDPItem& rhs) const { return (cur == rhs.cur) && (context == rhs.context); } /// Overloading Operator!= - inline bool operator!= (const CxtDPItem& rhs) const + inline bool operator!=(const CxtDPItem& rhs) const { return !(*this == rhs); } - }; } // End namespace SVF /// Specialise hash for CxtDPItem. -template <> -struct std::hash +template <> struct std::hash { - size_t operator()(const SVF::CxtDPItem &cdpi) const + size_t operator()(const SVF::CxtDPItem& cdpi) const { SVF::Hash> h; return h(std::make_pair(cdpi.getCurNodeID(), cdpi.getContexts())); @@ -573,43 +528,38 @@ struct std::hash }; /// Specialise hash for StmtDPItem. -template -struct std::hash> +template struct std::hash> { - size_t operator()(const SVF::StmtDPItem &sdpi) const + size_t operator()(const SVF::StmtDPItem& sdpi) const { - SVF::Hash> h; + SVF::Hash> h; return h(std::make_pair(sdpi.getCurNodeID(), sdpi.getLoc())); } }; /// Specialise hash for CxtStmtDPItem. -template -struct std::hash> +template struct std::hash> { - size_t operator()(const SVF::CxtStmtDPItem &csdpi) const + size_t operator()(const SVF::CxtStmtDPItem& csdpi) const { - SVF::Hash>> h; - return h(std::make_pair(csdpi.getCurNodeID(), - std::make_pair(csdpi.getLoc(), csdpi.getCond()))); + SVF::Hash>> h; + return h(std::make_pair(csdpi.getCurNodeID(), std::make_pair(csdpi.getLoc(), csdpi.getCond()))); } }; /// Specialise hash for ContextCond. -template <> -struct std::hash +template <> struct std::hash { - size_t operator()(const SVF::ContextCond &cc) const + size_t operator()(const SVF::ContextCond& cc) const { std::hash h; return h(cc.getContexts()); } }; -template <> -struct std::hash +template <> struct std::hash { - size_t operator()(const SVF::ContextCond &cc) const + size_t operator()(const SVF::ContextCond& cc) const { std::hash h; return h(cc.getContexts()); diff --git a/svf/include/Util/ExtAPI.h b/svf/include/Util/ExtAPI.h index f2715a9c0..bce39cd86 100644 --- a/svf/include/Util/ExtAPI.h +++ b/svf/include/Util/ExtAPI.h @@ -36,7 +36,8 @@ #include #include -/// For a more detailed explanation of how External APIs are handled in SVF, please refer to the SVF Wiki: https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c +/// For a more detailed explanation of how External APIs are handled in SVF, please refer to the SVF Wiki: +/// https://github.com/SVF-tools/SVF/wiki/Handling-External-APIs-with-extapi.c namespace SVF { @@ -44,8 +45,7 @@ namespace SVF class ExtAPI { private: - - static ExtAPI *extOp; + static ExtAPI* extOp; // extapi.bc file path static std::string extBcPath; @@ -53,8 +53,7 @@ class ExtAPI ExtAPI() = default; public: - - static ExtAPI *getExtAPI(); + static ExtAPI* getExtAPI(); static void destory(); @@ -71,29 +70,29 @@ class ExtAPI bool hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation); // Does (F) have a static var X (unavailable to us) that its return points to? - bool has_static(const SVFFunction *F); + bool has_static(const SVFFunction* F); // Does (F) have a memcpy_like operation? - bool is_memcpy(const SVFFunction *F); + bool is_memcpy(const SVFFunction* F); // Does (F) have a memset_like operation? - bool is_memset(const SVFFunction *F); + bool is_memset(const SVFFunction* F); // Does (F) allocate a new object and return it? - bool is_alloc(const SVFFunction *F); + bool is_alloc(const SVFFunction* F); // Does (F) allocate a new object and assign it to one of its arguments? - bool is_arg_alloc(const SVFFunction *F); + bool is_arg_alloc(const SVFFunction* F); // Get the position of argument which holds the new object - s32_t get_alloc_arg_pos(const SVFFunction *F); + s32_t get_alloc_arg_pos(const SVFFunction* F); // Does (F) reallocate a new object? - bool is_realloc(const SVFFunction *F); + bool is_realloc(const SVFFunction* F); // Should (F) be considered "external" (either not defined in the program // or a user-defined version of a known alloc or no-op)? - bool is_ext(const SVFFunction *F); + bool is_ext(const SVFFunction* F); }; } // End namespace SVF diff --git a/svf/include/Util/GeneralType.h b/svf/include/Util/GeneralType.h index e2d7f7204..66d95af86 100644 --- a/svf/include/Util/GeneralType.h +++ b/svf/include/Util/GeneralType.h @@ -90,38 +90,35 @@ template struct Hash } }; -template , - typename KeyEqual = std::equal_to, +template , typename KeyEqual = std::equal_to, typename Allocator = std::allocator> using Set = std::unordered_set; -template , - typename KeyEqual = std::equal_to, +template , typename KeyEqual = std::equal_to, typename Allocator = std::allocator>> - using Map = std::unordered_map; - - template , - typename Allocator = std::allocator> - using OrderedSet = std::set; - - template , - typename Allocator = std::allocator>> - using OrderedMap = std::map; - - typedef std::pair NodePair; - typedef OrderedSet OrderedNodeSet; - typedef Set NodeSet; - typedef Set NodePairSet; - typedef Map NodePairMap; - typedef std::vector NodeVector; - typedef std::vector EdgeVector; - typedef std::stack NodeStack; - typedef std::list NodeList; - typedef std::deque NodeDeque; - typedef NodeSet EdgeSet; - typedef std::vector CallStrCxt; - typedef unsigned Version; - typedef Set VersionSet; - typedef std::pair VersionedVar; - typedef Set VersionedVarSet; -} \ No newline at end of file +using Map = std::unordered_map; + +template , typename Allocator = std::allocator> +using OrderedSet = std::set; + +template , + typename Allocator = std::allocator>> +using OrderedMap = std::map; + +typedef std::pair NodePair; +typedef OrderedSet OrderedNodeSet; +typedef Set NodeSet; +typedef Set NodePairSet; +typedef Map NodePairMap; +typedef std::vector NodeVector; +typedef std::vector EdgeVector; +typedef std::stack NodeStack; +typedef std::list NodeList; +typedef std::deque NodeDeque; +typedef NodeSet EdgeSet; +typedef std::vector CallStrCxt; +typedef unsigned Version; +typedef Set VersionSet; +typedef std::pair VersionedVar; +typedef Set VersionedVarSet; +} // namespace SVF \ No newline at end of file diff --git a/svf/include/Util/GraphReachSolver.h b/svf/include/Util/GraphReachSolver.h index 733ec9ff2..3e42f77fa 100644 --- a/svf/include/Util/GraphReachSolver.h +++ b/svf/include/Util/GraphReachSolver.h @@ -40,35 +40,29 @@ namespace SVF * Generic Graph Reachability solver for demand-driven analysis based on different graphs (e.g. SVFIR, VFG, ThreadVFG) * Extend this class for sophisticated CFL-reachability resolution (e.g. field, flow, path) */ -template -class GraphReachSolver +template class GraphReachSolver { public: - ///Define the GTraits and node iterator + /// Define the GTraits and node iterator typedef SVF::GenericGraphTraits GTraits; - typedef typename GTraits::NodeType GNODE; - typedef typename GTraits::EdgeType GEDGE; + typedef typename GTraits::NodeType GNODE; + typedef typename GTraits::EdgeType GEDGE; typedef typename GTraits::nodes_iterator node_iterator; typedef typename GTraits::ChildIteratorType child_iterator; /// Define inverse GTraits and note iterator - typedef SVF::GenericGraphTraits > InvGTraits; + typedef SVF::GenericGraphTraits> InvGTraits; typedef typename InvGTraits::ChildIteratorType inv_child_iterator; /// Define worklist typedef FIFOWorkList WorkList; protected: - /// Constructor - GraphReachSolver(): _graph(nullptr) - { - } + GraphReachSolver() : _graph(nullptr) {} /// Destructor - virtual ~GraphReachSolver() - { - } + virtual ~GraphReachSolver() {} /// Get/Set graph methods //@{ const inline GraphType graph() const @@ -104,7 +98,7 @@ class GraphReachSolver child_iterator EE = GTraits::child_end(v); for (; EI != EE; ++EI) { - FWProcessOutgoingEdge(item,*(EI.getCurrent()) ); + FWProcessOutgoingEdge(item, *(EI.getCurrent())); } } } @@ -123,18 +117,14 @@ class GraphReachSolver inv_child_iterator EE = InvGTraits::child_end(v); for (; EI != EE; ++EI) { - BWProcessIncomingEdge(item,*(EI.getCurrent()) ); + BWProcessIncomingEdge(item, *(EI.getCurrent())); } } } /// Process the DP item //@{ - virtual void FWProcessCurNode(const DPIm&) - { - } - virtual void BWProcessCurNode(const DPIm&) - { - } + virtual void FWProcessCurNode(const DPIm&) {} + virtual void BWProcessCurNode(const DPIm&) {} //@} /// Propagation for the solving, to be implemented in the child class //@{ @@ -172,13 +162,11 @@ class GraphReachSolver //@} private: - /// Graph GraphType _graph; /// Worklist for resolution WorkList worklist; - }; } // End namespace SVF diff --git a/svf/include/Util/NodeIDAllocator.h b/svf/include/Util/NodeIDAllocator.h index 643404d83..679c0bbe3 100644 --- a/svf/include/Util/NodeIDAllocator.h +++ b/svf/include/Util/NodeIDAllocator.h @@ -54,7 +54,7 @@ class NodeIDAllocator ///@} /// Return (singleton) allocator. - static NodeIDAllocator *get(void); + static NodeIDAllocator* get(void); /// Deletes the (singleton) allocator. static void unset(void); @@ -109,7 +109,7 @@ class NodeIDAllocator enum Strategy strategy; /// Single allocator. - static NodeIDAllocator *allocator; + static NodeIDAllocator* allocator; public: /// Perform clustering given points-to sets with nodes allocated according to the @@ -149,17 +149,20 @@ class NodeIDAllocator /// or a subset, depending on the client's wish. /// TODO: interfaces are getting unwieldy, an initialised object may be better. /// TODO: kind of sucks pta can't be const here because getPts isn't. - static std::vector cluster(BVDataPTAImpl *pta, const std::vector> keys, std::vector>> &candidates, std::string evalSubtitle=""); + static std::vector cluster(BVDataPTAImpl* pta, const std::vector> keys, + std::vector>>& candidates, + std::string evalSubtitle = ""); // Returns a reverse node mapping for mapping generated by cluster(). - static std::vector getReverseNodeMapping(const std::vector &nodeMapping); + static std::vector getReverseNodeMapping(const std::vector& nodeMapping); /// Fills in *NumWords statistics in stats.. - static void evaluate(const std::vector &nodeMap, const Map pointsToSets, Map &stats, bool accountForOcc); + static void evaluate(const std::vector& nodeMap, const Map pointsToSets, + Map& stats, bool accountForOcc); /// Prints statistics to SVFUtil::outs(). /// TODO: make stats const. - static void printStats(std::string title, Map &stats); + static void printStats(std::string title, Map& stats); private: /// Returns an index into a condensed matrix (upper triangle, excluding diagonals) corresponding @@ -167,7 +170,7 @@ class NodeIDAllocator static inline size_t condensedIndex(size_t n, size_t i, size_t j); /// Returns the minimum number of bits required to represent pts in a perfect world. - static inline unsigned requiredBits(const PointsTo &pts); + static inline unsigned requiredBits(const PointsTo& pts); /// Returns the minimum number of bits required to represent n items in a perfect world. static inline unsigned requiredBits(const size_t n); @@ -175,29 +178,31 @@ class NodeIDAllocator /// Builds the upper triangle of the distance matrix, as an array of length /// (numObjects * (numObjects - 1)) / 2, as required by fastcluster. /// Responsibility of caller to `delete`. - static inline double *getDistanceMatrix(const std::vector> pointsToSets, - const size_t numObjects, const Map &nodeMap, - double &distanceMatrixTime); + static inline double* getDistanceMatrix(const std::vector> pointsToSets, + const size_t numObjects, const Map& nodeMap, + double& distanceMatrixTime); /// Traverses the dendrogram produced by fastcluster, making node o, where o is the nth leaf (per /// recursive DFS) map to n. index is the dendrogram node to work off. The traversal should start /// at the top, which is the "last" (consider that it is 2D) element of the dendrogram, numObjects - 1. - static inline void traverseDendrogram(std::vector &nodeMap, const int *dendrogram, const size_t numObjects, unsigned &allocCounter, Set &visited, const int index, const std::vector ®ionNodeMap); + static inline void traverseDendrogram(std::vector& nodeMap, const int* dendrogram, + const size_t numObjects, unsigned& allocCounter, Set& visited, + const int index, const std::vector& regionNodeMap); /// Returns a vector mapping object IDs to a label such that if two objects appear /// in the same points-to set, they have the same label. The "appear in the same /// points-to set" is encoded by graph which is an adjacency list ensuring that /// x in pt(p) and y in pt(p) -> x is reachable from y. - static inline std::vector regionObjects(const Map> &graph, size_t numObjects, size_t &numLabels); + static inline std::vector regionObjects(const Map>& graph, size_t numObjects, + size_t& numLabels); // From all the candidates, returns the best mapping for pointsToSets (points-to set -> # occurrences). static inline std::pair> determineBestMapping( - const std::vector>> &candidates, - Map pointsToSets, const std::string &evalSubtitle, double &evalTime); - + const std::vector>>& candidates, + Map pointsToSets, const std::string& evalSubtitle, double& evalTime); }; }; -} // namespace SVF +} // namespace SVF -#endif // ifdef NODEIDALLOCATOR_H_ +#endif // ifdef NODEIDALLOCATOR_H_ diff --git a/svf/include/Util/Options.h b/svf/include/Util/Options.h index 54cb7ac68..4aabc5c11 100644 --- a/svf/include/Util/Options.h +++ b/svf/include/Util/Options.h @@ -159,7 +159,7 @@ class Options static const Option PrintInterLev; static const Option DoLockAnalysis; - //MTAStat.cpp + // MTAStat.cpp static const Option AllPairMHP; // TCT.cpp @@ -232,8 +232,8 @@ class Options static const Option CFLGraph; static const Option PrintCFL; static const Option FlexSymMap; - static const Option PEGTransfer; - static const Option CFLSVFG; + static const Option PEGTransfer; + static const Option CFLSVFG; static const Option POCRAlias; static const Option POCRHybrid; static const Option Customized; @@ -267,6 +267,6 @@ class Options // float precision for symbolic abstraction static const Option AEPrecision; }; -} // namespace SVF +} // namespace SVF -#endif // ifdef OPTIONS_H_ +#endif // ifdef OPTIONS_H_ diff --git a/svf/include/Util/PTAStat.h b/svf/include/Util/PTAStat.h index 39f3ef98d..e3a2da1c6 100644 --- a/svf/include/Util/PTAStat.h +++ b/svf/include/Util/PTAStat.h @@ -45,7 +45,7 @@ class PointerAnalysis; /*! * Pointer Analysis Statistics */ -class PTAStat: public SVFStat +class PTAStat : public SVFStat { public: PTAStat(PointerAnalysis* p); @@ -69,7 +69,6 @@ class PTAStat: public SVFStat void callgraphStat() override; - protected: PointerAnalysis* pta; u32_t _vmrssUsageBefore; diff --git a/svf/include/Util/SVFBugReport.h b/svf/include/Util/SVFBugReport.h index 433772496..4e11931e3 100644 --- a/svf/include/Util/SVFBugReport.h +++ b/svf/include/Util/SVFBugReport.h @@ -47,7 +47,6 @@ namespace SVF * Bug Detector Recoder */ - class SVFBugEvent { public: @@ -62,10 +61,11 @@ class SVFBugEvent protected: u32_t typeAndInfoFlag; - const SVFInstruction *eventInst; + const SVFInstruction* eventInst; public: - SVFBugEvent(u32_t typeAndInfoFlag, const SVFInstruction *eventInst): typeAndInfoFlag(typeAndInfoFlag), eventInst(eventInst) { }; + SVFBugEvent(u32_t typeAndInfoFlag, const SVFInstruction* eventInst) + : typeAndInfoFlag(typeAndInfoFlag), eventInst(eventInst){}; virtual ~SVFBugEvent() = default; inline u32_t getEventType() const @@ -83,7 +83,18 @@ class GenericBug typedef std::vector EventStack; public: - enum BugType {FULLBUFOVERFLOW, PARTIALBUFOVERFLOW, NEVERFREE, PARTIALLEAK, DOUBLEFREE, FILENEVERCLOSE, FILEPARTIALCLOSE, FULLNULLPTRDEREFERENCE, PARTIALNULLPTRDEREFERENCE}; + enum BugType + { + FULLBUFOVERFLOW, + PARTIALBUFOVERFLOW, + NEVERFREE, + PARTIALLEAK, + DOUBLEFREE, + FILENEVERCLOSE, + FILEPARTIALCLOSE, + FULLNULLPTRDEREFERENCE, + PARTIALNULLPTRDEREFERENCE + }; static const std::map BugType2Str; protected: @@ -92,13 +103,12 @@ class GenericBug public: /// note: should be initialized with a bugEventStack - GenericBug(BugType bugType, const EventStack &bugEventStack): - bugType(bugType), bugEventStack(bugEventStack) + GenericBug(BugType bugType, const EventStack& bugEventStack) : bugType(bugType), bugEventStack(bugEventStack) { assert(bugEventStack.size() != 0 && "bugEventStack should NOT be empty!"); } virtual ~GenericBug() = default; - //GenericBug(const GenericBug &) = delete; + // GenericBug(const GenericBug &) = delete; /// returns bug type inline BugType getBugType() const { @@ -114,60 +124,62 @@ class GenericBug return bugEventStack; } - virtual cJSON *getBugDescription() const = 0; + virtual cJSON* getBugDescription() const = 0; virtual void printBugToTerminal() const = 0; }; -class BufferOverflowBug: public GenericBug +class BufferOverflowBug : public GenericBug { protected: s64_t allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound; public: - BufferOverflowBug(GenericBug::BugType bugType, const EventStack &eventStack, - s64_t allocLowerBound, s64_t allocUpperBound, - s64_t accessLowerBound, s64_t accessUpperBound): - GenericBug(bugType, eventStack), allocLowerBound(allocLowerBound), - allocUpperBound(allocUpperBound), accessLowerBound(accessLowerBound), - accessUpperBound(accessUpperBound) { } - - cJSON *getBugDescription() const; + BufferOverflowBug(GenericBug::BugType bugType, const EventStack& eventStack, s64_t allocLowerBound, + s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound) + : GenericBug(bugType, eventStack), allocLowerBound(allocLowerBound), allocUpperBound(allocUpperBound), + accessLowerBound(accessLowerBound), accessUpperBound(accessUpperBound) + { + } + + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::PARTIALBUFOVERFLOW || bug->getBugType() == GenericBug::FULLBUFOVERFLOW; } }; -class FullBufferOverflowBug: public BufferOverflowBug +class FullBufferOverflowBug : public BufferOverflowBug { public: - FullBufferOverflowBug(const EventStack &eventStack, - s64_t allocLowerBound, s64_t allocUpperBound, - s64_t accessLowerBound, s64_t accessUpperBound): - BufferOverflowBug(GenericBug::FULLBUFOVERFLOW, eventStack, allocLowerBound, - allocUpperBound, accessLowerBound, accessUpperBound) { } + FullBufferOverflowBug(const EventStack& eventStack, s64_t allocLowerBound, s64_t allocUpperBound, + s64_t accessLowerBound, s64_t accessUpperBound) + : BufferOverflowBug(GenericBug::FULLBUFOVERFLOW, eventStack, allocLowerBound, allocUpperBound, accessLowerBound, + accessUpperBound) + { + } /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::FULLBUFOVERFLOW; } }; -class PartialBufferOverflowBug: public BufferOverflowBug +class PartialBufferOverflowBug : public BufferOverflowBug { public: - PartialBufferOverflowBug( const EventStack &eventStack, - s64_t allocLowerBound, s64_t allocUpperBound, - s64_t accessLowerBound, s64_t accessUpperBound): - BufferOverflowBug(GenericBug::PARTIALBUFOVERFLOW, eventStack, allocLowerBound, - allocUpperBound, accessLowerBound, accessUpperBound) { } + PartialBufferOverflowBug(const EventStack& eventStack, s64_t allocLowerBound, s64_t allocUpperBound, + s64_t accessLowerBound, s64_t accessUpperBound) + : BufferOverflowBug(GenericBug::PARTIALBUFOVERFLOW, eventStack, allocLowerBound, allocUpperBound, + accessLowerBound, accessUpperBound) + { + } /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::PARTIALBUFOVERFLOW; } @@ -176,14 +188,13 @@ class PartialBufferOverflowBug: public BufferOverflowBug class NeverFreeBug : public GenericBug { public: - NeverFreeBug(const EventStack &bugEventStack): - GenericBug(GenericBug::NEVERFREE, bugEventStack) { }; + NeverFreeBug(const EventStack& bugEventStack) : GenericBug(GenericBug::NEVERFREE, bugEventStack){}; - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::NEVERFREE; } @@ -192,14 +203,13 @@ class NeverFreeBug : public GenericBug class PartialLeakBug : public GenericBug { public: - PartialLeakBug(const EventStack &bugEventStack): - GenericBug(GenericBug::PARTIALLEAK, bugEventStack) { } + PartialLeakBug(const EventStack& bugEventStack) : GenericBug(GenericBug::PARTIALLEAK, bugEventStack) {} - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::PARTIALLEAK; } @@ -208,14 +218,13 @@ class PartialLeakBug : public GenericBug class DoubleFreeBug : public GenericBug { public: - DoubleFreeBug(const EventStack &bugEventStack): - GenericBug(GenericBug::DOUBLEFREE, bugEventStack) { } + DoubleFreeBug(const EventStack& bugEventStack) : GenericBug(GenericBug::DOUBLEFREE, bugEventStack) {} - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::DOUBLEFREE; } @@ -224,14 +233,13 @@ class DoubleFreeBug : public GenericBug class FileNeverCloseBug : public GenericBug { public: - FileNeverCloseBug(const EventStack &bugEventStack): - GenericBug(GenericBug::FILENEVERCLOSE, bugEventStack) { }; + FileNeverCloseBug(const EventStack& bugEventStack) : GenericBug(GenericBug::FILENEVERCLOSE, bugEventStack){}; - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::FILENEVERCLOSE; } @@ -240,14 +248,13 @@ class FileNeverCloseBug : public GenericBug class FilePartialCloseBug : public GenericBug { public: - FilePartialCloseBug(const EventStack &bugEventStack): - GenericBug(GenericBug::FILEPARTIALCLOSE, bugEventStack) { } + FilePartialCloseBug(const EventStack& bugEventStack) : GenericBug(GenericBug::FILEPARTIALCLOSE, bugEventStack) {} - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::FILEPARTIALCLOSE; } @@ -256,14 +263,16 @@ class FilePartialCloseBug : public GenericBug class FullNullPtrDereferenceBug : public GenericBug { public: - FullNullPtrDereferenceBug(const EventStack &bugEventStack): - GenericBug(GenericBug::FULLNULLPTRDEREFERENCE, bugEventStack) { } + FullNullPtrDereferenceBug(const EventStack& bugEventStack) + : GenericBug(GenericBug::FULLNULLPTRDEREFERENCE, bugEventStack) + { + } - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::FULLNULLPTRDEREFERENCE; } @@ -272,14 +281,16 @@ class FullNullPtrDereferenceBug : public GenericBug class PartialNullPtrDereferenceBug : public GenericBug { public: - PartialNullPtrDereferenceBug(const EventStack &bugEventStack): - GenericBug(GenericBug::PARTIALNULLPTRDEREFERENCE, bugEventStack) { } + PartialNullPtrDereferenceBug(const EventStack& bugEventStack) + : GenericBug(GenericBug::PARTIALNULLPTRDEREFERENCE, bugEventStack) + { + } - cJSON *getBugDescription() const; + cJSON* getBugDescription() const; void printBugToTerminal() const; /// ClassOf - static inline bool classof(const GenericBug *bug) + static inline bool classof(const GenericBug* bug) { return bug->getBugType() == GenericBug::PARTIALNULLPTRDEREFERENCE; } @@ -290,13 +301,13 @@ class SVFBugReport public: SVFBugReport() = default; ~SVFBugReport(); - typedef SVF::Set BugSet; + typedef SVF::Set BugSet; protected: - BugSet bugSet; // maintain bugs + BugSet bugSet; // maintain bugs double time; // time (sec) - std::string mem; // string memory (KB) - double coverage; // coverage (%) + std::string mem; // string memory (KB) + double coverage; // coverage (%) public: // set time, mem and coverage @@ -312,44 +323,38 @@ class SVFBugReport * it will add the bug into bugQueue. * usage: addSaberBug(GenericBug::NEVERFREE, eventStack) */ - void addSaberBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack) + void addSaberBug(GenericBug::BugType bugType, const GenericBug::EventStack& eventStack) { /// create and add the bug - GenericBug *newBug = nullptr; - switch(bugType) - { - case GenericBug::NEVERFREE: + GenericBug* newBug = nullptr; + switch (bugType) { + case GenericBug::NEVERFREE: { newBug = new NeverFreeBug(eventStack); bugSet.insert(newBug); break; } - case GenericBug::PARTIALLEAK: - { + case GenericBug::PARTIALLEAK: { newBug = new PartialLeakBug(eventStack); bugSet.insert(newBug); break; } - case GenericBug::DOUBLEFREE: - { + case GenericBug::DOUBLEFREE: { newBug = new DoubleFreeBug(eventStack); bugSet.insert(newBug); break; } - case GenericBug::FILENEVERCLOSE: - { + case GenericBug::FILENEVERCLOSE: { newBug = new FileNeverCloseBug(eventStack); bugSet.insert(newBug); break; } - case GenericBug::FILEPARTIALCLOSE: - { + case GenericBug::FILEPARTIALCLOSE: { newBug = new FilePartialCloseBug(eventStack); bugSet.insert(newBug); break; } - default: - { + default: { assert(false && "saber does NOT have this bug type!"); break; } @@ -364,46 +369,43 @@ class SVFBugReport * it will add the bug into bugQueue. * usage: addAbsExecBug(GenericBug::FULLBUFOVERFLOW, eventStack, 0, 10, 11, 11) */ - void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack, - s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound) + void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack& eventStack, s64_t allocLowerBound, + s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound) { /// add bugs - GenericBug *newBug = nullptr; - switch(bugType) + GenericBug* newBug = nullptr; + switch (bugType) { - case GenericBug::FULLBUFOVERFLOW: - { - newBug = new FullBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound); + case GenericBug::FULLBUFOVERFLOW: { + newBug = new FullBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, + accessUpperBound); bugSet.insert(newBug); break; } - case GenericBug::PARTIALBUFOVERFLOW: - { - newBug = new PartialBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound); + case GenericBug::PARTIALBUFOVERFLOW: { + newBug = new PartialBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, + accessUpperBound); bugSet.insert(newBug); break; } - case GenericBug::FULLNULLPTRDEREFERENCE: - { + case GenericBug::FULLNULLPTRDEREFERENCE: { newBug = new FullNullPtrDereferenceBug(eventStack); bugSet.insert(newBug); break; } - case GenericBug::PARTIALNULLPTRDEREFERENCE: - { + case GenericBug::PARTIALNULLPTRDEREFERENCE: { newBug = new PartialNullPtrDereferenceBug(eventStack); bugSet.insert(newBug); break; } - default: - { + default: { assert(false && "Abstract Execution does NOT have this bug type!"); break; } } // when add a bug, also print it to terminal - //newBug->printBugToTerminal(); + // newBug->printBugToTerminal(); } /* @@ -416,12 +418,11 @@ class SVFBugReport * function: get underlying bugset * usage: getBugSet() */ - const BugSet &getBugSet() const + const BugSet& getBugSet() const { return bugSet; } - }; -} +} // namespace SVF #endif \ No newline at end of file diff --git a/svf/include/Util/SVFStat.h b/svf/include/Util/SVFStat.h index 298440851..ae1e82a87 100644 --- a/svf/include/Util/SVFStat.h +++ b/svf/include/Util/SVFStat.h @@ -33,14 +33,12 @@ namespace SVF { - /*! * Pointer Analysis Statistics */ class SVFStat { public: - typedef OrderedMap NUMStatMap; typedef OrderedMap TIMEStatMap; @@ -86,7 +84,7 @@ class SVFStat virtual void performStatPerQuery(NodeID) {} - virtual void printStatPerQuery(NodeID, const PointsTo &) {} + virtual void printStatPerQuery(NodeID, const PointsTo&) {} virtual void callgraphStat() {} @@ -100,4 +98,4 @@ class SVFStat }; // End class SVFStat } // End namespace SVF -#endif //SVF_SVFSTAT_H +#endif // SVF_SVFSTAT_H diff --git a/svf/include/Util/SVFUtil.h b/svf/include/Util/SVFUtil.h index 90c42d098..d5c688bc4 100644 --- a/svf/include/Util/SVFUtil.h +++ b/svf/include/Util/SVFUtil.h @@ -47,27 +47,27 @@ namespace SVFUtil { /// Overwrite llvm::outs() -inline std::ostream &outs() +inline std::ostream& outs() { return std::cout; } /// Overwrite llvm::errs() -inline std::ostream &errs() +inline std::ostream& errs() { return std::cerr; } /// Dump sparse bitvector set -void dumpSet(NodeBS To, OutStream & O = SVFUtil::outs()); -void dumpSet(PointsTo To, OutStream & O = SVFUtil::outs()); +void dumpSet(NodeBS To, OutStream& O = SVFUtil::outs()); +void dumpSet(PointsTo To, OutStream& O = SVFUtil::outs()); /// Dump points-to set -void dumpPointsToSet(unsigned node, NodeBS To) ; +void dumpPointsToSet(unsigned node, NodeBS To); void dumpSparseSet(const NodeBS& To); /// Dump alias set -void dumpAliasSet(unsigned node, NodeBS To) ; +void dumpAliasSet(unsigned node, NodeBS To); /// Returns successful message by converting a string into green string output std::string sucMsg(const std::string& msg); @@ -80,18 +80,17 @@ void writeWrnMsg(const std::string& msg); /// Print error message by converting a string into red string output //@{ -std::string errMsg(const std::string& msg); -std::string bugMsg1(const std::string& msg); -std::string bugMsg2(const std::string& msg); -std::string bugMsg3(const std::string& msg); +std::string errMsg(const std::string& msg); +std::string bugMsg1(const std::string& msg); +std::string bugMsg2(const std::string& msg); +std::string bugMsg3(const std::string& msg); //@} /// Print each pass/phase message by converting a string into blue string output -std::string pasMsg(const std::string& msg); +std::string pasMsg(const std::string& msg); /// Print memory usage in KB. -void reportMemoryUsageKB(const std::string& infor, - OutStream& O = SVFUtil::outs()); +void reportMemoryUsageKB(const std::string& infor, OutStream& O = SVFUtil::outs()); /// Get memory usage from system file. Return TRUE if succeed. bool getMemoryUsageKB(u32_t* vmrss_kb, u32_t* vmsize_kb); @@ -104,36 +103,32 @@ void increaseStackSize(); * 1. PointsTo with smaller size is smaller than the other; * 2. If the sizes are equal, comparing the points-to targets. */ -inline bool cmpPts (const PointsTo& lpts,const PointsTo& rpts) +inline bool cmpPts(const PointsTo& lpts, const PointsTo& rpts) { - if (lpts.count() != rpts.count()) - return (lpts.count() < rpts.count()); + if (lpts.count() != rpts.count()) return (lpts.count() < rpts.count()); else { PointsTo::iterator bit = lpts.begin(), eit = lpts.end(); PointsTo::iterator rbit = rpts.begin(), reit = rpts.end(); for (; bit != eit && rbit != reit; bit++, rbit++) { - if (*bit != *rbit) - return (*bit < *rbit); + if (*bit != *rbit) return (*bit < *rbit); } return false; } } -inline bool cmpNodeBS(const NodeBS& lpts,const NodeBS& rpts) +inline bool cmpNodeBS(const NodeBS& lpts, const NodeBS& rpts) { - if (lpts.count() != rpts.count()) - return (lpts.count() < rpts.count()); + if (lpts.count() != rpts.count()) return (lpts.count() < rpts.count()); else { NodeBS::iterator bit = lpts.begin(), eit = lpts.end(); NodeBS::iterator rbit = rpts.begin(), reit = rpts.end(); for (; bit != eit && rbit != reit; bit++, rbit++) { - if (*bit != *rbit) - return (*bit < *rbit); + if (*bit != *rbit) return (*bit < *rbit); } return false; @@ -156,7 +151,7 @@ typedef struct equalNodeBS } } equalNodeBS; -inline NodeBS ptsToNodeBS(const PointsTo &pts) +inline NodeBS ptsToNodeBS(const PointsTo& pts) { NodeBS nbs; for (const NodeID o : pts) nbs.set(o); @@ -178,8 +173,7 @@ inline bool isCallSite(const SVFInstruction* inst) /// Whether an instruction is a call or invoke instruction inline bool isCallSite(const SVFValue* val) { - if(SVFUtil::isa(val)) - return true; + if (SVFUtil::isa(val)) return true; else return false; } @@ -187,8 +181,7 @@ inline bool isCallSite(const SVFValue* val) /// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls inline bool isNonInstricCallSite(const SVFInstruction* inst) { - if(isIntrinsicInst(inst)) - return false; + if (isIntrinsicInst(inst)) return false; return isCallSite(inst); } @@ -243,20 +236,18 @@ inline const SVFFunction* getCallee(const CallSite cs) return cs.getCalledFunction(); } -inline const SVFFunction* getCallee(const SVFInstruction *inst) +inline const SVFFunction* getCallee(const SVFInstruction* inst) { - if (!isCallSite(inst)) - return nullptr; + if (!isCallSite(inst)) return nullptr; CallSite cs(inst); return getCallee(cs); } //@} /// Given a map mapping points-to sets to a count, adds from into to. -template -void mergePtsOccMaps(Map &to, const Map from) +template void mergePtsOccMaps(Map& to, const Map from) { - for (const typename Map::value_type &ptocc : from) + for (const typename Map::value_type& ptocc : from) { to[ptocc.first] += ptocc.second; } @@ -266,27 +257,25 @@ void mergePtsOccMaps(Map &to, const Map from) std::string hclustMethodToString(hclust_fast_methods method); /// Inserts an element into a Set/CondSet (with ::insert). -template -inline void insertKey(const Key &key, KeySet &keySet) +template inline void insertKey(const Key& key, KeySet& keySet) { keySet.insert(key); } /// Inserts a NodeID into a NodeBS. -inline void insertKey(const NodeID &key, NodeBS &keySet) +inline void insertKey(const NodeID& key, NodeBS& keySet) { keySet.set(key); } /// Removes an element from a Set/CondSet (or anything implementing ::erase). -template -inline void removeKey(const Key &key, KeySet &keySet) +template inline void removeKey(const Key& key, KeySet& keySet) { keySet.erase(key); } /// Removes a NodeID from a NodeBS. -inline void removeKey(const NodeID &key, NodeBS &keySet) +inline void removeKey(const NodeID& key, NodeBS& keySet) { keySet.reset(key); } @@ -304,7 +293,8 @@ bool startAnalysisLimitTimer(unsigned timeLimit); void stopAnalysisLimitTimer(bool limitTimerSet); /// Return true if the call is an external call (external library in function summary table) -/// If the library function is redefined in the application code (e.g., memcpy), it will return false and will not be treated as an external call. +/// If the library function is redefined in the application code (e.g., memcpy), it will return false and will not be +/// treated as an external call. //@{ inline bool isExtCall(const SVFFunction* fun) { @@ -326,8 +316,7 @@ inline bool isMemsetExtFun(const SVFFunction* fun) /// note that these two functions are not suppose to be used externally inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun) { - return fun && (ExtAPI::getExtAPI()->is_alloc(fun) - || ExtAPI::getExtAPI()->is_realloc(fun)); + return fun && (ExtAPI::getExtAPI()->is_alloc(fun) || ExtAPI::getExtAPI()->is_realloc(fun)); } inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun) @@ -363,9 +352,8 @@ inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::strin { for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it) { - const SVFFunction *fun = *it; - if (fun->getName()==funName) - return fun; + const SVFFunction* fun = *it; + if (fun->getName() == funName) return fun; } return nullptr; } @@ -375,27 +363,23 @@ inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule) { for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it) { - const SVFFunction *fun = *it; - if (isProgEntryFunction(fun)) - return (fun); + const SVFFunction* fun = *it; + if (isProgEntryFunction(fun)) return (fun); } return nullptr; } /// Return true if this is a program exit function call //@{ -inline bool isProgExitFunction (const SVFFunction * fun) +inline bool isProgExitFunction(const SVFFunction* fun) { - return fun && (fun->getName() == "exit" || - fun->getName() == "__assert_rtn" || - fun->getName() == "__assert_fail" ); + return fun && (fun->getName() == "exit" || fun->getName() == "__assert_rtn" || fun->getName() == "__assert_fail"); } /// Return true if this argument belongs to an uncalled function inline bool isArgOfUncalledFunction(const SVFValue* svfval) { - if(const SVFArgument* arg = SVFUtil::dyn_cast(svfval)) - return arg->isArgOfUncalledFunction(); + if (const SVFArgument* arg = SVFUtil::dyn_cast(svfval)) return arg->isArgOfUncalledFunction(); else return false; } @@ -406,7 +390,7 @@ inline const SVFValue* getForkedFun(const CallSite cs) { return ThreadAPI::getThreadAPI()->getForkedFun(cs.getInstruction()); } -inline const SVFValue* getForkedFun(const SVFInstruction *inst) +inline const SVFValue* getForkedFun(const SVFInstruction* inst) { return ThreadAPI::getThreadAPI()->getForkedFun(inst); } @@ -423,7 +407,7 @@ inline bool isExtCall(const CallSite cs) return isExtCall(getCallee(cs)); } -inline bool isExtCall(const SVFInstruction *inst) +inline bool isExtCall(const SVFInstruction* inst) { return isExtCall(getCallee(inst)); } @@ -433,7 +417,7 @@ inline bool isHeapAllocExtCallViaArg(const CallSite cs) return isHeapAllocExtFunViaArg(getCallee(cs)); } -inline bool isHeapAllocExtCallViaArg(const SVFInstruction *inst) +inline bool isHeapAllocExtCallViaArg(const SVFInstruction* inst) { return isHeapAllocExtFunViaArg(getCallee(inst)); } @@ -445,7 +429,7 @@ inline bool isHeapAllocExtCallViaRet(const CallSite cs) return isPtrTy && isHeapAllocExtFunViaRet(getCallee(cs)); } -inline bool isHeapAllocExtCallViaRet(const SVFInstruction *inst) +inline bool isHeapAllocExtCallViaRet(const SVFInstruction* inst) { bool isPtrTy = inst->getType()->isPointerTy(); return isPtrTy && isHeapAllocExtFunViaRet(getCallee(inst)); @@ -456,7 +440,7 @@ inline bool isHeapAllocExtCall(const CallSite cs) return isHeapAllocExtCallViaRet(cs) || isHeapAllocExtCallViaArg(cs); } -inline bool isHeapAllocExtCall(const SVFInstruction *inst) +inline bool isHeapAllocExtCall(const SVFInstruction* inst) { return isHeapAllocExtCallViaRet(inst) || isHeapAllocExtCallViaArg(inst); } @@ -481,7 +465,7 @@ inline bool isThreadForkCall(const CallSite cs) { return ThreadAPI::getThreadAPI()->isTDFork(cs.getInstruction()); } -inline bool isThreadForkCall(const SVFInstruction *inst) +inline bool isThreadForkCall(const SVFInstruction* inst) { return ThreadAPI::getThreadAPI()->isTDFork(inst); } @@ -535,16 +519,12 @@ inline const SVFValue* getActualParmAtForkSite(const CallSite cs) } //@} - inline bool isProgExitCall(const CallSite cs) { return isProgExitFunction(getCallee(cs)); } - -template -constexpr typename std::remove_reference::type && -move(T &&t) noexcept +template constexpr typename std::remove_reference::type&& move(T&& t) noexcept { return std::move(t); } @@ -559,45 +539,60 @@ template using void_t = typename make_void::type; /// @brief Type trait that checks if a type is iterable /// (can be applied on a range-based for loop) ///@{ -template struct is_iterable : std::false_type {}; +template struct is_iterable : std::false_type +{ +}; template -struct is_iterable()) != - std::end(std::declval()))>> -: std::true_type {}; +struct is_iterable()) != std::end(std::declval()))>> : std::true_type +{ +}; template constexpr bool is_iterable_v = is_iterable::value; ///@} /// @brief Type trait to check if a type is a map or unordered_map. ///@{ -template struct is_map : std::false_type {}; -template struct is_map> : std::true_type {}; -template -struct is_map> : std::true_type {}; +template struct is_map : std::false_type +{ +}; +template struct is_map> : std::true_type +{ +}; +template struct is_map> : std::true_type +{ +}; template constexpr bool is_map_v = is_map::value; ///@} /// @brief Type trait to check if a type is a set or unordered_set. ///@{ -template struct is_set : std::false_type {}; -template struct is_set> : std::true_type {}; -template -struct is_set> : std::true_type {}; +template struct is_set : std::false_type +{ +}; +template struct is_set> : std::true_type +{ +}; +template struct is_set> : std::true_type +{ +}; template constexpr bool is_set_v = is_set::value; ///@} /// @brief Type trait to check if a type is vector or list. -template struct is_sequence_container : std::false_type {}; -template -struct is_sequence_container> : std::true_type {}; -template -struct is_sequence_container> : std::true_type {}; -template -struct is_sequence_container> : std::true_type {}; -template -constexpr bool is_sequence_container_v = is_sequence_container::value; +template struct is_sequence_container : std::false_type +{ +}; +template struct is_sequence_container> : std::true_type +{ +}; +template struct is_sequence_container> : std::true_type +{ +}; +template struct is_sequence_container> : std::true_type +{ +}; +template constexpr bool is_sequence_container_v = is_sequence_container::value; ///@} - } // End namespace SVFUtil } // End namespace SVF diff --git a/svf/include/Util/SparseBitVector.h b/svf/include/Util/SparseBitVector.h index 2bcd1f543..c2f1ad49f 100644 --- a/svf/include/Util/SparseBitVector.h +++ b/svf/include/Util/SparseBitVector.h @@ -18,15 +18,15 @@ // Appease GCC? #ifdef __has_builtin -# define HAS_CLZ __has_builtin(__builtin_clz) -# define HAS_CLZLL __has_builtin(__builtin_clzll) -# define HAS_CTZ __has_builtin(__builtin_ctz) -# define HAS_CTZLL __has_builtin(__builtin_ctzll) +# define HAS_CLZ __has_builtin(__builtin_clz) +# define HAS_CLZLL __has_builtin(__builtin_clzll) +# define HAS_CTZ __has_builtin(__builtin_ctz) +# define HAS_CTZLL __has_builtin(__builtin_ctzll) #else -# define HAS_CLZ 0 -# define HAS_CLZLL 0 -# define HAS_CLZ 0 -# define HAS_CLZLL 0 +# define HAS_CLZ 0 +# define HAS_CLZLL 0 +# define HAS_CLZ 0 +# define HAS_CLZLL 0 #endif namespace SVF @@ -47,10 +47,8 @@ template struct TrailingZerosCounter { static unsigned count(T Val, ZeroBehavior) { - if (!Val) - return std::numeric_limits::digits; - if (Val & 0x1) - return 0; + if (!Val) return std::numeric_limits::digits; + if (Val & 0x1) return 0; // Bisection method. unsigned ZeroBits = 0; @@ -75,37 +73,35 @@ template struct TrailingZerosCounter { static unsigned count(T Val, ZeroBehavior) { - if (Val == 0) - return 32; + if (Val == 0) return 32; -#if HAS_CTZ || defined(__GNUC__) +# if HAS_CTZ || defined(__GNUC__) return __builtin_ctz(Val); -#elif defined(_MSC_VER) +# elif defined(_MSC_VER) unsigned long Index; _BitScanForward(&Index, Val); return Index; -#endif +# endif } }; -#if !defined(_MSC_VER) || defined(_M_X64) +# if !defined(_MSC_VER) || defined(_M_X64) template struct TrailingZerosCounter { static unsigned count(T Val, ZeroBehavior) { - if (Val == 0) - return 64; + if (Val == 0) return 64; -#if HAS_CTZLL || defined(__GNUC__) +# if HAS_CTZLL || defined(__GNUC__) return __builtin_ctzll(Val); -#elif defined(_MSC_VER) +# elif defined(_MSC_VER) unsigned long Index; _BitScanForward64(&Index, Val); return Index; -#endif +# endif } }; -#endif +# endif #endif /// Count number of 0's from the least significant bit to the most @@ -115,11 +111,9 @@ template struct TrailingZerosCounter /// /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. -template -unsigned countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) +template unsigned countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, + static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); return TrailingZerosCounter::count(Val, ZB); } @@ -145,16 +139,14 @@ template struct LeadingZerosCounter { static unsigned count(T Val, ZeroBehavior) { - if (!Val) - return std::numeric_limits::digits; + if (!Val) return std::numeric_limits::digits; // Bisection method. unsigned ZeroBits = 0; for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { T Tmp = Val >> Shift; - if (Tmp) - Val = Tmp; + if (Tmp) Val = Tmp; else ZeroBits |= Shift; } @@ -167,37 +159,35 @@ template struct LeadingZerosCounter { static unsigned count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && Val == 0) - return 32; + if (ZB != ZB_Undefined && Val == 0) return 32; -#if defined(__GNUC__) || HAS_CLZ +# if defined(__GNUC__) || HAS_CLZ return __builtin_clz(Val); -#elif defined(_MSC_VER) +# elif defined(_MSC_VER) unsigned long Index; _BitScanReverse(&Index, Val); return Index ^ 31; -#endif +# endif } }; -#if !defined(_MSC_VER) || defined(_M_X64) +# if !defined(_MSC_VER) || defined(_M_X64) template struct LeadingZerosCounter { static unsigned count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && Val == 0) - return 64; + if (ZB != ZB_Undefined && Val == 0) return 64; -#if defined(__GNUC__) || HAS_CLZLL +# if defined(__GNUC__) || HAS_CLZLL return __builtin_clzll(Val); -#elif defined(_MSC_VER) +# elif defined(_MSC_VER) unsigned long Index; _BitScanReverse64(&Index, Val); return Index ^ 63; -#endif +# endif } }; -#endif +# endif #endif /// Count number of 0's from the most significant bit to the least @@ -207,11 +197,9 @@ template struct LeadingZerosCounter /// /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. -template -unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) +template unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, + static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); return LeadingZerosCounter::count(Val, ZB); } @@ -235,11 +223,9 @@ template struct PopulationCounter /// Count the number of set bits in a value. /// Ex. countPopulation(0xF000F000) = 8 /// Returns 0 if the word is zero. -template -inline unsigned countPopulation(T Value) +template inline unsigned countPopulation(T Value) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, + static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); return PopulationCounter::count(Value); } @@ -281,20 +267,18 @@ template struct SparseBitVectorElement SparseBitVectorElement() = default; public: - explicit SparseBitVectorElement(unsigned Idx) : ElementIndex(Idx) {} + explicit SparseBitVectorElement(unsigned Idx) : ElementIndex(Idx) {} // Comparison. - bool operator==(const SparseBitVectorElement &RHS) const + bool operator==(const SparseBitVectorElement& RHS) const { - if (ElementIndex != RHS.ElementIndex) - return false; + if (ElementIndex != RHS.ElementIndex) return false; for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) - if (Bits[i] != RHS.Bits[i]) - return false; + if (Bits[i] != RHS.Bits[i]) return false; return true; } - bool operator!=(const SparseBitVectorElement &RHS) const + bool operator!=(const SparseBitVectorElement& RHS) const { return !(*this == RHS); } @@ -314,8 +298,7 @@ template struct SparseBitVectorElement bool empty() const { for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) - if (Bits[i]) - return false; + if (Bits[i]) return false; return true; } @@ -348,8 +331,7 @@ template struct SparseBitVectorElement size_type count() const { unsigned NumBits = 0; - for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) - NumBits += countPopulation(Bits[i]); + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) NumBits += countPopulation(Bits[i]); return NumBits; } @@ -357,8 +339,7 @@ template struct SparseBitVectorElement int find_first() const { for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) - if (Bits[i] != 0) - return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); + if (Bits[i] != 0) return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); assert(false && "SBV: find_first: SBV cannot be empty"); abort(); } @@ -369,9 +350,7 @@ template struct SparseBitVectorElement for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) { unsigned Idx = BITWORDS_PER_ELEMENT - I - 1; - if (Bits[Idx] != 0) - return Idx * BITWORD_SIZE + BITWORD_SIZE - - countLeadingZeros(Bits[Idx]) - 1; + if (Bits[Idx] != 0) return Idx * BITWORD_SIZE + BITWORD_SIZE - countLeadingZeros(Bits[Idx]) - 1; } assert(false && "SBV: find_last: SBV cannot be empty"); abort(); @@ -381,30 +360,26 @@ template struct SparseBitVectorElement /// "Curr" bit. Returns -1 if the next set bit is not found. int find_next(unsigned Curr) const { - if (Curr >= BITS_PER_ELEMENT) - return -1; + if (Curr >= BITS_PER_ELEMENT) return -1; unsigned WordPos = Curr / BITWORD_SIZE; unsigned BitPos = Curr % BITWORD_SIZE; BitWord Copy = Bits[WordPos]; - assert(WordPos <= BITWORDS_PER_ELEMENT - && "Word Position outside of element"); + assert(WordPos <= BITWORDS_PER_ELEMENT && "Word Position outside of element"); // Mask off previous bits. Copy &= ~0UL << BitPos; - if (Copy != 0) - return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); + if (Copy != 0) return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); // Check subsequent words. - for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i) - if (Bits[i] != 0) - return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); + for (unsigned i = WordPos + 1; i < BITWORDS_PER_ELEMENT; ++i) + if (Bits[i] != 0) return i * BITWORD_SIZE + countTrailingZeros(Bits[i]); return -1; } // Union this element with RHS and return true if this one changed. - bool unionWith(const SparseBitVectorElement &RHS) + bool unionWith(const SparseBitVectorElement& RHS) { bool changed = false; for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) @@ -412,27 +387,24 @@ template struct SparseBitVectorElement BitWord old = changed ? 0 : Bits[i]; Bits[i] |= RHS.Bits[i]; - if (!changed && old != Bits[i]) - changed = true; + if (!changed && old != Bits[i]) changed = true; } return changed; } // Return true if we have any bits in common with RHS - bool intersects(const SparseBitVectorElement &RHS) const + bool intersects(const SparseBitVectorElement& RHS) const { for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { - if (RHS.Bits[i] & Bits[i]) - return true; + if (RHS.Bits[i] & Bits[i]) return true; } return false; } // Intersect this Element with RHS and return true if this one changed. // BecameZero is set to true if this element became all-zero bits. - bool intersectWith(const SparseBitVectorElement &RHS, - bool &BecameZero) + bool intersectWith(const SparseBitVectorElement& RHS, bool& BecameZero) { bool changed = false; bool allzero = true; @@ -443,11 +415,9 @@ template struct SparseBitVectorElement BitWord old = changed ? 0 : Bits[i]; Bits[i] &= RHS.Bits[i]; - if (Bits[i] != 0) - allzero = false; + if (Bits[i] != 0) allzero = false; - if (!changed && old != Bits[i]) - changed = true; + if (!changed && old != Bits[i]) changed = true; } BecameZero = allzero; return changed; @@ -456,8 +426,7 @@ template struct SparseBitVectorElement // Intersect this Element with the complement of RHS and return true if this // one changed. BecameZero is set to true if this element became all-zero // bits. - bool intersectWithComplement(const SparseBitVectorElement &RHS, - bool &BecameZero) + bool intersectWithComplement(const SparseBitVectorElement& RHS, bool& BecameZero) { bool changed = false; bool allzero = true; @@ -468,11 +437,9 @@ template struct SparseBitVectorElement BitWord old = changed ? 0 : Bits[i]; Bits[i] &= ~RHS.Bits[i]; - if (Bits[i] != 0) - allzero = false; + if (Bits[i] != 0) allzero = false; - if (!changed && old != Bits[i]) - changed = true; + if (!changed && old != Bits[i]) changed = true; } BecameZero = allzero; return changed; @@ -480,9 +447,8 @@ template struct SparseBitVectorElement // Three argument version of intersectWithComplement that intersects // RHS1 & ~RHS2 into this element - void intersectWithComplement(const SparseBitVectorElement &RHS1, - const SparseBitVectorElement &RHS2, - bool &BecameZero) + void intersectWithComplement(const SparseBitVectorElement& RHS1, const SparseBitVectorElement& RHS2, + bool& BecameZero) { bool allzero = true; @@ -490,15 +456,13 @@ template struct SparseBitVectorElement for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i]; - if (Bits[i] != 0) - allzero = false; + if (Bits[i] != 0) allzero = false; } BecameZero = allzero; } }; -template -class SparseBitVector +template class SparseBitVector { friend class SVFIRWriter; friend class SVFIRReader; @@ -527,10 +491,8 @@ class SparseBitVector // of code with the only difference being whether the const cast is present // 'this' is always const in this particular function and we sort out the // difference in FindLowerBound and FindLowerBoundConst. - ElementListIter Begin = - const_cast *>(this)->Elements.begin(); - ElementListIter End = - const_cast *>(this)->Elements.end(); + ElementListIter Begin = const_cast*>(this)->Elements.begin(); + ElementListIter End = const_cast*>(this)->Elements.end(); if (Elements.empty()) { @@ -539,8 +501,7 @@ class SparseBitVector } // Make sure our current iterator is valid. - if (CurrElementIter == End) - --CurrElementIter; + if (CurrElementIter == End) --CurrElementIter; // Search from our current iterator, either backwards or forwards, // depending on what element we are looking for. @@ -551,15 +512,11 @@ class SparseBitVector } else if (CurrElementIter->index() > ElementIndex) { - while (ElementIter != Begin - && ElementIter->index() > ElementIndex) - --ElementIter; + while (ElementIter != Begin && ElementIter->index() > ElementIndex) --ElementIter; } else { - while (ElementIter != End && - ElementIter->index() < ElementIndex) - ++ElementIter; + while (ElementIter != End && ElementIter->index() < ElementIndex) ++ElementIter; } CurrElementIter = ElementIter; return ElementIter; @@ -580,7 +537,7 @@ class SparseBitVector private: bool AtEnd; - const SparseBitVector *BitVector = nullptr; + const SparseBitVector* BitVector = nullptr; // Current element inside of bitmap. ElementListConstIter Iter; @@ -597,8 +554,7 @@ class SparseBitVector // Move our iterator to the first non-zero bit in the bitmap. void AdvanceToFirstNonZero() { - if (AtEnd) - return; + if (AtEnd) return; if (BitVector->Elements.empty()) { AtEnd = true; @@ -616,8 +572,7 @@ class SparseBitVector // Move our iterator to the next non-zero bit. void AdvanceToNextNonZero() { - if (AtEnd) - return; + if (AtEnd) return; while (Bits && !(Bits & 1)) { @@ -628,7 +583,7 @@ class SparseBitVector // See if we ran out of Bits in this word. if (!Bits) { - int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ; + int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize); // If we ran out of set bits in this element, move to next element. if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) { @@ -663,8 +618,7 @@ class SparseBitVector public: SparseBitVectorIterator() = delete; - SparseBitVectorIterator(const SparseBitVector *RHS, - bool end = false):BitVector(RHS) + SparseBitVectorIterator(const SparseBitVector* RHS, bool end = false) : BitVector(RHS) { Iter = BitVector->Elements.begin(); BitNumber = 0; @@ -697,17 +651,16 @@ class SparseBitVector return BitNumber; } - bool operator==(const SparseBitVectorIterator &RHS) const + bool operator==(const SparseBitVectorIterator& RHS) const { // If they are both at the end, ignore the rest of the fields. - if (AtEnd && RHS.AtEnd) - return true; + if (AtEnd && RHS.AtEnd) return true; // Otherwise they are the same if they have the same bit number and // bitmap. return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber; } - bool operator!=(const SparseBitVectorIterator &RHS) const + bool operator!=(const SparseBitVectorIterator& RHS) const { return !(*this == RHS); } @@ -718,10 +671,11 @@ class SparseBitVector SparseBitVector() : Elements(), CurrElementIter(Elements.begin()) {} - SparseBitVector(const SparseBitVector &RHS) - : Elements(RHS.Elements), CurrElementIter(Elements.begin()) {} - SparseBitVector(SparseBitVector &&RHS) - noexcept : Elements(std::move(RHS.Elements)), CurrElementIter(Elements.begin()) {} + SparseBitVector(const SparseBitVector& RHS) : Elements(RHS.Elements), CurrElementIter(Elements.begin()) {} + SparseBitVector(SparseBitVector&& RHS) noexcept + : Elements(std::move(RHS.Elements)), CurrElementIter(Elements.begin()) + { + } // Clear. void clear() @@ -732,14 +686,13 @@ class SparseBitVector // Assignment SparseBitVector& operator=(const SparseBitVector& RHS) { - if (this == &RHS) - return *this; + if (this == &RHS) return *this; Elements = RHS.Elements; CurrElementIter = Elements.begin(); return *this; } - SparseBitVector &operator=(SparseBitVector &&RHS) + SparseBitVector& operator=(SparseBitVector&& RHS) { Elements = std::move(RHS.Elements); CurrElementIter = Elements.begin(); @@ -749,33 +702,27 @@ class SparseBitVector // Test, Reset, and Set a bit in the bitmap. bool test(unsigned Idx) const { - if (Elements.empty()) - return false; + if (Elements.empty()) return false; unsigned ElementIndex = Idx / ElementSize; ElementListConstIter ElementIter = FindLowerBoundConst(ElementIndex); // If we can't find an element that is supposed to contain this bit, there // is nothing more to do. - if (ElementIter == Elements.end() || - ElementIter->index() != ElementIndex) - return false; + if (ElementIter == Elements.end() || ElementIter->index() != ElementIndex) return false; return ElementIter->test(Idx % ElementSize); } void reset(unsigned Idx) { - if (Elements.empty()) - return; + if (Elements.empty()) return; unsigned ElementIndex = Idx / ElementSize; ElementListIter ElementIter = FindLowerBound(ElementIndex); // If we can't find an element that is supposed to contain this bit, there // is nothing more to do. - if (ElementIter == Elements.end() || - ElementIter->index() != ElementIndex) - return; + if (ElementIter == Elements.end() || ElementIter->index() != ElementIndex) return; ElementIter->reset(Idx % ElementSize); // When the element is zeroed out, delete it. @@ -798,15 +745,12 @@ class SparseBitVector { ElementIter = FindLowerBound(ElementIndex); - if (ElementIter == Elements.end() || - ElementIter->index() != ElementIndex) + if (ElementIter == Elements.end() || ElementIter->index() != ElementIndex) { // We may have hit the beginning of our SparseBitVector, in which case, // we may need to insert right after this element, which requires moving // the current iterator forward one, because insert does insert before. - if (ElementIter != Elements.end() && - ElementIter->index() < ElementIndex) - ++ElementIter; + if (ElementIter != Elements.end() && ElementIter->index() < ElementIndex) ++ElementIter; ElementIter = Elements.emplace(ElementIter, ElementIndex); } } @@ -826,38 +770,34 @@ class SparseBitVector return false; } - bool operator!=(const SparseBitVector &RHS) const + bool operator!=(const SparseBitVector& RHS) const { return !(*this == RHS); } - bool operator==(const SparseBitVector &RHS) const + bool operator==(const SparseBitVector& RHS) const { ElementListConstIter Iter1 = Elements.begin(); ElementListConstIter Iter2 = RHS.Elements.begin(); - for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end(); - ++Iter1, ++Iter2) + for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end(); ++Iter1, ++Iter2) { - if (*Iter1 != *Iter2) - return false; + if (*Iter1 != *Iter2) return false; } return Iter1 == Elements.end() && Iter2 == RHS.Elements.end(); } // Union our bitmap with the RHS and return true if we changed. - bool operator|=(const SparseBitVector &RHS) + bool operator|=(const SparseBitVector& RHS) { - if (this == &RHS) - return false; + if (this == &RHS) return false; bool changed = false; ElementListIter Iter1 = Elements.begin(); ElementListConstIter Iter2 = RHS.Elements.begin(); // If RHS is empty, we are done - if (RHS.Elements.empty()) - return false; + if (RHS.Elements.empty()) return false; while (Iter2 != RHS.Elements.end()) { @@ -883,18 +823,16 @@ class SparseBitVector } // Intersect our bitmap with the RHS and return true if ours changed. - bool operator&=(const SparseBitVector &RHS) + bool operator&=(const SparseBitVector& RHS) { - if (this == &RHS) - return false; + if (this == &RHS) return false; bool changed = false; ElementListIter Iter1 = Elements.begin(); ElementListConstIter Iter2 = RHS.Elements.begin(); // Check if both bitmaps are empty. - if (Elements.empty() && RHS.Elements.empty()) - return false; + if (Elements.empty() && RHS.Elements.empty()) return false; // Loop through, intersecting as we go, erasing elements when necessary. while (Iter2 != RHS.Elements.end()) @@ -944,7 +882,7 @@ class SparseBitVector // Intersect our bitmap with the complement of the RHS and return true // if ours changed. - bool intersectWithComplement(const SparseBitVector &RHS) + bool intersectWithComplement(const SparseBitVector& RHS) { if (this == &RHS) { @@ -961,8 +899,7 @@ class SparseBitVector ElementListConstIter Iter2 = RHS.Elements.begin(); // If either our bitmap or RHS is empty, we are done - if (Elements.empty() || RHS.Elements.empty()) - return false; + if (Elements.empty() || RHS.Elements.empty()) return false; // Loop through, intersecting as we go, erasing elements when necessary. while (Iter2 != RHS.Elements.end()) @@ -1002,15 +939,14 @@ class SparseBitVector return changed; } - bool intersectWithComplement(const SparseBitVector *RHS) const + bool intersectWithComplement(const SparseBitVector* RHS) const { return intersectWithComplement(*RHS); } // Three argument version of intersectWithComplement. // Result of RHS1 & ~RHS2 is stored into this bitmap. - void intersectWithComplement(const SparseBitVector &RHS1, - const SparseBitVector &RHS2) + void intersectWithComplement(const SparseBitVector& RHS1, const SparseBitVector& RHS2) { if (this == &RHS1) { @@ -1031,14 +967,12 @@ class SparseBitVector // If RHS1 is empty, we are done // If RHS2 is empty, we still have to copy RHS1 - if (RHS1.Elements.empty()) - return; + if (RHS1.Elements.empty()) return; // Loop through, intersecting as we go, erasing elements when necessary. while (Iter2 != RHS2.Elements.end()) { - if (Iter1 == RHS1.Elements.end()) - return; + if (Iter1 == RHS1.Elements.end()) return; if (Iter1->index() > Iter2->index()) { @@ -1049,8 +983,7 @@ class SparseBitVector bool BecameZero = false; Elements.emplace_back(Iter1->index()); Elements.back().intersectWithComplement(*Iter1, *Iter2, BecameZero); - if (BecameZero) - Elements.pop_back(); + if (BecameZero) Elements.pop_back(); ++Iter1; ++Iter2; } @@ -1064,32 +997,29 @@ class SparseBitVector std::copy(Iter1, RHS1.Elements.end(), std::back_inserter(Elements)); } - void intersectWithComplement(const SparseBitVector *RHS1, - const SparseBitVector *RHS2) + void intersectWithComplement(const SparseBitVector* RHS1, const SparseBitVector* RHS2) { intersectWithComplement(*RHS1, *RHS2); } - bool intersects(const SparseBitVector *RHS) const + bool intersects(const SparseBitVector* RHS) const { return intersects(*RHS); } // Return true if we share any bits in common with RHS - bool intersects(const SparseBitVector &RHS) const + bool intersects(const SparseBitVector& RHS) const { ElementListConstIter Iter1 = Elements.begin(); ElementListConstIter Iter2 = RHS.Elements.begin(); // Check if both bitmaps are empty. - if (Elements.empty() && RHS.Elements.empty()) - return false; + if (Elements.empty() && RHS.Elements.empty()) return false; // Loop through, intersecting stopping when we hit bits in common. while (Iter2 != RHS.Elements.end()) { - if (Iter1 == Elements.end()) - return false; + if (Iter1 == Elements.end()) return false; if (Iter1->index() > Iter2->index()) { @@ -1097,8 +1027,7 @@ class SparseBitVector } else if (Iter1->index() == Iter2->index()) { - if (Iter1->intersects(*Iter2)) - return true; + if (Iter1->intersects(*Iter2)) return true; ++Iter1; ++Iter2; } @@ -1112,7 +1041,7 @@ class SparseBitVector // Return true iff all bits set in this SparseBitVector are // also set in RHS. - bool contains(const SparseBitVector &RHS) const + bool contains(const SparseBitVector& RHS) const { SparseBitVector Result(*this); Result &= RHS; @@ -1122,18 +1051,16 @@ class SparseBitVector // Return the first set bit in the bitmap. Return -1 if no bits are set. int find_first() const { - if (Elements.empty()) - return -1; - const SparseBitVectorElement &First = *(Elements.begin()); + if (Elements.empty()) return -1; + const SparseBitVectorElement& First = *(Elements.begin()); return (First.index() * ElementSize) + First.find_first(); } // Return the last set bit in the bitmap. Return -1 if no bits are set. int find_last() const { - if (Elements.empty()) - return -1; - const SparseBitVectorElement &Last = *(Elements.rbegin()); + if (Elements.empty()) return -1; + const SparseBitVectorElement& Last = *(Elements.rbegin()); return (Last.index() * ElementSize) + Last.find_last(); } @@ -1146,10 +1073,7 @@ class SparseBitVector unsigned count() const { unsigned BitCount = 0; - for (ElementListConstIter Iter = Elements.begin(); - Iter != Elements.end(); - ++Iter) - BitCount += Iter->count(); + for (ElementListConstIter Iter = Elements.begin(); Iter != Elements.end(); ++Iter) BitCount += Iter->count(); return BitCount; } @@ -1169,29 +1093,25 @@ class SparseBitVector // code. template -inline bool operator |=(SparseBitVector &LHS, - const SparseBitVector *RHS) +inline bool operator|=(SparseBitVector& LHS, const SparseBitVector* RHS) { return LHS |= *RHS; } template -inline bool operator |=(SparseBitVector *LHS, - const SparseBitVector &RHS) +inline bool operator|=(SparseBitVector* LHS, const SparseBitVector& RHS) { return LHS->operator|=(RHS); } template -inline bool operator &=(SparseBitVector *LHS, - const SparseBitVector &RHS) +inline bool operator&=(SparseBitVector* LHS, const SparseBitVector& RHS) { return LHS->operator&=(RHS); } template -inline bool operator &=(SparseBitVector &LHS, - const SparseBitVector *RHS) +inline bool operator&=(SparseBitVector& LHS, const SparseBitVector* RHS) { return LHS &= *RHS; } @@ -1199,9 +1119,8 @@ inline bool operator &=(SparseBitVector &LHS, // Convenience functions for infix union, intersection, difference operators. template -inline SparseBitVector -operator|(const SparseBitVector &LHS, - const SparseBitVector &RHS) +inline SparseBitVector operator|(const SparseBitVector& LHS, + const SparseBitVector& RHS) { SparseBitVector Result(LHS); Result |= RHS; @@ -1209,9 +1128,8 @@ operator|(const SparseBitVector &LHS, } template -inline SparseBitVector -operator&(const SparseBitVector &LHS, - const SparseBitVector &RHS) +inline SparseBitVector operator&(const SparseBitVector& LHS, + const SparseBitVector& RHS) { SparseBitVector Result(LHS); Result &= RHS; @@ -1219,9 +1137,8 @@ operator&(const SparseBitVector &LHS, } template -inline SparseBitVector -operator-(const SparseBitVector &LHS, - const SparseBitVector &RHS) +inline SparseBitVector operator-(const SparseBitVector& LHS, + const SparseBitVector& RHS) { SparseBitVector Result; Result.intersectWithComplement(LHS, RHS); @@ -1229,13 +1146,11 @@ operator-(const SparseBitVector &LHS, } // Dump a SparseBitVector to a stream -template -void dump(const SparseBitVector &LHS, std::ostream &out) +template void dump(const SparseBitVector& LHS, std::ostream& out) { out << "["; - typename SparseBitVector::iterator bi = LHS.begin(), - be = LHS.end(); + typename SparseBitVector::iterator bi = LHS.begin(), be = LHS.end(); if (bi != be) { out << *bi; diff --git a/svf/include/Util/ThreadAPI.h b/svf/include/Util/ThreadAPI.h index 63b4c49ec..57ade72f1 100644 --- a/svf/include/Util/ThreadAPI.h +++ b/svf/include/Util/ThreadAPI.h @@ -47,17 +47,17 @@ class ThreadAPI public: enum TD_TYPE { - TD_DUMMY = 0, /// dummy type - TD_FORK, /// create a new thread - TD_JOIN, /// wait for a thread to join - TD_DETACH, /// detach a thread directly instead wait for it to join - TD_ACQUIRE, /// acquire a lock - TD_TRY_ACQUIRE, /// try to acquire a lock - TD_RELEASE, /// release a lock - TD_EXIT, /// exit/kill a thread - TD_CANCEL, /// cancel a thread by another - TD_COND_WAIT, /// wait a condition - TD_COND_SIGNAL, /// signal a condition + TD_DUMMY = 0, /// dummy type + TD_FORK, /// create a new thread + TD_JOIN, /// wait for a thread to join + TD_DETACH, /// detach a thread directly instead wait for it to join + TD_ACQUIRE, /// acquire a lock + TD_TRY_ACQUIRE, /// try to acquire a lock + TD_RELEASE, /// release a lock + TD_EXIT, /// exit/kill a thread + TD_CANCEL, /// cancel a thread by another + TD_COND_WAIT, /// wait a condition + TD_COND_SIGNAL, /// signal a condition TD_COND_BROADCAST, /// broadcast a condition TD_MUTEX_INI, /// initial a mutex variable TD_MUTEX_DESTROY, /// initial a mutex variable @@ -75,7 +75,7 @@ class ThreadAPI TDAPIMap tdAPIMap; /// Constructor - ThreadAPI () + ThreadAPI() { init(); } @@ -89,11 +89,10 @@ class ThreadAPI /// Get the function type if it is a threadAPI function inline TD_TYPE getType(const SVFFunction* F) const { - if(F) + if (F) { - TDAPIMap::const_iterator it= tdAPIMap.find(F->getName()); - if(it != tdAPIMap.end()) - return it->second; + TDAPIMap::const_iterator it = tdAPIMap.find(F->getName()); + if (it != tdAPIMap.end()) return it->second; } return TD_DUMMY; } @@ -102,7 +101,7 @@ class ThreadAPI /// Return a static reference static ThreadAPI* getThreadAPI() { - if(tdAPI == nullptr) + if (tdAPI == nullptr) { tdAPI = new ThreadAPI(); } @@ -111,7 +110,7 @@ class ThreadAPI static void destroy() { - if(tdAPI != nullptr) + if (tdAPI != nullptr) { delete tdAPI; tdAPI = nullptr; @@ -120,15 +119,15 @@ class ThreadAPI /// Return the callee/callsite/func //@{ - const SVFFunction* getCallee(const ICFGNode *inst) const; - const SVFFunction* getCallee(const SVFInstruction *inst) const; - const CallSite getSVFCallSite(const SVFInstruction *inst) const; - const CallSite getSVFCallSite(const ICFGNode *inst) const; + const SVFFunction* getCallee(const ICFGNode* inst) const; + const SVFFunction* getCallee(const SVFInstruction* inst) const; + const CallSite getSVFCallSite(const SVFInstruction* inst) const; + const CallSite getSVFCallSite(const ICFGNode* inst) const; //@} /// Return true if this call create a new thread //@{ - inline bool isTDFork(const ICFGNode *inst) const + inline bool isTDFork(const ICFGNode* inst) const { return getType(getCallee(inst)) == TD_FORK; } @@ -142,7 +141,7 @@ class ThreadAPI //@{ /// Return the first argument of the call, /// Note that, it is the pthread_t pointer - inline const SVFValue* getForkedThread(const ICFGNode *inst) const + inline const SVFValue* getForkedThread(const ICFGNode* inst) const { assert(isTDFork(inst) && "not a thread fork function!"); CallSite cs = getSVFCallSite(inst); @@ -157,7 +156,7 @@ class ThreadAPI /// Return the third argument of the call, /// Note that, it could be function type or a void* pointer - inline const SVFValue* getForkedFun(const ICFGNode *inst) const + inline const SVFValue* getForkedFun(const ICFGNode* inst) const { assert(isTDFork(inst) && "not a thread fork function!"); CallSite cs = getSVFCallSite(inst); @@ -172,7 +171,7 @@ class ThreadAPI /// Return the forth argument of the call, /// Note that, it is the sole argument of start routine ( a void* pointer ) - inline const SVFValue* getActualParmAtForkSite(const ICFGNode *inst) const + inline const SVFValue* getActualParmAtForkSite(const ICFGNode* inst) const { assert(isTDFork(inst) && "not a thread fork function!"); CallSite cs = getSVFCallSite(inst); @@ -188,7 +187,7 @@ class ThreadAPI /// Return true if this call wait for a worker thread //@{ - inline bool isTDJoin(const ICFGNode *inst) const + inline bool isTDJoin(const ICFGNode* inst) const { return getType(getCallee(inst)) == TD_JOIN; } @@ -202,10 +201,10 @@ class ThreadAPI //@{ /// Return the first argument of the call, /// Note that, it is the pthread_t pointer - const SVFValue* getJoinedThread(const ICFGNode *inst) const; + const SVFValue* getJoinedThread(const ICFGNode* inst) const; /// Return the send argument of the call, /// Note that, it is the pthread_t pointer - inline const SVFValue* getRetParmAtJoinedSite(const ICFGNode *inst) const + inline const SVFValue* getRetParmAtJoinedSite(const ICFGNode* inst) const { assert(isTDJoin(inst) && "not a thread join function!"); CallSite cs = getSVFCallSite(inst); @@ -219,10 +218,9 @@ class ThreadAPI } //@} - /// Return true if this call exits/terminate a thread //@{ - inline bool isTDExit(const ICFGNode *inst) const + inline bool isTDExit(const ICFGNode* inst) const { return getType(getCallee(inst)) == TD_EXIT; } @@ -248,7 +246,7 @@ class ThreadAPI /// Return true if this call release a lock //@{ - inline bool isTDRelease(const ICFGNode *inst) const + inline bool isTDRelease(const ICFGNode* inst) const { return getType(getCallee(inst)) == TD_RELEASE; } @@ -262,12 +260,12 @@ class ThreadAPI /// Return lock value //@{ /// First argument of pthread_mutex_lock/pthread_mutex_unlock - const SVFValue* getLockVal(const ICFGNode *inst) const; + const SVFValue* getLockVal(const ICFGNode* inst) const; //@} /// Return true if this call waits for a barrier //@{ - inline bool isTDBarWait(const ICFGNode *inst) const + inline bool isTDBarWait(const ICFGNode* inst) const { return getType(getCallee(inst)) == TD_BAR_WAIT; } diff --git a/svf/include/Util/WorkList.h b/svf/include/Util/WorkList.h old mode 100755 new mode 100644 index 302efb00f..aa42623a2 --- a/svf/include/Util/WorkList.h +++ b/svf/include/Util/WorkList.h @@ -32,7 +32,6 @@ * */ - #ifndef WORKLIST_H_ #define WORKLIST_H_ @@ -52,13 +51,12 @@ namespace SVF * New nodes pushed at back and popped from front. * Elements in the list are unique as they're recorded by Set. */ -template -class List +template class List { class ListNode { public: - ListNode(const Data &d) + ListNode(const Data& d) { data = d; next = nullptr; @@ -67,7 +65,7 @@ class List ~ListNode() {} Data data; - ListNode *next; + ListNode* next; }; typedef Set DataSet; @@ -87,18 +85,17 @@ class List return (head == nullptr); } - inline bool find(const Data &data) const + inline bool find(const Data& data) const { return nodeSet.find(data) != nodeSet.end(); } - void push(const Data &data) + void push(const Data& data) { if (nodeSet.find(data) == nodeSet.end()) { - Node *new_node = new Node(data); - if (head == nullptr) - head = new_node;// the list is empty + Node* new_node = new Node(data); + if (head == nullptr) head = new_node; // the list is empty else tail->next = new_node; tail = new_node; @@ -109,12 +106,11 @@ class List { assert(head != nullptr && "list is empty"); /// get node from list head - Node *head_node = head; + Node* head_node = head; /// change list head to the next node head = head->next; - if (head == nullptr) - tail = nullptr; /// the last node is popped. + if (head == nullptr) tail = nullptr; /// the last node is popped. Data data = head_node->data; nodeSet.erase(data); @@ -124,8 +120,8 @@ class List private: DataSet nodeSet; - Node *head; - Node *tail; + Node* head; + Node* tail; }; /** @@ -133,11 +129,11 @@ class List * New nodes will be pushed at back and popped from front. * Elements in the list are unique as they're recorded by Set. */ -template -class FIFOWorkList +template class FIFOWorkList { typedef Set DataSet; typedef std::deque DataDeque; + public: FIFOWorkList() {} @@ -154,7 +150,7 @@ class FIFOWorkList return data_list.size(); } - inline bool find(const Data &data) const + inline bool find(const Data& data) const { return data_set.find(data) != data_set.end(); } @@ -162,7 +158,7 @@ class FIFOWorkList /** * Push a data into the work list. */ - inline bool push(const Data &data) + inline bool push(const Data& data) { if (!find(data)) { @@ -187,10 +183,10 @@ class FIFOWorkList /** * Get reference of top data from the END of work list. */ - inline Data &front() + inline Data& front() { assert(!empty() && "work list is empty"); - Data &data = data_list.front(); + Data& data = data_list.front(); return data; } @@ -217,7 +213,7 @@ class FIFOWorkList private: DataSet data_set; ///< store all data in the work list. - DataDeque data_list; ///< work list using std::vector. + DataDeque data_list; ///< work list using std::vector. }; /** @@ -225,11 +221,11 @@ class FIFOWorkList * New nodes will be pushed at back and popped from back. * Elements in the list are unique as they're recorded by Set. */ -template -class FILOWorkList +template class FILOWorkList { typedef Set DataSet; typedef std::vector DataVector; + public: FILOWorkList() {} @@ -246,15 +242,16 @@ class FILOWorkList return data_list.size(); } - inline bool find(const Data &data) const + inline bool find(const Data& data) const { - return data_set.find(data) != data_set.end();; + return data_set.find(data) != data_set.end(); + ; } /** * Push a data into the work list. */ - inline bool push(const Data &data) + inline bool push(const Data& data) { if (!find(data)) { @@ -291,10 +288,10 @@ class FILOWorkList /** * Get reference of top data from the END of work list. */ - inline Data &back() + inline Data& back() { assert(!empty() && "work list is empty"); - Data &data = data_list.back(); + Data& data = data_list.back(); return data; } @@ -308,8 +305,8 @@ class FILOWorkList } private: - DataSet data_set; ///< store all data in the work list. - DataVector data_list; ///< work list using std::vector. + DataSet data_set; ///< store all data in the work list. + DataVector data_list; ///< work list using std::vector. }; } // End namespace SVF diff --git a/svf/include/Util/Z3Expr.h b/svf/include/Util/Z3Expr.h index 3a1f33fbd..816edd9e9 100644 --- a/svf/include/Util/Z3Expr.h +++ b/svf/include/Util/Z3Expr.h @@ -38,43 +38,28 @@ namespace SVF class Z3Expr { public: - static z3::context *ctx; + static z3::context* ctx; static z3::solver* solver; private: z3::expr e; - - public: + Z3Expr() : e(nullExpr()) {} - Z3Expr() : e(nullExpr()) - { - } + Z3Expr(const z3::expr& _e) : e(_e) {} - Z3Expr(const z3::expr &_e) : e(_e) - { - } + Z3Expr(int i) : e(getContext().int_val(i)) {} - Z3Expr(int i) : e(getContext().int_val(i)) - { - } + Z3Expr(const Z3Expr& z3Expr) : e(z3Expr.getExpr()) {} - Z3Expr(const Z3Expr &z3Expr) : e(z3Expr.getExpr()) - { - } + Z3Expr(float f) : Z3Expr((double)f) {} - Z3Expr(float f) : Z3Expr((double) f) - { - } - - Z3Expr(double f): e(getContext().real_val(std::to_string(f).c_str())) - { - } + Z3Expr(double f) : e(getContext().real_val(std::to_string(f).c_str())) {} virtual ~Z3Expr() = default; - inline Z3Expr &operator=(const Z3Expr &rhs) + inline Z3Expr& operator=(const Z3Expr& rhs) { if (this->id() != rhs.id()) { @@ -83,16 +68,16 @@ class Z3Expr return *this; } - const z3::expr &getExpr() const + const z3::expr& getExpr() const { return e; } /// Get z3 solver, singleton design here to make sure we only have one context - static z3::solver &getSolver(); + static z3::solver& getSolver(); /// Get z3 context, singleton design here to make sure we only have one context - static z3::context &getContext(); + static z3::context& getContext(); /// release z3 context static void releaseContext(); @@ -100,7 +85,6 @@ class Z3Expr /// release z3 solver static void releaseSolver(); - /// null expression static z3::expr nullExpr() { @@ -150,123 +134,123 @@ class Z3Expr } //{% reload operator - friend Z3Expr operator==(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator==(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() == rhs.getExpr(); } - friend Z3Expr operator!=(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator!=(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() != rhs.getExpr(); } - friend Z3Expr operator>(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator>(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() > rhs.getExpr(); } - friend Z3Expr operator<(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator<(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() < rhs.getExpr(); } - friend Z3Expr operator<=(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator<=(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() <= rhs.getExpr(); } - friend Z3Expr operator>=(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator>=(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() >= rhs.getExpr(); } - friend Z3Expr operator+(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator+(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() + rhs.getExpr(); } - friend Z3Expr operator-(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator-(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() - rhs.getExpr(); } - friend Z3Expr operator*(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator*(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() * rhs.getExpr(); } - friend Z3Expr operator/(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator/(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() / rhs.getExpr(); } - friend Z3Expr operator%(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator%(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() % rhs.getExpr(); } - friend Z3Expr operator^(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator^(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() ^ rhs.getExpr(); } - friend Z3Expr operator&(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator&(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() & rhs.getExpr(); } - friend Z3Expr operator|(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator|(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() | rhs.getExpr(); } - friend Z3Expr ashr(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr ashr(const Z3Expr& lhs, const Z3Expr& rhs) { return ashr(lhs.getExpr(), rhs.getExpr()); } - friend Z3Expr shl(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr shl(const Z3Expr& lhs, const Z3Expr& rhs) { return shl(lhs.getExpr(), rhs.getExpr()); } - friend Z3Expr int2bv(u32_t n, const Z3Expr &e) + friend Z3Expr int2bv(u32_t n, const Z3Expr& e) { return int2bv(n, e.getExpr()); } - friend Z3Expr bv2int(const Z3Expr &e, bool isSigned) + friend Z3Expr bv2int(const Z3Expr& e, bool isSigned) { return z3::bv2int(e.getExpr(), isSigned); } - friend Z3Expr operator&&(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator&&(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() && rhs.getExpr(); } - friend Z3Expr operator||(const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr operator||(const Z3Expr& lhs, const Z3Expr& rhs) { return lhs.getExpr() || rhs.getExpr(); } - friend Z3Expr operator!(const Z3Expr &lhs) + friend Z3Expr operator!(const Z3Expr& lhs) { return !lhs.getExpr(); } - friend Z3Expr ite(const Z3Expr &cond, const Z3Expr &lhs, const Z3Expr &rhs) + friend Z3Expr ite(const Z3Expr& cond, const Z3Expr& lhs, const Z3Expr& rhs) { return ite(cond.getExpr(), lhs.getExpr(), rhs.getExpr()); } - friend std::ostream &operator<<(std::ostream &out, const Z3Expr &expr) + friend std::ostream& operator<<(std::ostream& out, const Z3Expr& expr) { out << expr.getExpr(); return out; } - friend bool eq(const Z3Expr &lhs, const Z3Expr &rhs) + friend bool eq(const Z3Expr& lhs, const Z3Expr& rhs) { return eq(lhs.getExpr().simplify(), rhs.getExpr().simplify()); } @@ -278,11 +262,10 @@ class Z3Expr //%} /// output Z3 expression as a string - static std::string dumpStr(const Z3Expr &z3Expr); - + static std::string dumpStr(const Z3Expr& z3Expr); /// get the number of subexpression of a Z3 expression - static u32_t getExprSize(const Z3Expr &z3Expr); + static u32_t getExprSize(const Z3Expr& z3Expr); /// Return the unique true condition static inline Z3Expr getTrueCond() @@ -290,7 +273,6 @@ class Z3Expr return getContext().bool_val(true); } - /// Return the unique false condition static inline Z3Expr getFalseCond() { @@ -298,28 +280,26 @@ class Z3Expr } /// compute NEG - static inline Z3Expr NEG(const Z3Expr &z3Expr) + static inline Z3Expr NEG(const Z3Expr& z3Expr) { return (!z3Expr).simplify(); } /// compute AND, used for branch condition - static Z3Expr AND(const Z3Expr &lhs, const Z3Expr &rhs); + static Z3Expr AND(const Z3Expr& lhs, const Z3Expr& rhs); /// compute OR, used for branch condition - static Z3Expr OR(const Z3Expr &lhs, const Z3Expr &rhs); + static Z3Expr OR(const Z3Expr& lhs, const Z3Expr& rhs); }; } // End namespace SVF /// Specialise hash for AbsCxtDPItem. -template<> -struct std::hash +template <> struct std::hash { - size_t operator()(const SVF::Z3Expr &z3Expr) const + size_t operator()(const SVF::Z3Expr& z3Expr) const { return z3Expr.id(); } }; -#endif //Z3_EXAMPLE_Z3EXPR_H - +#endif // Z3_EXAMPLE_Z3EXPR_H diff --git a/svf/include/Util/cJSON.h b/svf/include/Util/cJSON.h index 106e53744..d530ee70e 100644 --- a/svf/include/Util/cJSON.h +++ b/svf/include/Util/cJSON.h @@ -29,53 +29,54 @@ extern "C" #endif #if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) -#define __WINDOWS__ +# define __WINDOWS__ #endif #ifdef __WINDOWS__ -/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + /* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called + from a project with a different default calling convention. For windows you have 3 define options: -CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols -CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) -CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols + CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) + CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol -For *nix builds that support visibility attribute, you can define similar behavior by + For *nix builds that support visibility attribute, you can define similar behavior by -setting default visibility to hidden by adding --fvisibility=hidden (for gcc) -or --xldscope=hidden (for sun cc) -to CFLAGS + setting default visibility to hidden by adding + -fvisibility=hidden (for gcc) + or + -xldscope=hidden (for sun cc) + to CFLAGS -then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does -*/ + */ -#define CJSON_CDECL __cdecl -#define CJSON_STDCALL __stdcall +# define CJSON_CDECL __cdecl +# define CJSON_STDCALL __stdcall /* export symbols by default, this is necessary for copy pasting the C and header file */ -#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_EXPORT_SYMBOLS -#endif - -#if defined(CJSON_HIDE_SYMBOLS) -#define CJSON_PUBLIC(type) type CJSON_STDCALL -#elif defined(CJSON_EXPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL -#elif defined(CJSON_IMPORT_SYMBOLS) -#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL -#endif +# if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +# define CJSON_EXPORT_SYMBOLS +# endif + +# if defined(CJSON_HIDE_SYMBOLS) +# define CJSON_PUBLIC(type) type CJSON_STDCALL +# elif defined(CJSON_EXPORT_SYMBOLS) +# define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +# elif defined(CJSON_IMPORT_SYMBOLS) +# define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +# endif #else /* !__WINDOWS__ */ -#define CJSON_CDECL -#define CJSON_STDCALL - -#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) -#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type -#else -#define CJSON_PUBLIC(type) type -#endif +# define CJSON_CDECL +# define CJSON_STDCALL + +# if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +# define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +# else +# define CJSON_PUBLIC(type) type +# endif #endif /* project version */ @@ -87,211 +88,230 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ /* cJSON Types: */ #define cJSON_Invalid (0) -#define cJSON_False (1 << 0) -#define cJSON_True (1 << 1) -#define cJSON_NULL (1 << 2) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) #define cJSON_Number (1 << 3) #define cJSON_String (1 << 4) -#define cJSON_Array (1 << 5) +#define cJSON_Array (1 << 5) #define cJSON_Object (1 << 6) -#define cJSON_Raw (1 << 7) /* raw json */ +#define cJSON_Raw (1 << 7) /* raw json */ #define cJSON_IsReference 256 #define cJSON_StringIsConst 512 -/* The cJSON structure: */ -typedef struct cJSON -{ - /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ - struct cJSON *next; - struct cJSON *prev; - /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ - struct cJSON *child; - - /* The type of the item, as above. */ - int type; - - /* The item's string, if type==cJSON_String and type == cJSON_Raw */ - char *valuestring; - /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ - int valueint; - /* The item's number, if type==cJSON_Number */ - double valuedouble; - - /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ - char *string; -} cJSON; - -typedef struct cJSON_Hooks -{ - /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ - void *(CJSON_CDECL *malloc_fn)(size_t sz); - void (CJSON_CDECL *free_fn)(void *ptr); -} cJSON_Hooks; - -typedef int cJSON_bool; + /* The cJSON structure: */ + typedef struct cJSON + { + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem + */ + struct cJSON* next; + struct cJSON* prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON* child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char* valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char* string; + } cJSON; + + typedef struct cJSON_Hooks + { + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the + * hooks allow passing those functions directly. */ + void*(CJSON_CDECL* malloc_fn)(size_t sz); + void(CJSON_CDECL* free_fn)(void* ptr); + } cJSON_Hooks; + + typedef int cJSON_bool; /* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. * This is to prevent stack overflows. */ #ifndef CJSON_NESTING_LIMIT -#define CJSON_NESTING_LIMIT 1000 +# define CJSON_NESTING_LIMIT 1000 #endif -/* returns the version of cJSON as a string */ -CJSON_PUBLIC(const char*) cJSON_Version(void); - -/* Supply malloc, realloc and free functions to cJSON */ -CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); - -/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ -/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ -CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ -CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); - -/* Render a cJSON entity to text for transfer/storage. */ -CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); -/* Render a cJSON entity to text for transfer/storage without any formatting. */ -CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); -/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ -CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); -/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ -/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ -CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); -/* Delete a cJSON entity and all subentities. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); - -/* Returns the number of items in an array (or object). */ -CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); -/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ -CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); -/* Get item "string" from object. Case insensitive. */ -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); -CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); - -/* Check item type and return its value */ -CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); -CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); - -/* These functions check the type of an item */ -CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); -CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); - -/* These calls create a cJSON item of the appropriate type. */ -CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); -CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); -CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); -/* raw json */ -CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); -CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); -CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); - -/* Create a string where valuestring references a string so - * it will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); -/* Create an object/array that only references it's elements so - * they will not be freed by cJSON_Delete */ -CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); -CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); - -/* These utilities create an Array of count items. - * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ -CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); -CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); - -/* Append item to the specified array/object. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); -/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. - * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before - * writing to `item->string` */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); -/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); - -/* Remove/Detach items from Arrays/Objects. */ -CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); -CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); -CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); -CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); - -/* Update array items. */ -CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); - -/* Duplicate a cJSON item */ -CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); -/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will - * need to be released. With recurse!=0, it will duplicate any children connected to the item. - * The item->next and ->prev pointers are always zero on return from Duplicate. */ -/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. - * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ -CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); - -/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. - * The input pointer json cannot point to a read-only address area, such as a string constant, - * but should point to a readable and writable address area. */ -CJSON_PUBLIC(void) cJSON_Minify(char *json); - -/* Helper functions for creating and adding items to an object at the same time. - * They return the added item or NULL on failure. */ -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); -CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); -CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + /* returns the version of cJSON as a string */ + CJSON_PUBLIC(const char*) cJSON_Version(void); + + /* Supply malloc, realloc and free functions to cJSON */ + CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + + /* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with + * cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The + * exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ + /* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ + CJSON_PUBLIC(cJSON*) cJSON_Parse(const char* value); + CJSON_PUBLIC(cJSON*) cJSON_ParseWithLength(const char* value, size_t buffer_length); + /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to + * the final byte parsed. */ + /* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the + * error so will match cJSON_GetErrorPtr(). */ + CJSON_PUBLIC(cJSON*) + cJSON_ParseWithOpts(const char* value, const char** return_parse_end, cJSON_bool require_null_terminated); + CJSON_PUBLIC(cJSON*) + cJSON_ParseWithLengthOpts(const char* value, size_t buffer_length, const char** return_parse_end, + cJSON_bool require_null_terminated); + + /* Render a cJSON entity to text for transfer/storage. */ + CJSON_PUBLIC(char*) cJSON_Print(const cJSON* item); + /* Render a cJSON entity to text for transfer/storage without any formatting. */ + CJSON_PUBLIC(char*) cJSON_PrintUnformatted(const cJSON* item); + /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well + * reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ + CJSON_PUBLIC(char*) cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt); + /* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success + * and 0 on failure. */ + /* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes + * more than you actually need */ + CJSON_PUBLIC(cJSON_bool) + cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format); + /* Delete a cJSON entity and all subentities. */ + CJSON_PUBLIC(void) cJSON_Delete(cJSON* item); + + /* Returns the number of items in an array (or object). */ + CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON* array); + /* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ + CJSON_PUBLIC(cJSON*) cJSON_GetArrayItem(const cJSON* array, int index); + /* Get item "string" from object. Case insensitive. */ + CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char* const string); + CJSON_PUBLIC(cJSON*) cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string); + CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON* object, const char* string); + /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars + * back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ + CJSON_PUBLIC(const char*) cJSON_GetErrorPtr(void); + + /* Check item type and return its value */ + CJSON_PUBLIC(char*) cJSON_GetStringValue(const cJSON* const item); + CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON* const item); + + /* These functions check the type of an item */ + CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON* const item); + CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON* const item); + + /* These calls create a cJSON item of the appropriate type. */ + CJSON_PUBLIC(cJSON*) cJSON_CreateNull(void); + CJSON_PUBLIC(cJSON*) cJSON_CreateTrue(void); + CJSON_PUBLIC(cJSON*) cJSON_CreateFalse(void); + CJSON_PUBLIC(cJSON*) cJSON_CreateBool(cJSON_bool boolean); + CJSON_PUBLIC(cJSON*) cJSON_CreateNumber(double num); + CJSON_PUBLIC(cJSON*) cJSON_CreateString(const char* string); + /* raw json */ + CJSON_PUBLIC(cJSON*) cJSON_CreateRaw(const char* raw); + CJSON_PUBLIC(cJSON*) cJSON_CreateArray(void); + CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void); + + /* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ + CJSON_PUBLIC(cJSON*) cJSON_CreateStringReference(const char* string); + /* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ + CJSON_PUBLIC(cJSON*) cJSON_CreateObjectReference(const cJSON* child); + CJSON_PUBLIC(cJSON*) cJSON_CreateArrayReference(const cJSON* child); + + /* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access + * will be out of bounds.*/ + CJSON_PUBLIC(cJSON*) cJSON_CreateIntArray(const int* numbers, int count); + CJSON_PUBLIC(cJSON*) cJSON_CreateFloatArray(const float* numbers, int count); + CJSON_PUBLIC(cJSON*) cJSON_CreateDoubleArray(const double* numbers, int count); + CJSON_PUBLIC(cJSON*) cJSON_CreateStringArray(const char* const* strings, int count); + + /* Append item to the specified array/object. */ + CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON* array, cJSON* item); + CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item); + /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON + * object. WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) + * is zero before writing to `item->string` */ + CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item); + /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new + * cJSON, but don't want to corrupt your existing cJSON. */ + CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item); + CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item); + + /* Remove/Detach items from Arrays/Objects. */ + CJSON_PUBLIC(cJSON*) cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item); + CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromArray(cJSON* array, int which); + CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON* array, int which); + CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObject(cJSON* object, const char* string); + CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string); + CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON* object, const char* string); + CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string); + + /* Update array items. */ + CJSON_PUBLIC(cJSON_bool) + cJSON_InsertItemInArray(cJSON* array, int which, cJSON* newitem); /* Shifts pre-existing items to the right. */ + CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement); + CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem); + CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem); + CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem); + + /* Duplicate a cJSON item */ + CJSON_PUBLIC(cJSON*) cJSON_Duplicate(const cJSON* item, cJSON_bool recurse); + /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ + /* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered + * unequal. case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ + CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive); + + /* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable address area. */ + CJSON_PUBLIC(void) cJSON_Minify(char* json); + + /* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ + CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON* const object, const char* const name); + CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON* const object, const char* const name); + CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON* const object, const char* const name); + CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON* const object, const char* const name, const cJSON_bool boolean); + CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON* const object, const char* const name, const double number); + CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON* const object, const char* const name, const char* const string); + CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON* const object, const char* const name, const char* const raw); + CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON* const object, const char* const name); + CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON* const object, const char* const name); /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) -/* helper for the cJSON_SetNumberValue macro */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); -#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) -/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ -CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + /* helper for the cJSON_SetNumberValue macro */ + CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON* object, double number); +#define cJSON_SetNumberValue(object, number) \ + ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) + /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ + CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON* object, const char* valuestring); /* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/ -#define cJSON_SetBoolValue(object, boolValue) ( \ - (object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \ - (object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \ - cJSON_Invalid\ -) +#define cJSON_SetBoolValue(object, boolValue) \ + ((object != NULL && ((object)->type & (cJSON_False | cJSON_True))) \ + ? (object)->type = \ + ((object)->type & (~(cJSON_False | cJSON_True))) | ((boolValue) ? cJSON_True : cJSON_False) \ + : cJSON_Invalid) /* Macro for iterating over an array or object */ -#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) +#define cJSON_ArrayForEach(element, array) \ + for (element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) -/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ -CJSON_PUBLIC(void *) cJSON_malloc(size_t size); -CJSON_PUBLIC(void) cJSON_free(void *object); + /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ + CJSON_PUBLIC(void*) cJSON_malloc(size_t size); + CJSON_PUBLIC(void) cJSON_free(void* object); #ifdef __cplusplus } diff --git a/svf/include/Util/iterator.h b/svf/include/Util/iterator.h index dbe4581bc..555bc5155 100644 --- a/svf/include/Util/iterator.h +++ b/svf/include/Util/iterator.h @@ -61,9 +61,8 @@ namespace SVF /// - DerivedT &operator+=(DifferenceTypeT N); /// - DerivedT &operator-=(DifferenceTypeT N); /// -template +template class iter_facade_base { public: @@ -76,10 +75,10 @@ class iter_facade_base protected: enum { - IsRandomAccess = std::is_base_of::value, - IsBidirectional = std::is_base_of::value, + IsRandomAccess = std::is_base_of < std::random_access_iterator_tag, + IteratorCategoryT > ::value, + IsBidirectional = std::is_base_of < std::bidirectional_iterator_tag, + IteratorCategoryT > ::value, }; /// A proxy object for computing a reference via indirecting a copy of an @@ -107,108 +106,89 @@ class iter_facade_base { static_assert(std::is_base_of::value, "Must pass the derived type to this template!"); - static_assert( - IsRandomAccess, - "The '+' operator is only defined for random access iterators."); - DerivedT tmp = *static_cast(this); + static_assert(IsRandomAccess, "The '+' operator is only defined for random access iterators."); + DerivedT tmp = *static_cast(this); tmp += n; return tmp; } - friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i) + friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i) { - static_assert( - IsRandomAccess, - "The '+' operator is only defined for random access iterators."); + static_assert(IsRandomAccess, "The '+' operator is only defined for random access iterators."); return i + n; } DerivedT operator-(DifferenceTypeT n) const { - static_assert( - IsRandomAccess, - "The '-' operator is only defined for random access iterators."); - DerivedT tmp = *static_cast(this); + static_assert(IsRandomAccess, "The '-' operator is only defined for random access iterators."); + DerivedT tmp = *static_cast(this); tmp -= n; return tmp; } - DerivedT &operator++() + DerivedT& operator++() { static_assert(std::is_base_of::value, "Must pass the derived type to this template!"); - return static_cast(this)->operator+=(1); + return static_cast(this)->operator+=(1); } DerivedT operator++(int) { - DerivedT tmp = *static_cast(this); - ++*static_cast(this); + DerivedT tmp = *static_cast(this); + ++*static_cast(this); return tmp; } - DerivedT &operator--() + DerivedT& operator--() { - static_assert( - IsBidirectional, - "The decrement operator is only defined for bidirectional iterators."); - return static_cast(this)->operator-=(1); + static_assert(IsBidirectional, "The decrement operator is only defined for bidirectional iterators."); + return static_cast(this)->operator-=(1); } DerivedT operator--(int) { - static_assert( - IsBidirectional, - "The decrement operator is only defined for bidirectional iterators."); - DerivedT tmp = *static_cast(this); - --*static_cast(this); + static_assert(IsBidirectional, "The decrement operator is only defined for bidirectional iterators."); + DerivedT tmp = *static_cast(this); + --*static_cast(this); return tmp; } #ifndef __cpp_impl_three_way_comparison - bool operator!=(const DerivedT &RHS) const + bool operator!=(const DerivedT& RHS) const { - return !(static_cast(*this) == RHS); + return !(static_cast(*this) == RHS); } #endif - bool operator>(const DerivedT &RHS) const + bool operator>(const DerivedT& RHS) const { - static_assert( - IsRandomAccess, - "Relational operators are only defined for random access iterators."); - return !(static_cast(*this) < RHS) && - !(static_cast(*this) == RHS); + static_assert(IsRandomAccess, "Relational operators are only defined for random access iterators."); + return !(static_cast(*this) < RHS) && !(static_cast(*this) == RHS); } - bool operator<=(const DerivedT &RHS) const + bool operator<=(const DerivedT& RHS) const { - static_assert( - IsRandomAccess, - "Relational operators are only defined for random access iterators."); - return !(static_cast(*this) > RHS); + static_assert(IsRandomAccess, "Relational operators are only defined for random access iterators."); + return !(static_cast(*this) > RHS); } - bool operator>=(const DerivedT &RHS) const + bool operator>=(const DerivedT& RHS) const { - static_assert( - IsRandomAccess, - "Relational operators are only defined for random access iterators."); - return !(static_cast(*this) < RHS); + static_assert(IsRandomAccess, "Relational operators are only defined for random access iterators."); + return !(static_cast(*this) < RHS); } PointerT operator->() { - return &static_cast(this)->operator*(); + return &static_cast(this)->operator*(); } PointerT operator->() const { - return &static_cast(this)->operator*(); + return &static_cast(this)->operator*(); } ReferenceProxy operator[](DifferenceTypeT n) { - static_assert(IsRandomAccess, - "Subscripting is only defined for random access iterators."); - return ReferenceProxy(static_cast(this)->operator+(n)); + static_assert(IsRandomAccess, "Subscripting is only defined for random access iterators."); + return ReferenceProxy(static_cast(this)->operator+(n)); } ReferenceProxy operator[](DifferenceTypeT n) const { - static_assert(IsRandomAccess, - "Subscripting is only defined for random access iterators."); - return ReferenceProxy(static_cast(this)->operator+(n)); + static_assert(IsRandomAccess, "Subscripting is only defined for random access iterators."); + return ReferenceProxy(static_cast(this)->operator+(n)); } }; @@ -217,24 +197,17 @@ class iter_facade_base /// This class can be used through CRTP to adapt one iterator into another. /// Typically this is done through providing in the derived class a custom \c /// operator* implementation. Other methods can be overridden as well. -template < - typename DerivedT, typename WrappedIteratorT, - typename IteratorCategoryT = - typename std::iterator_traits::iterator_category, - typename T = typename std::iterator_traits::value_type, - typename DifferenceTypeT = - typename std::iterator_traits::difference_type, - typename PointerT = std::conditional_t< - std::is_same::value_type>::value, - typename std::iterator_traits::pointer, T *>, - typename ReferenceT = std::conditional_t< - std::is_same::value_type>::value, - typename std::iterator_traits::reference, T &>> -class iter_adaptor_base - : public iter_facade_base +template ::iterator_category, + typename T = typename std::iterator_traits::value_type, + typename DifferenceTypeT = typename std::iterator_traits::difference_type, + typename PointerT = + std::conditional_t::value_type>::value, + typename std::iterator_traits::pointer, T*>, + typename ReferenceT = + std::conditional_t::value_type>::value, + typename std::iterator_traits::reference, T&>> +class iter_adaptor_base : public iter_facade_base { using BaseT = typename iter_adaptor_base::iter_facade_base; @@ -249,7 +222,7 @@ class iter_adaptor_base "Must pass the derived type to this template!"); } - const WrappedIteratorT &wrapped() const + const WrappedIteratorT& wrapped() const { return I; } @@ -257,60 +230,48 @@ class iter_adaptor_base public: using difference_type = DifferenceTypeT; - DerivedT &operator+=(difference_type n) + DerivedT& operator+=(difference_type n) { - static_assert( - BaseT::IsRandomAccess, - "The '+=' operator is only defined for random access iterators."); + static_assert(BaseT::IsRandomAccess, "The '+=' operator is only defined for random access iterators."); I += n; - return *static_cast(this); + return *static_cast(this); } - DerivedT &operator-=(difference_type n) + DerivedT& operator-=(difference_type n) { - static_assert( - BaseT::IsRandomAccess, - "The '-=' operator is only defined for random access iterators."); + static_assert(BaseT::IsRandomAccess, "The '-=' operator is only defined for random access iterators."); I -= n; - return *static_cast(this); + return *static_cast(this); } using BaseT::operator-; - difference_type operator-(const DerivedT &RHS) const + difference_type operator-(const DerivedT& RHS) const { - static_assert( - BaseT::IsRandomAccess, - "The '-' operator is only defined for random access iterators."); + static_assert(BaseT::IsRandomAccess, "The '-' operator is only defined for random access iterators."); return I - RHS.I; } // We have to explicitly provide ++ and -- rather than letting the facade // forward to += because WrappedIteratorT might not support +=. using BaseT::operator++; - DerivedT &operator++() + DerivedT& operator++() { ++I; - return *static_cast(this); + return *static_cast(this); } using BaseT::operator--; - DerivedT &operator--() + DerivedT& operator--() { - static_assert( - BaseT::IsBidirectional, - "The decrement operator is only defined for bidirectional iterators."); + static_assert(BaseT::IsBidirectional, "The decrement operator is only defined for bidirectional iterators."); --I; - return *static_cast(this); + return *static_cast(this); } - friend bool operator==(const iter_adaptor_base &LHS, - const iter_adaptor_base &RHS) + friend bool operator==(const iter_adaptor_base& LHS, const iter_adaptor_base& RHS) { return LHS.I == RHS.I; } - friend bool operator<(const iter_adaptor_base &LHS, - const iter_adaptor_base &RHS) + friend bool operator<(const iter_adaptor_base& LHS, const iter_adaptor_base& RHS) { - static_assert( - BaseT::IsRandomAccess, - "Relational operators are only defined for random access iterators."); + static_assert(BaseT::IsRandomAccess, "Relational operators are only defined for random access iterators."); return LHS.I < RHS.I; } @@ -329,66 +290,50 @@ class iter_adaptor_base /// \code /// using iterator = pointee_iter::iterator>; /// \endcode -template ())>> -struct pointee_iter - : iter_adaptor_base< - pointee_iter, WrappedIteratorT, - typename std::iterator_traits::iterator_category, - T> +template ())>> +struct pointee_iter : iter_adaptor_base, WrappedIteratorT, + typename std::iterator_traits::iterator_category, T> { pointee_iter() = default; - template - pointee_iter(U &&u) - : pointee_iter::iter_adaptor_base(std::forward(u)) {} + template pointee_iter(U&& u) : pointee_iter::iter_adaptor_base(std::forward(u)) {} - T &operator*() const + T& operator*() const { return **this->I; } }; -template ()))> -iter_range> - make_pointee_range(RangeT &&Range) +template ()))> +iter_range> make_pointee_range(RangeT&& Range) { using PointeeIteratorT = pointee_iter; return make_range(PointeeIteratorT(std::begin(std::forward(Range))), PointeeIteratorT(std::end(std::forward(Range)))); } -template ())> -class pointer_iterator - : public iter_adaptor_base< - pointer_iterator, WrappedIteratorT, - typename std::iterator_traits::iterator_category, - T> +template ())> +class pointer_iterator : public iter_adaptor_base, WrappedIteratorT, + typename std::iterator_traits::iterator_category, T> { mutable T Ptr; public: pointer_iterator() = default; - explicit pointer_iterator(WrappedIteratorT u) - : pointer_iterator::iter_adaptor_base(std::move(u)) {} + explicit pointer_iterator(WrappedIteratorT u) : pointer_iterator::iter_adaptor_base(std::move(u)) {} - T &operator*() + T& operator*() { return Ptr = &*this->I; } - const T &operator*() const + const T& operator*() const { return Ptr = &*this->I; } }; -template ()))> -iter_range> - make_pointer_range(RangeT &&Range) +template ()))> +iter_range> make_pointer_range(RangeT&& Range) { using PointerIteratorT = pointer_iterator; return make_range(PointerIteratorT(std::begin(std::forward(Range))), @@ -396,12 +341,10 @@ iter_range> } template ())>, + typename T1 = std::remove_reference_t())>, typename T2 = std::add_pointer_t> -using raw_pointer_iterator = - pointer_iterator, T2>; +using raw_pointer_iterator = pointer_iterator, T2>; -} // end namespace llvm +} // namespace SVF #endif // LLVM_ADT_ITERATOR_H diff --git a/svf/include/Util/iterator_range.h b/svf/include/Util/iterator_range.h index d569cb6c0..7a2cac939 100644 --- a/svf/include/Util/iterator_range.h +++ b/svf/include/Util/iterator_range.h @@ -27,21 +27,23 @@ namespace SVF /// /// This just wraps two iterators into a range-compatible interface. Nothing /// fancy at all. -template -class iter_range +template class iter_range { IteratorT begin_iterator, end_iterator; public: - //TODO: Add SFINAE to test that the Container's iterators match the range's - // iterators. + // TODO: Add SFINAE to test that the Container's iterators match the range's + // iterators. template - iter_range(Container &&c) - //TODO: Consider ADL/non-member begin/end calls. - : begin_iterator(c.begin()), end_iterator(c.end()) {} + iter_range(Container&& c) + // TODO: Consider ADL/non-member begin/end calls. + : begin_iterator(c.begin()), end_iterator(c.end()) + { + } iter_range(IteratorT begin_iterator, IteratorT end_iterator) - : begin_iterator(std::move(begin_iterator)), - end_iterator(std::move(end_iterator)) {} + : begin_iterator(std::move(begin_iterator)), end_iterator(std::move(end_iterator)) + { + } IteratorT begin() const { @@ -71,6 +73,6 @@ template iter_range make_range(std::pair p) return iter_range(std::move(p.first), std::move(p.second)); } -} +} // namespace SVF #endif diff --git a/svf/include/WPA/Andersen.h b/svf/include/WPA/Andersen.h index c327843ba..ed5a9f6a5 100644 --- a/svf/include/WPA/Andersen.h +++ b/svf/include/WPA/Andersen.h @@ -28,8 +28,8 @@ * * The field-sensitive implementation is improved based on * - * Yuxiang Lei and Yulei Sui. "Fast and Precise Handling of Positive Weight Cycles for Field-sensitive Pointer Analysis". - * 26th International Static Analysis Symposium (SAS'19) + * Yuxiang Lei and Yulei Sui. "Fast and Precise Handling of Positive Weight Cycles for Field-sensitive Pointer + * Analysis". 26th International Static Analysis Symposium (SAS'19) */ #ifndef INCLUDE_WPA_ANDERSEN_H_ @@ -52,13 +52,12 @@ class SVFModule; */ typedef WPASolver WPAConstraintSolver; -class AndersenBase: public WPAConstraintSolver, public BVDataPTAImpl +class AndersenBase : public WPAConstraintSolver, public BVDataPTAImpl { public: - /// Constructor AndersenBase(SVFIR* _pag, PTATY type = Andersen_BASE, bool alias_check = true) - : BVDataPTAImpl(_pag, type, alias_check), consCG(nullptr) + : BVDataPTAImpl(_pag, type, alias_check), consCG(nullptr) { iterationForPrintStat = OnTheFlyIterBudgetForStat; } @@ -89,19 +88,16 @@ class AndersenBase: public WPAConstraintSolver, public BVDataPTAImpl /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const AndersenBase *) + static inline bool classof(const AndersenBase*) { return true; } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { - return ( pta->getAnalysisTy() == Andersen_BASE - || pta->getAnalysisTy() == Andersen_WPA - || pta->getAnalysisTy() == AndersenWaveDiff_WPA - || pta->getAnalysisTy() == AndersenSCD_WPA - || pta->getAnalysisTy() == AndersenSFR_WPA - || pta->getAnalysisTy() == TypeCPP_WPA - || pta->getAnalysisTy() == Steensgaard_WPA); + return (pta->getAnalysisTy() == Andersen_BASE || pta->getAnalysisTy() == Andersen_WPA || + pta->getAnalysisTy() == AndersenWaveDiff_WPA || pta->getAnalysisTy() == AndersenSCD_WPA || + pta->getAnalysisTy() == AndersenSFR_WPA || pta->getAnalysisTy() == TypeCPP_WPA || + pta->getAnalysisTy() == Steensgaard_WPA); } //@} @@ -138,11 +134,11 @@ class AndersenBase: public WPAConstraintSolver, public BVDataPTAImpl /// Statistics //@{ - static u32_t numOfProcessedAddr; /// Number of processed Addr edge - static u32_t numOfProcessedCopy; /// Number of processed Copy edge - static u32_t numOfProcessedGep; /// Number of processed Gep edge - static u32_t numOfProcessedLoad; /// Number of processed Load edge - static u32_t numOfProcessedStore; /// Number of processed Store edge + static u32_t numOfProcessedAddr; /// Number of processed Addr edge + static u32_t numOfProcessedCopy; /// Number of processed Copy edge + static u32_t numOfProcessedGep; /// Number of processed Gep edge + static u32_t numOfProcessedLoad; /// Number of processed Load edge + static u32_t numOfProcessedStore; /// Number of processed Store edge static u32_t numOfSfrs; static u32_t numOfFieldExpand; @@ -165,25 +161,18 @@ class AndersenBase: public WPAConstraintSolver, public BVDataPTAImpl /*! * Inclusion-based Pointer Analysis */ -class Andersen: public AndersenBase +class Andersen : public AndersenBase { - public: typedef SCCDetection CGSCC; typedef OrderedMap CallSite2DummyValPN; /// Constructor - Andersen(SVFIR* _pag, PTATY type = Andersen_WPA, bool alias_check = true) - : AndersenBase(_pag, type, alias_check) - { - } + Andersen(SVFIR* _pag, PTATY type = Andersen_WPA, bool alias_check = true) : AndersenBase(_pag, type, alias_check) {} /// Destructor - virtual ~Andersen() - { - - } + virtual ~Andersen() {} /// Initialize analysis virtual void initialize(); @@ -202,16 +191,14 @@ class Andersen: public AndersenBase /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const Andersen *) + static inline bool classof(const Andersen*) { return true; } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { - return (pta->getAnalysisTy() == Andersen_WPA - || pta->getAnalysisTy() == AndersenWaveDiff_WPA - || pta->getAnalysisTy() == AndersenSCD_WPA - || pta->getAnalysisTy() == AndersenSFR_WPA); + return (pta->getAnalysisTy() == Andersen_WPA || pta->getAnalysisTy() == AndersenWaveDiff_WPA || + pta->getAnalysisTy() == AndersenSCD_WPA || pta->getAnalysisTy() == AndersenSFR_WPA); } //@} @@ -229,10 +216,9 @@ class Andersen: public AndersenBase { id = sccRepNode(id); ptd = sccRepNode(ptd); - return getPTDataTy()->unionPts(id,ptd); + return getPTDataTy()->unionPts(id, ptd); } - void dumpTopLevelPtsTo(); void setDetectPWC(bool flag) @@ -241,9 +227,9 @@ class Andersen: public AndersenBase } protected: - - CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocator - void heapAllocatorViaIndCall(CallSite cs,NodePairSet &cpySrcNodes); + CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which created at an indirect + ///< callsite, which invokes a heap allocator + void heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes); /// Handle diff points-to set. virtual inline void computeDiffPts(NodeID id) @@ -257,8 +243,7 @@ class Andersen: public AndersenBase virtual inline const PointsTo& getDiffPts(NodeID id) { NodeID rep = sccRepNode(id); - if (Options::DiffPts()) - return getDiffPTDataTy()->getDiffPts(rep); + if (Options::DiffPts()) return getDiffPTDataTy()->getDiffPts(rep); else return getPTDataTy()->getPts(rep); } @@ -266,8 +251,7 @@ class Andersen: public AndersenBase /// Handle propagated points-to set. inline void updatePropaPts(NodeID dstId, NodeID srcId) { - if (!Options::DiffPts()) - return; + if (!Options::DiffPts()) return; NodeID srcRep = sccRepNode(srcId); NodeID dstRep = sccRepNode(dstId); getDiffPTDataTy()->updatePropaPtsMap(srcRep, dstRep); @@ -318,9 +302,9 @@ class Andersen: public AndersenBase void connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet& cpySrcNodes); /// Merge sub node to its rep - virtual void mergeNodeToRep(NodeID nodeId,NodeID newRepId); + virtual void mergeNodeToRep(NodeID nodeId, NodeID newRepId); - virtual bool mergeSrcToTgt(NodeID srcId,NodeID tgtId); + virtual bool mergeSrcToTgt(NodeID srcId, NodeID tgtId); /// Merge sub node in a SCC cycle to their rep node //@{ @@ -336,30 +320,27 @@ class Andersen: public AndersenBase //@} /// Updates subnodes of its rep, and rep node of its subs - void updateNodeRepAndSubs(NodeID nodeId,NodeID newRepId); + void updateNodeRepAndSubs(NodeID nodeId, NodeID newRepId); /// SCC detection virtual NodeStack& SCCDetect(); - - /// Sanitize pts for field insensitive objects void sanitizePts() { - for(ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it!=eit; ++it) + for (ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it != eit; ++it) { const PointsTo& pts = getPts(it->first); NodeBS fldInsenObjs; for (NodeID o : pts) { - if(isFieldInsensitive(o)) - fldInsenObjs.set(o); + if (isFieldInsensitive(o)) fldInsenObjs.set(o); } for (NodeID o : fldInsenObjs) { - const NodeBS &allFields = consCG->getAllFieldsObjVars(o); + const NodeBS& allFields = consCG->getAllFieldsObjVars(o); for (NodeID f : allFields) addPts(it->first, f); } } @@ -376,8 +357,6 @@ class Andersen: public AndersenBase virtual void cluster(void) const; }; - - /** * Wave propagation with diff points-to set. */ @@ -385,16 +364,18 @@ class AndersenWaveDiff : public Andersen { private: - static AndersenWaveDiff* diffWave; // static instance public: - AndersenWaveDiff(SVFIR* _pag, PTATY type = AndersenWaveDiff_WPA, bool alias_check = true): Andersen(_pag, type, alias_check) {} + AndersenWaveDiff(SVFIR* _pag, PTATY type = AndersenWaveDiff_WPA, bool alias_check = true) + : Andersen(_pag, type, alias_check) + { + } /// Create an singleton instance directly instead of invoking llvm pass manager static AndersenWaveDiff* createAndersenWaveDiff(SVFIR* _pag) { - if(diffWave==nullptr) + if (diffWave == nullptr) { diffWave = new AndersenWaveDiff(_pag, AndersenWaveDiff_WPA, false); diffWave->analyze(); @@ -404,8 +385,7 @@ class AndersenWaveDiff : public Andersen } static void releaseAndersenWaveDiff() { - if (diffWave) - delete diffWave; + if (diffWave) delete diffWave; diffWave = nullptr; } diff --git a/svf/include/WPA/AndersenPWC.h b/svf/include/WPA/AndersenPWC.h index 48f1fa016..5bc72100d 100644 --- a/svf/include/WPA/AndersenPWC.h +++ b/svf/include/WPA/AndersenPWC.h @@ -30,7 +30,6 @@ #ifndef PROJECT_ANDERSENSFR_H #define PROJECT_ANDERSENSFR_H - #include "WPA/Andersen.h" #include "WPA/CSC.h" #include "MemoryModel/PointsTo.h" @@ -52,13 +51,10 @@ class AndersenSCD : public Andersen NodeToNodeMap pwcReps; public: - AndersenSCD(SVFIR* _pag, PTATY type = AndersenSCD_WPA) : - Andersen(_pag,type) - { - } + AndersenSCD(SVFIR* _pag, PTATY type = AndersenSCD_WPA) : Andersen(_pag, type) {} /// Create an singleton instance directly instead of invoking llvm pass manager - static AndersenSCD *createAndersenSCD(SVFIR* _pag) + static AndersenSCD* createAndersenSCD(SVFIR* _pag) { if (scdAndersen == nullptr) { @@ -71,8 +67,7 @@ class AndersenSCD : public Andersen static void releaseAndersenSCD() { - if (scdAndersen) - delete scdAndersen; + if (scdAndersen) delete scdAndersen; scdAndersen = nullptr; } @@ -91,11 +86,8 @@ class AndersenSCD : public Andersen virtual bool updateCallGraph(const CallSiteToFunPtrMap& callsites); virtual void processPWC(ConstraintNode* rep); virtual void handleCopyGep(ConstraintNode* node); - }; - - /*! * Selective Cycle Detection with Stride-based Field Representation */ @@ -114,13 +106,10 @@ class AndersenSFR : public AndersenSCD FieldReps fieldReps; public: - AndersenSFR(SVFIR* _pag, PTATY type = AndersenSFR_WPA) : - AndersenSCD(_pag, type), csc(nullptr) - { - } + AndersenSFR(SVFIR* _pag, PTATY type = AndersenSFR_WPA) : AndersenSCD(_pag, type), csc(nullptr) {} /// Create an singleton instance directly instead of invoking llvm pass manager - static AndersenSFR *createAndersenSFR(SVFIR* _pag) + static AndersenSFR* createAndersenSFR(SVFIR* _pag) { if (sfrAndersen == nullptr) { @@ -133,15 +122,14 @@ class AndersenSFR : public AndersenSCD static void releaseAndersenSFR() { - if (sfrAndersen) - delete sfrAndersen; + if (sfrAndersen) delete sfrAndersen; } ~AndersenSFR() { if (csc != nullptr) { - delete(csc); + delete (csc); csc = nullptr; } } @@ -152,9 +140,8 @@ class AndersenSFR : public AndersenSCD void fieldExpand(NodeSet& initials, APOffset offset, NodeBS& strides, PointsTo& expandPts); bool processGepPts(const PointsTo& pts, const GepCGEdge* edge); bool mergeSrcToTgt(NodeID nodeId, NodeID newRepId); - }; } // End namespace SVF -#endif //PROJECT_ANDERSENSFR_H +#endif // PROJECT_ANDERSENSFR_H diff --git a/svf/include/WPA/CSC.h b/svf/include/WPA/CSC.h index a65168475..1c91f497d 100644 --- a/svf/include/WPA/CSC.h +++ b/svf/include/WPA/CSC.h @@ -41,7 +41,7 @@ namespace SVF { -typedef SCCDetection CGSCC; +typedef SCCDetection CGSCC; /*! * class CSC: cycle stride calculation @@ -58,15 +58,14 @@ class CSC CGSCC* _scc; NodeID _I; - IdToIdMap _D; // the sum of weight of a path relevant to a certain node, while accessing the node via DFS - NodeStack _S; // a stack holding a DFS branch - NodeSet _visited; // a set holding visited nodes -// NodeStrides nodeStrides; -// IdToIdMap pwcReps; + IdToIdMap _D; // the sum of weight of a path relevant to a certain node, while accessing the node via DFS + NodeStack _S; // a stack holding a DFS branch + NodeSet _visited; // a set holding visited nodes + // NodeStrides nodeStrides; + // IdToIdMap pwcReps; public: - CSC(ConstraintGraph* g, CGSCC* c) - : _consG(g), _scc(c), _I(0) {} + CSC(ConstraintGraph* g, CGSCC* c) : _consG(g), _scc(c), _I(0) {} void find(NodeStack& candidates); void visit(NodeID nodeId, s32_t _w); @@ -81,15 +80,15 @@ class CSC { _visited.insert(nId); } -// inline iterator begin() { return pwcReps.begin(); } -// -// inline iterator end() { return pwcReps.end(); } + // inline iterator begin() { return pwcReps.begin(); } + // + // inline iterator end() { return pwcReps.end(); } -// NodeStrides &getNodeStrides() { return nodeStrides; } + // NodeStrides &getNodeStrides() { return nodeStrides; } -// const NodeSet& getPWCReps() const { return _pwcReps; } + // const NodeSet& getPWCReps() const { return _pwcReps; } }; } // End namespace SVF -#endif //PROJECT_CSC_H +#endif // PROJECT_CSC_H diff --git a/svf/include/WPA/FlowSensitive.h b/svf/include/WPA/FlowSensitive.h index 79c493170..9aa8d882c 100644 --- a/svf/include/WPA/FlowSensitive.h +++ b/svf/include/WPA/FlowSensitive.h @@ -49,6 +49,7 @@ typedef WPAFSSolver WPASVFGFSSolver; class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl { friend class FlowSensitiveStat; + protected: typedef SVFG::SVFGEdgeSetTy SVFGEdgeSetTy; @@ -121,11 +122,11 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl /// Methods for support type inquiry through isa, cast, and dyn_cast //@{ - static inline bool classof(const FlowSensitive *) + static inline bool classof(const FlowSensitive*) { return true; } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { return pta->getAnalysisTy() == FSSPARSE_WPA; } @@ -160,12 +161,12 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl /// Handle weak updates virtual bool weakUpdateOutFromIn(const SVFGNode* node) { - return getDFPTDataTy()->updateAllDFOutFromIn(node->getId(),0,false); + return getDFPTDataTy()->updateAllDFOutFromIn(node->getId(), 0, false); } /// Handle strong updates virtual bool strongUpdateOutFromIn(const SVFGNode* node, NodeID singleton) { - return getDFPTDataTy()->updateAllDFOutFromIn(node->getId(),singleton,true); + return getDFPTDataTy()->updateAllDFOutFromIn(node->getId(), singleton, true); } //@} @@ -176,11 +177,11 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl virtual inline bool propDFOutToIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar) { - return getDFPTDataTy()->updateAllDFInFromOut(srcStmt->getId(), srcVar, dstStmt->getId(),dstVar); + return getDFPTDataTy()->updateAllDFInFromOut(srcStmt->getId(), srcVar, dstStmt->getId(), dstVar); } virtual inline bool propDFInToIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar) { - return getDFPTDataTy()->updateAllDFInFromIn(srcStmt->getId(), srcVar, dstStmt->getId(),dstVar); + return getDFPTDataTy()->updateAllDFInFromIn(srcStmt->getId(), srcVar, dstStmt->getId(), dstVar); } //@} @@ -188,24 +189,24 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl //@{ inline bool updateOutFromIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar) { - return getDFPTDataTy()->updateDFOutFromIn(srcStmt->getId(),srcVar, dstStmt->getId(),dstVar); + return getDFPTDataTy()->updateDFOutFromIn(srcStmt->getId(), srcVar, dstStmt->getId(), dstVar); } virtual inline bool updateInFromIn(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar) { - return getDFPTDataTy()->updateDFInFromIn(srcStmt->getId(),srcVar, dstStmt->getId(),dstVar); + return getDFPTDataTy()->updateDFInFromIn(srcStmt->getId(), srcVar, dstStmt->getId(), dstVar); } virtual inline bool updateInFromOut(const SVFGNode* srcStmt, NodeID srcVar, const SVFGNode* dstStmt, NodeID dstVar) { - return getDFPTDataTy()->updateDFInFromOut(srcStmt->getId(),srcVar, dstStmt->getId(),dstVar); + return getDFPTDataTy()->updateDFInFromOut(srcStmt->getId(), srcVar, dstStmt->getId(), dstVar); } virtual inline bool unionPtsFromIn(const SVFGNode* stmt, NodeID srcVar, NodeID dstVar) { - return getDFPTDataTy()->updateTLVPts(stmt->getId(),srcVar,dstVar); + return getDFPTDataTy()->updateTLVPts(stmt->getId(), srcVar, dstVar); } virtual inline bool unionPtsFromTop(const SVFGNode* stmt, NodeID srcVar, NodeID dstVar) { - return getDFPTDataTy()->updateATVPts(srcVar,stmt->getId(),dstVar); + return getDFPTDataTy()->updateATVPts(srcVar, stmt->getId(), dstVar); } inline void clearAllDFOutVarFlag(const SVFGNode* stmt) @@ -240,18 +241,18 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl bool isStrongUpdate(const SVFGNode* node, NodeID& singleton); /// Fills may/noAliases for the location/pointer pairs in cmp. - virtual void countAliases(Set> cmp, unsigned *mayAliases, unsigned *noAliases); + virtual void countAliases(Set> cmp, unsigned* mayAliases, unsigned* noAliases); SVFG* svfg; - ///Get points-to set for a node from data flow IN/OUT set at a statement. + /// Get points-to set for a node from data flow IN/OUT set at a statement. //@{ inline const PointsTo& getDFInPtsSet(const SVFGNode* stmt, const NodeID node) { - return getDFPTDataTy()->getDFInPtsSet(stmt->getId(),node); + return getDFPTDataTy()->getDFInPtsSet(stmt->getId(), node); } inline const PointsTo& getDFOutPtsSet(const SVFGNode* stmt, const NodeID node) { - return getDFPTDataTy()->getDFOutPtsSet(stmt->getId(),node); + return getDFPTDataTy()->getDFOutPtsSet(stmt->getId(), node); } //@} @@ -276,40 +277,40 @@ class FlowSensitive : public WPASVFGFSSolver, public BVDataPTAImpl static std::unique_ptr fspta; SVFGBuilder memSSA; - AndersenWaveDiff *ander; + AndersenWaveDiff* ander; /// Save candidate mappings for evaluation's sake. std::vector>> candidateMappings; /// Statistics. //@{ - u32_t numOfProcessedAddr; /// Number of processed Addr node - u32_t numOfProcessedCopy; /// Number of processed Copy node - u32_t numOfProcessedGep; /// Number of processed Gep node - u32_t numOfProcessedPhi; /// Number of processed Phi node - u32_t numOfProcessedLoad; /// Number of processed Load node - u32_t numOfProcessedStore; /// Number of processed Store node - u32_t numOfProcessedActualParam; /// Number of processed actual param node - u32_t numOfProcessedFormalRet; /// Number of processed formal ret node - u32_t numOfProcessedMSSANode; /// Number of processed mssa node + u32_t numOfProcessedAddr; /// Number of processed Addr node + u32_t numOfProcessedCopy; /// Number of processed Copy node + u32_t numOfProcessedGep; /// Number of processed Gep node + u32_t numOfProcessedPhi; /// Number of processed Phi node + u32_t numOfProcessedLoad; /// Number of processed Load node + u32_t numOfProcessedStore; /// Number of processed Store node + u32_t numOfProcessedActualParam; /// Number of processed actual param node + u32_t numOfProcessedFormalRet; /// Number of processed formal ret node + u32_t numOfProcessedMSSANode; /// Number of processed mssa node u32_t maxSCCSize; u32_t numOfSCC; u32_t numOfNodesInSCC; - double solveTime; ///< time of solve. - double sccTime; ///< time of SCC detection. - double processTime; ///< time of processNode. - double propagationTime; ///< time of points-to propagation. - double directPropaTime; ///< time of points-to propagation of address-taken objects - double indirectPropaTime; ///< time of points-to propagation of top-level pointers - double updateTime; ///< time of strong/weak updates. - double addrTime; ///< time of handling address edges - double copyTime; ///< time of handling copy edges - double gepTime; ///< time of handling gep edges - double loadTime; ///< time of load edges - double storeTime; ///< time of store edges - double phiTime; ///< time of phi nodes. + double solveTime; ///< time of solve. + double sccTime; ///< time of SCC detection. + double processTime; ///< time of processNode. + double propagationTime; ///< time of points-to propagation. + double directPropaTime; ///< time of points-to propagation of address-taken objects + double indirectPropaTime; ///< time of points-to propagation of top-level pointers + double updateTime; ///< time of strong/weak updates. + double addrTime; ///< time of handling address edges + double copyTime; ///< time of handling copy edges + double gepTime; ///< time of handling gep edges + double loadTime; ///< time of load edges + double storeTime; ///< time of store edges + double phiTime; ///< time of phi nodes. double updateCallGraphTime; ///< time of updating call graph NodeBS svfgHasSU; diff --git a/svf/include/WPA/Steensgaard.h b/svf/include/WPA/Steensgaard.h index 4aeb037d3..e81632a9e 100644 --- a/svf/include/WPA/Steensgaard.h +++ b/svf/include/WPA/Steensgaard.h @@ -41,8 +41,7 @@ class Steensgaard : public AndersenBase } static void releaseSteensgaard() { - if (steens) - delete steens; + if (steens) delete steens; steens = nullptr; } @@ -93,8 +92,7 @@ class Steensgaard : public AndersenBase inline NodeID getEC(NodeID id) const { NodeToEquivClassMap::const_iterator it = nodeToECMap.find(id); - if (it == nodeToECMap.end()) - return id; + if (it == nodeToECMap.end()) return id; else return it->second; } @@ -117,8 +115,7 @@ class Steensgaard : public AndersenBase } protected: - CallSite2DummyValPN - callsite2DummyValPN; ///< Map an instruction to a dummy obj which + CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which ///< created at an indirect callsite, which invokes ///< a heap allocator void heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes); @@ -127,8 +124,7 @@ class Steensgaard : public AndersenBase virtual bool updateCallGraph(const CallSiteToFunPtrMap& callsites); /// Connect formal and actual parameters for indirect callsites - void connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, - NodePairSet& cpySrcNodes); + void connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet& cpySrcNodes); private: static Steensgaard* steens; // static instance diff --git a/svf/include/WPA/TypeAnalysis.h b/svf/include/WPA/TypeAnalysis.h index b078b4f41..2b068be4a 100644 --- a/svf/include/WPA/TypeAnalysis.h +++ b/svf/include/WPA/TypeAnalysis.h @@ -35,20 +35,15 @@ namespace SVF { -class TypeAnalysis: public AndersenBase +class TypeAnalysis : public AndersenBase { public: /// Constructor - TypeAnalysis(SVFIR* pag) - : AndersenBase(pag, TypeCPP_WPA) - { - } + TypeAnalysis(SVFIR* pag) : AndersenBase(pag, TypeCPP_WPA) {} /// Destructor - virtual ~TypeAnalysis() - { - } + virtual ~TypeAnalysis() {} /// Type analysis void analyze(); @@ -67,11 +62,11 @@ class TypeAnalysis: public AndersenBase /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const TypeAnalysis *) + static inline bool classof(const TypeAnalysis*) { return true; } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { return (pta->getAnalysisTy() == TypeCPP_WPA); } diff --git a/svf/include/WPA/VersionedFlowSensitive.h b/svf/include/WPA/VersionedFlowSensitive.h index af92c6fe6..85170eea5 100644 --- a/svf/include/WPA/VersionedFlowSensitive.h +++ b/svf/include/WPA/VersionedFlowSensitive.h @@ -38,7 +38,7 @@ class VersionedFlowSensitive : public FlowSensitive public: typedef Map ObjToVersionMap; - typedef Map VarToPropNodeMap; + typedef Map VarToPropNodeMap; typedef std::vector LocVersionMap; /// (o -> (v -> versions with rely on o:v). @@ -51,7 +51,7 @@ class VersionedFlowSensitive : public FlowSensitive static VersionedVar atKey(NodeID, Version); /// Constructor - VersionedFlowSensitive(SVFIR *_pag, PTATY type = VFS_WPA); + VersionedFlowSensitive(SVFIR* _pag, PTATY type = VFS_WPA); /// Initialize analysis virtual void initialize() override; @@ -67,18 +67,18 @@ class VersionedFlowSensitive : public FlowSensitive /// Methods to support type inquiry through isa, cast, and dyn_cast //@{ - static inline bool classof(const VersionedFlowSensitive *) + static inline bool classof(const VersionedFlowSensitive*) { return true; } - static inline bool classof(const PointerAnalysis *pta) + static inline bool classof(const PointerAnalysis* pta) { return pta->getAnalysisTy() == VFS_WPA; } //@} /// Create single instance of versioned flow-sensitive points-to analysis. - static VersionedFlowSensitive *createVFSWPA(SVFIR *_pag) + static VersionedFlowSensitive* createVFSWPA(SVFIR* _pag) { if (vfspta == nullptr) { @@ -117,7 +117,7 @@ class VersionedFlowSensitive : public FlowSensitive /// Meld label the prelabeled SVFG. void meldLabel(void); /// Melds v2 into v1 (in place), returns whether a change occurred. - static bool meld(MeldVersion &mv1, const MeldVersion &mv2); + static bool meld(MeldVersion& mv1, const MeldVersion& mv2); /// Removes all indirect edges in the SVFG. void removeAllIndirectSVFGEdges(void); @@ -129,7 +129,7 @@ class VersionedFlowSensitive : public FlowSensitive /// Propagates version v of o to version vp of o. time indicates whether it should record time /// taken itself. - void propagateVersion(const NodeID o, const Version v, const Version vp, bool time=true); + void propagateVersion(const NodeID o, const Version v, const Version vp, bool time = true); /// Fills in isStoreMap and isLoadMap. virtual void buildIsStoreLoadMaps(void); @@ -152,7 +152,7 @@ class VersionedFlowSensitive : public FlowSensitive virtual bool deltaSource(const NodeID l) const; /// Shared code for getConsume and getYield. They wrap this function. - Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const; + Version getVersion(const NodeID l, const NodeID o, const LocVersionMap& lvm) const; /// Returns the consumed version of o at l. If no such version exists, returns invalidVersion. Version getConsume(const NodeID l, const NodeID o) const; @@ -161,7 +161,7 @@ class VersionedFlowSensitive : public FlowSensitive Version getYield(const NodeID l, const NodeID o) const; /// Shared code for setConsume and setYield. They wrap this function. - void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm); + void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap& lvm); /// Sets the consumed version of o at l to v. void setConsume(const NodeID l, const NodeID o, const Version v); @@ -170,10 +170,10 @@ class VersionedFlowSensitive : public FlowSensitive void setYield(const NodeID l, const NodeID o, const Version v); /// Returns the versions of o which rely on o:v. - std::vector &getReliantVersions(const NodeID o, const Version v); + std::vector& getReliantVersions(const NodeID o, const Version v); /// Returns the statements which rely on o:v. - NodeBS &getStmtReliance(const NodeID o, const Version v); + NodeBS& getStmtReliance(const NodeID o, const Version v); /// Dumps versionReliance and stmtReliance. void dumpReliances(void) const; @@ -190,7 +190,7 @@ class VersionedFlowSensitive : public FlowSensitive void readPtsFromFile(const std::string& filename) override; /// Dumps a MeldVersion to stdout. - static void dumpMeldVersion(MeldVersion &v); + static void dumpMeldVersion(MeldVersion& v); /// Maps locations to objects to a version. The object version is what is /// consumed at that location. @@ -219,7 +219,7 @@ class VersionedFlowSensitive : public FlowSensitive Set prelabeledObjects; /// Points-to DS for working with versions. - BVDataPTAImpl::VersionedPTDataTy *vPtD; + BVDataPTAImpl::VersionedPTDataTy* vPtD; /// deltaMap[l] means SVFG node l is a delta node, i.e., may get new /// incoming edges due to OTF callgraph construction. @@ -246,7 +246,7 @@ class VersionedFlowSensitive : public FlowSensitive double versionPropTime; ///< Time to propagate versions to versions which rely on them. //@} - static VersionedFlowSensitive *vfspta; + static VersionedFlowSensitive* vfspta; class SCC { @@ -270,23 +270,15 @@ class VersionedFlowSensitive : public FlowSensitive /// to stores are also skipped to as they yield a new version (they /// cannot be part of an SCC containing more than themselves). /// Skipped edges still form part of the footprint. - static unsigned detectSCCs(VersionedFlowSensitive *vfs, - const SVFG *svfg, const NodeID object, - const std::vector &startingNodes, - std::vector &partOf, - std::vector &footprint); + static unsigned detectSCCs(VersionedFlowSensitive* vfs, const SVFG* svfg, const NodeID object, + const std::vector& startingNodes, std::vector& partOf, + std::vector& footprint); private: /// Called by detectSCCs then called recursively. - static void visit(VersionedFlowSensitive *vfs, - const NodeID object, - std::vector &partOf, - std::vector &footprint, - std::vector &nodeData, - std::stack &stack, - int &index, - int ¤tSCC, - const SVFGNode *v); + static void visit(VersionedFlowSensitive* vfs, const NodeID object, std::vector& partOf, + std::vector& footprint, std::vector& nodeData, + std::stack& stack, int& index, int& currentSCC, const SVFGNode* v); }; }; diff --git a/svf/include/WPA/WPAFSSolver.h b/svf/include/WPA/WPAFSSolver.h index c220b418b..929bb8d20 100644 --- a/svf/include/WPA/WPAFSSolver.h +++ b/svf/include/WPA/WPAFSSolver.h @@ -32,7 +32,6 @@ * */ - #ifndef WPAFSSOLVER_H_ #define WPAFSSOLVER_H_ @@ -44,13 +43,11 @@ namespace SVF /*! * Flow-sensitive Solver */ -template -class WPAFSSolver : public WPASolver +template class WPAFSSolver : public WPASolver { public: /// Constructor - WPAFSSolver() : WPASolver() - {} + WPAFSSolver() : WPASolver() {} /// Destructor virtual ~WPAFSSolver() {} @@ -61,7 +58,7 @@ class WPAFSSolver : public WPASolver } protected: - NodeStack nodeStack; ///< stack used for processing nodes. + NodeStack nodeStack; ///< stack used for processing nodes. /// SCC detection virtual NodeStack& SCCDetect() @@ -98,13 +95,10 @@ class WPAFSSolver : public WPASolver } }; - - /*! * Solver based on SCC cycles. */ -template -class WPASCCSolver : public WPAFSSolver +template class WPASCCSolver : public WPAFSSolver { public: typedef typename WPASolver::GTraits GTraits; @@ -120,8 +114,7 @@ class WPASCCSolver : public WPAFSSolver { /// All nodes will be solved afterwards, so the worklist /// can be cleared before each solve iteration. - while (!this->isWorklistEmpty()) - this->popFromWorklist(); + while (!this->isWorklistEmpty()) this->popFromWorklist(); NodeStack& nodeStack = this->SCCDetect(); @@ -136,8 +129,7 @@ class WPASCCSolver : public WPAFSSolver for (NodeBS::iterator it = sccNodes.begin(), eit = sccNodes.end(); it != eit; ++it) this->pushIntoWorklist(*it); - while (!this->isWorklistEmpty()) - this->processNode(this->popFromWorklist()); + while (!this->isWorklistEmpty()) this->processNode(this->popFromWorklist()); } } @@ -148,15 +140,13 @@ class WPASCCSolver : public WPAFSSolver child_iterator EE = GTraits::direct_child_end(v); for (; EI != EE; ++EI) { - if (this->propFromSrcToDst(*(EI.getCurrent()))) - addNodeIntoWorkList(this->Node_Index(*EI)); + if (this->propFromSrcToDst(*(EI.getCurrent()))) addNodeIntoWorkList(this->Node_Index(*EI)); } } virtual inline void addNodeIntoWorkList(NodeID node) { - if (isInCurrentSCC(node)) - this->pushIntoWorklist(node); + if (isInCurrentSCC(node)) this->pushIntoWorklist(node); } inline bool isInCurrentSCC(NodeID node) @@ -168,16 +158,13 @@ class WPASCCSolver : public WPAFSSolver curSCCID = this->getSCCDetector()->repNode(id); } - NodeID curSCCID; ///< index of current SCC. + NodeID curSCCID; ///< index of current SCC. }; - - /*! * Only solve nodes which need to be analyzed. */ -template -class WPAMinimumSolver : public WPASCCSolver +template class WPAMinimumSolver : public WPASCCSolver { public: typedef typename WPASolver::GTraits GTraits; @@ -197,8 +184,7 @@ class WPAMinimumSolver : public WPASCCSolver if (!this->isWorklistEmpty()) { solveAll = false; - while (!this->isWorklistEmpty()) - addNewCandidate(this->popFromWorklist()); + while (!this->isWorklistEmpty()) addNewCandidate(this->popFromWorklist()); } NodeStack& nodeStack = this->SCCDetect(); @@ -212,22 +198,20 @@ class WPAMinimumSolver : public WPASCCSolver NodeBS sccNodes = this->getSCCDetector()->subNodes(rep); if (solveAll == false) - sccNodes &= getCandidates(); /// get nodes which need to be processed in this SCC cycle + sccNodes &= getCandidates(); /// get nodes which need to be processed in this SCC cycle for (NodeBS::iterator it = sccNodes.begin(), eit = sccNodes.end(); it != eit; ++it) this->pushIntoWorklist(*it); - while (!this->isWorklistEmpty()) - this->processNode(this->popFromWorklist()); + while (!this->isWorklistEmpty()) this->processNode(this->popFromWorklist()); - removeCandidates(sccNodes); /// remove nodes which have been processed from the candidate set + removeCandidates(sccNodes); /// remove nodes which have been processed from the candidate set } } virtual inline void addNodeIntoWorkList(NodeID node) { - if (this->isInCurrentSCC(node)) - this->pushIntoWorklist(node); + if (this->isInCurrentSCC(node)) this->pushIntoWorklist(node); else addNewCandidate(node); } @@ -246,7 +230,7 @@ class WPAMinimumSolver : public WPASCCSolver candidates.intersectWithComplement(nodes); } - NodeBS candidates; ///< nodes which need to be analyzed in current iteration. + NodeBS candidates; ///< nodes which need to be analyzed in current iteration. }; } // End namespace SVF diff --git a/svf/include/WPA/WPAPass.h b/svf/include/WPA/WPAPass.h index 646c80a4f..f9cc751a3 100644 --- a/svf/include/WPA/WPAPass.h +++ b/svf/include/WPA/WPAPass.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * @file: WPA.h * @author: yesen @@ -33,7 +32,6 @@ * */ - #ifndef WPA_H_ #define WPA_H_ @@ -61,22 +59,19 @@ class WPAPass enum AliasCheckRule { - Conservative, ///< return MayAlias if any pta says alias - Veto, ///< return NoAlias if any pta says no alias - Precise ///< return alias result by the most precise pta + Conservative, ///< return MayAlias if any pta says alias + Veto, ///< return NoAlias if any pta says no alias + Precise ///< return alias result by the most precise pta }; /// Constructor needs TargetLibraryInfo to be passed to the AliasAnalysis - WPAPass() - { - - } + WPAPass() {} /// Destructor virtual ~WPAPass(); /// Interface expose to users of our pointer analysis, given Value infos - virtual AliasResult alias(const SVFValue* V1, const SVFValue* V2); + virtual AliasResult alias(const SVFValue* V1, const SVFValue* V2); /// Retrieve points-to set information virtual const PointsTo& getPts(const SVFValue* value); @@ -88,13 +83,15 @@ class WPAPass /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref any memory location virtual ModRefInfo getModRefInfo(const CallSite callInst); - /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref a specific memory location, given Location infos + /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref a specific memory + /// location, given Location infos // virtual inline ModRefInfo getModRefInfo(const CallSite callInst, const MemoryLocation& Loc) // { // return getModRefInfo(callInst, Loc.Ptr); // } - /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref a specific memory location, given Value infos + /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref a specific memory + /// location, given Value infos virtual ModRefInfo getModRefInfo(const CallSite callInst, const SVFValue* V); /// Interface of mod-ref analysis between two CallSite instructions @@ -113,9 +110,9 @@ class WPAPass /// Create pointer analysis according to specified kind and analyze the module. void runPointerAnalysis(SVFIR* pag, u32_t kind); - PTAVector ptaVector; ///< all pointer analysis to be executed. - PointerAnalysis* _pta; ///< pointer analysis to be executed. - SVFG* _svfg; ///< svfg generated through -ander pointer analysis + PTAVector ptaVector; ///< all pointer analysis to be executed. + PointerAnalysis* _pta; ///< pointer analysis to be executed. + SVFG* _svfg; ///< svfg generated through -ander pointer analysis }; } // End namespace SVF diff --git a/svf/include/WPA/WPASolver.h b/svf/include/WPA/WPASolver.h index 892dd68af..99373e336 100644 --- a/svf/include/WPA/WPASolver.h +++ b/svf/include/WPA/WPASolver.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * WPASolver.h * @@ -39,15 +38,14 @@ namespace SVF /* * Generic graph solver for whole program pointer analysis */ -template -class WPASolver +template class WPASolver { public: - ///Define the GTraits and node iterator for printing + /// Define the GTraits and node iterator for printing typedef SVF::GenericGraphTraits GTraits; - typedef typename GTraits::NodeRef GNODE; - typedef typename GTraits::EdgeType GEDGE; + typedef typename GTraits::NodeRef GNODE; + typedef typename GTraits::EdgeType GEDGE; typedef typename GTraits::ChildIteratorType child_iterator; typedef SCCDetection SCC; @@ -55,11 +53,8 @@ class WPASolver typedef FIFOWorkList WorkList; protected: - /// Constructor - WPASolver(): reanalyze(false), iterationForPrintStat(1000), _graph(nullptr), numOfIteration(0) - { - } + WPASolver() : reanalyze(false), iterationForPrintStat(1000), _graph(nullptr), numOfIteration(0) {} /// Destructor virtual ~WPASolver() = default; @@ -130,8 +125,7 @@ class WPASolver child_iterator EE = GTraits::direct_child_end(*v); for (; EI != EE; ++EI) { - if (propFromSrcToDst(*(EI.getCurrent()))) - pushIntoWorklist(Node_Index(*EI)); + if (propFromSrcToDst(*(EI.getCurrent()))) pushIntoWorklist(Node_Index(*EI)); } } /// Propagate information from source to destination node, to be implemented in the child class @@ -172,7 +166,6 @@ class WPASolver /// print out statistics for i-th iteration u32_t iterationForPrintStat; - /// Get node on the graph inline GNODE* Node(NodeID id) { diff --git a/svf/include/WPA/WPAStat.h b/svf/include/WPA/WPAStat.h index 13d1cb2b9..2164fa9d4 100644 --- a/svf/include/WPA/WPAStat.h +++ b/svf/include/WPA/WPAStat.h @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * FlowSensitiveStat.h * @@ -65,10 +64,7 @@ class AndersenStat : public PTAStat AndersenStat(AndersenBase* p); - virtual ~AndersenStat() - { - - } + virtual ~AndersenStat() {} virtual void performStat(); @@ -88,9 +84,9 @@ class FlowSensitiveStat : public PTAStat typedef FlowSensitive::DFInOutMap DFInOutMap; typedef FlowSensitive::PtsMap PtsMap; - FlowSensitive * fspta; + FlowSensitive* fspta; - FlowSensitiveStat(FlowSensitive* pta): PTAStat(pta) + FlowSensitiveStat(FlowSensitive* pta) : PTAStat(pta) { fspta = pta; clearStat(); @@ -147,34 +143,34 @@ class FlowSensitiveStat : public PTAStat u32_t _PotentialNumOfVarHaveINOUTPts[2]; /// sizes of points-to set - u32_t _MaxPtsSize; ///< max points-to set size. - u32_t _MaxTopLvlPtsSize; ///< max points-to set size in top-level pointers. - u32_t _MaxInOutPtsSize[2]; ///< max points-to set size in IN/OUT set. + u32_t _MaxPtsSize; ///< max points-to set size. + u32_t _MaxTopLvlPtsSize; ///< max points-to set size in top-level pointers. + u32_t _MaxInOutPtsSize[2]; ///< max points-to set size in IN/OUT set. - u32_t _TotalPtsSize; ///< total points-to set size. + u32_t _TotalPtsSize; ///< total points-to set size. - double _AvgPtsSize; ///< average points-to set size. - double _AvgTopLvlPtsSize; ///< average points-to set size in top-level pointers. - double _AvgInOutPtsSize[2]; ///< average points-to set size in IN set. - double _AvgAddrTakenVarPtsSize; ///< average points-to set size of addr-taken variables. + double _AvgPtsSize; ///< average points-to set size. + double _AvgTopLvlPtsSize; ///< average points-to set size in top-level pointers. + double _AvgInOutPtsSize[2]; ///< average points-to set size in IN set. + double _AvgAddrTakenVarPtsSize; ///< average points-to set size of addr-taken variables. - u32_t _MaxAddrTakenVarPts; ///< max points-to set size of addr-taken variables. - u32_t _NumOfAddrTakeVar; ///< number of occurrences of addr-taken variables in load/store. + u32_t _MaxAddrTakenVarPts; ///< max points-to set size of addr-taken variables. + u32_t _NumOfAddrTakeVar; ///< number of occurrences of addr-taken variables in load/store. }; class VersionedFlowSensitiveStat : public PTAStat { public: - VersionedFlowSensitive *vfspta; + VersionedFlowSensitive* vfspta; - VersionedFlowSensitiveStat(VersionedFlowSensitive* pta): PTAStat(pta) + VersionedFlowSensitiveStat(VersionedFlowSensitive* pta) : PTAStat(pta) { vfspta = pta; clearStat(); startClk(); } - virtual ~VersionedFlowSensitiveStat() { } + virtual ~VersionedFlowSensitiveStat() {} virtual void performStat(); diff --git a/svf/lib/AE/Core/AbstractState.cpp b/svf/lib/AE/Core/AbstractState.cpp index 5b58d7943..feba734ef 100644 --- a/svf/lib/AE/Core/AbstractState.cpp +++ b/svf/lib/AE/Core/AbstractState.cpp @@ -34,7 +34,7 @@ using namespace SVF; using namespace SVFUtil; -bool AbstractState::equals(const AbstractState&other) const +bool AbstractState::equals(const AbstractState& other) const { return *this == other; } @@ -43,12 +43,12 @@ u32_t AbstractState::hash() const { size_t h = getVarToVal().size() * 2; Hash hf; - for (const auto &t: getVarToVal()) + for (const auto& t : getVarToVal()) { h ^= hf(t.first) + 0x9e3779b9 + (h << 6) + (h >> 2); } size_t h2 = getLocToVal().size() * 2; - for (const auto &t: getLocToVal()) + for (const auto& t : getLocToVal()) { h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); } @@ -95,7 +95,6 @@ AbstractState AbstractState::narrowing(const AbstractState& other) it->second.getInterval().narrow_with(other._addrToAbsVal.at(key).getInterval()); } return es; - } /// domain join with other, important! other widen this. @@ -156,10 +155,10 @@ void AbstractState::meetWith(const AbstractState& other) AddressValue AbstractState::getGepObjAddrs(u32_t pointer, IntervalValue offset) { AddressValue gepAddrs; - APOffset lb = offset.lb().getIntNumeral() < Options::MaxFieldLimit() ? offset.lb().getIntNumeral() - : Options::MaxFieldLimit(); - APOffset ub = offset.ub().getIntNumeral() < Options::MaxFieldLimit() ? offset.ub().getIntNumeral() - : Options::MaxFieldLimit(); + APOffset lb = + offset.lb().getIntNumeral() < Options::MaxFieldLimit() ? offset.lb().getIntNumeral() : Options::MaxFieldLimit(); + APOffset ub = + offset.ub().getIntNumeral() < Options::MaxFieldLimit() ? offset.ub().getIntNumeral() : Options::MaxFieldLimit(); for (APOffset i = lb; i <= ub; i++) { AbstractValue addrs = (*this)[pointer]; @@ -232,8 +231,7 @@ void AbstractState::initObjVar(ObjVar* objVar) IntervalValue AbstractState::getElementIndex(const GepStmt* gep) { // If the GEP statement has a constant offset, return it directly as the interval value - if (gep->isConstantOffset()) - return IntervalValue((s64_t)gep->accumulateConstantOffset()); + if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantOffset()); IntervalValue res(0); // Iterate over the list of offset variable and type pairs in reverse order @@ -253,8 +251,7 @@ IntervalValue AbstractState::getElementIndex(const GepStmt* gep) else { IntervalValue idxItv = (*this)[PAG::getPAG()->getValueNode(value)].getInterval(); - if (idxItv.isBottom()) - idxLb = idxUb = 0; + if (idxItv.isBottom()) idxLb = idxUb = 0; else { idxLb = idxItv.lb().getIntNumeral(); @@ -274,7 +271,8 @@ IntervalValue AbstractState::getElementIndex(const GepStmt* gep) { if (Options::ModelArrays()) { - const std::vector& so = SymbolTableInfo::SymbolInfo()->getTypeInfo(type)->getFlattenedElemIdxVec(); + const std::vector& so = + SymbolTableInfo::SymbolInfo()->getTypeInfo(type)->getFlattenedElemIdxVec(); if (so.empty() || idxUb >= (APOffset)so.size() || idxLb < 0) { idxLb = idxUb = 0; @@ -305,8 +303,7 @@ IntervalValue AbstractState::getElementIndex(const GepStmt* gep) IntervalValue AbstractState::getByteOffset(const GepStmt* gep) { // If the GEP statement has a constant byte offset, return it directly as the interval value - if (gep->isConstantOffset()) - return IntervalValue((s64_t)gep->accumulateConstantByteOffset()); + if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantByteOffset()); IntervalValue res(0); // Initialize the result interval 'res' to 0. @@ -331,8 +328,8 @@ IntervalValue AbstractState::getByteOffset(const GepStmt* gep) { // Calculate the lower bound (lb) of the interval value s64_t lb = (double)Options::MaxFieldLimit() / elemByteSize >= op->getSExtValue() - ? op->getSExtValue() * elemByteSize - : Options::MaxFieldLimit(); + ? op->getSExtValue() * elemByteSize + : Options::MaxFieldLimit(); res = res + IntervalValue(lb, lb); } else @@ -340,19 +337,18 @@ IntervalValue AbstractState::getByteOffset(const GepStmt* gep) u32_t idx = PAG::getPAG()->getValueNode(idxOperandVar->getValue()); IntervalValue idxVal = (*this)[idx].getInterval(); - if (idxVal.isBottom()) - res = res + IntervalValue(0, 0); + if (idxVal.isBottom()) res = res + IntervalValue(0, 0); else { // Ensure the bounds are non-negative and within the field limit s64_t ub = (idxVal.ub().getIntNumeral() < 0) ? 0 : (double)Options::MaxFieldLimit() / elemByteSize >= idxVal.ub().getIntNumeral() - ? elemByteSize * idxVal.ub().getIntNumeral() - : Options::MaxFieldLimit(); + ? elemByteSize * idxVal.ub().getIntNumeral() + : Options::MaxFieldLimit(); s64_t lb = (idxVal.lb().getIntNumeral() < 0) ? 0 : (double)Options::MaxFieldLimit() / elemByteSize >= idxVal.lb().getIntNumeral() - ? elemByteSize * idxVal.lb().getIntNumeral() - : Options::MaxFieldLimit(); + ? elemByteSize * idxVal.lb().getIntNumeral() + : Options::MaxFieldLimit(); res = res + IntervalValue(lb, ub); } } @@ -394,11 +390,9 @@ void AbstractState::printAbstractState() const u32_t fieldWidth = 20; SVFUtil::outs().flags(std::ios::left); std::vector> varToAbsValVec(_varToAbsVal.begin(), _varToAbsVal.end()); - std::sort(varToAbsValVec.begin(), varToAbsValVec.end(), [](const auto &a, const auto &b) - { - return a.first < b.first; - }); - for (const auto &item: varToAbsValVec) + std::sort(varToAbsValVec.begin(), varToAbsValVec.end(), + [](const auto& a, const auto& b) { return a.first < b.first; }); + for (const auto& item : varToAbsValVec) { SVFUtil::outs() << std::left << std::setw(fieldWidth) << ("Var" + std::to_string(item.first)); if (item.second.isInterval()) @@ -409,7 +403,7 @@ void AbstractState::printAbstractState() const { SVFUtil::outs() << " Value: {"; u32_t i = 0; - for (const auto& addr: item.second.getAddrs()) + for (const auto& addr : item.second.getAddrs()) { ++i; if (i < item.second.getAddrs().size()) @@ -430,12 +424,10 @@ void AbstractState::printAbstractState() const } std::vector> addrToAbsValVec(_addrToAbsVal.begin(), _addrToAbsVal.end()); - std::sort(addrToAbsValVec.begin(), addrToAbsValVec.end(), [](const auto &a, const auto &b) - { - return a.first < b.first; - }); + std::sort(addrToAbsValVec.begin(), addrToAbsValVec.end(), + [](const auto& a, const auto& b) { return a.first < b.first; }); - for (const auto& item: addrToAbsValVec) + for (const auto& item : addrToAbsValVec) { std::ostringstream oss; oss << "0x" << std::hex << AbstractState::getVirtualMemAddress(item.first); @@ -448,7 +440,7 @@ void AbstractState::printAbstractState() const { SVFUtil::outs() << " Value: {"; u32_t i = 0; - for (const auto& addr: item.second.getAddrs()) + for (const auto& addr : item.second.getAddrs()) { ++i; if (i < item.second.getAddrs().size()) diff --git a/svf/lib/AE/Core/RelExeState.cpp b/svf/lib/AE/Core/RelExeState.cpp index 4035a041d..fad4bb399 100644 --- a/svf/lib/AE/Core/RelExeState.cpp +++ b/svf/lib/AE/Core/RelExeState.cpp @@ -42,17 +42,17 @@ using namespace SVFUtil; * @param expr * @param res */ -void RelExeState::extractSubVars(const Z3Expr &expr, Set &res) +void RelExeState::extractSubVars(const Z3Expr& expr, Set& res) { if (expr.getExpr().num_args() == 0) if (!expr.getExpr().is_true() && !expr.getExpr().is_false() && !expr.is_numeral()) { - const std::string &exprStr = expr.to_string(); + const std::string& exprStr = expr.to_string(); res.insert(std::stoi(exprStr.substr(1, exprStr.size() - 1))); } for (u32_t i = 0; i < expr.getExpr().num_args(); ++i) { - const z3::expr &e = expr.getExpr().arg(i); + const z3::expr& e = expr.getExpr().arg(i); extractSubVars(e, res); } } @@ -63,7 +63,7 @@ void RelExeState::extractSubVars(const Z3Expr &expr, Set &res) * @param expr * @param res */ -void RelExeState::extractCmpVars(const Z3Expr &expr, Set &res) +void RelExeState::extractCmpVars(const Z3Expr& expr, Set& res) { Set r; extractSubVars(expr, r); @@ -73,7 +73,7 @@ void RelExeState::extractCmpVars(const Z3Expr &expr, Set &res) { return; } - for (const auto &id: r) + for (const auto& id : r) { extractCmpVars((*this)[id], res); } @@ -87,12 +87,12 @@ void RelExeState::extractCmpVars(const Z3Expr &expr, Set &res) * @param initVars the vars on the right hand side of cmp statement, e.g., {a} for "cmp = a > 1" * @return */ -Z3Expr RelExeState::buildRelZ3Expr(u32_t cmp, s32_t succ, Set &vars, Set &initVars) +Z3Expr RelExeState::buildRelZ3Expr(u32_t cmp, s32_t succ, Set& vars, Set& initVars) { Z3Expr res = (getZ3Expr(cmp) == succ).simplify(); extractSubVars(res, initVars); extractCmpVars(res, vars); - for (const auto &id: vars) + for (const auto& id : vars) { res = (res && toZ3Expr(id) == getZ3Expr(id)).simplify(); } @@ -101,7 +101,7 @@ Z3Expr RelExeState::buildRelZ3Expr(u32_t cmp, s32_t succ, Set &vars, Set< return res; } -RelExeState &RelExeState::operator=(const RelExeState &rhs) +RelExeState& RelExeState::operator=(const RelExeState& rhs) { if (*this != rhs) { @@ -116,10 +116,9 @@ RelExeState &RelExeState::operator=(const RelExeState &rhs) * @param rhs * @return */ -bool RelExeState::operator==(const RelExeState &rhs) const +bool RelExeState::operator==(const RelExeState& rhs) const { - return eqVarToValMap(_varToVal, rhs.getVarToVal()) && - eqVarToValMap(_addrToVal, rhs.getLocToVal()); + return eqVarToValMap(_varToVal, rhs.getVarToVal()) && eqVarToValMap(_addrToVal, rhs.getLocToVal()); } /*! @@ -127,37 +126,33 @@ bool RelExeState::operator==(const RelExeState &rhs) const * @param rhs * @return */ -bool RelExeState::operator<(const RelExeState &rhs) const +bool RelExeState::operator<(const RelExeState& rhs) const { - return lessThanVarToValMap(_varToVal, rhs.getVarToVal()) || - lessThanVarToValMap(_addrToVal, rhs.getLocToVal()); + return lessThanVarToValMap(_varToVal, rhs.getVarToVal()) || lessThanVarToValMap(_addrToVal, rhs.getLocToVal()); } -bool RelExeState::eqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const +bool RelExeState::eqVarToValMap(const VarToValMap& lhs, const VarToValMap& rhs) const { if (lhs.size() != rhs.size()) return false; - for (const auto &item: lhs) + for (const auto& item : lhs) { auto it = rhs.find(item.first); // return false if SVFVar not exists in rhs or z3Expr not equal - if (it == rhs.end() || !eq(item.second, it->second)) - return false; + if (it == rhs.end() || !eq(item.second, it->second)) return false; } return true; } -bool RelExeState::lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const +bool RelExeState::lessThanVarToValMap(const VarToValMap& lhs, const VarToValMap& rhs) const { if (lhs.size() != rhs.size()) return lhs.size() < rhs.size(); - for (const auto &item: lhs) + for (const auto& item : lhs) { auto it = rhs.find(item.first); // lhs > rhs if SVFVar not exists in rhs - if (it == rhs.end()) - return false; + if (it == rhs.end()) return false; // judge from expr id - if (!eq(item.second, it->second)) - return item.second.id() < it->second.id(); + if (!eq(item.second, it->second)) return item.second.id() < it->second.id(); } return false; } @@ -167,7 +162,7 @@ bool RelExeState::lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap * @param loc location, e.g., int_val(0x7f..01) * @param value */ -void RelExeState::store(const Z3Expr &loc, const Z3Expr &value) +void RelExeState::store(const Z3Expr& loc, const Z3Expr& value) { assert(loc.is_numeral() && "location must be numeral"); s32_t virAddr = z3Expr2NumValue(loc); @@ -180,7 +175,7 @@ void RelExeState::store(const Z3Expr &loc, const Z3Expr &value) * @param loc location, e.g., int_val(0x7f..01) * @return */ -Z3Expr &RelExeState::load(const Z3Expr &loc) +Z3Expr& RelExeState::load(const Z3Expr& loc) { assert(loc.is_numeral() && "location must be numeral"); s32_t virAddr = z3Expr2NumValue(loc); @@ -197,12 +192,12 @@ void RelExeState::printExprValues() { std::cout.flags(std::ios::left); std::cout << "-----------Var and Value-----------\n"; - for (const auto &item: getVarToVal()) + for (const auto& item : getVarToVal()) { std::stringstream exprName; exprName << "Var" << item.first; std::cout << std::setw(25) << exprName.str(); - const Z3Expr &sim = item.second.simplify(); + const Z3Expr& sim = item.second.simplify(); if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) { std::cout << "\t Value: " << std::hex << "0x" << z3Expr2NumValue(sim) << "\n"; diff --git a/svf/lib/AE/Core/RelationSolver.cpp b/svf/lib/AE/Core/RelationSolver.cpp index a5cc9dd9d..7954a0830 100644 --- a/svf/lib/AE/Core/RelationSolver.cpp +++ b/svf/lib/AE/Core/RelationSolver.cpp @@ -33,8 +33,7 @@ using namespace SVF; using namespace SVFUtil; -AbstractState RelationSolver::bilateral(const AbstractState&domain, const Z3Expr& phi, - u32_t descend_check) +AbstractState RelationSolver::bilateral(const AbstractState& domain, const Z3Expr& phi, u32_t descend_check) { /// init variables AbstractState upper = domain.top(); @@ -72,10 +71,8 @@ AbstractState RelationSolver::bilateral(const AbstractState&domain, const Z3Expr { z3::func_decl v = m[i]; // assert(v.arity() == 0); - if (v.arity() != 0) - continue; - solution.emplace(std::stoi(v.name().str()), - m.get_const_interp(v).get_numeral_int()); + if (v.arity() != 0) continue; + solution.emplace(std::stoi(v.name().str()), m.get_const_interp(v).get_numeral_int()); } for (const auto& item : domain.getVarToVal()) { @@ -98,8 +95,7 @@ AbstractState RelationSolver::bilateral(const AbstractState&domain, const Z3Expr if (checkRes == z3::unknown) { /// for timeout reason return upper - if (solver.reason_unknown() == "timeout") - return upper; + if (solver.reason_unknown() == "timeout") return upper; } AbstractState newUpper = domain.top(); newUpper.meetWith(upper); @@ -133,11 +129,9 @@ AbstractState RelationSolver::RSY(const AbstractState& domain, const Z3Expr& phi for (u32_t i = 0; i < m.size(); i++) { z3::func_decl v = m[i]; - if (v.arity() != 0) - continue; + if (v.arity() != 0) continue; - solution.emplace(std::stoi(v.name().str()), - m.get_const_interp(v).get_numeral_int()); + solution.emplace(std::stoi(v.name().str()), m.get_const_interp(v).get_numeral_int()); } for (const auto& item : domain.getVarToVal()) { @@ -158,8 +152,7 @@ AbstractState RelationSolver::RSY(const AbstractState& domain, const Z3Expr& phi if (checkRes == z3::unknown) { /// for timeout reason return upper - if (solver.reason_unknown() == "timeout") - return domain.top(); + if (solver.reason_unknown() == "timeout") return domain.top(); } break; } @@ -167,8 +160,8 @@ AbstractState RelationSolver::RSY(const AbstractState& domain, const Z3Expr& phi return lower; } -AbstractState RelationSolver::abstract_consequence( - const AbstractState& lower, const AbstractState& upper, const AbstractState& domain) const +AbstractState RelationSolver::abstract_consequence(const AbstractState& lower, const AbstractState& upper, + const AbstractState& domain) const { /*Returns the "abstract consequence" of lower and upper. @@ -180,9 +173,8 @@ AbstractState RelationSolver::abstract_consequence( of the SMT solver in many cases. In certain cases, other choices for the abstract consequence will lead to better algorithm performance.*/ - for (auto it = domain.getVarToVal().begin(); - it != domain.getVarToVal().end(); ++it) - /// for variable in self.variables: + for (auto it = domain.getVarToVal().begin(); it != domain.getVarToVal().end(); ++it) + /// for variable in self.variables: { AbstractState proposed = domain.top(); /// proposed = self.top.copy() proposed[it->first] = lower[it->first].getInterval(); @@ -202,31 +194,24 @@ Z3Expr RelationSolver::gamma_hat(const AbstractState& exeState) const for (auto& item : exeState.getVarToVal()) { IntervalValue interval = item.second.getInterval(); - if (interval.isBottom()) - return Z3Expr::getContext().bool_val(false); - if (interval.isTop()) - continue; + if (interval.isBottom()) return Z3Expr::getContext().bool_val(false); + if (interval.isTop()) continue; Z3Expr v = toIntZ3Expr(item.first); - res = (res && v >= (int)interval.lb().getNumeral() && - v <= (int)interval.ub().getNumeral()).simplify(); + res = (res && v >= (int)interval.lb().getNumeral() && v <= (int)interval.ub().getNumeral()).simplify(); } return res; } -Z3Expr RelationSolver::gamma_hat(const AbstractState& alpha, - const AbstractState& exeState) const +Z3Expr RelationSolver::gamma_hat(const AbstractState& alpha, const AbstractState& exeState) const { Z3Expr res(Z3Expr::getContext().bool_val(true)); for (auto& item : exeState.getVarToVal()) { IntervalValue interval = alpha[item.first].getInterval(); - if (interval.isBottom()) - return Z3Expr::getContext().bool_val(false); - if (interval.isTop()) - continue; + if (interval.isBottom()) return Z3Expr::getContext().bool_val(false); + if (interval.isTop()) continue; Z3Expr v = toIntZ3Expr(item.first); - res = (res && v >= (int)interval.lb().getNumeral() && - v <= (int)interval.ub().getNumeral()).simplify(); + res = (res && v >= (int)interval.lb().getNumeral() && v <= (int)interval.ub().getNumeral()).simplify(); } return res; } @@ -237,19 +222,17 @@ Z3Expr RelationSolver::gamma_hat(u32_t id, const AbstractState& exeState) const assert(it != exeState.getVarToVal().end() && "id not in varToVal?"); Z3Expr v = toIntZ3Expr(id); // Z3Expr v = Z3Expr::getContext().int_const(std::to_string(id).c_str()); - Z3Expr res = (v >= (int)it->second.getInterval().lb().getNumeral() && - v <= (int)it->second.getInterval().ub().getNumeral()); + Z3Expr res = + (v >= (int)it->second.getInterval().lb().getNumeral() && v <= (int)it->second.getInterval().ub().getNumeral()); return res; } -AbstractState RelationSolver::beta(const Map& sigma, - const AbstractState& exeState) const +AbstractState RelationSolver::beta(const Map& sigma, const AbstractState& exeState) const { AbstractState res; for (const auto& item : exeState.getVarToVal()) { - res[item.first] = IntervalValue( - sigma.at(item.first), sigma.at(item.first)); + res[item.first] = IntervalValue(sigma.at(item.first), sigma.at(item.first)); } return res; } @@ -267,12 +250,12 @@ void RelationSolver::updateMap(Map& map, u32_t key, const s32_t& v } } -AbstractState RelationSolver::BS(const AbstractState& domain, const Z3Expr &phi) +AbstractState RelationSolver::BS(const AbstractState& domain, const Z3Expr& phi) { /// because key of _varToItvVal is u32_t, -key may out of range for int /// so we do key + bias for -key u32_t bias = 0; - s32_t infinity = INT32_MAX/2 - 1; + s32_t infinity = INT32_MAX / 2 - 1; // int infinity = (INT32_MAX) - 1; // int infinity = 20; @@ -280,33 +263,28 @@ AbstractState RelationSolver::BS(const AbstractState& domain, const Z3Expr &phi) Map low_values, high_values; Z3Expr new_phi = phi; /// init low, ret, high - for (const auto& item: domain.getVarToVal()) + for (const auto& item : domain.getVarToVal()) { IntervalValue interval = item.second.getInterval(); updateMap(ret, item.first, interval.ub().getIntNumeral()); - if (interval.lb().is_minus_infinity()) - updateMap(low_values, item.first, -infinity); + if (interval.lb().is_minus_infinity()) updateMap(low_values, item.first, -infinity); else updateMap(low_values, item.first, interval.lb().getIntNumeral()); - if (interval.ub().is_plus_infinity()) - updateMap(high_values, item.first, infinity); + if (interval.ub().is_plus_infinity()) updateMap(high_values, item.first, infinity); else updateMap(high_values, item.first, interval.ub().getIntNumeral()); - if (item.first > bias) - bias = item.first + 1; + if (item.first > bias) bias = item.first + 1; } - for (const auto& item: domain.getVarToVal()) + for (const auto& item : domain.getVarToVal()) { /// init objects -x IntervalValue interval = item.second.getInterval(); u32_t reverse_key = item.first + bias; updateMap(ret, reverse_key, -interval.lb().getIntNumeral()); - if (interval.ub().is_plus_infinity()) - updateMap(low_values, reverse_key, -infinity); + if (interval.ub().is_plus_infinity()) updateMap(low_values, reverse_key, -infinity); else updateMap(low_values, reverse_key, -interval.ub().getIntNumeral()); - if (interval.lb().is_minus_infinity()) - updateMap(high_values, reverse_key, infinity); + if (interval.lb().is_minus_infinity()) updateMap(high_values, reverse_key, infinity); else updateMap(high_values, reverse_key, -interval.lb().getIntNumeral()); /// add a relation that x == -(x+bias) @@ -316,25 +294,23 @@ AbstractState RelationSolver::BS(const AbstractState& domain, const Z3Expr &phi) BoxedOptSolver(new_phi.simplify(), ret, low_values, high_values); /// fill in the return values AbstractState retInv; - for (const auto& item: ret) + for (const auto& item : ret) { if (item.first >= bias) { - if (!retInv.inVarToValTable(item.first-bias)) - retInv[item.first-bias] = IntervalValue::top(); + if (!retInv.inVarToValTable(item.first - bias)) retInv[item.first - bias] = IntervalValue::top(); if (item.second == (infinity)) - retInv[item.first - bias] = IntervalValue(BoundedInt::minus_infinity(), - retInv[item.first - bias].getInterval().ub()); + retInv[item.first - bias] = + IntervalValue(BoundedInt::minus_infinity(), retInv[item.first - bias].getInterval().ub()); else - retInv[item.first - bias] = IntervalValue(float(-item.second), retInv[item.first - bias].getInterval().ub()); - + retInv[item.first - bias] = + IntervalValue(float(-item.second), retInv[item.first - bias].getInterval().ub()); } else { if (item.second == (infinity)) - retInv[item.first] = IntervalValue(retInv[item.first].getInterval().lb(), - BoundedInt::plus_infinity()); + retInv[item.first] = IntervalValue(retInv[item.first].getInterval().lb(), BoundedInt::plus_infinity()); else retInv[item.first] = IntervalValue(retInv[item.first].getInterval().lb(), float(item.second)); } @@ -342,7 +318,8 @@ AbstractState RelationSolver::BS(const AbstractState& domain, const Z3Expr &phi) return retInv; } -Map RelationSolver::BoxedOptSolver(const Z3Expr& phi, Map& ret, Map& low_values, Map& high_values) +Map RelationSolver::BoxedOptSolver(const Z3Expr& phi, Map& ret, + Map& low_values, Map& high_values) { /// this is the S in the original paper Map L_phi; @@ -361,27 +338,21 @@ Map RelationSolver::BoxedOptSolver(const Z3Expr& phi, Map& L_phi, - Map& mid_values, - Map& ret, - Map& low_values, +void RelationSolver::decide_cpa_ext(const Z3Expr& phi, Map& L_phi, Map& mid_values, + Map& ret, Map& low_values, Map& high_values) { while (1) { Z3Expr join_expr(Z3Expr::getContext().bool_val(false)); - for (const auto& item : L_phi) - join_expr = (join_expr || item.second); + for (const auto& item : L_phi) join_expr = (join_expr || item.second); join_expr = (join_expr && phi).simplify(); z3::solver& solver = Z3Expr::getSolver(); solver.push(); @@ -393,7 +364,7 @@ void RelationSolver::decide_cpa_ext(const Z3Expr& phi, { z3::model m = solver.get_model(); solver.pop(); - for(const auto & item : L_phi) + for (const auto& item : L_phi) { u32_t id = item.first; int value = m.eval(toIntZ3Expr(id).getExpr()).get_numeral_int(); @@ -422,10 +393,8 @@ void RelationSolver::decide_cpa_ext(const Z3Expr& phi, else /// unknown or unsat, we consider unknown as unsat { solver.pop(); - for (const auto& item : L_phi) - high_values.at(item.first) = mid_values.at(item.first) - 1; + for (const auto& item : L_phi) high_values.at(item.first) = mid_values.at(item.first) - 1; return; } } - } \ No newline at end of file diff --git a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp index 190a0be87..f7be1cd03 100644 --- a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +++ b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - // // Created by Jiawei Wang on 2024/1/10. // @@ -42,49 +41,45 @@ using namespace z3; // X' is reverse predicate of X // == -> !=, != -> ==, > -> <=, >= -> <, < -> >=, <= -> > -Map _reverse_predicate = -{ - {CmpStmt::Predicate::FCMP_OEQ, CmpStmt::Predicate::FCMP_ONE}, // == -> != - {CmpStmt::Predicate::FCMP_UEQ, CmpStmt::Predicate::FCMP_UNE}, // == -> != - {CmpStmt::Predicate::FCMP_OGT, CmpStmt::Predicate::FCMP_OLE}, // > -> <= - {CmpStmt::Predicate::FCMP_OGE, CmpStmt::Predicate::FCMP_OLT}, // >= -> < - {CmpStmt::Predicate::FCMP_OLT, CmpStmt::Predicate::FCMP_OGE}, // < -> >= - {CmpStmt::Predicate::FCMP_OLE, CmpStmt::Predicate::FCMP_OGT}, // <= -> > - {CmpStmt::Predicate::FCMP_ONE, CmpStmt::Predicate::FCMP_OEQ}, // != -> == - {CmpStmt::Predicate::FCMP_UNE, CmpStmt::Predicate::FCMP_UEQ}, // != -> == - {CmpStmt::Predicate::ICMP_EQ, CmpStmt::Predicate::ICMP_NE}, // == -> != - {CmpStmt::Predicate::ICMP_NE, CmpStmt::Predicate::ICMP_EQ}, // != -> == - {CmpStmt::Predicate::ICMP_UGT, CmpStmt::Predicate::ICMP_ULE}, // > -> <= - {CmpStmt::Predicate::ICMP_ULT, CmpStmt::Predicate::ICMP_UGE}, // < -> >= - {CmpStmt::Predicate::ICMP_UGE, CmpStmt::Predicate::ICMP_ULT}, // >= -> < - {CmpStmt::Predicate::ICMP_SGT, CmpStmt::Predicate::ICMP_SLE}, // > -> <= - {CmpStmt::Predicate::ICMP_SLT, CmpStmt::Predicate::ICMP_SGE}, // < -> >= - {CmpStmt::Predicate::ICMP_SGE, CmpStmt::Predicate::ICMP_SLT}, // >= -> < +Map _reverse_predicate = { + {CmpStmt::Predicate::FCMP_OEQ, CmpStmt::Predicate::FCMP_ONE}, // == -> != + {CmpStmt::Predicate::FCMP_UEQ, CmpStmt::Predicate::FCMP_UNE}, // == -> != + {CmpStmt::Predicate::FCMP_OGT, CmpStmt::Predicate::FCMP_OLE}, // > -> <= + {CmpStmt::Predicate::FCMP_OGE, CmpStmt::Predicate::FCMP_OLT}, // >= -> < + {CmpStmt::Predicate::FCMP_OLT, CmpStmt::Predicate::FCMP_OGE}, // < -> >= + {CmpStmt::Predicate::FCMP_OLE, CmpStmt::Predicate::FCMP_OGT}, // <= -> > + {CmpStmt::Predicate::FCMP_ONE, CmpStmt::Predicate::FCMP_OEQ}, // != -> == + {CmpStmt::Predicate::FCMP_UNE, CmpStmt::Predicate::FCMP_UEQ}, // != -> == + {CmpStmt::Predicate::ICMP_EQ, CmpStmt::Predicate::ICMP_NE}, // == -> != + {CmpStmt::Predicate::ICMP_NE, CmpStmt::Predicate::ICMP_EQ}, // != -> == + {CmpStmt::Predicate::ICMP_UGT, CmpStmt::Predicate::ICMP_ULE}, // > -> <= + {CmpStmt::Predicate::ICMP_ULT, CmpStmt::Predicate::ICMP_UGE}, // < -> >= + {CmpStmt::Predicate::ICMP_UGE, CmpStmt::Predicate::ICMP_ULT}, // >= -> < + {CmpStmt::Predicate::ICMP_SGT, CmpStmt::Predicate::ICMP_SLE}, // > -> <= + {CmpStmt::Predicate::ICMP_SLT, CmpStmt::Predicate::ICMP_SGE}, // < -> >= + {CmpStmt::Predicate::ICMP_SGE, CmpStmt::Predicate::ICMP_SLT}, // >= -> < }; - -Map _switch_lhsrhs_predicate = -{ - {CmpStmt::Predicate::FCMP_OEQ, CmpStmt::Predicate::FCMP_OEQ}, // == -> == - {CmpStmt::Predicate::FCMP_UEQ, CmpStmt::Predicate::FCMP_UEQ}, // == -> == - {CmpStmt::Predicate::FCMP_OGT, CmpStmt::Predicate::FCMP_OLT}, // > -> < - {CmpStmt::Predicate::FCMP_OGE, CmpStmt::Predicate::FCMP_OLE}, // >= -> <= - {CmpStmt::Predicate::FCMP_OLT, CmpStmt::Predicate::FCMP_OGT}, // < -> > - {CmpStmt::Predicate::FCMP_OLE, CmpStmt::Predicate::FCMP_OGE}, // <= -> >= - {CmpStmt::Predicate::FCMP_ONE, CmpStmt::Predicate::FCMP_ONE}, // != -> != - {CmpStmt::Predicate::FCMP_UNE, CmpStmt::Predicate::FCMP_UNE}, // != -> != - {CmpStmt::Predicate::ICMP_EQ, CmpStmt::Predicate::ICMP_EQ}, // == -> == - {CmpStmt::Predicate::ICMP_NE, CmpStmt::Predicate::ICMP_NE}, // != -> != - {CmpStmt::Predicate::ICMP_UGT, CmpStmt::Predicate::ICMP_ULT}, // > -> < - {CmpStmt::Predicate::ICMP_ULT, CmpStmt::Predicate::ICMP_UGT}, // < -> > - {CmpStmt::Predicate::ICMP_UGE, CmpStmt::Predicate::ICMP_ULE}, // >= -> <= - {CmpStmt::Predicate::ICMP_SGT, CmpStmt::Predicate::ICMP_SLT}, // > -> < - {CmpStmt::Predicate::ICMP_SLT, CmpStmt::Predicate::ICMP_SGT}, // < -> > - {CmpStmt::Predicate::ICMP_SGE, CmpStmt::Predicate::ICMP_SLE}, // >= -> <= +Map _switch_lhsrhs_predicate = { + {CmpStmt::Predicate::FCMP_OEQ, CmpStmt::Predicate::FCMP_OEQ}, // == -> == + {CmpStmt::Predicate::FCMP_UEQ, CmpStmt::Predicate::FCMP_UEQ}, // == -> == + {CmpStmt::Predicate::FCMP_OGT, CmpStmt::Predicate::FCMP_OLT}, // > -> < + {CmpStmt::Predicate::FCMP_OGE, CmpStmt::Predicate::FCMP_OLE}, // >= -> <= + {CmpStmt::Predicate::FCMP_OLT, CmpStmt::Predicate::FCMP_OGT}, // < -> > + {CmpStmt::Predicate::FCMP_OLE, CmpStmt::Predicate::FCMP_OGE}, // <= -> >= + {CmpStmt::Predicate::FCMP_ONE, CmpStmt::Predicate::FCMP_ONE}, // != -> != + {CmpStmt::Predicate::FCMP_UNE, CmpStmt::Predicate::FCMP_UNE}, // != -> != + {CmpStmt::Predicate::ICMP_EQ, CmpStmt::Predicate::ICMP_EQ}, // == -> == + {CmpStmt::Predicate::ICMP_NE, CmpStmt::Predicate::ICMP_NE}, // != -> != + {CmpStmt::Predicate::ICMP_UGT, CmpStmt::Predicate::ICMP_ULT}, // > -> < + {CmpStmt::Predicate::ICMP_ULT, CmpStmt::Predicate::ICMP_UGT}, // < -> > + {CmpStmt::Predicate::ICMP_UGE, CmpStmt::Predicate::ICMP_ULE}, // >= -> <= + {CmpStmt::Predicate::ICMP_SGT, CmpStmt::Predicate::ICMP_SLT}, // > -> < + {CmpStmt::Predicate::ICMP_SLT, CmpStmt::Predicate::ICMP_SGT}, // < -> > + {CmpStmt::Predicate::ICMP_SGE, CmpStmt::Predicate::ICMP_SLE}, // >= -> <= }; - -void AbstractInterpretation::runOnModule(ICFG *icfg) +void AbstractInterpretation::runOnModule(ICFG* icfg) { _stat->startClk(); _icfg = icfg; @@ -113,9 +108,7 @@ AbstractInterpretation::AbstractInterpretation() AbstractInterpretation::~AbstractInterpretation() { delete _stat; - for (auto it: _funcToWTO) - delete it.second; - + for (auto it : _funcToWTO) delete it.second; } /** @@ -155,8 +148,7 @@ void AbstractInterpretation::analyse() initWTO(); // handle Global ICFGNode of SVFModule handleGlobalNode(); - getAbsStateFromTrace( - _icfg->getGlobalICFGNode())[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); + getAbsStateFromTrace(_icfg->getGlobalICFGNode())[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); if (const SVFFunction* fun = _svfir->getModule()->getSVFFunction("main")) { ICFGWTO* wto = _funcToWTO[fun]; @@ -171,7 +163,7 @@ void AbstractInterpretation::handleGlobalNode() _abstractTrace[node] = AbstractState(); _abstractTrace[node][SymbolTableInfo::NullPtr] = AddressValue(); // Global Node, we just need to handle addr, load, store, copy and gep - for (const SVFStmt *stmt: node->getSVFStmts()) + for (const SVFStmt* stmt : node->getSVFStmts()) { handleSVFStatement(stmt); } @@ -180,15 +172,15 @@ void AbstractInterpretation::handleGlobalNode() /// get execution state by merging states of predecessor blocks /// Scenario 1: preblock -----(intraEdge)----> block, join the preES of inEdges /// Scenario 2: preblock -----(callEdge)----> block -bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode * icfgNode) +bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode* icfgNode) { std::vector workList; AbstractState preAs; - for (auto& edge: icfgNode->getInEdges()) + for (auto& edge : icfgNode->getInEdges()) { if (_abstractTrace.find(edge->getSrcNode()) != _abstractTrace.end()) { - const IntraCFGEdge *intraCfgEdge = SVFUtil::dyn_cast(edge); + const IntraCFGEdge* intraCfgEdge = SVFUtil::dyn_cast(edge); if (intraCfgEdge && intraCfgEdge->getCondition()) { AbstractState tmpEs = _abstractTrace[edge->getSrcNode()]; @@ -208,7 +200,6 @@ bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode * icfgNo } else { - } } if (workList.size() == 0) @@ -229,9 +220,7 @@ bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode * icfgNo } } - -bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t succ, - AbstractState& as) +bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t succ, AbstractState& as) { AbstractState new_es = as; // get cmp stmt's op0, op1, and predicate @@ -247,24 +236,24 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s as = new_es; return true; } - const LoadStmt *load_op0 = nullptr; - const LoadStmt *load_op1 = nullptr; + const LoadStmt* load_op0 = nullptr; + const LoadStmt* load_op1 = nullptr; // get '%1 = load i32 s', and load inst may not exist SVFVar* loadVar0 = _svfir->getGNode(op0); if (!loadVar0->getInEdges().empty()) { - SVFStmt *loadVar0InStmt = *loadVar0->getInEdges().begin(); - if (const LoadStmt *loadStmt = SVFUtil::dyn_cast(loadVar0InStmt)) + SVFStmt* loadVar0InStmt = *loadVar0->getInEdges().begin(); + if (const LoadStmt* loadStmt = SVFUtil::dyn_cast(loadVar0InStmt)) { load_op0 = loadStmt; } - else if (const CopyStmt *copyStmt = SVFUtil::dyn_cast(loadVar0InStmt)) + else if (const CopyStmt* copyStmt = SVFUtil::dyn_cast(loadVar0InStmt)) { loadVar0 = _svfir->getGNode(copyStmt->getRHSVarID()); if (!loadVar0->getInEdges().empty()) { - SVFStmt *loadVar0InStmt2 = *loadVar0->getInEdges().begin(); - if (const LoadStmt *loadStmt = SVFUtil::dyn_cast(loadVar0InStmt2)) + SVFStmt* loadVar0InStmt2 = *loadVar0->getInEdges().begin(); + if (const LoadStmt* loadStmt = SVFUtil::dyn_cast(loadVar0InStmt2)) { load_op0 = loadStmt; } @@ -275,18 +264,18 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s SVFVar* loadVar1 = _svfir->getGNode(op1); if (!loadVar1->getInEdges().empty()) { - SVFStmt *loadVar1InStmt = *loadVar1->getInEdges().begin(); - if (const LoadStmt *loadStmt = SVFUtil::dyn_cast(loadVar1InStmt)) + SVFStmt* loadVar1InStmt = *loadVar1->getInEdges().begin(); + if (const LoadStmt* loadStmt = SVFUtil::dyn_cast(loadVar1InStmt)) { load_op1 = loadStmt; } - else if (const CopyStmt *copyStmt = SVFUtil::dyn_cast(loadVar1InStmt)) + else if (const CopyStmt* copyStmt = SVFUtil::dyn_cast(loadVar1InStmt)) { loadVar1 = _svfir->getGNode(copyStmt->getRHSVarID()); if (!loadVar1->getInEdges().empty()) { - SVFStmt *loadVar1InStmt2 = *loadVar1->getInEdges().begin(); - if (const LoadStmt *loadStmt = SVFUtil::dyn_cast(loadVar1InStmt2)) + SVFStmt* loadVar1InStmt2 = *loadVar1->getInEdges().begin(); + if (const LoadStmt* loadStmt = SVFUtil::dyn_cast(loadVar1InStmt2)) { load_op1 = loadStmt; } @@ -296,7 +285,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s // for const X const, we may get concrete resVal instantly // for var X const, we may get [0,1] if the intersection of var and const is not empty set IntervalValue resVal = new_es[res_id].getInterval(); - resVal.meet_with(IntervalValue((s64_t) succ, succ)); + resVal.meet_with(IntervalValue((s64_t)succ, succ)); // If Var X const generates bottom value, it means this branch path is not feasible. if (resVal.isBottom()) { @@ -334,10 +323,12 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s { predicate = _reverse_predicate[predicate]; } - else {} + else + { + } // change interval range according to the compare predicate AddressValue addrs; - if(load_op0 && new_es.inVarToAddrsTable(load_op0->getRHSVarID())) + if (load_op0 && new_es.inVarToAddrsTable(load_op0->getRHSVarID())) addrs = new_es[load_op0->getRHSVarID()].getAddrs(); IntervalValue &lhs = new_es[op0].getInterval(), &rhs = new_es[op1].getInterval(); @@ -345,12 +336,11 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s { case CmpStmt::Predicate::ICMP_EQ: case CmpStmt::Predicate::FCMP_OEQ: - case CmpStmt::Predicate::FCMP_UEQ: - { + case CmpStmt::Predicate::FCMP_UEQ: { // Var == Const, so [var.lb, var.ub].meet_with(const) lhs.meet_with(rhs); // if lhs is register value, we should also change its mem obj - for (const auto &addr: addrs) + for (const auto& addr : addrs) { NodeID objId = new_es.getInternalID(addr); if (new_es.inAddrToValTable(objId)) @@ -372,31 +362,28 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s // Var > Const, so [var.lb, var.ub].meet_with([Const+1, +INF]) lhs.meet_with(IntervalValue(rhs.lb() + 1, IntervalValue::plus_infinity())); // if lhs is register value, we should also change its mem obj - for (const auto &addr: addrs) + for (const auto& addr : addrs) { NodeID objId = new_es.getInternalID(addr); if (new_es.inAddrToValTable(objId)) { - new_es.load(addr).meet_with( - IntervalValue(rhs.lb() + 1, IntervalValue::plus_infinity())); + new_es.load(addr).meet_with(IntervalValue(rhs.lb() + 1, IntervalValue::plus_infinity())); } } break; case CmpStmt::Predicate::ICMP_UGE: case CmpStmt::Predicate::ICMP_SGE: case CmpStmt::Predicate::FCMP_OGE: - case CmpStmt::Predicate::FCMP_UGE: - { + case CmpStmt::Predicate::FCMP_UGE: { // Var >= Const, so [var.lb, var.ub].meet_with([Const, +INF]) lhs.meet_with(IntervalValue(rhs.lb(), IntervalValue::plus_infinity())); // if lhs is register value, we should also change its mem obj - for (const auto &addr: addrs) + for (const auto& addr : addrs) { NodeID objId = new_es.getInternalID(addr); if (new_es.inAddrToValTable(objId)) { - new_es.load(addr).meet_with( - IntervalValue(rhs.lb(), IntervalValue::plus_infinity())); + new_es.load(addr).meet_with(IntervalValue(rhs.lb(), IntervalValue::plus_infinity())); } } break; @@ -404,18 +391,16 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s case CmpStmt::Predicate::ICMP_ULT: case CmpStmt::Predicate::ICMP_SLT: case CmpStmt::Predicate::FCMP_OLT: - case CmpStmt::Predicate::FCMP_ULT: - { + case CmpStmt::Predicate::FCMP_ULT: { // Var < Const, so [var.lb, var.ub].meet_with([-INF, const.ub-1]) lhs.meet_with(IntervalValue(IntervalValue::minus_infinity(), rhs.ub() - 1)); // if lhs is register value, we should also change its mem obj - for (const auto &addr: addrs) + for (const auto& addr : addrs) { NodeID objId = new_es.getInternalID(addr); if (new_es.inAddrToValTable(objId)) { - new_es.load(addr).meet_with( - IntervalValue(IntervalValue::minus_infinity(), rhs.ub() - 1)); + new_es.load(addr).meet_with(IntervalValue(IntervalValue::minus_infinity(), rhs.ub() - 1)); } } break; @@ -423,18 +408,16 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s case CmpStmt::Predicate::ICMP_ULE: case CmpStmt::Predicate::ICMP_SLE: case CmpStmt::Predicate::FCMP_OLE: - case CmpStmt::Predicate::FCMP_ULE: - { + case CmpStmt::Predicate::FCMP_ULE: { // Var <= Const, so [var.lb, var.ub].meet_with([-INF, const.ub]) lhs.meet_with(IntervalValue(IntervalValue::minus_infinity(), rhs.ub())); // if lhs is register value, we should also change its mem obj - for (const auto &addr: addrs) + for (const auto& addr : addrs) { NodeID objId = new_es.getInternalID(addr); if (new_es.inAddrToValTable(objId)) { - new_es.load(addr).meet_with( - IntervalValue(IntervalValue::minus_infinity(), rhs.ub())); + new_es.load(addr).meet_with(IntervalValue(IntervalValue::minus_infinity(), rhs.ub())); } } break; @@ -451,14 +434,13 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s return true; } -bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t succ, - AbstractState& as) +bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t succ, AbstractState& as) { AbstractState new_es = as; IntervalValue& switch_cond = new_es[var->getId()].getInterval(); s64_t value = succ; FIFOWorkList workList; - for (SVFStmt *cmpVarInStmt: var->getInEdges()) + for (SVFStmt* cmpVarInStmt : var->getInEdges()) { workList.push(cmpVarInStmt); } @@ -467,7 +449,7 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc { return false; } - while(!workList.empty()) + while (!workList.empty()) { const SVFStmt* stmt = workList.pop(); if (SVFUtil::isa(stmt)) @@ -479,8 +461,8 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc { if (new_es.inVarToAddrsTable(load->getRHSVarID())) { - AddressValue &addrs = new_es[load->getRHSVarID()].getAddrs(); - for (const auto &addr: addrs) + AddressValue& addrs = new_es[load->getRHSVarID()].getAddrs(); + for (const auto& addr : addrs) { NodeID objId = new_es.getInternalID(addr); if (new_es.inAddrToValTable(objId)) @@ -495,37 +477,32 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc return true; } -bool AbstractInterpretation::isBranchFeasible(const IntraCFGEdge* intraEdge, - AbstractState& as) +bool AbstractInterpretation::isBranchFeasible(const IntraCFGEdge* intraEdge, AbstractState& as) { - const SVFValue *cond = intraEdge->getCondition(); + const SVFValue* cond = intraEdge->getCondition(); NodeID cmpID = _svfir->getValueNode(cond); - SVFVar *cmpVar = _svfir->getGNode(cmpID); + SVFVar* cmpVar = _svfir->getGNode(cmpID); if (cmpVar->getInEdges().empty()) { - return isSwitchBranchFeasible(cmpVar, - intraEdge->getSuccessorCondValue(), as); + return isSwitchBranchFeasible(cmpVar, intraEdge->getSuccessorCondValue(), as); } else { - assert(!cmpVar->getInEdges().empty() && - "no in edges?"); - SVFStmt *cmpVarInStmt = *cmpVar->getInEdges().begin(); - if (const CmpStmt *cmpStmt = SVFUtil::dyn_cast(cmpVarInStmt)) + assert(!cmpVar->getInEdges().empty() && "no in edges?"); + SVFStmt* cmpVarInStmt = *cmpVar->getInEdges().begin(); + if (const CmpStmt* cmpStmt = SVFUtil::dyn_cast(cmpVarInStmt)) { - return isCmpBranchFeasible(cmpStmt, - intraEdge->getSuccessorCondValue(), as); + return isCmpBranchFeasible(cmpStmt, intraEdge->getSuccessorCondValue(), as); } else { - return isSwitchBranchFeasible( - cmpVar, intraEdge->getSuccessorCondValue(), as); + return isSwitchBranchFeasible(cmpVar, intraEdge->getSuccessorCondValue(), as); } } return true; } /// handle instructions in svf basic blocks -void AbstractInterpretation::handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto) +void AbstractInterpretation::handleSingletonWTO(const ICFGSingletonWTO* icfgSingletonWto) { const ICFGNode* node = icfgSingletonWto->getICFGNode(); _stat->getBlockTrace()++; @@ -538,7 +515,7 @@ void AbstractInterpretation::handleSingletonWTO(const ICFGSingletonWTO *icfgSing const ICFGNode* curNode = *it; _stat->getICFGNodeTrace()++; // handle SVF Stmt - for (const SVFStmt *stmt: curNode->getSVFStmts()) + for (const SVFStmt* stmt : curNode->getSVFStmts()) { handleSVFStatement(stmt); } @@ -549,7 +526,6 @@ void AbstractInterpretation::handleSingletonWTO(const ICFGSingletonWTO *icfgSing } else { - } _stat->countStateSize(); } @@ -570,14 +546,12 @@ void AbstractInterpretation::handleWTOComponent(const SVF::ICFGWTOComp* wtoNode) { if (const ICFGSingletonWTO* node = SVFUtil::dyn_cast(wtoNode)) { - if (mergeStatesFromPredecessors(node->getICFGNode())) - handleSingletonWTO(node); + if (mergeStatesFromPredecessors(node->getICFGNode())) handleSingletonWTO(node); } // Handle WTO cycles else if (const ICFGCycleWTO* cycle = SVFUtil::dyn_cast(wtoNode)) { - if (mergeStatesFromPredecessors(cycle->head()->getICFGNode())) - handleCycleWTO(cycle); + if (mergeStatesFromPredecessors(cycle->head()->getICFGNode())) handleCycleWTO(cycle); } // Assert false for unknown WTO types else @@ -613,40 +587,39 @@ void AbstractInterpretation::handleCallSite(const ICFGNode* node) } else { - assert (false && "it is not call node"); + assert(false && "it is not call node"); } } -bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode* callNode) { - const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); + const SVFFunction* callfun = SVFUtil::getCallee(callNode->getCallSite()); return SVFUtil::isExtCall(callfun); } -void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::extCallPass(const SVF::CallICFGNode* callNode) { _callSiteStack.push_back(callNode); handleExtAPI(callNode); _callSiteStack.pop_back(); } -bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode* callNode) { - const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); + const SVFFunction* callfun = SVFUtil::getCallee(callNode->getCallSite()); return _recursiveFuns.find(callfun) != _recursiveFuns.end(); } -void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode* callNode) { AbstractState& as = getAbsStateFromTrace(callNode); SkipRecursiveCall(callNode); - const RetICFGNode *retNode = callNode->getRetICFGNode(); + const RetICFGNode* retNode = callNode->getRetICFGNode(); if (retNode->getSVFStmts().size() > 0) { - if (const RetPE *retPE = SVFUtil::dyn_cast(*retNode->getSVFStmts().begin())) + if (const RetPE* retPE = SVFUtil::dyn_cast(*retNode->getSVFStmts().begin())) { - if (!retPE->getLHSVar()->isPointer() && - !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr()) + if (!retPE->getLHSVar()->isPointer() && !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr()) { as[retPE->getLHSVarID()] = IntervalValue::top(); } @@ -655,15 +628,15 @@ void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode _abstractTrace[retNode] = as; } -bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode* callNode) { - const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); + const SVFFunction* callfun = SVFUtil::getCallee(callNode->getCallSite()); return _funcToWTO.find(callfun) != _funcToWTO.end(); } -void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode* callNode) { AbstractState& as = getAbsStateFromTrace(callNode); - const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); + const SVFFunction* callfun = SVFUtil::getCallee(callNode->getCallSite()); _callSiteStack.push_back(callNode); _abstractTrace[callNode] = as; @@ -673,18 +646,18 @@ void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode _callSiteStack.pop_back(); // handle Ret node - const RetICFGNode *retNode = callNode->getRetICFGNode(); + const RetICFGNode* retNode = callNode->getRetICFGNode(); // resume ES to callnode _abstractTrace[retNode] = _abstractTrace[callNode]; } -bool AbstractInterpretation::isIndirectCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isIndirectCall(const SVF::CallICFGNode* callNode) { const auto callsiteMaps = _svfir->getIndirectCallsites(); return callsiteMaps.find(callNode) != callsiteMaps.end(); } -void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode* callNode) { AbstractState& as = getAbsStateFromTrace(callNode); const auto callsiteMaps = _svfir->getIndirectCallsites(); @@ -695,8 +668,8 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo } AbstractValue Addrs = as[call_id]; NodeID addr = *Addrs.getAddrs().begin(); - SVFVar *func_var = _svfir->getGNode(AbstractState::getInternalID(addr)); - const SVFFunction *callfun = SVFUtil::dyn_cast(func_var->getValue()); + SVFVar* func_var = _svfir->getGNode(AbstractState::getInternalID(addr)); + const SVFFunction* callfun = SVFUtil::dyn_cast(func_var->getValue()); if (callfun) { _callSiteStack.push_back(callNode); @@ -706,15 +679,13 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo handleWTOComponents(wto->getWTOComponents()); _callSiteStack.pop_back(); // handle Ret node - const RetICFGNode *retNode = callNode->getRetICFGNode(); + const RetICFGNode* retNode = callNode->getRetICFGNode(); _abstractTrace[retNode] = _abstractTrace[callNode]; } } - - /// handle wto cycle (loop) -void AbstractInterpretation::handleCycleWTO(const ICFGCycleWTO*cycle) +void AbstractInterpretation::handleCycleWTO(const ICFGCycleWTO* cycle) { const ICFGNode* cycle_head = cycle->head()->getICFGNode(); // Flag to indicate if we are in the increasing phase @@ -760,17 +731,17 @@ void AbstractInterpretation::handleCycleWTO(const ICFGCycleWTO*cycle) } } -void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt) +void AbstractInterpretation::handleSVFStatement(const SVFStmt* stmt) { - if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) + if (const AddrStmt* addr = SVFUtil::dyn_cast(stmt)) { updateStateOnAddr(addr); } - else if (const BinaryOPStmt *binary = SVFUtil::dyn_cast(stmt)) + else if (const BinaryOPStmt* binary = SVFUtil::dyn_cast(stmt)) { updateStateOnBinary(binary); } - else if (const CmpStmt *cmp = SVFUtil::dyn_cast(stmt)) + else if (const CmpStmt* cmp = SVFUtil::dyn_cast(stmt)) { updateStateOnCmp(cmp); } @@ -781,36 +752,36 @@ void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt) { // branch stmt is handled in hasBranchES } - else if (const LoadStmt *load = SVFUtil::dyn_cast(stmt)) + else if (const LoadStmt* load = SVFUtil::dyn_cast(stmt)) { updateStateOnLoad(load); } - else if (const StoreStmt *store = SVFUtil::dyn_cast(stmt)) + else if (const StoreStmt* store = SVFUtil::dyn_cast(stmt)) { updateStateOnStore(store); } - else if (const CopyStmt *copy = SVFUtil::dyn_cast(stmt)) + else if (const CopyStmt* copy = SVFUtil::dyn_cast(stmt)) { updateStateOnCopy(copy); } - else if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) + else if (const GepStmt* gep = SVFUtil::dyn_cast(stmt)) { updateStateOnGep(gep); } - else if (const SelectStmt *select = SVFUtil::dyn_cast(stmt)) + else if (const SelectStmt* select = SVFUtil::dyn_cast(stmt)) { updateStateOnSelect(select); } - else if (const PhiStmt *phi = SVFUtil::dyn_cast(stmt)) + else if (const PhiStmt* phi = SVFUtil::dyn_cast(stmt)) { updateStateOnPhi(phi); } - else if (const CallPE *callPE = SVFUtil::dyn_cast(stmt)) + else if (const CallPE* callPE = SVFUtil::dyn_cast(stmt)) { // To handle Call Edge updateStateOnCall(callPE); } - else if (const RetPE *retPE = SVFUtil::dyn_cast(stmt)) + else if (const RetPE* retPE = SVFUtil::dyn_cast(stmt)) { updateStateOnRet(retPE); } @@ -818,15 +789,14 @@ void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt) assert(false && "implement this part"); } - -void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode) +void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode* callNode) { AbstractState& as = getAbsStateFromTrace(callNode); - const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); - const RetICFGNode *retNode = callNode->getRetICFGNode(); + const SVFFunction* callfun = SVFUtil::getCallee(callNode->getCallSite()); + const RetICFGNode* retNode = callNode->getRetICFGNode(); if (retNode->getSVFStmts().size() > 0) { - if (const RetPE *retPE = SVFUtil::dyn_cast(*retNode->getSVFStmts().begin())) + if (const RetPE* retPE = SVFUtil::dyn_cast(*retNode->getSVFStmts().begin())) { AbstractState as; if (!retPE->getLHSVar()->isPointer() && !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr()) @@ -837,32 +807,31 @@ void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode) { if (retNode->getOutEdges().size() == 1) { - } else { return; } } - FIFOWorkList blkWorkList; - FIFOWorkList instWorklist; - for (const SVFBasicBlock * bb: callfun->getReachableBBs()) + FIFOWorkList blkWorkList; + FIFOWorkList instWorklist; + for (const SVFBasicBlock* bb : callfun->getReachableBBs()) { - for (const SVFInstruction* inst: bb->getInstructionList()) + for (const SVFInstruction* inst : bb->getInstructionList()) { const ICFGNode* node = _icfg->getICFGNode(inst); - for (const SVFStmt *stmt: node->getSVFStmts()) + for (const SVFStmt* stmt : node->getSVFStmts()) { - if (const StoreStmt *store = SVFUtil::dyn_cast(stmt)) + if (const StoreStmt* store = SVFUtil::dyn_cast(stmt)) { - const SVFVar *rhsVar = store->getRHSVar(); + const SVFVar* rhsVar = store->getRHSVar(); u32_t lhs = store->getLHSVarID(); if (as.inVarToAddrsTable(lhs)) { if (!rhsVar->isPointer() && !rhsVar->isConstDataOrAggDataButNotNullPtr()) { - const AbstractValue &addrs = as[lhs]; - for (const auto &addr: addrs.getAddrs()) + const AbstractValue& addrs = as[lhs]; + for (const auto& addr : addrs.getAddrs()) { as.store(addr, IntervalValue::top()); } @@ -885,10 +854,10 @@ void AEStat::countStateSize() generalNumMap["ES_Loc_Addr_AVG_Num"] = 0; } ++count; -// generalNumMap["ES_Var_AVG_Num"] += -// _ae->getCurState().getVarToVal().size(); -// generalNumMap["ES_Loc_AVG_Num"] += -// _ae->getCurState().getLocToVal().size(); + // generalNumMap["ES_Var_AVG_Num"] += + // _ae->getCurState().getVarToVal().size(); + // generalNumMap["ES_Loc_AVG_Num"] += + // _ae->getCurState().getLocToVal().size(); } void AEStat::finializeStat() @@ -905,14 +874,14 @@ void AEStat::finializeStat() generalNumMap["ICFG_Node_Num"] = _ae->_svfir->getICFG()->nodeNum; u32_t callSiteNum = 0; u32_t extCallSiteNum = 0; - Set funs; - for (const auto &it: *_ae->_svfir->getICFG()) + Set funs; + for (const auto& it : *_ae->_svfir->getICFG()) { if (it.second->getFun()) { funs.insert(it.second->getFun()); } - if (const CallICFGNode *callNode = dyn_cast(it.second)) + if (const CallICFGNode* callNode = dyn_cast(it.second)) { if (!isExtCall(callNode->getCallSite())) { @@ -929,7 +898,6 @@ void AEStat::finializeStat() generalNumMap["NonEXT_CallSite_Num"] = callSiteNum; generalNumMap["Bug_Num"] = _ae->_nodeToBugInfo.size(); timeStatMap["Total_Time(sec)"] = (double)(endTime - startTime) / TIMEINTERVAL; - } void AEStat::performStat() @@ -982,11 +950,13 @@ void AEStat::reportBug() f.open(Options::OutputName()); } - std::cerr << "######################Full Overflow (" + std::to_string(_ae->_nodeToBugInfo.size()) + " found)######################\n"; - f << "######################Full Overflow (" + std::to_string(_ae->_nodeToBugInfo.size()) + " found)######################\n"; + std::cerr << "######################Full Overflow (" + std::to_string(_ae->_nodeToBugInfo.size()) + + " found)######################\n"; + f << "######################Full Overflow (" + std::to_string(_ae->_nodeToBugInfo.size()) + + " found)######################\n"; std::cerr << "---------------------------------------------\n"; f << "---------------------------------------------\n"; - for (auto& it: _ae->_nodeToBugInfo) + for (auto& it : _ae->_nodeToBugInfo) { std::cerr << it.second << "\n---------------------------------------------\n"; f << it.second << "\n---------------------------------------------\n"; @@ -995,19 +965,20 @@ void AEStat::reportBug() void AbstractInterpretation::initExtFunMap() { -#define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \ - auto sse_##FUNC_NAME = [this](const CallSite &cs) { \ - /* run real ext function */ \ - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); \ - AbstractState& as = getAbsStateFromTrace(callNode); \ - u32_t rhs_id = _svfir->getValueNode(cs.getArgument(0)); \ - if (!as.inVarToValTable(rhs_id)) return; \ - u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \ - s32_t res = FUNC_NAME(rhs); \ - u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); \ - as[lhsId] = IntervalValue(res); \ - return; \ - }; \ +#define SSE_FUNC_PROCESS(LLVM_NAME, FUNC_NAME) \ + auto sse_##FUNC_NAME = [this](const CallSite& cs) { \ + /* run real ext function */ \ + const CallICFGNode* callNode = \ + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); \ + AbstractState& as = getAbsStateFromTrace(callNode); \ + u32_t rhs_id = _svfir->getValueNode(cs.getArgument(0)); \ + if (!as.inVarToValTable(rhs_id)) return; \ + u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \ + s32_t res = FUNC_NAME(rhs); \ + u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); \ + as[lhsId] = IntervalValue(res); \ + return; \ + }; \ _func_map[#FUNC_NAME] = sse_##FUNC_NAME; SSE_FUNC_PROCESS(isalnum, isalnum); @@ -1029,12 +1000,12 @@ void AbstractInterpretation::initExtFunMap() SSE_FUNC_PROCESS(cosh, cosh); SSE_FUNC_PROCESS(tanh, tanh); - auto sse_svf_assert = [this](const CallSite &cs) - { - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + auto sse_svf_assert = [this](const CallSite& cs) { + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); _checkpoints.erase(callNode); u32_t arg0 = _svfir->getValueNode(cs.getArgument(0)); - AbstractState&as = getAbsStateFromTrace(callNode); + AbstractState& as = getAbsStateFromTrace(callNode); as[arg0].getInterval().meet_with(IntervalValue(1, 1)); if (as[arg0].getInterval().equals(IntervalValue(1, 1))) { @@ -1042,23 +1013,24 @@ void AbstractInterpretation::initExtFunMap() } else { - SVFUtil::errs() <<"svf_assert Fail. " << cs.getInstruction()->toString() << "\n"; + SVFUtil::errs() << "svf_assert Fail. " << cs.getInstruction()->toString() << "\n"; assert(false); } return; }; _func_map["svf_assert"] = sse_svf_assert; - auto svf_print = [&](const CallSite &cs) - { + auto svf_print = [&](const CallSite& cs) { if (cs.arg_size() < 2) return; - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); - AbstractState&as = getAbsStateFromTrace(callNode); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); std::string text = strRead(as, cs.getArgument(1)); assert(as.inVarToValTable(num_id) && "print() should pass integer"); IntervalValue itv = as[num_id].getInterval(); - std::cout << "Text: " << text <<", Value: " << cs.getArgument(0)->toString() << ", PrintVal: " << itv.toString() << std::endl; + std::cout << "Text: " << text << ", Value: " << cs.getArgument(0)->toString() + << ", PrintVal: " << itv.toString() << std::endl; return; }; _func_map["svf_print"] = svf_print; @@ -1076,11 +1048,10 @@ std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* r { // dead loop for string and break if there's a \0. If no \0, it will throw err. if (!as.inVarToAddrsTable(_svfir->getValueNode(rhs))) continue; - AbstractValue expr0 = - as.getGepObjAddrs(_svfir->getValueNode(rhs), IntervalValue(index)); + AbstractValue expr0 = as.getGepObjAddrs(_svfir->getValueNode(rhs), IntervalValue(index)); AbstractValue val; - for (const auto &addr: expr0.getAddrs()) + for (const auto& addr : expr0.getAddrs()) { val.join_with(as.load(addr)); } @@ -1088,33 +1059,29 @@ std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* r { break; } - if ((char) val.getInterval().getIntNumeral() == '\0') + if ((char)val.getInterval().getIntNumeral() == '\0') { break; } - str0.push_back((char) val.getInterval().getIntNumeral()); + str0.push_back((char)val.getInterval().getIntNumeral()); } return str0; } -void AbstractInterpretation::handleExtAPI(const CallICFGNode *call) +void AbstractInterpretation::handleExtAPI(const CallICFGNode* call) { AbstractState& as = getAbsStateFromTrace(call); - const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite()); + const SVFFunction* fun = SVFUtil::getCallee(call->getCallSite()); assert(fun && "SVFFunction* is nullptr"); CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); ExtAPIType extType = UNCLASSIFIED; // get type of mem api - for (const std::string &annotation: fun->getAnnotations()) + for (const std::string& annotation : fun->getAnnotations()) { - if (annotation.find("MEMCPY") != std::string::npos) - extType = MEMCPY; - if (annotation.find("MEMSET") != std::string::npos) - extType = MEMSET; - if (annotation.find("STRCPY") != std::string::npos) - extType = STRCPY; - if (annotation.find("STRCAT") != std::string::npos) - extType = STRCAT; + if (annotation.find("MEMCPY") != std::string::npos) extType = MEMCPY; + if (annotation.find("MEMSET") != std::string::npos) extType = MEMSET; + if (annotation.find("STRCPY") != std::string::npos) extType = STRCPY; + if (annotation.find("STRCAT") != std::string::npos) extType = STRCAT; } if (extType == UNCLASSIFIED) { @@ -1127,7 +1094,6 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call) u32_t lhsId = _svfir->getValueNode(SVFUtil::getSVFCallSite(call->getCallSite()).getInstruction()); if (as.inVarToAddrsTable(lhsId)) { - } else { @@ -1136,7 +1102,8 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call) return; } } - // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2") + // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), + // annotate("BUF_CHECK:Arg1, Arg2") else if (extType == MEMCPY) { IntervalValue len = as[_svfir->getValueNode(cs.getArgument(2))].getInterval(); @@ -1147,7 +1114,7 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call) // memset dst is arg0, elem is arg1, size is arg2 IntervalValue len = as[_svfir->getValueNode(cs.getArgument(2))].getInterval(); IntervalValue elem = as[_svfir->getValueNode(cs.getArgument(1))].getInterval(); - handleMemset(as,cs.getArgument(0), elem, len); + handleMemset(as, cs.getArgument(0), elem, len); } else if (extType == STRCPY) { @@ -1159,7 +1126,6 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call) } else { - } return; } @@ -1170,9 +1136,9 @@ void AbstractInterpretation::collectCheckPoint() for (auto it = _svfir->getICFG()->begin(); it != _svfir->getICFG()->end(); ++it) { const ICFGNode* node = it->second; - if (const CallICFGNode *call = SVFUtil::dyn_cast(node)) + if (const CallICFGNode* call = SVFUtil::dyn_cast(node)) { - if (const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite())) + if (const SVFFunction* fun = SVFUtil::getCallee(call->getCallSite())) { if (_checkpoint_names.find(fun->getName()) != _checkpoint_names.end()) { @@ -1192,17 +1158,15 @@ void AbstractInterpretation::checkPointAllSet() else { SVFUtil::errs() << SVFUtil::errMsg("At least one svf_assert has not been checked!!") << "\n"; - for (const CallICFGNode* call: _checkpoints) + for (const CallICFGNode* call : _checkpoints) { SVFUtil::errs() << call->toString() + "\n"; } assert(false); } - } - -void AbstractInterpretation::handleStrcpy(const CallICFGNode *call) +void AbstractInterpretation::handleStrcpy(const CallICFGNode* call) { // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk // get the dst and src @@ -1215,7 +1179,7 @@ void AbstractInterpretation::handleStrcpy(const CallICFGNode *call) handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral()); } -u32_t AbstractInterpretation::getAllocaInstByteSize(AbstractState& as, const AddrStmt *addr) +u32_t AbstractInterpretation::getAllocaInstByteSize(AbstractState& as, const AddrStmt* addr) { if (const ObjVar* objvar = SVFUtil::dyn_cast(addr->getRHSVar())) { @@ -1232,34 +1196,34 @@ u32_t AbstractInterpretation::getAllocaInstByteSize(AbstractState& as, const Add // Default element size is set to 1. u32_t elementSize = 1; u64_t res = elementSize; - for (const SVFValue* value: sizes) + for (const SVFValue* value : sizes) { if (!as.inVarToValTable(_svfir->getValueNode(value))) { as[_svfir->getValueNode(value)] = IntervalValue(Options::MaxFieldLimit()); } - IntervalValue itv = - as[_svfir->getValueNode(value)].getInterval(); - res = res * itv.ub().getIntNumeral() > Options::MaxFieldLimit()? Options::MaxFieldLimit(): res * itv.ub().getIntNumeral(); + IntervalValue itv = as[_svfir->getValueNode(value)].getInterval(); + res = res * itv.ub().getIntNumeral() > Options::MaxFieldLimit() ? Options::MaxFieldLimit() + : res * itv.ub().getIntNumeral(); } return (u32_t)res; } } - assert (false && "Addr rhs value is not ObjVar"); + assert(false && "Addr rhs value is not ObjVar"); abort(); } -IntervalValue AbstractInterpretation::traceMemoryAllocationSize(AbstractState& as, const SVFValue *value) +IntervalValue AbstractInterpretation::traceMemoryAllocationSize(AbstractState& as, const SVFValue* value) { /// Usually called by a GepStmt overflow check, or external API (like memcpy) overflow check /// Defitions of Terms: /// source node: malloc or gepStmt(array), sink node: gepStmt or external API (like memcpy) /// it tracks the value flow from sink to source, and accumulates offset /// then compare the accumulated offset and malloc size (or gepStmt array size) - SVF::FILOWorkList worklist; - Set visited; + SVF::FILOWorkList worklist; + Set visited; visited.insert(value); - Map gep_offsets; + Map gep_offsets; worklist.push(value); IntervalValue total_bytes(0); while (!worklist.empty()) @@ -1271,22 +1235,22 @@ IntervalValue AbstractInterpretation::traceMemoryAllocationSize(AbstractState& a /// CallNode means Source Node if (const CallICFGNode* callnode = SVFUtil::dyn_cast(node)) { - //to handle Ret PE + // to handle Ret PE AccessMemoryViaRetNode(callnode, worklist, visited); } - for (const SVFStmt *stmt: node->getSVFStmts()) + for (const SVFStmt* stmt : node->getSVFStmts()) { - if (const CopyStmt *copy = SVFUtil::dyn_cast(stmt)) + if (const CopyStmt* copy = SVFUtil::dyn_cast(stmt)) { // Copy Stmt, forward to lhs AccessMemoryViaCopyStmt(copy, worklist, visited); } - else if (const LoadStmt *load = SVFUtil::dyn_cast(stmt)) + else if (const LoadStmt* load = SVFUtil::dyn_cast(stmt)) { // Load Stmt, forward to the Var from last Store Stmt AccessMemoryViaLoadStmt(as, load, worklist, visited); } - else if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) + else if (const GepStmt* gep = SVFUtil::dyn_cast(stmt)) { // there are 3 type of gepStmt // 1. ptr get offset @@ -1335,7 +1299,7 @@ IntervalValue AbstractInterpretation::traceMemoryAllocationSize(AbstractState& a worklist.push(gep->getRHSVar()->getValue()); } } - else if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) + else if (const AddrStmt* addr = SVFUtil::dyn_cast(stmt)) { // addrStmt is source node. u32_t arr_type_size = getAllocaInstByteSize(as, addr); @@ -1349,7 +1313,8 @@ IntervalValue AbstractInterpretation::traceMemoryAllocationSize(AbstractState& a const SVFType* svftype = gvalue->getType(); if (SVFUtil::isa(svftype)) { - if(const SVFArrayType* ptrArrType = SVFUtil::dyn_cast(getPointeeElement(as, _svfir->getValueNode(value)))) + if (const SVFArrayType* ptrArrType = + SVFUtil::dyn_cast(getPointeeElement(as, _svfir->getValueNode(value)))) arr_type_size = ptrArrType->getByteSize(); else arr_type_size = svftype->getByteSize(); @@ -1372,8 +1337,7 @@ IntervalValue AbstractInterpretation::traceMemoryAllocationSize(AbstractState& a return IntervalValue(0); } - -IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SVFValue *strValue) +IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SVFValue* strValue) { IntervalValue dst_size = traceMemoryAllocationSize(as, strValue); u32_t len = 0; @@ -1383,14 +1347,13 @@ IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SV { for (u32_t index = 0; index < dst_size.lb().getIntNumeral(); index++) { - AbstractValue expr0 = - as.getGepObjAddrs(dstid, IntervalValue(index)); + AbstractValue expr0 = as.getGepObjAddrs(dstid, IntervalValue(index)); AbstractValue val; - for (const auto &addr: expr0.getAddrs()) + for (const auto& addr : expr0.getAddrs()) { val.join_with(as.load(addr)); } - if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0') + if (val.getInterval().is_numeral() && (char)val.getInterval().getIntNumeral() == '\0') { break; } @@ -1426,13 +1389,12 @@ IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SV } } - -void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call) +void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode* call) { // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat // to check it is strcat group or strncat group AbstractState& as = getAbsStateFromTrace(call); - const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite()); + const SVFFunction* fun = SVFUtil::getCallee(call->getCallSite()); const std::vector strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"}; const std::vector strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"}; if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end()) @@ -1464,7 +1426,8 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call) } } -void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue *dst, const SVF::SVFValue *src, IntervalValue len, u32_t start_idx) +void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue* dst, const SVF::SVFValue* src, + IntervalValue len, u32_t start_idx) { u32_t dstId = _svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType(). u32_t srcId = _svfir->getValueNode(src); @@ -1492,20 +1455,18 @@ void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue { assert(false && "we cannot support this type"); } - u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral()); + u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t)len.lb().getIntNumeral()); u32_t range_val = size / elemSize; if (as.inVarToAddrsTable(srcId) && as.inVarToAddrsTable(dstId)) { for (u32_t index = 0; index < range_val; index++) { // dead loop for string and break if there's a \0. If no \0, it will throw err. - AbstractValue expr_src = - as.getGepObjAddrs(srcId, IntervalValue(index)); - AbstractValue expr_dst = - as.getGepObjAddrs(dstId, IntervalValue(index + start_idx)); - for (const auto &dst: expr_dst.getAddrs()) + AbstractValue expr_src = as.getGepObjAddrs(srcId, IntervalValue(index)); + AbstractValue expr_dst = as.getGepObjAddrs(dstId, IntervalValue(index + start_idx)); + for (const auto& dst : expr_dst.getAddrs()) { - for (const auto &src: expr_src.getAddrs()) + for (const auto& src : expr_src.getAddrs()) { u32_t objId = AbstractState::getInternalID(src); if (as.inAddrToValTable(objId)) @@ -1527,7 +1488,7 @@ const SVFType* AbstractInterpretation::getPointeeElement(AbstractState& as, Node if (as.inVarToAddrsTable(id)) { const AbstractValue& addrs = as[id]; - for (auto addr: addrs.getAddrs()) + for (auto addr : addrs.getAddrs()) { NodeID addr_id = AbstractState::getInternalID(addr); if (addr_id == 0) // nullptr has no memobj, skip @@ -1542,10 +1503,11 @@ const SVFType* AbstractInterpretation::getPointeeElement(AbstractState& as, Node return nullptr; } -void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue *dst, IntervalValue elem, IntervalValue len) +void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue* dst, IntervalValue elem, + IntervalValue len) { u32_t dstId = _svfir->getValueNode(dst); - u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral()); + u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t)len.lb().getIntNumeral()); u32_t elemSize = 1; if (dst->getType()->isArrayTy()) { @@ -1574,7 +1536,7 @@ void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue if (as.inVarToAddrsTable(dstId)) { AbstractValue lhs_gep = as.getGepObjAddrs(dstId, IntervalValue(index)); - for (const auto &addr: lhs_gep.getAddrs()) + for (const auto& addr : lhs_gep.getAddrs()) { u32_t objId = AbstractState::getInternalID(addr); if (as.inAddrToValTable(objId)) @@ -1594,21 +1556,21 @@ void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue } } - - -void AbstractInterpretation::AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList& worklist, Set& visited) +void AbstractInterpretation::AccessMemoryViaRetNode(const CallICFGNode* callnode, + SVF::FILOWorkList& worklist, + Set& visited) { if (callnode->getRetICFGNode()->getSVFStmts().size() > 0) { - const RetPE *ret = SVFUtil::dyn_cast(*callnode->getRetICFGNode()->getSVFStmts().begin()); - SVF::ValVar *ret_gnode = SVFUtil::dyn_cast(_svfir->getGNode(ret->getRHSVar()->getId())); + const RetPE* ret = SVFUtil::dyn_cast(*callnode->getRetICFGNode()->getSVFStmts().begin()); + SVF::ValVar* ret_gnode = SVFUtil::dyn_cast(_svfir->getGNode(ret->getRHSVar()->getId())); if (ret_gnode->hasIncomingEdges(SVFStmt::PEDGEK::Phi)) { - const SVFStmt::SVFStmtSetTy &stmt_set = ret_gnode->getIncomingEdges(SVFStmt::PEDGEK::Phi); + const SVFStmt::SVFStmtSetTy& stmt_set = ret_gnode->getIncomingEdges(SVFStmt::PEDGEK::Phi); for (auto it = stmt_set.begin(); it != stmt_set.end(); ++it) { - const SVFStmt *stmt = *it; - if (const PhiStmt *phi = SVFUtil::dyn_cast(stmt)) + const SVFStmt* stmt = *it; + if (const PhiStmt* phi = SVFUtil::dyn_cast(stmt)) { if (!visited.count(phi->getOpVar(0)->getValue())) { @@ -1621,7 +1583,8 @@ void AbstractInterpretation::AccessMemoryViaRetNode(const CallICFGNode *callnode } } -void AbstractInterpretation::AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList& worklist, Set& visited) +void AbstractInterpretation::AccessMemoryViaCopyStmt(const CopyStmt* copy, SVF::FILOWorkList& worklist, + Set& visited) { if (!visited.count(copy->getRHSVar()->getValue())) { @@ -1630,17 +1593,19 @@ void AbstractInterpretation::AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF:: } } -void AbstractInterpretation::AccessMemoryViaLoadStmt(AbstractState& as, const LoadStmt *load, SVF::FILOWorkList& worklist, Set& visited) +void AbstractInterpretation::AccessMemoryViaLoadStmt(AbstractState& as, const LoadStmt* load, + SVF::FILOWorkList& worklist, + Set& visited) { if (as.inVarToAddrsTable(load->getLHSVarID())) { - const AbstractValue &Addrs = as[load->getLHSVarID()]; - for (auto vaddr: Addrs.getAddrs()) + const AbstractValue& Addrs = as[load->getLHSVarID()]; + for (auto vaddr : Addrs.getAddrs()) { NodeID id = AbstractState::getInternalID(vaddr); if (id == 0) // nullptr has no memobj, skip continue; - const auto *val = _svfir->getGNode(id); + const auto* val = _svfir->getGNode(id); if (!visited.count(val->getValue())) { visited.insert(val->getValue()); @@ -1650,26 +1615,26 @@ void AbstractInterpretation::AccessMemoryViaLoadStmt(AbstractState& as, const Lo } } -void AbstractInterpretation::AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, - SVF::FILOWorkList &worklist, - Set &visited) +void AbstractInterpretation::AccessMemoryViaCallArgs(const SVF::SVFArgument* arg, + SVF::FILOWorkList& worklist, + Set& visited) { - std::vector callstack = _callSiteStack; - SVF::ValVar *arg_gnode = SVFUtil::cast(_svfir->getGNode(_svfir->getValueNode(arg))); + std::vector callstack = _callSiteStack; + SVF::ValVar* arg_gnode = SVFUtil::cast(_svfir->getGNode(_svfir->getValueNode(arg))); if (arg_gnode->hasIncomingEdges(SVFStmt::PEDGEK::Call)) { while (!callstack.empty()) { - const CallICFGNode *cur_call = callstack.back(); + const CallICFGNode* cur_call = callstack.back(); callstack.pop_back(); - for (const SVFStmt *stmt: cur_call->getSVFStmts()) + for (const SVFStmt* stmt : cur_call->getSVFStmts()) { - if (const CallPE *callPE = SVFUtil::dyn_cast(stmt)) + if (const CallPE* callPE = SVFUtil::dyn_cast(stmt)) { if (callPE->getLHSVarID() == _svfir->getValueNode(arg)) { if (!SVFUtil::isa(callPE->getRHSVar()) && - !SVFUtil::isa(callPE->getRHSVar())) + !SVFUtil::isa(callPE->getRHSVar())) { if (!visited.count(callPE->getRHSVar()->getValue())) { @@ -1685,23 +1650,22 @@ void AbstractInterpretation::AccessMemoryViaCallArgs(const SVF::SVFArgument *arg } } -void AbstractInterpretation::updateStateOnGep(const GepStmt *gep) +void AbstractInterpretation::updateStateOnGep(const GepStmt* gep) { AbstractState& as = getAbsStateFromTrace(gep->getICFGNode()); u32_t rhs = gep->getRHSVarID(); u32_t lhs = gep->getLHSVarID(); IntervalValue offsetPair = as.getElementIndex(gep); AbstractValue gepAddrs; - APOffset lb = offsetPair.lb().getIntNumeral() < Options::MaxFieldLimit()? - offsetPair.lb().getIntNumeral(): Options::MaxFieldLimit(); - APOffset ub = offsetPair.ub().getIntNumeral() < Options::MaxFieldLimit()? - offsetPair.ub().getIntNumeral(): Options::MaxFieldLimit(); - for (APOffset i = lb; i <= ub; i++) - gepAddrs.join_with(as.getGepObjAddrs(rhs,IntervalValue(i))); + APOffset lb = offsetPair.lb().getIntNumeral() < Options::MaxFieldLimit() ? offsetPair.lb().getIntNumeral() + : Options::MaxFieldLimit(); + APOffset ub = offsetPair.ub().getIntNumeral() < Options::MaxFieldLimit() ? offsetPair.ub().getIntNumeral() + : Options::MaxFieldLimit(); + for (APOffset i = lb; i <= ub; i++) gepAddrs.join_with(as.getGepObjAddrs(rhs, IntervalValue(i))); as[lhs] = gepAddrs; } -void AbstractInterpretation::updateStateOnSelect(const SelectStmt *select) +void AbstractInterpretation::updateStateOnSelect(const SelectStmt* select) { AbstractState& as = getAbsStateFromTrace(select->getICFGNode()); u32_t res = select->getResID(); @@ -1719,7 +1683,7 @@ void AbstractInterpretation::updateStateOnSelect(const SelectStmt *select) } } -void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi) +void AbstractInterpretation::updateStateOnPhi(const PhiStmt* phi) { const ICFGNode* icfgNode = phi->getICFGNode(); AbstractState& as = getAbsStateFromTrace(icfgNode); @@ -1738,8 +1702,7 @@ void AbstractInterpretation::updateStateOnPhi(const PhiStmt *phi) as[res] = rhs; } - -void AbstractInterpretation::updateStateOnCall(const CallPE *callPE) +void AbstractInterpretation::updateStateOnCall(const CallPE* callPE) { AbstractState& as = getAbsStateFromTrace(callPE->getICFGNode()); NodeID lhs = callPE->getLHSVarID(); @@ -1747,7 +1710,7 @@ void AbstractInterpretation::updateStateOnCall(const CallPE *callPE) as[lhs] = as[rhs]; } -void AbstractInterpretation::updateStateOnRet(const RetPE *retPE) +void AbstractInterpretation::updateStateOnRet(const RetPE* retPE) { AbstractState& as = getAbsStateFromTrace(retPE->getICFGNode()); NodeID lhs = retPE->getLHSVarID(); @@ -1755,8 +1718,7 @@ void AbstractInterpretation::updateStateOnRet(const RetPE *retPE) as[lhs] = as[rhs]; } - -void AbstractInterpretation::updateStateOnAddr(const AddrStmt *addr) +void AbstractInterpretation::updateStateOnAddr(const AddrStmt* addr) { AbstractState& as = getAbsStateFromTrace(addr->getICFGNode()); as.initObjVar(SVFUtil::cast(addr->getRHSVar())); @@ -1765,8 +1727,7 @@ void AbstractInterpretation::updateStateOnAddr(const AddrStmt *addr) as[addr->getLHSVarID()] = as[addr->getRHSVarID()]; } - -void AbstractInterpretation::updateStateOnBinary(const BinaryOPStmt *binary) +void AbstractInterpretation::updateStateOnBinary(const BinaryOPStmt* binary) { /// Find the comparison predicates in "class BinaryOPStmt:OpCode" under SVF/svf/include/SVFIR/SVFStatements.h /// You are only required to handle integer predicates, including Add, FAdd, Sub, FSub, Mul, FMul, SDiv, FDiv, UDiv, @@ -1828,7 +1789,7 @@ void AbstractInterpretation::updateStateOnBinary(const BinaryOPStmt *binary) as[res] = resVal; } -void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) +void AbstractInterpretation::updateStateOnCmp(const CmpStmt* cmp) { AbstractState& as = getAbsStateFromTrace(cmp->getICFGNode()); u32_t op0 = cmp->getOpVarID(0); @@ -1842,7 +1803,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) if (as[op0].isInterval() && as[op1].isInterval()) { IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval(); - //AbstractValue + // AbstractValue auto predicate = cmp->getPredicate(); switch (predicate) { @@ -1887,8 +1848,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) case CmpStmt::FCMP_TRUE: resVal = IntervalValue(1, 1); break; - default: - { + default: { assert(false && "undefined compare: "); } } @@ -1902,8 +1862,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) { case CmpStmt::ICMP_EQ: case CmpStmt::FCMP_OEQ: - case CmpStmt::FCMP_UEQ: - { + case CmpStmt::FCMP_UEQ: { if (lhs.hasIntersect(rhs)) { resVal = IntervalValue(0, 1); @@ -1920,8 +1879,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) } case CmpStmt::ICMP_NE: case CmpStmt::FCMP_ONE: - case CmpStmt::FCMP_UNE: - { + case CmpStmt::FCMP_UNE: { if (lhs.hasIntersect(rhs)) { resVal = IntervalValue(0, 1); @@ -1939,8 +1897,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) case CmpStmt::ICMP_UGT: case CmpStmt::ICMP_SGT: case CmpStmt::FCMP_OGT: - case CmpStmt::FCMP_UGT: - { + case CmpStmt::FCMP_UGT: { if (lhs.size() == 1 && rhs.size() == 1) { resVal = IntervalValue(*lhs.begin() > *rhs.begin()); @@ -1954,8 +1911,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) case CmpStmt::ICMP_UGE: case CmpStmt::ICMP_SGE: case CmpStmt::FCMP_OGE: - case CmpStmt::FCMP_UGE: - { + case CmpStmt::FCMP_UGE: { if (lhs.size() == 1 && rhs.size() == 1) { resVal = IntervalValue(*lhs.begin() >= *rhs.begin()); @@ -1969,8 +1925,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) case CmpStmt::ICMP_ULT: case CmpStmt::ICMP_SLT: case CmpStmt::FCMP_OLT: - case CmpStmt::FCMP_ULT: - { + case CmpStmt::FCMP_ULT: { if (lhs.size() == 1 && rhs.size() == 1) { resVal = IntervalValue(*lhs.begin() < *rhs.begin()); @@ -1984,8 +1939,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) case CmpStmt::ICMP_ULE: case CmpStmt::ICMP_SLE: case CmpStmt::FCMP_OLE: - case CmpStmt::FCMP_ULE: - { + case CmpStmt::FCMP_ULE: { if (lhs.size() == 1 && rhs.size() == 1) { resVal = IntervalValue(*lhs.begin() <= *rhs.begin()); @@ -2002,8 +1956,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) case CmpStmt::FCMP_TRUE: resVal = IntervalValue(1, 1); break; - default: - { + default: { assert(false && "undefined compare: "); } } @@ -2012,7 +1965,7 @@ void AbstractInterpretation::updateStateOnCmp(const CmpStmt *cmp) } } -void AbstractInterpretation::updateStateOnLoad(const LoadStmt *load) +void AbstractInterpretation::updateStateOnLoad(const LoadStmt* load) { AbstractState& as = getAbsStateFromTrace(load->getICFGNode()); u32_t rhs = load->getRHSVarID(); @@ -2020,7 +1973,7 @@ void AbstractInterpretation::updateStateOnLoad(const LoadStmt *load) as[lhs] = as.loadValue(rhs); } -void AbstractInterpretation::updateStateOnStore(const StoreStmt *store) +void AbstractInterpretation::updateStateOnStore(const StoreStmt* store) { AbstractState& as = getAbsStateFromTrace(store->getICFGNode()); u32_t rhs = store->getRHSVarID(); @@ -2028,10 +1981,9 @@ void AbstractInterpretation::updateStateOnStore(const StoreStmt *store) as.storeValue(lhs, as[rhs]); } -void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy) +void AbstractInterpretation::updateStateOnCopy(const CopyStmt* copy) { - auto getZExtValue = [](AbstractState& as, const SVFVar* var) - { + auto getZExtValue = [](AbstractState& as, const SVFVar* var) { const SVFType* type = var->getType(); if (SVFUtil::isa(type)) { @@ -2075,11 +2027,9 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy) return IntervalValue::top(); // TODO: may have better solution }; - auto getTruncValue = [](const AbstractState& as, const SVF::SVFVar* var, - const SVFType* dstType) - { + auto getTruncValue = [](const AbstractState& as, const SVF::SVFVar* var, const SVFType* dstType) { const IntervalValue& itv = as[var->getId()].getInterval(); - if(itv.isBottom()) return itv; + if (itv.isBottom()) return itv; // get the value of ub and lb s64_t int_lb = itv.lb().getIntNumeral(); s64_t int_ub = itv.ub().getIntNumeral(); @@ -2169,7 +2119,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy) } else if (copy->getCopyKind() == CopyStmt::INTTOPTR) { - //insert nullptr + // insert nullptr } else if (copy->getCopyKind() == CopyStmt::PTRTOINT) { @@ -2265,5 +2215,3 @@ IntervalValue AbstractInterpretation::getRangeLimitFromType(const SVFType* type) // other types, return top interval } } - - diff --git a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp index 7edb8bc36..27bbe64dc 100644 --- a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp +++ b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - // // Created by Jiawei Wang on 2024/1/12. // @@ -46,27 +45,27 @@ std::string IntervalToIntStr(const IntervalValue& inv) s64_t ub_val = inv.ub().getNumeral(); // check lb - s32_t lb_s32 = (lb_val < static_cast(INT_MIN)) ? INT_MIN : - (lb_val > static_cast(INT_MAX)) ? INT_MAX : - static_cast(lb_val); + s32_t lb_s32 = (lb_val < static_cast(INT_MIN)) ? INT_MIN + : (lb_val > static_cast(INT_MAX)) ? INT_MAX + : static_cast(lb_val); // check ub - s32_t ub_s32 = (ub_val < static_cast(INT_MIN)) ? INT_MIN : - (ub_val > static_cast(INT_MAX)) ? INT_MAX : - static_cast(ub_val); + s32_t ub_s32 = (ub_val < static_cast(INT_MIN)) ? INT_MIN + : (ub_val > static_cast(INT_MAX)) ? INT_MAX + : static_cast(ub_val); return "[" + std::to_string(lb_s32) + ", " + std::to_string(ub_s32) + "]"; } } -void BufOverflowChecker::handleSVFStatement(const SVFStmt *stmt) +void BufOverflowChecker::handleSVFStatement(const SVFStmt* stmt) { AbstractInterpretation::handleSVFStatement(stmt); AbstractState& as = getAbsStateFromTrace(stmt->getICFGNode()); // for gep stmt, add the gep stmt to the addrToGep map - if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) + if (const GepStmt* gep = SVFUtil::dyn_cast(stmt)) { - for (NodeID addrID: as[gep->getLHSVarID()].getAddrs()) + for (NodeID addrID : as[gep->getLHSVarID()].getAddrs()) { NodeID objId = AbstractState::getInternalID(addrID); _addrToGep[objId] = gep; @@ -76,52 +75,52 @@ void BufOverflowChecker::handleSVFStatement(const SVFStmt *stmt) void BufOverflowChecker::initExtAPIBufOverflowCheckRules() { - //void llvm_memcpy_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memcpy_p0i8_p0i8_i64"] = {{0, 2}, {1,2}}; - //void llvm_memcpy_p0_p0_i64(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memcpy_p0_p0_i64"] = {{0, 2}, {1,2}}; - //void llvm_memcpy_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memcpy_p0i8_p0i8_i32"] = {{0, 2}, {1,2}}; - //void llvm_memcpy(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memcpy"] = {{0, 2}, {1,2}}; - //void llvm_memmove(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memmove"] = {{0, 2}, {1,2}}; - //void llvm_memmove_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memmove_p0i8_p0i8_i64"] = {{0, 2}, {1,2}}; - //void llvm_memmove_p0_p0_i64(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memmove_p0_p0_i64"] = {{0, 2}, {1,2}}; - //void llvm_memmove_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["llvm_memmove_p0i8_p0i8_i32"] = {{0, 2}, {1,2}}; - //void __memcpy_chk(char* dst, char* src, int sz, int flag){} - _extAPIBufOverflowCheckRules["__memcpy_chk"] = {{0, 2}, {1,2}}; - //void *memmove(void *str1, const void *str2, unsigned long n) - _extAPIBufOverflowCheckRules["memmove"] = {{0, 2}, {1,2}}; - //void bcopy(const void *s1, void *s2, unsigned long n){} - _extAPIBufOverflowCheckRules["bcopy"] = {{0, 2}, {1,2}}; - //void *memccpy( void * restrict dest, const void * restrict src, int c, unsigned long count) - _extAPIBufOverflowCheckRules["memccpy"] = {{0, 3}, {1,3}}; - //void __memmove_chk(char* dst, char* src, int sz){} - _extAPIBufOverflowCheckRules["__memmove_chk"] = {{0, 2}, {1,2}}; - //void llvm_memset(char* dst, char elem, int sz, int flag){} + // void llvm_memcpy_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memcpy_p0i8_p0i8_i64"] = {{0, 2}, {1, 2}}; + // void llvm_memcpy_p0_p0_i64(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memcpy_p0_p0_i64"] = {{0, 2}, {1, 2}}; + // void llvm_memcpy_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memcpy_p0i8_p0i8_i32"] = {{0, 2}, {1, 2}}; + // void llvm_memcpy(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memcpy"] = {{0, 2}, {1, 2}}; + // void llvm_memmove(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memmove"] = {{0, 2}, {1, 2}}; + // void llvm_memmove_p0i8_p0i8_i64(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memmove_p0i8_p0i8_i64"] = {{0, 2}, {1, 2}}; + // void llvm_memmove_p0_p0_i64(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memmove_p0_p0_i64"] = {{0, 2}, {1, 2}}; + // void llvm_memmove_p0i8_p0i8_i32(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["llvm_memmove_p0i8_p0i8_i32"] = {{0, 2}, {1, 2}}; + // void __memcpy_chk(char* dst, char* src, int sz, int flag){} + _extAPIBufOverflowCheckRules["__memcpy_chk"] = {{0, 2}, {1, 2}}; + // void *memmove(void *str1, const void *str2, unsigned long n) + _extAPIBufOverflowCheckRules["memmove"] = {{0, 2}, {1, 2}}; + // void bcopy(const void *s1, void *s2, unsigned long n){} + _extAPIBufOverflowCheckRules["bcopy"] = {{0, 2}, {1, 2}}; + // void *memccpy( void * restrict dest, const void * restrict src, int c, unsigned long count) + _extAPIBufOverflowCheckRules["memccpy"] = {{0, 3}, {1, 3}}; + // void __memmove_chk(char* dst, char* src, int sz){} + _extAPIBufOverflowCheckRules["__memmove_chk"] = {{0, 2}, {1, 2}}; + // void llvm_memset(char* dst, char elem, int sz, int flag){} _extAPIBufOverflowCheckRules["llvm_memset"] = {{0, 2}}; - //void llvm_memset_p0i8_i32(char* dst, char elem, int sz, int flag){} + // void llvm_memset_p0i8_i32(char* dst, char elem, int sz, int flag){} _extAPIBufOverflowCheckRules["llvm_memset_p0i8_i32"] = {{0, 2}}; - //void llvm_memset_p0i8_i64(char* dst, char elem, int sz, int flag){} + // void llvm_memset_p0i8_i64(char* dst, char elem, int sz, int flag){} _extAPIBufOverflowCheckRules["llvm_memset_p0i8_i64"] = {{0, 2}}; - //void llvm_memset_p0_i64(char* dst, char elem, int sz, int flag){} + // void llvm_memset_p0_i64(char* dst, char elem, int sz, int flag){} _extAPIBufOverflowCheckRules["llvm_memset_p0_i64"] = {{0, 2}}; - //char *__memset_chk(char * dest, int c, unsigned long destlen, int flag) + // char *__memset_chk(char * dest, int c, unsigned long destlen, int flag) _extAPIBufOverflowCheckRules["__memset_chk"] = {{0, 2}}; - //char *wmemset(wchar_t * dst, wchar_t elem, int sz, int flag) { + // char *wmemset(wchar_t * dst, wchar_t elem, int sz, int flag) { _extAPIBufOverflowCheckRules["wmemset"] = {{0, 2}}; - //char *strncpy(char *dest, const char *src, unsigned long n) - _extAPIBufOverflowCheckRules["strncpy"] = {{0, 2}, {1,2}}; - //unsigned long iconv(void* cd, char **restrict inbuf, unsigned long *restrict inbytesleft, char **restrict outbuf, unsigned long *restrict outbytesleft) + // char *strncpy(char *dest, const char *src, unsigned long n) + _extAPIBufOverflowCheckRules["strncpy"] = {{0, 2}, {1, 2}}; + // unsigned long iconv(void* cd, char **restrict inbuf, unsigned long *restrict inbytesleft, char **restrict outbuf, + // unsigned long *restrict outbytesleft) _extAPIBufOverflowCheckRules["iconv"] = {{1, 2}, {3, 4}}; } - -bool BufOverflowChecker::detectStrcpy(const CallICFGNode *call) +bool BufOverflowChecker::detectStrcpy(const CallICFGNode* call) { AbstractState& as = getAbsStateFromTrace(call); CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); @@ -135,11 +134,11 @@ bool BufOverflowChecker::detectStrcpy(const CallICFGNode *call) void BufOverflowChecker::initExtFunMap() { - auto sse_scanf = [&](const CallSite &cs) - { - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + auto sse_scanf = [&](const CallSite& cs) { + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); AbstractState& as = getAbsStateFromTrace(callNode); - //scanf("%d", &data); + // scanf("%d", &data); if (cs.arg_size() < 2) return; u32_t dst_id = _svfir->getValueNode(cs.getArgument(1)); @@ -152,7 +151,7 @@ void BufOverflowChecker::initExtFunMap() else { AbstractValue Addrs = as[dst_id]; - for (auto vaddr: Addrs.getAddrs()) + for (auto vaddr : Addrs.getAddrs()) { u32_t objId = AbstractState::getInternalID(vaddr); AbstractValue range = getRangeLimitFromType(_svfir->getGNode(objId)->getType()); @@ -160,11 +159,11 @@ void BufOverflowChecker::initExtFunMap() } } }; - auto sse_fscanf = [&](const CallSite &cs) - { - //fscanf(stdin, "%d", &data); + auto sse_fscanf = [&](const CallSite& cs) { + // fscanf(stdin, "%d", &data); if (cs.arg_size() < 3) return; - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); AbstractState& as = getAbsStateFromTrace(callNode); u32_t dst_id = _svfir->getValueNode(cs.getArgument(2)); if (!as.inVarToAddrsTable(dst_id)) @@ -176,7 +175,7 @@ void BufOverflowChecker::initExtFunMap() else { AbstractValue Addrs = as[dst_id]; - for (auto vaddr: Addrs.getAddrs()) + for (auto vaddr : Addrs.getAddrs()) { u32_t objId = AbstractState::getInternalID(vaddr); AbstractValue range = getRangeLimitFromType(_svfir->getGNode(objId)->getType()); @@ -194,11 +193,11 @@ void BufOverflowChecker::initExtFunMap() _func_map["__isoc99_sscanf"] = sse_scanf; _func_map["vscanf"] = sse_scanf; - auto sse_fread = [&](const CallSite &cs) - { + auto sse_fread = [&](const CallSite& cs) { if (cs.arg_size() < 3) return; - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); - AbstractState&as = getAbsStateFromTrace(callNode); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t block_count_id = _svfir->getValueNode(cs.getArgument(2)); u32_t block_size_id = _svfir->getValueNode(cs.getArgument(1)); IntervalValue block_count = as[block_count_id].getInterval(); @@ -208,16 +207,15 @@ void BufOverflowChecker::initExtFunMap() }; _func_map["fread"] = sse_fread; - auto sse_sprintf = [&](const CallSite &cs) - { + auto sse_sprintf = [&](const CallSite& cs) { // printf is difficult to predict since it has no byte size arguments }; - auto sse_snprintf = [&](const CallSite &cs) - { + auto sse_snprintf = [&](const CallSite& cs) { if (cs.arg_size() < 2) return; - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); - AbstractState&as = getAbsStateFromTrace(callNode); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); u32_t dst_id = _svfir->getValueNode(cs.getArgument(0)); // get elem size of arg2 @@ -240,9 +238,8 @@ void BufOverflowChecker::initExtFunMap() { if (Options::BufferOverflowCheck()) { - BufOverflowException bug( - "snprintf dst_id or dst is not defined nor initializesd.\n", - 0, 0, 0, 0, cs.getArgument(0)); + BufOverflowException bug("snprintf dst_id or dst is not defined nor initializesd.\n", 0, 0, 0, 0, + cs.getArgument(0)); addBugToRecoder(bug, _svfir->getICFG()->getICFGNode(cs.getInstruction())); return; } @@ -260,29 +257,28 @@ void BufOverflowChecker::initExtFunMap() _func_map["swprintf"] = sse_snprintf; _func_map["_snwprintf"] = sse_snprintf; - - auto sse_itoa = [&](const CallSite &cs) - { + auto sse_itoa = [&](const CallSite& cs) { // itoa(num, ch, 10); // num: int, ch: char*, 10 is decimal if (cs.arg_size() < 3) return; - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); - AbstractState&as = getAbsStateFromTrace(callNode); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); - u32_t num = (u32_t) as[num_id].getInterval().getNumeral(); + u32_t num = (u32_t)as[num_id].getInterval().getNumeral(); std::string snum = std::to_string(num); - canSafelyAccessMemory(cs.getArgument(1), IntervalValue((s32_t)snum.size()), _svfir->getICFG()->getICFGNode(cs.getInstruction())); + canSafelyAccessMemory(cs.getArgument(1), IntervalValue((s32_t)snum.size()), + _svfir->getICFG()->getICFGNode(cs.getInstruction())); }; _func_map["itoa"] = sse_itoa; - - auto sse_strlen = [&](const CallSite &cs) - { + auto sse_strlen = [&](const CallSite& cs) { // check the arg size if (cs.arg_size() < 1) return; const SVFValue* strValue = cs.getArgument(0); - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); AbstractState& as = getAbsStateFromTrace(callNode); IntervalValue dst_size = getStrlen(as, strValue); u32_t elemSize = 1; @@ -303,27 +299,28 @@ void BufOverflowChecker::initExtFunMap() _func_map["strlen"] = sse_strlen; _func_map["wcslen"] = sse_strlen; - auto sse_recv = [&](const CallSite &cs) - { + auto sse_recv = [&](const CallSite& cs) { // recv(sockfd, buf, len, flags); if (cs.arg_size() < 4) return; - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); - AbstractState&as = getAbsStateFromTrace(callNode); + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t len_id = _svfir->getValueNode(cs.getArgument(2)); IntervalValue len = as[len_id].getInterval() - IntervalValue(1); u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); as[lhsId] = len; - canSafelyAccessMemory(cs.getArgument(1), len, _svfir->getICFG()->getICFGNode(cs.getInstruction()));; + canSafelyAccessMemory(cs.getArgument(1), len, _svfir->getICFG()->getICFGNode(cs.getInstruction())); + ; }; _func_map["recv"] = sse_recv; _func_map["__recv"] = sse_recv; - auto safe_bufaccess = [&](const CallSite &cs) - { - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + auto safe_bufaccess = [&](const CallSite& cs) { + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); _checkpoints.erase(callNode); - //void SAFE_BUFACCESS(void* data, int size); + // void SAFE_BUFACCESS(void* data, int size); if (cs.arg_size() < 2) return; - AbstractState&as = getAbsStateFromTrace(callNode); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); IntervalValue val = as[size_id].getInterval(); if (val.isBottom()) @@ -331,7 +328,8 @@ void BufOverflowChecker::initExtFunMap() val = IntervalValue(0); assert(false && "SAFE_BUFACCESS size is bottom"); } - bool isSafe = canSafelyAccessMemory(cs.getArgument(0), val, _svfir->getICFG()->getICFGNode(cs.getInstruction())); + bool isSafe = + canSafelyAccessMemory(cs.getArgument(0), val, _svfir->getICFG()->getICFGNode(cs.getInstruction())); if (isSafe) { std::cout << "safe buffer access success\n"; @@ -347,20 +345,21 @@ void BufOverflowChecker::initExtFunMap() }; _func_map["SAFE_BUFACCESS"] = safe_bufaccess; - auto unsafe_bufaccess = [&](const CallSite &cs) - { - const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); + auto unsafe_bufaccess = [&](const CallSite& cs) { + const CallICFGNode* callNode = + SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); _checkpoints.erase(callNode); - //void UNSAFE_BUFACCESS(void* data, int size); + // void UNSAFE_BUFACCESS(void* data, int size); if (cs.arg_size() < 2) return; - AbstractState&as = getAbsStateFromTrace(callNode); + AbstractState& as = getAbsStateFromTrace(callNode); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); IntervalValue val = as[size_id].getInterval(); if (val.isBottom()) { assert(false && "UNSAFE_BUFACCESS size is bottom"); } - bool isSafe = canSafelyAccessMemory(cs.getArgument(0), val, _svfir->getICFG()->getICFGNode(cs.getInstruction())); + bool isSafe = + canSafelyAccessMemory(cs.getArgument(0), val, _svfir->getICFG()->getICFGNode(cs.getInstruction())); if (!isSafe) { std::cout << "detect buffer overflow success\n"; @@ -382,10 +381,10 @@ void BufOverflowChecker::initExtFunMap() _checkpoint_names.insert("UNSAFE_BUFACCESS"); } -bool BufOverflowChecker::detectStrcat(const CallICFGNode *call) +bool BufOverflowChecker::detectStrcat(const CallICFGNode* call) { AbstractState& as = getAbsStateFromTrace(call); - const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite()); + const SVFFunction* fun = SVFUtil::getCallee(call->getCallSite()); // check the arg size // if it is strcat group, we need to check the length of string, // e.g. strcat(str1, str2); which checks AllocSize(str1) >= Strlen(str1) + Strlen(str2); @@ -421,11 +420,11 @@ bool BufOverflowChecker::detectStrcat(const CallICFGNode *call) } } -void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) +void BufOverflowChecker::handleExtAPI(const CallICFGNode* call) { AbstractState& as = getAbsStateFromTrace(call); AbstractInterpretation::handleExtAPI(call); - const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite()); + const SVFFunction* fun = SVFUtil::getCallee(call->getCallSite()); assert(fun && "SVFFunction* is nullptr"); CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); // check the type of mem api, @@ -436,18 +435,15 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) // for other ext api like printf, scanf, etc., they have their own handlers ExtAPIType extType = UNCLASSIFIED; // get type of mem api - for (const std::string &annotation: fun->getAnnotations()) + for (const std::string& annotation : fun->getAnnotations()) { - if (annotation.find("MEMCPY") != std::string::npos) - extType = MEMCPY; - if (annotation.find("MEMSET") != std::string::npos) - extType = MEMSET; - if (annotation.find("STRCPY") != std::string::npos) - extType = STRCPY; - if (annotation.find("STRCAT") != std::string::npos) - extType = STRCAT; + if (annotation.find("MEMCPY") != std::string::npos) extType = MEMCPY; + if (annotation.find("MEMSET") != std::string::npos) extType = MEMSET; + if (annotation.find("STRCPY") != std::string::npos) extType = STRCPY; + if (annotation.find("STRCAT") != std::string::npos) extType = STRCAT; } - // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2") + // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), + // annotate("BUF_CHECK:Arg1, Arg2") if (extType == MEMCPY) { if (_extAPIBufOverflowCheckRules.count(fun->getName()) == 0) @@ -459,9 +455,10 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) // call parseMemcpyBufferCheckArgs to parse the BUF_CHECK annotation std::vector> args = _extAPIBufOverflowCheckRules.at(fun->getName()); // loop the args and check the offset - for (auto arg: args) + for (auto arg : args) { - IntervalValue offset = as[_svfir->getValueNode(cs.getArgument(arg.second))].getInterval() - IntervalValue(1); + IntervalValue offset = + as[_svfir->getValueNode(cs.getArgument(arg.second))].getInterval() - IntervalValue(1); canSafelyAccessMemory(cs.getArgument(arg.first), offset, call); } } @@ -476,9 +473,10 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) } std::vector> args = _extAPIBufOverflowCheckRules.at(fun->getName()); // loop the args and check the offset - for (auto arg: args) + for (auto arg : args) { - IntervalValue offset = as[_svfir->getValueNode(cs.getArgument(arg.second))].getInterval() - IntervalValue(1); + IntervalValue offset = + as[_svfir->getValueNode(cs.getArgument(arg.second))].getInterval() - IntervalValue(1); canSafelyAccessMemory(cs.getArgument(arg.first), offset, call); } } @@ -492,15 +490,14 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) } else { - } return; } -bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const IntervalValue &len, const ICFGNode *curNode) +bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue* value, const IntervalValue& len, const ICFGNode* curNode) { AbstractState& as = getAbsStateFromTrace(curNode); - const SVFValue *firstValue = value; + const SVFValue* firstValue = value; /// Usually called by a GepStmt overflow check, or external API (like memcpy) overflow check /// Defitions of Terms: /// source node: malloc or gepStmt(array), sink node: gepStmt or external API (like memcpy) @@ -509,34 +506,34 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte /// it tracks the value flow from sink to source, and accumulates offset /// then compare the accumulated offset and malloc size (or gepStmt array size) - SVF::FILOWorkList worklist; - Set visited; + SVF::FILOWorkList worklist; + Set visited; visited.insert(value); - Map gep_offsets; + Map gep_offsets; IntervalValue total_bytes = len; worklist.push(value); - std::vector callstack = _callSiteStack; + std::vector callstack = _callSiteStack; while (!worklist.empty()) { value = worklist.pop(); - if (const SVFInstruction *ins = SVFUtil::dyn_cast(value)) + if (const SVFInstruction* ins = SVFUtil::dyn_cast(value)) { - const ICFGNode *node = _svfir->getICFG()->getICFGNode(ins); - if (const CallICFGNode *callnode = SVFUtil::dyn_cast(node)) + const ICFGNode* node = _svfir->getICFG()->getICFGNode(ins); + if (const CallICFGNode* callnode = SVFUtil::dyn_cast(node)) { AccessMemoryViaRetNode(callnode, worklist, visited); } - for (const SVFStmt *stmt: node->getSVFStmts()) + for (const SVFStmt* stmt : node->getSVFStmts()) { - if (const CopyStmt *copy = SVFUtil::dyn_cast(stmt)) + if (const CopyStmt* copy = SVFUtil::dyn_cast(stmt)) { AccessMemoryViaCopyStmt(copy, worklist, visited); } - else if (const LoadStmt *load = SVFUtil::dyn_cast(stmt)) + else if (const LoadStmt* load = SVFUtil::dyn_cast(stmt)) { AccessMemoryViaLoadStmt(as, load, worklist, visited); } - else if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) + else if (const GepStmt* gep = SVFUtil::dyn_cast(stmt)) { // there are 3 type of gepStmt // 1. ptr get offset @@ -571,19 +568,20 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte if (gep->getOffsetVarAndGepTypePairVec().size() > 0) { - const SVFVar *gepVal = gep->getOffsetVarAndGepTypePairVec().back().first; - const SVFType *gepType = gep->getOffsetVarAndGepTypePairVec().back().second; + const SVFVar* gepVal = gep->getOffsetVarAndGepTypePairVec().back().first; + const SVFType* gepType = gep->getOffsetVarAndGepTypePairVec().back().second; if (gepType->isArrayTy()) { - const SVFArrayType *gepArrType = SVFUtil::dyn_cast(gepType); + const SVFArrayType* gepArrType = SVFUtil::dyn_cast(gepType); IntervalValue gepArrTotalByte(0); - const SVFValue *idxValue = gepVal->getValue(); + const SVFValue* idxValue = gepVal->getValue(); u32_t arrElemSize = gepArrType->getTypeOfElement()->getByteSize(); - if (const SVFConstantInt *op = SVFUtil::dyn_cast(idxValue)) + if (const SVFConstantInt* op = SVFUtil::dyn_cast(idxValue)) { - u32_t lb = (double) Options::MaxFieldLimit() / arrElemSize >= op->getSExtValue() ? - op->getSExtValue() * arrElemSize : Options::MaxFieldLimit(); + u32_t lb = (double)Options::MaxFieldLimit() / arrElemSize >= op->getSExtValue() + ? op->getSExtValue() * arrElemSize + : Options::MaxFieldLimit(); gepArrTotalByte = gepArrTotalByte + IntervalValue(lb, lb); } else @@ -596,14 +594,16 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte } else { - u32_t ub = (idxVal.ub().getNumeral() < 0) ? 0 : - (double) Options::MaxFieldLimit() / arrElemSize >= - idxVal.ub().getNumeral() ? - arrElemSize * idxVal.ub().getNumeral() : Options::MaxFieldLimit(); - u32_t lb = (idxVal.lb().getNumeral() < 0) ? 0 : - ((double) Options::MaxFieldLimit() / arrElemSize >= - idxVal.lb().getNumeral()) ? - arrElemSize * idxVal.lb().getNumeral() : Options::MaxFieldLimit(); + u32_t ub = + (idxVal.ub().getNumeral() < 0) ? 0 + : (double)Options::MaxFieldLimit() / arrElemSize >= idxVal.ub().getNumeral() + ? arrElemSize * idxVal.ub().getNumeral() + : Options::MaxFieldLimit(); + u32_t lb = + (idxVal.lb().getNumeral() < 0) ? 0 + : ((double)Options::MaxFieldLimit() / arrElemSize >= idxVal.lb().getNumeral()) + ? arrElemSize * idxVal.lb().getNumeral() + : Options::MaxFieldLimit(); gepArrTotalByte = gepArrTotalByte + IntervalValue(lb, ub); } } @@ -611,23 +611,19 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte if (total_bytes.ub().getNumeral() >= gepArrType->getByteSize()) { std::string msg = - "Buffer overflow!! Accessing buffer range: " + - IntervalToIntStr(total_bytes) + - "\nAllocated Gep buffer size: " + - std::to_string(gepArrType->getByteSize()) + "\n"; + "Buffer overflow!! Accessing buffer range: " + IntervalToIntStr(total_bytes) + + "\nAllocated Gep buffer size: " + std::to_string(gepArrType->getByteSize()) + "\n"; msg += "Position: " + firstValue->toString() + "\n"; msg += " The following is the value flow. [[\n"; for (auto it = gep_offsets.begin(); it != gep_offsets.end(); ++it) { - msg += it->first->toString() + ", Offset: " + IntervalToIntStr(it->second) + - "\n"; + msg += it->first->toString() + ", Offset: " + IntervalToIntStr(it->second) + "\n"; } msg += "]].\nAlloc Site: " + gep->toString() + "\n"; BufOverflowException bug(SVFUtil::errMsg(msg), gepArrType->getByteSize(), - gepArrType->getByteSize(), - total_bytes.lb().getNumeral(), total_bytes.ub().getNumeral(), - firstValue); + gepArrType->getByteSize(), total_bytes.lb().getNumeral(), + total_bytes.ub().getNumeral(), firstValue); addBugToRecoder(bug, curNode); return false; } @@ -641,7 +637,6 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte { total_bytes = total_bytes + byteOffset; } - } if (!visited.count(gep->getRHSVar()->getValue())) { @@ -649,16 +644,14 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte worklist.push(gep->getRHSVar()->getValue()); } } - else if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) + else if (const AddrStmt* addr = SVFUtil::dyn_cast(stmt)) { // addrStmt is source node. u32_t arr_type_size = getAllocaInstByteSize(as, addr); - if (total_bytes.ub().getNumeral() >= arr_type_size || - total_bytes.lb().getNumeral() < 0) + if (total_bytes.ub().getNumeral() >= arr_type_size || total_bytes.lb().getNumeral() < 0) { - std::string msg = - "Buffer overflow!! Accessing buffer range: " + IntervalToIntStr(total_bytes) + - "\nAllocated buffer size: " + std::to_string(arr_type_size) + "\n"; + std::string msg = "Buffer overflow!! Accessing buffer range: " + IntervalToIntStr(total_bytes) + + "\nAllocated buffer size: " + std::to_string(arr_type_size) + "\n"; msg += "Position: " + firstValue->toString() + "\n"; msg += " The following is the value flow. [[\n"; for (auto it = gep_offsets.begin(); it != gep_offsets.end(); ++it) @@ -680,14 +673,14 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte } } } - else if (const SVF::SVFGlobalValue *gvalue = SVFUtil::dyn_cast(value)) + else if (const SVF::SVFGlobalValue* gvalue = SVFUtil::dyn_cast(value)) { u32_t arr_type_size = 0; - const SVFType *svftype = gvalue->getType(); + const SVFType* svftype = gvalue->getType(); if (SVFUtil::isa(svftype)) { - if (const SVFArrayType *ptrArrType = SVFUtil::dyn_cast( - getPointeeElement(as, _svfir->getValueNode(gvalue)))) + if (const SVFArrayType* ptrArrType = + SVFUtil::dyn_cast(getPointeeElement(as, _svfir->getValueNode(gvalue)))) arr_type_size = ptrArrType->getByteSize(); else arr_type_size = svftype->getByteSize(); @@ -717,7 +710,7 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte return true; } } - else if (const SVF::SVFArgument *arg = SVFUtil::dyn_cast(value)) + else if (const SVF::SVFArgument* arg = SVFUtil::dyn_cast(value)) { AccessMemoryViaCallArgs(arg, worklist, visited); } @@ -734,34 +727,33 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte return true; } - // -bool BufOverflowChecker::detectBufOverflow(const ICFGNode *node) +bool BufOverflowChecker::detectBufOverflow(const ICFGNode* node) { - AbstractState &as = getAbsStateFromTrace(node); - for (auto* stmt: node->getSVFStmts()) + AbstractState& as = getAbsStateFromTrace(node); + for (auto* stmt : node->getSVFStmts()) { - if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) + if (const GepStmt* gep = SVFUtil::dyn_cast(stmt)) { const SVFVar* gepRhs = gep->getRHSVar(); if (const SVFInstruction* inst = SVFUtil::dyn_cast(gepRhs->getValue())) { const ICFGNode* icfgNode = _svfir->getICFG()->getICFGNode(inst); - for (const SVFStmt* stmt2: icfgNode->getSVFStmts()) + for (const SVFStmt* stmt2 : icfgNode->getSVFStmts()) { - if (const GepStmt *gep2 = SVFUtil::dyn_cast(stmt2)) + if (const GepStmt* gep2 = SVFUtil::dyn_cast(stmt2)) { return canSafelyAccessMemory(gep2->getLHSVar()->getValue(), IntervalValue(0, 0), node); } } } } - else if (const LoadStmt* load = SVFUtil::dyn_cast(stmt)) + else if (const LoadStmt* load = SVFUtil::dyn_cast(stmt)) { if (as.inVarToAddrsTable(load->getRHSVarID())) { AbstractValue Addrs = as[load->getRHSVarID()]; - for (auto vaddr: Addrs.getAddrs()) + for (auto vaddr : Addrs.getAddrs()) { u32_t objId = AbstractState::getInternalID(vaddr); if (_addrToGep.find(objId) != _addrToGep.end()) @@ -772,12 +764,12 @@ bool BufOverflowChecker::detectBufOverflow(const ICFGNode *node) } } } - else if (const StoreStmt* store = SVFUtil::dyn_cast(stmt)) + else if (const StoreStmt* store = SVFUtil::dyn_cast(stmt)) { if (as.inVarToAddrsTable(store->getLHSVarID())) { AbstractValue Addrs = as[store->getLHSVarID()]; - for (auto vaddr: Addrs.getAddrs()) + for (auto vaddr : Addrs.getAddrs()) { u32_t objId = AbstractState::getInternalID(vaddr); if (_addrToGep.find(objId) != _addrToGep.end()) @@ -805,7 +797,7 @@ void BufOverflowChecker::addBugToRecoder(const BufOverflowException& e, const IC } GenericBug::EventStack eventStack; SVFBugEvent sourceInstEvent(SVFBugEvent::EventType::SourceInst, inst); - for (const auto &callsite: _callSiteStack) + for (const auto& callsite : _callSiteStack) { SVFBugEvent callSiteEvent(SVFBugEvent::EventType::CallSite, callsite->getCallSite()); eventStack.push_back(callSiteEvent); @@ -826,4 +818,4 @@ void BufOverflowChecker::addBugToRecoder(const BufOverflowException& e, const IC _nodeToBugInfo[node] = e.what(); } -} +} // namespace SVF diff --git a/svf/lib/AE/Svfexe/ICFGSimplification.cpp b/svf/lib/AE/Svfexe/ICFGSimplification.cpp index b66d128f0..b70314da6 100644 --- a/svf/lib/AE/Svfexe/ICFGSimplification.cpp +++ b/svf/lib/AE/Svfexe/ICFGSimplification.cpp @@ -23,7 +23,6 @@ // 46th International Conference on Software Engineering. (ICSE24) //===----------------------------------------------------------------------===// - // // Created by Jiawei Wang on 2024/2/25. // @@ -42,15 +41,13 @@ void ICFGSimplification::mergeAdjacentNodes(ICFG* icfg) { for (const auto& inst : *bb) { - if (SVFUtil::isIntrinsicInst(inst)) - continue; + if (SVFUtil::isIntrinsicInst(inst)) continue; const ICFGNode* icfgNode = icfg->getICFGNode(inst); // e.g. // block: entry // insts: call = i32 %fun(i32 %arg) // We put the callnode in an icfgnode alone, and the retnode is similar. - if (const CallICFGNode* callNode = - SVFUtil::dyn_cast(icfgNode)) + if (const CallICFGNode* callNode = SVFUtil::dyn_cast(icfgNode)) { bbToNodes[bb].push_back(callNode); subNodes.insert(callNode); @@ -113,7 +110,7 @@ void ICFGSimplification::mergeAdjacentNodes(ICFG* icfg) } } - for (auto &it: subNodes) + for (auto& it : subNodes) { ICFGNode* head = const_cast(it); if (head->getOutEdges().size() != 1) @@ -131,7 +128,7 @@ void ICFGSimplification::mergeAdjacentNodes(ICFG* icfg) icfg->removeICFGEdge(*head->getOutEdges().begin()); std::vector rm_edges; // Step 1: merge the out edges of next to head - for (ICFGEdge* outEdge: next->getOutEdges()) + for (ICFGEdge* outEdge : next->getOutEdges()) { rm_edges.push_back(outEdge); ICFGNode* post = outEdge->getDstNode(); @@ -140,7 +137,8 @@ void ICFGSimplification::mergeAdjacentNodes(ICFG* icfg) IntraCFGEdge* intraEdge = SVFUtil::dyn_cast(outEdge); if (intraEdge->getCondition()) { - icfg->addConditionalIntraEdge(head, post, intraEdge->getCondition(), intraEdge->getSuccessorCondValue()); + icfg->addConditionalIntraEdge(head, post, intraEdge->getCondition(), + intraEdge->getSuccessorCondValue()); } else { @@ -155,19 +153,16 @@ void ICFGSimplification::mergeAdjacentNodes(ICFG* icfg) // Step 3: remove the edges from next to its next, since next has been merged to head // if only one out edge, we may continue to merge the next node if it is not a subnode next = (*next->getOutEdges().begin())->getDstNode(); - for (ICFGEdge* edge: rm_edges) - icfg->removeICFGEdge(edge); - + for (ICFGEdge* edge : rm_edges) icfg->removeICFGEdge(edge); } else { // if more than one out edges, we don't merge any following nodes. - for (ICFGEdge* edge: rm_edges) - icfg->removeICFGEdge(edge); + for (ICFGEdge* edge : rm_edges) icfg->removeICFGEdge(edge); break; } } } } } -} \ No newline at end of file +} // namespace SVF \ No newline at end of file diff --git a/svf/lib/CFL/CFGNormalizer.cpp b/svf/lib/CFL/CFGNormalizer.cpp index b07c30e19..573c96009 100644 --- a/svf/lib/CFL/CFGNormalizer.cpp +++ b/svf/lib/CFL/CFGNormalizer.cpp @@ -39,9 +39,9 @@ using namespace SVF; -CFGrammar* CFGNormalizer::normalize(GrammarBase *generalGrammar) +CFGrammar* CFGNormalizer::normalize(GrammarBase* generalGrammar) { - CFGrammar *grammar = new CFGrammar(); + CFGrammar* grammar = new CFGrammar(); grammar->setStartKind(generalGrammar->getStartKind()); grammar->setTerminals(generalGrammar->getTerminals()); grammar->setNonterminals(generalGrammar->getNonterminals()); @@ -58,20 +58,20 @@ CFGrammar* CFGNormalizer::normalize(GrammarBase *generalGrammar) return grammar; } - -CFGrammar* CFGNormalizer::fillAttribute(CFGrammar *grammar, const Map>& kindToAttrsMap) +CFGrammar* CFGNormalizer::fillAttribute(CFGrammar* grammar, + const Map>& kindToAttrsMap) { NodeSet nodeSet = {}; - for (auto pair: kindToAttrsMap) + for (auto pair : kindToAttrsMap) { - for (auto attri: pair.second) + for (auto attri : pair.second) { nodeSet.insert(attri); } } - for(auto symProdsPair: grammar->getRawProductions()) + for (auto symProdsPair : grammar->getRawProductions()) { - for(auto prod: symProdsPair.second) + for (auto prod : symProdsPair.second) { /// rawProductions production does not include lhs /// so append to the begin of the production @@ -79,7 +79,7 @@ CFGrammar* CFGNormalizer::fillAttribute(CFGrammar *grammar, const Map new_grammar = {}; std::string tempStr = ""; @@ -97,10 +97,10 @@ void CFGNormalizer::ebnf_bin(CFGrammar *grammar) auto rawProductions = grammar->getRawProductions(); - for(auto itr : rawProductions) + for (auto itr : rawProductions) { auto head = *(grammar->getRawProductions().find(itr.first)); - for(auto rule: head.second) + for (auto rule : head.second) { if (rule.size() < 3) continue; @@ -132,12 +132,12 @@ void CFGNormalizer::ebnf_bin(CFGrammar *grammar) for (unsigned i = 0; i < long_run.size(); i++) { GrammarBase::VariableAttribute variableAttribute = long_run[i].variableAttribute; - if ( variableAttribute != 0) + if (variableAttribute != 0) { variableAttributeSet.insert(variableAttribute); } } - if ( variableAttributeSet.size() == 1) + if (variableAttributeSet.size() == 1) { tempStr += "_"; tempStr += char(*variableAttributeSet.begin()); @@ -150,7 +150,7 @@ void CFGNormalizer::ebnf_bin(CFGrammar *grammar) new_grammar[X] = {}; GrammarBase::Production temp_p = long_run; GrammarBase::Symbol RHX; - if (long_run.size() ==2) + if (long_run.size() == 2) { new_grammar[X].insert(temp_p); long_run.clear(); @@ -174,7 +174,7 @@ void CFGNormalizer::ebnf_bin(CFGrammar *grammar) { RHX = check_head(grammar->getRawProductions(), long_run); } - if(RHX == u32_t(-1)) + if (RHX == u32_t(-1)) { tempStr = "X"; std::ostringstream ss; @@ -184,12 +184,12 @@ void CFGNormalizer::ebnf_bin(CFGrammar *grammar) for (unsigned i = 0; i < long_run.size(); i++) { GrammarBase::VariableAttribute variableAttribute = long_run[i].variableAttribute; - if ( variableAttribute != 0) + if (variableAttribute != 0) { variableAttributeSet.insert(variableAttribute); } } - if ( variableAttributeSet.size() == 1) + if (variableAttributeSet.size() == 1) { tempStr += "_"; tempStr += char(*variableAttributeSet.begin()); @@ -217,42 +217,43 @@ void CFGNormalizer::ebnf_bin(CFGrammar *grammar) } } -///Loop through provided production based on existence of attribute of attribute variable -///and expand to productions set -///e.g Xi -> Y Zi with Xi i = 0, 1, Yi i = 0,2 -///Will get {X0 -> Y Z0, X1 -> Y Z1, X2 -> Y Z2} -void CFGNormalizer::getFilledProductions(GrammarBase::Production &prod, const NodeSet& nodeSet, CFGrammar *grammar, GrammarBase::Productions& normalProds) +/// Loop through provided production based on existence of attribute of attribute variable +/// and expand to productions set +/// e.g Xi -> Y Zi with Xi i = 0, 1, Yi i = 0,2 +/// Will get {X0 -> Y Z0, X1 -> Y Z1, X2 -> Y Z2} +void CFGNormalizer::getFilledProductions(GrammarBase::Production& prod, const NodeSet& nodeSet, CFGrammar* grammar, + GrammarBase::Productions& normalProds) { normalProds.clear(); CFLFIFOWorkList worklist; worklist.push(prod); - while( worklist.empty() == false ) + while (worklist.empty() == false) { GrammarBase::Production currentProduction = worklist.pop(); /// Get the first encounter variable attribute to expand GrammarBase::VariableAttribute currentVariableAttribute = 0; // GrammarBase::Kind baseKind; - for ( GrammarBase::Symbol &symbol : currentProduction ) + for (GrammarBase::Symbol& symbol : currentProduction) { - if ( currentVariableAttribute == 0 ) + if (currentVariableAttribute == 0) { currentVariableAttribute = symbol.variableAttribute; // baseKind = symbol.kind; } } - if ( currentVariableAttribute == 0) + if (currentVariableAttribute == 0) { normalProds.insert(currentProduction); continue; } //*(kindToAttriMap.find(baseKind)); - //for (auto attribute : nodeSet.second) + // for (auto attribute : nodeSet.second) for (auto attribute : nodeSet) { GrammarBase::Production fillingProduction = currentProduction; - for ( GrammarBase::Symbol &symbol : fillingProduction ) + for (GrammarBase::Symbol& symbol : fillingProduction) { - if ( symbol.variableAttribute == currentVariableAttribute) + if (symbol.variableAttribute == currentVariableAttribute) { symbol.attribute = attribute; symbol.variableAttribute = 0; @@ -260,14 +261,14 @@ void CFGNormalizer::getFilledProductions(GrammarBase::Production &prod, const No } /// Check whether all symbol expanded bool continueToFill = false; - for ( GrammarBase::Symbol &symbol : fillingProduction ) + for (GrammarBase::Symbol& symbol : fillingProduction) { - if ( symbol.variableAttribute != 0 ) + if (symbol.variableAttribute != 0) { continueToFill = true; } } - if ( continueToFill == false) + if (continueToFill == false) { normalProds.insert(fillingProduction); } @@ -279,7 +280,7 @@ void CFGNormalizer::getFilledProductions(GrammarBase::Production &prod, const No } } -int CFGNormalizer::ebnfBracketMatch(GrammarBase::Production &prod, int i, CFGrammar *grammar) +int CFGNormalizer::ebnfBracketMatch(GrammarBase::Production& prod, int i, CFGrammar* grammar) { int index = i; while (index >= 0) @@ -293,12 +294,12 @@ int CFGNormalizer::ebnfBracketMatch(GrammarBase::Production &prod, int i, CFGram return 0; } -void CFGNormalizer::barReplace(CFGrammar *grammar) +void CFGNormalizer::barReplace(CFGrammar* grammar) { - for (auto &symbolToProductionsPair : grammar->getRawProductions()) + for (auto& symbolToProductionsPair : grammar->getRawProductions()) { GrammarBase::Productions productions; - //GrammarBase::Productions Originalproductions = symbolToProductionsPair.second; + // GrammarBase::Productions Originalproductions = symbolToProductionsPair.second; for (auto ebnfProduction : symbolToProductionsPair.second) { size_t i = 1; @@ -307,15 +308,15 @@ void CFGNormalizer::barReplace(CFGrammar *grammar) { if (grammar->kindToStr(ebnfProduction[i].kind) == "|") { - GrammarBase::Production tempPro(ebnfProduction.begin()+j, ebnfProduction.begin()+i); - tempPro.insert(tempPro.begin(), symbolToProductionsPair.first ); + GrammarBase::Production tempPro(ebnfProduction.begin() + j, ebnfProduction.begin() + i); + tempPro.insert(tempPro.begin(), symbolToProductionsPair.first); productions.insert(tempPro); - j = i+1; + j = i + 1; } i++; } - GrammarBase::Production tempPro(ebnfProduction.begin()+j, ebnfProduction.begin()+i); - tempPro.insert(tempPro.begin(), symbolToProductionsPair.first ); + GrammarBase::Production tempPro(ebnfProduction.begin() + j, ebnfProduction.begin() + i); + tempPro.insert(tempPro.begin(), symbolToProductionsPair.first); productions.insert(tempPro); } symbolToProductionsPair.second.clear(); @@ -323,14 +324,14 @@ void CFGNormalizer::barReplace(CFGrammar *grammar) } } -void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar) +void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar* grammar) { /// Replace Sign Group With tempNonterminal 'X' /// And load the replace in newProductions SVF::Map newProductions; std::string tempNonterminal = "X"; - for (auto &symbolToProductionsPair : grammar->getRawProductions()) + for (auto& symbolToProductionsPair : grammar->getRawProductions()) { GrammarBase::Productions productions = symbolToProductionsPair.second; for (auto ebnfProduction : symbolToProductionsPair.second) @@ -363,15 +364,15 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar) { productions.erase(ebnfProduction); ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1); - ebnfProduction.insert(ebnfProduction.begin() + signGroupStart, grammar->strToSymbol(newProductions[groupString])); + ebnfProduction.insert(ebnfProduction.begin() + signGroupStart, + grammar->strToSymbol(newProductions[groupString])); productions.insert(ebnfProduction); } - else if ( (signGroupStart == 1) && (i == ebnfProduction.size() -1)) + else if ((signGroupStart == 1) && (i == ebnfProduction.size() - 1)) { newProductions[groupString] = grammar->kindToStr(ebnfProduction[0].kind); productions.erase(ebnfProduction); ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1); - } else { @@ -394,7 +395,7 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar) } symbolToProductionsPair.second = productions; } - for(auto rep: newProductions) + for (auto rep : newProductions) { /// For Both * and ? need to insert epsilon rule std::string new_nonterminal = rep.second; @@ -410,9 +411,10 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar) GrammarBase::Production withoutSign = {}; if (sign == '*') { - for (auto &word : normalProd) + for (auto& word : normalProd) { - if (word != grammar->strToSymbol("*") && word != grammar->strToSymbol("(") && word != grammar->strToSymbol(")")) + if (word != grammar->strToSymbol("*") && word != grammar->strToSymbol("(") && + word != grammar->strToSymbol(")")) { withoutSign.push_back(word); } @@ -421,9 +423,10 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar) } if (sign == '?') { - for (auto &word : normalProd) + for (auto& word : normalProd) { - if (word != grammar->strToSymbol("?") && word != grammar->strToSymbol("(") && word != grammar->strToSymbol(")")) + if (word != grammar->strToSymbol("?") && word != grammar->strToSymbol("(") && + word != grammar->strToSymbol(")")) { withoutSign.push_back(word); } @@ -435,7 +438,7 @@ void CFGNormalizer::ebnfSignReplace(char sign, CFGrammar *grammar) } } -void CFGNormalizer::strTrans(std::string LHS, CFGrammar *grammar, GrammarBase::Production& normalProd) +void CFGNormalizer::strTrans(std::string LHS, CFGrammar* grammar, GrammarBase::Production& normalProd) { std::smatch matches; std::regex LHSReg("\\s*(.*)"); @@ -454,11 +457,12 @@ void CFGNormalizer::strTrans(std::string LHS, CFGrammar *grammar, GrammarBase::P normalProd.push_back(grammar->strToSymbol(LHS)); } -GrammarBase::Symbol CFGNormalizer::check_head(GrammarBase::SymbolMap &grammar, GrammarBase::Production &rule) +GrammarBase::Symbol CFGNormalizer::check_head( + GrammarBase::SymbolMap& grammar, GrammarBase::Production& rule) { - for(auto symProdPair: grammar) + for (auto symProdPair : grammar) { - for(auto prod: symProdPair.second) + for (auto prod : symProdPair.second) { if (rule == prod) { @@ -471,13 +475,14 @@ GrammarBase::Symbol CFGNormalizer::check_head(GrammarBase::SymbolMapstrToKind("epsilon")) != prod.end())) { - if (std::find(grammar->getEpsilonProds().begin(), grammar->getEpsilonProds().end(), prod) == grammar->getEpsilonProds().end()) + if (std::find(grammar->getEpsilonProds().begin(), grammar->getEpsilonProds().end(), prod) == + grammar->getEpsilonProds().end()) { grammar->getEpsilonProds().insert(prod); } @@ -494,12 +499,12 @@ void CFGNormalizer::insertToCFLGrammar(CFGrammar *grammar, GrammarBase::Producti } } -void CFGNormalizer::removeFirstSymbol(CFGrammar *grammar) +void CFGNormalizer::removeFirstSymbol(CFGrammar* grammar) { // Remove First Terminal - for(auto head : grammar->getRawProductions()) + for (auto head : grammar->getRawProductions()) { - for(auto rule: head.second) + for (auto rule : head.second) { GrammarBase::Production long_run = rule; diff --git a/svf/lib/CFL/CFGrammar.cpp b/svf/lib/CFL/CFGrammar.cpp index 5764bc543..e820e701e 100644 --- a/svf/lib/CFL/CFGrammar.cpp +++ b/svf/lib/CFL/CFGrammar.cpp @@ -36,13 +36,12 @@ using namespace SVF; - void GrammarBase::setRawProductions(SymbolMap& rawProductions) { this->rawProductions = rawProductions; } -void GrammarBase::setKindToAttrsMap(const Map>& kindToAttrsMap) +void GrammarBase::setKindToAttrsMap(const Map>& kindToAttrsMap) { this->kindToAttrsMap = kindToAttrsMap; } @@ -56,16 +55,13 @@ GrammarBase::Kind GrammarBase::strToKind(std::string str) const { auto tit = terminals.find(str); - if(tit!=terminals.end()) - return tit->second; + if (tit != terminals.end()) return tit->second; auto nit = nonterminals.find(str); - if(nit!=nonterminals.end()) - return nit->second; + if (nit != nonterminals.end()) return nit->second; auto sit = EBNFSigns.find(str); - if(sit!=EBNFSigns.end()) - return sit->second; + if (sit != EBNFSigns.end()) return sit->second; assert(false && "kind not found!"); abort(); @@ -78,17 +74,17 @@ GrammarBase::Symbol GrammarBase::strToSymbol(const std::string str) const std::string kindStr = extractKindStrFromSymbolStr(str); symbol.kind = strToKind(kindStr); - if ( attributeStr == "") return symbol; + if (attributeStr == "") return symbol; - if ( (attributeStr.size() == 1) && (std::isalpha(attributeStr[attributeStr.size()-1])) ) + if ((attributeStr.size() == 1) && (std::isalpha(attributeStr[attributeStr.size() - 1]))) { - symbol.variableAttribute = (u32_t)attributeStr[attributeStr.size()-1]; + symbol.variableAttribute = (u32_t)attributeStr[attributeStr.size() - 1]; } else { - for( char &c : attributeStr) + for (char& c : attributeStr) { - if ( std::isdigit(c) == false ) + if (std::isdigit(c) == false) { SVFUtil::errs() << SVFUtil::errMsg("\t Symbol Attribute Parse Failure :") << str << " Attribute:" << attributeStr << " (only number or single alphabet.)"; @@ -104,7 +100,7 @@ std::string GrammarBase::kindToStr(Kind kind) const { std::string key = ""; - for (auto &i : terminals) + for (auto& i : terminals) { if (i.second == kind) { @@ -114,7 +110,7 @@ std::string GrammarBase::kindToStr(Kind kind) const } std::string nkey = ""; - for (auto &ni : nonterminals) + for (auto& ni : nonterminals) { if (ni.second == kind) { @@ -124,7 +120,7 @@ std::string GrammarBase::kindToStr(Kind kind) const } std::string signs = ""; - for (auto &i : EBNFSigns) + for (auto& i : EBNFSigns) { if (i.second == kind) { @@ -142,12 +138,12 @@ std::string GrammarBase::symToStrDump(Symbol sym) const Attribute attribute = sym.attribute; std::string key = ""; - for (auto &i : terminals) + for (auto& i : terminals) { if (i.second == kind) { key = i.first; - if(attribute != 0) + if (attribute != 0) { key.append("_"); key.append(std::to_string(attribute)); @@ -157,12 +153,12 @@ std::string GrammarBase::symToStrDump(Symbol sym) const } std::string nkey = ""; - for (auto &ni : nonterminals) + for (auto& ni : nonterminals) { if (ni.second == kind) { nkey = ni.first; - if(attribute != 0) + if (attribute != 0) { nkey.append("_"); nkey.append(std::to_string(attribute)); @@ -208,7 +204,7 @@ std::string GrammarBase::extractKindStrFromSymbolStr(const std::string& symbolSt { std::string kindStr; // symbolStr end with '_', the whole symbolStr treat as kind, not with attribute. - auto underscorePosition = symbolStr.find_last_of("_", symbolStr.size()-1); + auto underscorePosition = symbolStr.find_last_of("_", symbolStr.size() - 1); if (underscorePosition == std::string::npos) { return symbolStr; @@ -220,12 +216,12 @@ std::string GrammarBase::extractAttributeStrFromSymbolStr(const std::string& sym { std::string attributeStr; // symbolStr end with '_', the whole symbolStr treat as kind, not with attribute. - auto underscorePosition = symbolStr.find_last_of("_", symbolStr.size()-1); + auto underscorePosition = symbolStr.find_last_of("_", symbolStr.size() - 1); if (underscorePosition == std::string::npos) { return ""; } - return symbolStr.substr(underscorePosition+1); + return symbolStr.substr(underscorePosition + 1); } GrammarBase::Symbol GrammarBase::insertSymbol(std::string symbolStr) @@ -253,18 +249,18 @@ GrammarBase::Symbol GrammarBase::insertNonTerminalSymbol(std::string symbolStr) std::string attributeStr = extractAttributeStrFromSymbolStr(symbolStr); symbol.kind = insertNonterminalKind(kindStr); - if ( attributeStr == "") return symbol; + if (attributeStr == "") return symbol; - if ( (attributeStr.size() == 1) && (std::isalpha(attributeStr[attributeStr.size()-1])) ) + if ((attributeStr.size() == 1) && (std::isalpha(attributeStr[attributeStr.size() - 1]))) { attributeKinds.insert(symbol.kind); - symbol.variableAttribute = (u32_t)attributeStr[attributeStr.size()-1]; + symbol.variableAttribute = (u32_t)attributeStr[attributeStr.size() - 1]; } else { - for( char &c : attributeStr) + for (char& c : attributeStr) { - if ( std::isdigit(c) == false ) + if (std::isdigit(c) == false) { SVFUtil::errs() << SVFUtil::errMsg("\t Symbol Attribute Parse Failure :") << symbolStr << " Attribute:" << attributeStr << " (only number or single alphabet.)"; @@ -284,18 +280,18 @@ GrammarBase::Symbol GrammarBase::insertTerminalSymbol(std::string symbolStr) std::string attributeStr = extractAttributeStrFromSymbolStr(symbolStr); symbol.kind = insertTerminalKind(kindStr); - if ( attributeStr == "") return symbol; + if (attributeStr == "") return symbol; - if ( (attributeStr.size() == 1) && (std::isalpha(attributeStr[attributeStr.size()-1])) ) + if ((attributeStr.size() == 1) && (std::isalpha(attributeStr[attributeStr.size() - 1]))) { attributeKinds.insert(symbol.kind); - symbol.variableAttribute = (u32_t)attributeStr[attributeStr.size()-1]; + symbol.variableAttribute = (u32_t)attributeStr[attributeStr.size() - 1]; } else { - for( char &c : attributeStr) + for (char& c : attributeStr) { - if ( std::isdigit(c) == false ) + if (std::isdigit(c) == false) { SVFUtil::errs() << SVFUtil::errMsg("\t Symbol Attribute Parse Failure :") << symbolStr << " Attribute:" << attributeStr << " (only number or single alphabet.)"; @@ -321,19 +317,18 @@ GrammarBase::Symbol GrammarBase::insertEBNFSigns(std::string symbolStr) sign = strToKind(symbolStr); } return sign; - } void GrammarBase::insertAttribute(Kind kind, Attribute attribute) { attributeKinds.insert(kind); - if (kindToAttrsMap.find(kind)!= kindToAttrsMap.end()) + if (kindToAttrsMap.find(kind) != kindToAttrsMap.end()) { kindToAttrsMap[kind].insert(attribute); } else { - Set attrs {attribute}; + Set attrs{attribute}; kindToAttrsMap.insert(make_pair(kind, attrs)); } } @@ -356,7 +351,7 @@ void CFGrammar::dump(std::string fileName) const gramFile << "Epsilon Production:\n"; std::vector strV; - for (auto pro: this->epsilonProds) + for (auto pro : this->epsilonProds) { std::stringstream ss; for (auto sym : pro) @@ -370,7 +365,7 @@ void CFGrammar::dump(std::string fileName) const strV.insert(strV.begin(), ss.str()); } std::sort(strV.begin(), strV.end()); - for (auto pro: strV) + for (auto pro : strV) { gramFile << '\t'; gramFile << pro; @@ -380,9 +375,9 @@ void CFGrammar::dump(std::string fileName) const gramFile << "Single Production:\n"; strV = {}; - for (auto symProPair: singleRHSToProds) + for (auto symProPair : singleRHSToProds) { - for (auto pro: symProPair.second) + for (auto pro : symProPair.second) { std::stringstream ss; int i = 0; @@ -399,7 +394,7 @@ void CFGrammar::dump(std::string fileName) const } } std::sort(strV.begin(), strV.end()); - for (auto pro: strV) + for (auto pro : strV) { gramFile << '\t'; gramFile << pro; @@ -409,9 +404,9 @@ void CFGrammar::dump(std::string fileName) const gramFile << "Binary Production:\n"; strV = {}; - for (auto symProPair: firstRHSToProds) + for (auto symProPair : firstRHSToProds) { - for (auto pro: symProPair.second) + for (auto pro : symProPair.second) { std::stringstream ss; int i = 0; @@ -429,7 +424,7 @@ void CFGrammar::dump(std::string fileName) const } } std::sort(strV.begin(), strV.end()); - for (auto pro: strV) + for (auto pro : strV) { gramFile << '\t'; gramFile << pro; diff --git a/svf/lib/CFL/CFLAlias.cpp b/svf/lib/CFL/CFLAlias.cpp index 4a97ba8ff..2c9db9527 100644 --- a/svf/lib/CFL/CFLAlias.cpp +++ b/svf/lib/CFL/CFLAlias.cpp @@ -38,7 +38,7 @@ using namespace SVFUtil; */ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, CallEdgeMap& newEdges) { - for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter) + for (CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter != eiter; ++iter) { const CallICFGNode* cs = iter->first; @@ -50,7 +50,7 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges); } else - resolveIndCalls(iter->first,getCFLPts(iter->second),newEdges); + resolveIndCalls(iter->first, getCFLPts(iter->second), newEdges); } } @@ -62,12 +62,13 @@ void CFLAlias::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F) { assert(F); - DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() << " to callee " << *F << "\n"); + DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() + << " to callee " << *F << "\n"); CallICFGNode* callBlockNode = svfir->getICFG()->getCallICFGNode(cs.getInstruction()); RetICFGNode* retBlockNode = svfir->getICFG()->getRetICFGNode(cs.getInstruction()); - if(SVFUtil::isHeapAllocExtFunViaRet(F) && svfir->callsiteHasRet(retBlockNode)) + if (SVFUtil::isHeapAllocExtFunViaRet(F) && svfir->callsiteHasRet(retBlockNode)) { heapAllocatorViaIndCall(cs); } @@ -94,20 +95,20 @@ void CFLAlias::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F) // connect actual and formal param const SVFIR::SVFVarList& csArgList = svfir->getCallSiteArgsList(callBlockNode); const SVFIR::SVFVarList& funArgList = svfir->getFunArgsList(F); - //Go through the fixed parameters. + // Go through the fixed parameters. DBOUT(DPAGBuild, outs() << " args:"); SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end(); - SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end(); + SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end(); for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt) { - //Some programs (e.g. Linux kernel) leave unneeded parameters empty. - if (csArgIt == csArgEit) + // Some programs (e.g. Linux kernel) leave unneeded parameters empty. + if (csArgIt == csArgEit) { DBOUT(DAndersen, outs() << " !! not enough args\n"); break; } - const PAGNode *cs_arg = *csArgIt ; - const PAGNode *fun_arg = *funArgIt; + const PAGNode* cs_arg = *csArgIt; + const PAGNode* fun_arg = *funArgIt; if (cs_arg->isPointer() && fun_arg->isPointer()) { @@ -118,22 +119,22 @@ void CFLAlias::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F) } } - //Any remaining actual args must be varargs. + // Any remaining actual args must be varargs. if (F->isVarArg()) { NodeID vaF = svfir->getVarargNode(F); DBOUT(DPAGBuild, outs() << "\n varargs:"); for (; csArgIt != csArgEit; ++csArgIt) { - const PAGNode *cs_arg = *csArgIt; + const PAGNode* cs_arg = *csArgIt; if (cs_arg->isPointer()) { NodeID vnAA = cs_arg->getId(); - addCopyEdge(vnAA,vaF); + addCopyEdge(vnAA, vaF); } } } - if(csArgIt != csArgEit) + if (csArgIt != csArgEit) { writeWrnMsg("too many args to non-vararg func."); writeWrnMsg("(" + cs.getInstruction()->getSourceLoc() + ")"); @@ -148,7 +149,7 @@ void CFLAlias::heapAllocatorViaIndCall(CallSite cs) const PAGNode* cs_return = svfir->getCallSiteRet(retBlockNode); NodeID srcret; CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs); - if(it != callsite2DummyValPN.end()) + if (it != callsite2DummyValPN.end()) { srcret = it->second; } @@ -156,7 +157,7 @@ void CFLAlias::heapAllocatorViaIndCall(CallSite cs) { NodeID valNode = svfir->addDummyValNode(); NodeID objNode = svfir->addDummyObjNode(cs.getType()); - callsite2DummyValPN.insert(std::make_pair(cs,valNode)); + callsite2DummyValPN.insert(std::make_pair(cs, valNode)); graph->addCFLNode(valNode, new CFLNode(valNode)); graph->addCFLNode(objNode, new CFLNode(objNode)); srcret = valNode; @@ -172,13 +173,13 @@ void CFLAlias::heapAllocatorViaIndCall(CallSite cs) bool CFLAlias::updateCallGraph(const CallSiteToFunPtrMap& callsites) { CallEdgeMap newEdges; - onTheFlyCallGraphSolve(callsites,newEdges); - for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it ) + onTheFlyCallGraphSolve(callsites, newEdges); + for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it != eit; ++it) { CallSite cs = SVFUtil::getSVFCallSite(it->first->getCallSite()); - for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) + for (FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { - connectCaller2CalleeParams(cs,*cit); + connectCaller2CalleeParams(cs, *cit); } } @@ -214,15 +215,13 @@ void CFLAlias::finalize() { numOfChecks = solver->numOfChecks; - if(Options::PrintCFL() == true) + if (Options::PrintCFL() == true) { - if (Options::CFLGraph().empty()) - svfir->dump("IR"); + if (Options::CFLGraph().empty()) svfir->dump("IR"); grammar->dump("Grammar"); graph->dump("CFLGraph"); } - if (Options::CFLGraph().empty()) - PointerAnalysis::finalize(); + if (Options::CFLGraph().empty()) PointerAnalysis::finalize(); } void CFLAlias::solve() diff --git a/svf/lib/CFL/CFLBase.cpp b/svf/lib/CFL/CFLBase.cpp index 70f634b9f..70c383027 100644 --- a/svf/lib/CFL/CFLBase.cpp +++ b/svf/lib/CFL/CFLBase.cpp @@ -27,7 +27,6 @@ * Author: Pei Xu */ - #include "CFL/CFLBase.h" namespace SVF @@ -53,12 +52,12 @@ void CFLBase::checkParameter() bool pagfile = (filename.rfind("PAGGrammar.txt") == filename.length() - std::string("PAGGrammar.txt").length()); bool pegfile = (filename.rfind("PEGGrammar.txt") == filename.length() - std::string("PEGGrammar.txt").length()); bool vfgfile = (filename.rfind("VFGGrammar.txt") == filename.length() - std::string("VFGGrammar.txt").length()); - if (!Options::Customized() && !(pagfile || pegfile || vfgfile)) + if (!Options::Customized() && !(pagfile || pegfile || vfgfile)) { SVFUtil::errs() << "Invalid alias grammar file: " << Options::GrammarFilename() << "\n" << "Please use a file that ends with either 'CFGrammar.txt' or 'PEGGrammar.txt', " << "or use the -customized flag to allow custom grammar files.\n"; - assert(false && "grammar loading failed!"); // exit with error + assert(false && "grammar loading failed!"); // exit with error } } @@ -84,7 +83,7 @@ void CFLBase::buildCFLGraph() if (Options::CFLGraph().empty()) // built from svfir { PointerAnalysis::initialize(); - ConstraintGraph *consCG = new ConstraintGraph(svfir); + ConstraintGraph* consCG = new ConstraintGraph(svfir); if (Options::PEGTransfer()) graph = cflGraphBuilder.buildBiPEGgraph(consCG, grammarBase->getStartKind(), grammarBase, svfir); else @@ -150,10 +149,9 @@ CFLGraph* CFLBase::getCFLGraph() void CFLBase::countSumEdges() { numOfStartEdges = 0; - for(auto it = getCFLGraph()->getCFLEdges().begin(); it != getCFLGraph()->getCFLEdges().end(); it++ ) + for (auto it = getCFLGraph()->getCFLEdges().begin(); it != getCFLGraph()->getCFLEdges().end(); it++) { - if ((*it)->getEdgeKind() == grammar->getStartKind()) - numOfStartEdges++; + if ((*it)->getEdgeKind() == grammar->getStartKind()) numOfStartEdges++; } } diff --git a/svf/lib/CFL/CFLGraphBuilder.cpp b/svf/lib/CFL/CFLGraphBuilder.cpp index 7774f8188..c1dd657f5 100644 --- a/svf/lib/CFL/CFLGraphBuilder.cpp +++ b/svf/lib/CFL/CFLGraphBuilder.cpp @@ -51,27 +51,27 @@ void CFLGraphBuilder::addAttribute(CFGrammar::Kind kind, CFGrammar::Attribute at } /// build label and kind connect from the grammar -void CFLGraphBuilder::buildlabelToKindMap(GrammarBase *grammar) +void CFLGraphBuilder::buildlabelToKindMap(GrammarBase* grammar) { - for(auto pairV : grammar->getTerminals()) + for (auto pairV : grammar->getTerminals()) { - if(labelToKindMap.find(pairV.first) == labelToKindMap.end()) + if (labelToKindMap.find(pairV.first) == labelToKindMap.end()) { labelToKindMap.insert(pairV); } - if(kindToLabelMap.find(pairV.second) == kindToLabelMap.end()) + if (kindToLabelMap.find(pairV.second) == kindToLabelMap.end()) { kindToLabelMap.insert(make_pair(pairV.second, pairV.first)); } } - for(auto pairV : grammar->getNonterminals()) + for (auto pairV : grammar->getNonterminals()) { - if(labelToKindMap.find(pairV.first) == labelToKindMap.end()) + if (labelToKindMap.find(pairV.first) == labelToKindMap.end()) { labelToKindMap.insert(pairV); } - if(kindToLabelMap.find(pairV.second) == kindToLabelMap.end()) + if (kindToLabelMap.find(pairV.second) == kindToLabelMap.end()) { kindToLabelMap.insert(make_pair(pairV.second, pairV.first)); } @@ -82,7 +82,7 @@ void CFLGraphBuilder::buildlabelToKindMap(GrammarBase *grammar) CFLNode* CFLGraphBuilder::addGNode(u32_t NodeID) { CFLNode* cflNode; - if (cflGraph->hasGNode(NodeID)==false) + if (cflGraph->hasGNode(NodeID) == false) { cflNode = new CFLNode(NodeID); cflGraph->addCFLNode(NodeID, cflNode); @@ -94,23 +94,22 @@ CFLNode* CFLGraphBuilder::addGNode(u32_t NodeID) return cflNode; } - /// Method to build a bidirectional CFL graph by copying nodes and edges /// from any graph inherited from GenericGraph -template -CFLGraph* CFLGraphBuilder::build(GenericGraph* graph, GrammarBase *grammar, BuildDirection direction) +template +CFLGraph* CFLGraphBuilder::build(GenericGraph* graph, GrammarBase* grammar, BuildDirection direction) { cflGraph = new CFLGraph(grammar->getStartKind()); // buildlabelToKindMap(grammar); - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { CFLNode* node = new CFLNode((*it).first); cflGraph->addCFLNode((*it).first, node); } - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { N* node = (*it).second; - for(E* edge : node->getOutEdges()) + for (E* edge : node->getOutEdges()) { CFGrammar::Kind edgeLabel = edge->getEdgeKind(); cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); @@ -118,28 +117,27 @@ CFLGraph* CFLGraphBuilder::build(GenericGraph* graph, GrammarBase *grammar, { std::string label = grammar->kindToStr(edge); label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), grammar->strToKind(label)); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + grammar->strToKind(label)); } } } return cflGraph; } -CFLGraph* CFLGraphBuilder::build(std::string fileName, GrammarBase *grammar, BuildDirection direction) +CFLGraph* CFLGraphBuilder::build(std::string fileName, GrammarBase* grammar, BuildDirection direction) { bool isDot = (fileName.rfind(".dot") == fileName.length() - std::string(".dot").length()); - if (isDot) - return buildFromDot(fileName, grammar, direction); + if (isDot) return buildFromDot(fileName, grammar, direction); bool isJson = (fileName.rfind(".json") == fileName.length() - std::string(".json").length()); - if (isJson) - return buildFromJson(fileName, grammar, direction); + if (isJson) return buildFromJson(fileName, grammar, direction); return buildFromText(fileName, grammar, direction); } //// Build graph from text file -CFLGraph* CFLGraphBuilder::buildFromText(std::string fileName, GrammarBase *grammar, BuildDirection direction) +CFLGraph* CFLGraphBuilder::buildFromText(std::string fileName, GrammarBase* grammar, BuildDirection direction) { buildlabelToKindMap(grammar); cflGraph = new CFLGraph(grammar->getStartKind()); @@ -150,30 +148,28 @@ CFLGraph* CFLGraphBuilder::buildFromText(std::string fileName, GrammarBase *gram if (!inputFile.is_open()) { - SVFUtil::errs() << "Error opening " << fileName << std::endl; + SVFUtil::errs() << "Error opening " << fileName << std::endl; abort(); } std::string line; current = labelToKindMap.size(); - u32_t lineNum = 0 ; + u32_t lineNum = 0; while (getline(inputFile, line)) { std::vector vec = SVFUtil::split(line, '\t'); - if (vec.empty()) - continue; + if (vec.empty()) continue; lineNum += 1; NodeID srcID = std::stoi(vec[0]); NodeID dstID = std::stoi(vec[1]); - CFLNode *src = addGNode(srcID); - CFLNode *dst = addGNode(dstID); + CFLNode* src = addGNode(srcID); + CFLNode* dst = addGNode(dstID); std::string label = vec[2]; - if (labelToKindMap.find(label) != labelToKindMap.end()) - cflGraph->addCFLEdge(src, dst, labelToKindMap[label]); + if (labelToKindMap.find(label) != labelToKindMap.end()) cflGraph->addCFLEdge(src, dst, labelToKindMap[label]); else { - if(Options::FlexSymMap() == true) + if (Options::FlexSymMap() == true) { labelToKindMap.insert({label, current++}); cflGraph->addCFLEdge(src, dst, labelToKindMap[label]); @@ -193,7 +189,7 @@ CFLGraph* CFLGraphBuilder::buildFromText(std::string fileName, GrammarBase *gram return cflGraph; } -CFLGraph * CFLGraphBuilder::buildFromDot(std::string fileName, GrammarBase *grammar, BuildDirection direction) +CFLGraph* CFLGraphBuilder::buildFromDot(std::string fileName, GrammarBase* grammar, BuildDirection direction) { buildlabelToKindMap(grammar); cflGraph = new CFLGraph(grammar->getStartKind()); @@ -202,7 +198,7 @@ CFLGraph * CFLGraphBuilder::buildFromDot(std::string fileName, GrammarBase *gram std::cout << "Building CFL Graph from dot file: " << fileName << "..\n"; std::regex reg("Node(\\w+)\\s*->\\s*Node(\\w+)\\s*\\[.*label=(.*)\\]"); std::cout << std::boolalpha; - u32_t lineNum = 0 ; + u32_t lineNum = 0; current = labelToKindMap.size(); while (getline(inputFile, lineString)) @@ -214,13 +210,13 @@ CFLGraph * CFLGraphBuilder::buildFromDot(std::string fileName, GrammarBase *gram u32_t srcID = std::stoul(matches.str(1), nullptr, 16); u32_t dstID = std::stoul(matches.str(2), nullptr, 16); std::string label = matches.str(3); - CFLNode *src = addGNode(srcID); - CFLNode *dst = addGNode(dstID); + CFLNode* src = addGNode(srcID); + CFLNode* dst = addGNode(dstID); if (labelToKindMap.find(label) != labelToKindMap.end()) cflGraph->addCFLEdge(src, dst, labelToKindMap[label]); else { - if(Options::FlexSymMap() == true) + if (Options::FlexSymMap() == true) { labelToKindMap.insert({label, current++}); cflGraph->addCFLEdge(src, dst, labelToKindMap[label]); @@ -241,75 +237,78 @@ CFLGraph * CFLGraphBuilder::buildFromDot(std::string fileName, GrammarBase *gram } //// Build graph from json file -CFLGraph* CFLGraphBuilder::buildFromJson(std::string fileName, GrammarBase *grammar, BuildDirection direction) +CFLGraph* CFLGraphBuilder::buildFromJson(std::string fileName, GrammarBase* grammar, BuildDirection direction) { cflGraph = new CFLGraph(grammar->getStartKind()); return cflGraph; } - -CFLGraph* AliasCFLGraphBuilder::buildBigraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar) +CFLGraph* AliasCFLGraphBuilder::buildBigraph(ConstraintGraph* graph, Kind startKind, GrammarBase* grammar) { cflGraph = new CFLGraph(startKind); buildlabelToKindMap(grammar); - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { CFLNode* node = new CFLNode((*it).first); cflGraph->addCFLNode((*it).first, node); } - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { ConstraintNode* node = (*it).second; - for(ConstraintEdge* edge : node->getOutEdges()) + for (ConstraintEdge* edge : node->getOutEdges()) { CFGrammar::Kind edgeLabel = edge->getEdgeKind(); // Need to get the offset from the Const Edge // The offset present edge is only from Normal Gep CG at moment - if(NormalGepCGEdge::classof(edge)) + if (NormalGepCGEdge::classof(edge)) { - NormalGepCGEdge *nGepEdge = SVFUtil::dyn_cast(edge); - CFGrammar::Attribute attr = nGepEdge->getConstantFieldIdx(); + NormalGepCGEdge* nGepEdge = SVFUtil::dyn_cast(edge); + CFGrammar::Attribute attr = nGepEdge->getConstantFieldIdx(); addAttribute(edgeLabel, attr); edgeLabel = CFGrammar::getAttributedKind(attr, edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edge->getEdgeKind()]; - label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFGrammar::getAttributedKind(attr, labelToKindMap[label])); + label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + CFGrammar::getAttributedKind(attr, labelToKindMap[label])); addAttribute(labelToKindMap[label], attr); } else { - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edge->getEdgeKind()]; label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), labelToKindMap[label]); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + labelToKindMap[label]); } } } return cflGraph; } -CFLGraph* AliasCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar, SVFIR* pag) +CFLGraph* AliasCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph* graph, Kind startKind, GrammarBase* grammar, + SVFIR* pag) { cflGraph = new CFLGraph(startKind); buildlabelToKindMap(grammar); - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { CFLNode* node = new CFLNode((*it).first); cflGraph->addCFLNode((*it).first, node); } - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { ConstraintNode* node = (*it).second; - for(ConstraintEdge* edge : node->getOutEdges()) + for (ConstraintEdge* edge : node->getOutEdges()) { /// Process Store if (edge->getEdgeKind() == ConstraintEdge::Store) { - if (pag->isNullPtr(edge->getSrcID())) - continue; + if (pag->isNullPtr(edge->getSrcID())) continue; /// Check Dst of Store Dereference Node ConstraintNode* Dst = edge->getDstNode(); ConstraintNode* DerefNode = nullptr; @@ -336,13 +335,15 @@ CFLGraph* AliasCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph *graph, Kind sta cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), CFLDerefNode, labelToKindMap[label]); } /// Add Copy Edge - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(CFLDerefNode->getId()), ConstraintEdge::Copy); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(CFLDerefNode->getId()), + ConstraintEdge::Copy); std::string label = kindToLabelMap[ConstraintEdge::Copy]; label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(CFLDerefNode->getId()), cflGraph->getGNode(edge->getSrcID()), labelToKindMap[label]); + cflGraph->addCFLEdge(cflGraph->getGNode(CFLDerefNode->getId()), cflGraph->getGNode(edge->getSrcID()), + labelToKindMap[label]); } /// Process Load - else if ( edge->getEdgeKind() == ConstraintEdge::Load) + else if (edge->getEdgeKind() == ConstraintEdge::Load) { /// Check Src of Load Dereference Node ConstraintNode* Src = edge->getSrcNode(); @@ -368,42 +369,48 @@ CFLGraph* AliasCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph *graph, Kind sta cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), CFLDerefNode, labelToKindMap[label]); } /// Add Copy Edge - cflGraph->addCFLEdge(cflGraph->getGNode(CFLDerefNode->getId()), cflGraph->getGNode(edge->getDstID()), ConstraintEdge::Copy); + cflGraph->addCFLEdge(cflGraph->getGNode(CFLDerefNode->getId()), cflGraph->getGNode(edge->getDstID()), + ConstraintEdge::Copy); std::string label = kindToLabelMap[ConstraintEdge::Copy]; label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(CFLDerefNode->getId()), labelToKindMap[label]); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(CFLDerefNode->getId()), + labelToKindMap[label]); } - else if ( edge->getEdgeKind() == ConstraintEdge::VariantGep) + else if (edge->getEdgeKind() == ConstraintEdge::VariantGep) { /// Handle VGep normalize to Normal Gep by connecting all geps' srcs to vgep dest /// Example: In Test Case: Ctest field-ptr-arith-varIdx.c.bc /// BFS Search the 8 LEVEL up to find the ValueNode, and the number of level search is arbitrary /// the more the level search the more valueNode and the Vgep Dst will possibly connect - connectVGep(cflGraph, graph, edge->getSrcNode(), edge->getDstNode(), 8, pag); + connectVGep(cflGraph, graph, edge->getSrcNode(), edge->getDstNode(), 8, pag); } else { CFGrammar::Kind edgeLabel = edge->getEdgeKind(); // Need to get the offset from the Const Edge // The offset present edge is only from Normal Gep CG at moment - if(NormalGepCGEdge::classof(edge)) + if (NormalGepCGEdge::classof(edge)) { - NormalGepCGEdge *nGepEdge = SVFUtil::dyn_cast(edge); - CFGrammar::Attribute attr = nGepEdge->getConstantFieldIdx(); + NormalGepCGEdge* nGepEdge = SVFUtil::dyn_cast(edge); + CFGrammar::Attribute attr = nGepEdge->getConstantFieldIdx(); addAttribute(edgeLabel, attr); edgeLabel = CFGrammar::getAttributedKind(attr, edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edge->getEdgeKind()]; - label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFGrammar::getAttributedKind(attr, labelToKindMap[label])); + label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + CFGrammar::getAttributedKind(attr, labelToKindMap[label])); addAttribute(labelToKindMap[label], attr); } else { - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edge->getEdgeKind()]; label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), labelToKindMap[label]); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + labelToKindMap[label]); } } } @@ -411,14 +418,16 @@ CFLGraph* AliasCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph *graph, Kind sta return cflGraph; } -void AliasCFLGraphBuilder::AliasCFLGraphBuilder::connectVGep(CFLGraph *cflGraph, ConstraintGraph *graph, ConstraintNode *src, ConstraintNode *dst, u32_t level, SVFIR* pag) +void AliasCFLGraphBuilder::AliasCFLGraphBuilder::connectVGep(CFLGraph* cflGraph, ConstraintGraph* graph, + ConstraintNode* src, ConstraintNode* dst, u32_t level, + SVFIR* pag) { if (level == 0) return; level -= 1; for (auto eit = src->getAddrInEdges().begin(); eit != src->getAddrInEdges().end(); eit++) { const MemObj* mem = pag->getBaseObj((*eit)->getSrcID()); - for (u32_t maxField = 0 ; maxField < mem->getNumOfElements(); maxField++) + for (u32_t maxField = 0; maxField < mem->getNumOfElements(); maxField++) { addBiGepCFLEdge(cflGraph, (*eit)->getDstNode(), dst, maxField); } @@ -430,7 +439,8 @@ void AliasCFLGraphBuilder::AliasCFLGraphBuilder::connectVGep(CFLGraph *cflGraph, return; } -void AliasCFLGraphBuilder::addBiCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Kind kind) +void AliasCFLGraphBuilder::addBiCFLEdge(CFLGraph* cflGraph, ConstraintNode* src, ConstraintNode* dst, + CFGrammar::Kind kind) { cflGraph->addCFLEdge(cflGraph->getGNode(src->getId()), cflGraph->getGNode(dst->getId()), kind); std::string label = kindToLabelMap[kind]; @@ -439,96 +449,110 @@ void AliasCFLGraphBuilder::addBiCFLEdge(CFLGraph *cflGraph, ConstraintNode* src return; } -void AliasCFLGraphBuilder::addBiGepCFLEdge(CFLGraph *cflGraph, ConstraintNode* src, ConstraintNode* dst, CFGrammar::Attribute attri) +void AliasCFLGraphBuilder::addBiGepCFLEdge(CFLGraph* cflGraph, ConstraintNode* src, ConstraintNode* dst, + CFGrammar::Attribute attri) { CFLEdge::GEdgeFlag edgeLabel = CFGrammar::getAttributedKind(attri, ConstraintEdge::NormalGep); cflGraph->addCFLEdge(cflGraph->getGNode(src->getId()), cflGraph->getGNode(dst->getId()), edgeLabel); std::string label = kindToLabelMap[ConstraintEdge::NormalGep]; label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(dst->getId()), cflGraph->getGNode(src->getId()), CFGrammar::getAttributedKind(attri, labelToKindMap[label])); + cflGraph->addCFLEdge(cflGraph->getGNode(dst->getId()), cflGraph->getGNode(src->getId()), + CFGrammar::getAttributedKind(attri, labelToKindMap[label])); return; } -CFLGraph* VFCFLGraphBuilder::buildBigraph(SVFG *graph, Kind startKind, GrammarBase *grammar) +CFLGraph* VFCFLGraphBuilder::buildBigraph(SVFG* graph, Kind startKind, GrammarBase* grammar) { cflGraph = new CFLGraph(startKind); buildlabelToKindMap(grammar); - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { CFLNode* node = new CFLNode((*it).first); cflGraph->addCFLNode((*it).first, node); } - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { VFGNode* node = (*it).second; - for(VFGEdge* edge : node->getOutEdges()) + for (VFGEdge* edge : node->getOutEdges()) { CFGrammar::Kind edgeLabel; // Get 'a' edge : IntraDirectVF || IntraIndirectVF - if (edge->getEdgeKind() == VFGEdge::IntraDirectVF || edge->getEdgeKind() == VFGEdge::IntraIndirectVF || edge->getEdgeKind() == VFGEdge::TheadMHPIndirectVF ) + if (edge->getEdgeKind() == VFGEdge::IntraDirectVF || edge->getEdgeKind() == VFGEdge::IntraIndirectVF || + edge->getEdgeKind() == VFGEdge::TheadMHPIndirectVF) { edgeLabel = 0; - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edge->getEdgeKind()]; label.append("bar"); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), labelToKindMap[label]); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + labelToKindMap[label]); } // Get 'call' edge : CallDirVF || CallIndVF - else if ( edge->getEdgeKind() == VFGEdge::CallDirVF ) + else if (edge->getEdgeKind() == VFGEdge::CallDirVF) { edgeLabel = 1; - CallDirSVFGEdge *attributedEdge = SVFUtil::dyn_cast(edge); - CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); + CallDirSVFGEdge* attributedEdge = SVFUtil::dyn_cast(edge); + CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); addAttribute(edgeLabel, attr); edgeLabel = CFGrammar::getAttributedKind(attr, edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edgeLabel]; - label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFGrammar::getAttributedKind(attr, labelToKindMap[label])); + label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + CFGrammar::getAttributedKind(attr, labelToKindMap[label])); addAttribute(labelToKindMap[label], attr); } // Get 'call' edge : CallIndVF - else if ( edge->getEdgeKind() == VFGEdge::CallIndVF ) + else if (edge->getEdgeKind() == VFGEdge::CallIndVF) { edgeLabel = 1; - CallIndSVFGEdge *attributedEdge = SVFUtil::dyn_cast(edge); - CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); + CallIndSVFGEdge* attributedEdge = SVFUtil::dyn_cast(edge); + CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); addAttribute(edgeLabel, attr); edgeLabel = CFGrammar::getAttributedKind(attr, edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edgeLabel]; - label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFGrammar::getAttributedKind(attr, labelToKindMap[label])); + label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + CFGrammar::getAttributedKind(attr, labelToKindMap[label])); addAttribute(labelToKindMap[label], attr); } // Get 'ret' edge : RetDirVF - else if ( edge->getEdgeKind() == VFGEdge::RetDirVF ) + else if (edge->getEdgeKind() == VFGEdge::RetDirVF) { edgeLabel = 2; - RetDirSVFGEdge *attributedEdge = SVFUtil::dyn_cast(edge); - CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); + RetDirSVFGEdge* attributedEdge = SVFUtil::dyn_cast(edge); + CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); addAttribute(edgeLabel, attr); edgeLabel = CFGrammar::getAttributedKind(attr, edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edgeLabel]; - label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFGrammar::getAttributedKind(attr, labelToKindMap[label])); + label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + CFGrammar::getAttributedKind(attr, labelToKindMap[label])); addAttribute(labelToKindMap[label], attr); } // Get 'ret' edge : RetIndVF - else if ( edge->getEdgeKind() == VFGEdge::RetIndVF ) + else if (edge->getEdgeKind() == VFGEdge::RetIndVF) { edgeLabel = 2; - RetIndSVFGEdge *attributedEdge = SVFUtil::dyn_cast(edge); - CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); + RetIndSVFGEdge* attributedEdge = SVFUtil::dyn_cast(edge); + CFGrammar::Attribute attr = attributedEdge->getCallSiteId(); addAttribute(edgeLabel, attr); edgeLabel = CFGrammar::getAttributedKind(attr, edgeLabel); - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), edgeLabel); + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getSrcID()), cflGraph->getGNode(edge->getDstID()), + edgeLabel); std::string label = kindToLabelMap[edgeLabel]; - label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar - cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), CFGrammar::getAttributedKind(attr, labelToKindMap[label])); + label.append("bar"); // for example Gep_i should be Gepbar_i, not Gep_ibar + cflGraph->addCFLEdge(cflGraph->getGNode(edge->getDstID()), cflGraph->getGNode(edge->getSrcID()), + CFGrammar::getAttributedKind(attr, labelToKindMap[label])); addAttribute(labelToKindMap[label], attr); } } @@ -536,11 +560,10 @@ CFLGraph* VFCFLGraphBuilder::buildBigraph(SVFG *graph, Kind startKind, GrammarBa return cflGraph; } -CFLGraph* VFCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph *graph, Kind startKind, GrammarBase *grammar, SVFIR* pag) +CFLGraph* VFCFLGraphBuilder::buildBiPEGgraph(ConstraintGraph* graph, Kind startKind, GrammarBase* grammar, SVFIR* pag) { - CFLGraph *cflGraph = new CFLGraph(startKind); + CFLGraph* cflGraph = new CFLGraph(startKind); return cflGraph; } - -} // end of SVF namespace +} // namespace SVF diff --git a/svf/lib/CFL/CFLSVFGBuilder.cpp b/svf/lib/CFL/CFLSVFGBuilder.cpp index a5f823f24..fe11f2a48 100644 --- a/svf/lib/CFL/CFLSVFGBuilder.cpp +++ b/svf/lib/CFL/CFLSVFGBuilder.cpp @@ -28,7 +28,6 @@ #include "Util/Options.h" #include "CFL/CFLSVFGBuilder.h" - using namespace SVF; using namespace SVFUtil; @@ -52,11 +51,9 @@ void CFLSVFGBuilder::buildSVFG() AddExtActualParmSVFGNodes(pta->getCallGraph()); - if(pta->printStat()) - svfg->performStat(); + if (pta->printStat()) svfg->performStat(); } - /*! * Remove Incoming Edge for strong-update (SU) store instruction * Because the SU node does not receive indirect value @@ -70,26 +67,27 @@ void CFLSVFGBuilder::buildSVFG() void CFLSVFGBuilder::rmIncomingEdgeForSUStore(BVDataPTAImpl* pta) { - for(SVFG::iterator it = svfg->begin(), eit = svfg->end(); it!=eit; ++it) + for (SVFG::iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it) { const SVFGNode* node = it->second; - if(const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { - if(SVFUtil::isa(stmtNode->getPAGEdge())) + if (SVFUtil::isa(stmtNode->getPAGEdge())) { NodeID singleton; - if(isStrongUpdate(node, singleton, pta)) + if (isStrongUpdate(node, singleton, pta)) { Set toRemove; - for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; ++it2) + for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; + ++it2) { if ((*it2)->isIndirectVFGEdge()) { toRemove.insert(*it2); } } - for (SVFGEdge* edge: toRemove) + for (SVFGEdge* edge : toRemove) { svfg->removeSVFGEdge(edge); } diff --git a/svf/lib/CFL/CFLSolver.cpp b/svf/lib/CFL/CFLSolver.cpp index c9ba1355d..c028a7e58 100644 --- a/svf/lib/CFL/CFLSolver.cpp +++ b/svf/lib/CFL/CFLSolver.cpp @@ -35,9 +35,9 @@ double CFLSolver::numOfChecks = 0; void CFLSolver::initialize() { - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { - for(const CFLEdge* edge : (*it).second->getOutEdges()) + for (const CFLEdge* edge : (*it).second->getOutEdges()) { pushIntoWorklist(edge); } @@ -45,13 +45,13 @@ void CFLSolver::initialize() /// Foreach production X -> epsilon /// add X(i,i) if not exist to E and to worklist - for(const Production& prod : grammar->getEpsilonProds()) + for (const Production& prod : grammar->getEpsilonProds()) { - for(auto it = graph->begin(); it!= graph->end(); it++) + for (auto it = graph->begin(); it != graph->end(); it++) { Symbol X = grammar->getLHSSymbol(prod); CFLNode* i = (*it).second; - if(const CFLEdge* edge = graph->addCFLEdge(i, i, X)) + if (const CFLEdge* edge = graph->addCFLEdge(i, i, X)) { pushIntoWorklist(edge); } @@ -68,11 +68,11 @@ void CFLSolver::processCFLEdge(const CFLEdge* Y_edge) /// add X(i,j) if not exist to E and to worklist Symbol Y = Y_edge->getEdgeKind(); if (grammar->hasProdsFromSingleRHS(Y)) - for(const Production& prod : grammar->getProdsFromSingleRHS(Y)) + for (const Production& prod : grammar->getProdsFromSingleRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); numOfChecks++; - if(const CFLEdge* newEdge = graph->addCFLEdge(i, j, X)) + if (const CFLEdge* newEdge = graph->addCFLEdge(i, j, X)) { pushIntoWorklist(newEdge); } @@ -82,14 +82,14 @@ void CFLSolver::processCFLEdge(const CFLEdge* Y_edge) /// Foreach outgoing edge Z(j,k) from node j do /// add X(i,k) if not exist to E and to worklist if (grammar->hasProdsFromFirstRHS(Y)) - for(const Production& prod : grammar->getProdsFromFirstRHS(Y)) + for (const Production& prod : grammar->getProdsFromFirstRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); - for(const CFLEdge* Z_edge : j->getOutEdgeWithTy(grammar->getSecondRHSSymbol(prod))) + for (const CFLEdge* Z_edge : j->getOutEdgeWithTy(grammar->getSecondRHSSymbol(prod))) { CFLNode* k = Z_edge->getDstNode(); numOfChecks++; - if(const CFLEdge* newEdge = graph->addCFLEdge(i, k, X)) + if (const CFLEdge* newEdge = graph->addCFLEdge(i, k, X)) { pushIntoWorklist(newEdge); } @@ -99,15 +99,15 @@ void CFLSolver::processCFLEdge(const CFLEdge* Y_edge) /// For each production X -> Z Y /// Foreach incoming edge Z(k,i) to node i do /// add X(k,j) if not exist to E and to worklist - if(grammar->hasProdsFromSecondRHS(Y)) - for(const Production& prod : grammar->getProdsFromSecondRHS(Y)) + if (grammar->hasProdsFromSecondRHS(Y)) + for (const Production& prod : grammar->getProdsFromSecondRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); - for(const CFLEdge* Z_edge : i->getInEdgeWithTy(grammar->getFirstRHSSymbol(prod))) + for (const CFLEdge* Z_edge : i->getInEdgeWithTy(grammar->getFirstRHSSymbol(prod))) { CFLNode* k = Z_edge->getSrcNode(); numOfChecks++; - if(const CFLEdge* newEdge = graph->addCFLEdge(k, j, X)) + if (const CFLEdge* newEdge = graph->addCFLEdge(k, j, X)) { pushIntoWorklist(newEdge); } @@ -115,13 +115,12 @@ void CFLSolver::processCFLEdge(const CFLEdge* Y_edge) } } - void CFLSolver::solve() { /// initial worklist initialize(); - while(!isWorklistEmpty()) + while (!isWorklistEmpty()) { /// Select and remove an edge Y(i,j) from worklist const CFLEdge* Y_edge = popFromWorklist(); @@ -131,8 +130,7 @@ void CFLSolver::solve() void POCRSolver::buildCFLData() { - for (CFLEdge* edge: graph->getCFLEdges()) - addEdge(edge->getSrcID(), edge->getDstID(), edge->getEdgeKind()); + for (CFLEdge* edge : graph->getCFLEdges()) addEdge(edge->getSrcID(), edge->getDstID(), edge->getEdgeKind()); } void POCRSolver::processCFLEdge(const CFLEdge* Y_edge) @@ -144,7 +142,7 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge) /// add X(i,j) if not exist to E and to worklist Symbol Y = Y_edge->getEdgeKind(); if (grammar->hasProdsFromSingleRHS(Y)) - for(const Production& prod : grammar->getProdsFromSingleRHS(Y)) + for (const Production& prod : grammar->getProdsFromSingleRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); numOfChecks++; @@ -153,19 +151,18 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge) const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X); pushIntoWorklist(newEdge); } - } /// For each production X -> Y Z /// Foreach outgoing edge Z(j,k) from node j do /// add X(i,k) if not exist to E and to worklist if (grammar->hasProdsFromFirstRHS(Y)) - for(const Production& prod : grammar->getProdsFromFirstRHS(Y)) + for (const Production& prod : grammar->getProdsFromFirstRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); NodeBS diffDsts = addEdges(i->getId(), getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X); numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count(); - for (NodeID diffDst: diffDsts) + for (NodeID diffDst : diffDsts) { const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X); pushIntoWorklist(newEdge); @@ -175,13 +172,13 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge) /// For each production X -> Z Y /// Foreach incoming edge Z(k,i) to node i do /// add X(k,j) if not exist to E and to worklist - if(grammar->hasProdsFromSecondRHS(Y)) - for(const Production& prod : grammar->getProdsFromSecondRHS(Y)) + if (grammar->hasProdsFromSecondRHS(Y)) + for (const Production& prod : grammar->getProdsFromSecondRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X); numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count(); - for (NodeID diffSrc: diffSrcs) + for (NodeID diffSrc : diffSrcs) { const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X); pushIntoWorklist(newEdge); @@ -191,16 +188,16 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge) void POCRSolver::initialize() { - for(auto edge : graph->getCFLEdges()) + for (auto edge : graph->getCFLEdges()) { pushIntoWorklist(edge); } /// Foreach production X -> epsilon /// add X(i,i) if not exist to E and to worklist - for(const Production& prod : grammar->getEpsilonProds()) + for (const Production& prod : grammar->getEpsilonProds()) { - for(auto IDMap : getSuccMap()) + for (auto IDMap : getSuccMap()) { Symbol X = grammar->getLHSSymbol(prod); if (addEdge(IDMap.first, IDMap.first, X)) @@ -222,7 +219,7 @@ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge) /// add X(i,j) if not exist to E and to worklist Symbol Y = Y_edge->getEdgeKind(); if (grammar->hasProdsFromSingleRHS(Y)) - for(const Production& prod : grammar->getProdsFromSingleRHS(Y)) + for (const Production& prod : grammar->getProdsFromSingleRHS(Y)) { Symbol X = grammar->getLHSSymbol(prod); numOfChecks++; @@ -231,16 +228,16 @@ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge) const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X); pushIntoWorklist(newEdge); } - } /// For each production X -> Y Z /// Foreach outgoing edge Z(j,k) from node j do /// add X(i,k) if not exist to E and to worklist if (grammar->hasProdsFromFirstRHS(Y)) - for(const Production& prod : grammar->getProdsFromFirstRHS(Y)) + for (const Production& prod : grammar->getProdsFromFirstRHS(Y)) { - if ((grammar->getLHSSymbol(prod) == grammar->strToSymbol("F")) && (Y == grammar->strToSymbol("F")) && (grammar->getSecondRHSSymbol(prod) == grammar->strToSymbol("F"))) + if ((grammar->getLHSSymbol(prod) == grammar->strToSymbol("F")) && (Y == grammar->strToSymbol("F")) && + (grammar->getSecondRHSSymbol(prod) == grammar->strToSymbol("F"))) { addArc(i->getId(), j->getId()); } @@ -249,7 +246,7 @@ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge) Symbol X = grammar->getLHSSymbol(prod); NodeBS diffDsts = addEdges(i->getId(), getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X); numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count(); - for (NodeID diffDst: diffDsts) + for (NodeID diffDst : diffDsts) { const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X); pushIntoWorklist(newEdge); @@ -260,10 +257,11 @@ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge) /// For each production X -> Z Y /// Foreach incoming edge Z(k,i) to node i do /// add X(k,j) if not exist to E and to worklist - if(grammar->hasProdsFromSecondRHS(Y)) - for(const Production& prod : grammar->getProdsFromSecondRHS(Y)) + if (grammar->hasProdsFromSecondRHS(Y)) + for (const Production& prod : grammar->getProdsFromSecondRHS(Y)) { - if ((grammar->getLHSSymbol(prod) == grammar->strToSymbol("F")) && (Y == grammar->strToSymbol("F")) && (grammar->getFirstRHSSymbol(prod) == grammar->strToSymbol("F"))) + if ((grammar->getLHSSymbol(prod) == grammar->strToSymbol("F")) && (Y == grammar->strToSymbol("F")) && + (grammar->getFirstRHSSymbol(prod) == grammar->strToSymbol("F"))) { addArc(i->getId(), j->getId()); } @@ -272,7 +270,7 @@ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge) Symbol X = grammar->getLHSSymbol(prod); NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X); numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count(); - for (NodeID diffSrc: diffSrcs) + for (NodeID diffSrc : diffSrcs) { const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X); pushIntoWorklist(newEdge); @@ -283,7 +281,7 @@ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge) void POCRHybridSolver::initialize() { - for(auto edge : graph->getCFLEdges()) + for (auto edge : graph->getCFLEdges()) { pushIntoWorklist(edge); } @@ -296,9 +294,9 @@ void POCRHybridSolver::initialize() } /// add X(i,i) if not exist to E and to worklist - for(const Production& prod : grammar->getEpsilonProds()) + for (const Production& prod : grammar->getEpsilonProds()) { - for(auto IDMap : getSuccMap()) + for (auto IDMap : getSuccMap()) { Symbol X = grammar->getLHSSymbol(prod); if (addEdge(IDMap.first, IDMap.first, X)) @@ -313,26 +311,23 @@ void POCRHybridSolver::initialize() void POCRHybridSolver::addArc(NodeID src, NodeID dst) { - if(hasEdge(src, dst, grammar->strToSymbol("F"))) - return; + if (hasEdge(src, dst, grammar->strToSymbol("F"))) return; - for (auto& iter: indMap[src]) + for (auto& iter : indMap[src]) { meld(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst)); } } - void POCRHybridSolver::meld(NodeID x, TreeNode* uNode, TreeNode* vNode) { numOfChecks++; TreeNode* newVNode = addInd_h(x, vNode->id); - if (!newVNode) - return; + if (!newVNode) return; insertEdge_h(uNode, newVNode); - for (TreeNode* vChild: vNode->children) + for (TreeNode* vChild : vNode->children) { meld_h(x, newVNode, vChild); } @@ -341,8 +336,7 @@ void POCRHybridSolver::meld(NodeID x, TreeNode* uNode, TreeNode* vNode) bool POCRHybridSolver::hasInd_h(NodeID src, NodeID dst) { auto it = indMap.find(dst); - if (it == indMap.end()) - return false; + if (it == indMap.end()) return false; return (it->second.find(src) != it->second.end()); } @@ -350,8 +344,7 @@ POCRHybridSolver::TreeNode* POCRHybridSolver::addInd_h(NodeID src, NodeID dst) { TreeNode* newNode = new TreeNode(dst); auto resIns = indMap[dst].insert(std::make_pair(src, newNode)); - if (resIns.second) - return resIns.first->second; + if (resIns.second) return resIns.first->second; delete newNode; return nullptr; } @@ -360,7 +353,7 @@ void POCRHybridSolver::addArc_h(NodeID src, NodeID dst) { if (!hasInd_h(src, dst)) { - for (auto iter: indMap[src]) + for (auto iter : indMap[src]) { meld_h(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst)); } @@ -370,11 +363,10 @@ void POCRHybridSolver::addArc_h(NodeID src, NodeID dst) void POCRHybridSolver::meld_h(NodeID x, TreeNode* uNode, TreeNode* vNode) { TreeNode* newVNode = addInd_h(x, vNode->id); - if (!newVNode) - return; + if (!newVNode) return; insertEdge_h(uNode, newVNode); - for (TreeNode* vChild: vNode->children) + for (TreeNode* vChild : vNode->children) { meld_h(x, newVNode, vChild); } diff --git a/svf/lib/CFL/CFLStat.cpp b/svf/lib/CFL/CFLStat.cpp index c4d3ac11d..c28af6558 100644 --- a/svf/lib/CFL/CFLStat.cpp +++ b/svf/lib/CFL/CFLStat.cpp @@ -36,7 +36,7 @@ using namespace std; /*! * Constructor */ -CFLStat::CFLStat(CFLBase* p): PTAStat(p),pta(p) +CFLStat::CFLStat(CFLBase* p) : PTAStat(p), pta(p) { startClk(); } @@ -44,7 +44,7 @@ CFLStat::CFLStat(CFLBase* p): PTAStat(p),pta(p) /*! * Collect CFLGraph information */ -void CFLStat::CFLGraphStat() +void CFLStat::CFLGraphStat() { pta->countSumEdges(); CFLGraph* CFLGraph = pta->getCFLGraph(); @@ -94,4 +94,3 @@ void CFLStat::performStat() // Stat about Call graph and General stat PTAStat::performStat(); } - diff --git a/svf/lib/CFL/CFLVF.cpp b/svf/lib/CFL/CFLVF.cpp index 5af9ec1fd..66d89dd1d 100644 --- a/svf/lib/CFL/CFLVF.cpp +++ b/svf/lib/CFL/CFLVF.cpp @@ -40,7 +40,7 @@ void CFLVF::buildCFLGraph() { PointerAnalysis::initialize(); AndersenWaveDiff* ander = AndersenWaveDiff::createAndersenWaveDiff(pag); - svfg = memSSA.buildFullSVFG(ander); + svfg = memSSA.buildFullSVFG(ander); graph = cflGraphBuilder.buildBigraph(svfg, grammarBase->getStartKind(), grammarBase); } else @@ -74,22 +74,20 @@ void CFLVF::checkParameter() // Check for valid grammar file before parsing other options std::string filename = Options::GrammarFilename(); bool vfgfile = (filename.rfind("VFGGrammar.txt") == filename.length() - std::string("VFGGrammar.txt").length()); - if (!Options::Customized() && !vfgfile) + if (!Options::Customized() && !vfgfile) { SVFUtil::errs() << "Invalid VFG grammar file: " << Options::GrammarFilename() << "\n" << "Please use a file that ends with 'VFG.txt', " << "or use the -customized flag to allow custom grammar files.\n"; - assert(false && "grammar loading failed!"); // exit with error + assert(false && "grammar loading failed!"); // exit with error } } - void CFLVF::finalize() { - if(Options::PrintCFL()) + if (Options::PrintCFL()) { - if (Options::CFLGraph().empty()) - svfir->dump("IR"); + if (Options::CFLGraph().empty()) svfir->dump("IR"); grammar->dump("Grammar"); graph->dump("CFLGraph"); } diff --git a/svf/lib/CFL/GrammarBuilder.cpp b/svf/lib/CFL/GrammarBuilder.cpp index a59d247be..da9c6aa35 100644 --- a/svf/lib/CFL/GrammarBuilder.cpp +++ b/svf/lib/CFL/GrammarBuilder.cpp @@ -52,16 +52,18 @@ const inline std::string GrammarBuilder::parseProductionsString() const int lineNum = 0; while (getline(textFile, lineString)) { - if(lineNum == 1) + if (lineNum == 1) { startString = stripSpace(lineString); } - if(lineNum == 3) + if (lineNum == 3) { - symbolString = lineString.substr(lineString.find_first_not_of(WHITESPACE), lineString.find_last_not_of(WHITESPACE)+1); + symbolString = lineString.substr(lineString.find_first_not_of(WHITESPACE), + lineString.find_last_not_of(WHITESPACE) + 1); } - lines.append(lineString.substr(lineString.find_first_not_of(WHITESPACE), lineString.find_last_not_of(WHITESPACE)+1)); + lines.append( + lineString.substr(lineString.find_first_not_of(WHITESPACE), lineString.find_last_not_of(WHITESPACE) + 1)); lineNum++; } @@ -76,7 +78,7 @@ const inline std::string GrammarBuilder::parseProductionsString() const while ((pos = symbolString.find(" ")) != std::string::npos) { sString = stripSpace(symbolString.substr(0, pos)); - symbolString.erase(0, pos + 1); //Capital is Nonterminal, Otherwise is terminal + symbolString.erase(0, pos + 1); // Capital is Nonterminal, Otherwise is terminal grammar->insertSymbol(sString); } grammar->insertSymbol(symbolString); @@ -110,7 +112,6 @@ const inline std::string GrammarBuilder::stripSpace(std::string s) const return matches.str(1); } - /// build grammarbase from textfile GrammarBase* GrammarBuilder::build() const { @@ -130,14 +131,15 @@ GrammarBase* GrammarBuilder::build() const std::string LHS = wordProd.substr(pos + delimiter1.size(), wordProd.size() - 1); GrammarBase::Symbol RHSSymbol = grammar->insertSymbol(RHS); prod.push_back(RHSSymbol); - if (grammar->getRawProductions().find(RHSSymbol) == grammar->getRawProductions().end()) grammar->getRawProductions().insert({RHSSymbol, {}}); + if (grammar->getRawProductions().find(RHSSymbol) == grammar->getRawProductions().end()) + grammar->getRawProductions().insert({RHSSymbol, {}}); std::regex LHSRegEx("\\s*(.*)"); std::regex_search(LHS, matches, LHSRegEx); LHS = matches.str(1); while ((pos = LHS.find(delimiter)) != std::string::npos) { word = LHS.substr(0, pos); - LHS.erase(0, pos + delimiter.length()); //Capital is Nonterminal, Otherwise is terminal + LHS.erase(0, pos + delimiter.length()); // Capital is Nonterminal, Otherwise is terminal prod.push_back(grammar->insertSymbol(word)); } prod.push_back(grammar->insertSymbol(LHS)); @@ -149,4 +151,4 @@ GrammarBase* GrammarBuilder::build() const return grammar; }; -} +} // namespace SVF diff --git a/svf/lib/DDA/ContextDDA.cpp b/svf/lib/DDA/ContextDDA.cpp index 9bf962809..74e8ebc43 100644 --- a/svf/lib/DDA/ContextDDA.cpp +++ b/svf/lib/DDA/ContextDDA.cpp @@ -39,8 +39,8 @@ using namespace SVFUtil; /*! * Constructor */ -ContextDDA::ContextDDA(SVFIR* _pag, DDAClient* client) - : CondPTAImpl(_pag, PointerAnalysis::Cxt_DDA),DDAVFSolver(), +ContextDDA::ContextDDA(SVFIR* _pag, DDAClient* client) + : CondPTAImpl(_pag, PointerAnalysis::Cxt_DDA), DDAVFSolver(), _client(client) { flowDDA = new FlowDDA(_pag, client); @@ -51,8 +51,7 @@ ContextDDA::ContextDDA(SVFIR* _pag, DDAClient* client) */ ContextDDA::~ContextDDA() { - if(flowDDA) - delete flowDDA; + if (flowDDA) delete flowDDA; flowDDA = nullptr; } @@ -88,14 +87,12 @@ const CxtPtSet& ContextDDA::computeDDAPts(const CxtVar& var) DOTIMESTAT(ddaStat->_AnaTimePerQuery = DDAStat::getClk(true) - start); DOTIMESTAT(ddaStat->_TotalTimeOfQueries += ddaStat->_AnaTimePerQuery); - if(isOutOfBudgetQuery() == false) - unionPts(var,cpts); + if (isOutOfBudgetQuery() == false) unionPts(var, cpts); else handleOutOfBudgetDpm(dpm); - if (this->printStat()) - DOSTAT(stat->performStatPerQuery(id)); - DBOUT(DGENERAL, stat->printStatPerQuery(id,getBVPointsTo(getPts(var)))); + if (this->printStat()) DOSTAT(stat->performStatPerQuery(id)); + DBOUT(DGENERAL, stat->printStatPerQuery(id, getBVPointsTo(getPts(var)))); return this->getPts(var); } @@ -115,18 +112,18 @@ void ContextDDA::computeDDAPts(NodeID id) void ContextDDA::handleOutOfBudgetDpm(const CxtLocDPItem& dpm) { - DBOUT(DGENERAL,outs() << "~~~Out of budget query, downgrade to flow sensitive analysis \n"); + DBOUT(DGENERAL, outs() << "~~~Out of budget query, downgrade to flow sensitive analysis \n"); flowDDA->computeDDAPts(dpm.getCurNodeID()); const PointsTo& flowPts = flowDDA->getPts(dpm.getCurNodeID()); CxtPtSet cxtPts; - for(PointsTo::iterator it = flowPts.begin(), eit = flowPts.end(); it!=eit; ++it) + for (PointsTo::iterator it = flowPts.begin(), eit = flowPts.end(); it != eit; ++it) { ContextCond cxt; CxtVar var(cxt, *it); cxtPts.set(var); } - updateCachedPointsTo(dpm,cxtPts); - unionPts(dpm.getCondVar(),cxtPts); + updateCachedPointsTo(dpm, cxtPts); + unionPts(dpm.getCondVar(), cxtPts); addOutOfBudgetDpm(dpm); } @@ -135,15 +132,13 @@ void ContextDDA::handleOutOfBudgetDpm(const CxtLocDPItem& dpm) */ bool ContextDDA::isCondCompatible(const ContextCond& cxt1, const ContextCond& cxt2, bool singleton) const { - if(singleton) - return true; + if (singleton) return true; int i = cxt1.cxtSize() - 1; int j = cxt2.cxtSize() - 1; - for(; i >= 0 && j>=0; i--, j--) + for (; i >= 0 && j >= 0; i--, j--) { - if(cxt1[i] != cxt2[j]) - return false; + if (cxt1[i] != cxt2[j]) return false; } return true; } @@ -158,21 +153,20 @@ CxtPtSet ContextDDA::processGepPts(const GepSVFGNode* gep, const CxtPtSet& srcPt { CxtVar ptd = *piter; - if (isBlkObjOrConstantObj(ptd.get_id())) - tmpDstPts.set(ptd); + if (isBlkObjOrConstantObj(ptd.get_id())) tmpDstPts.set(ptd); else { const GepStmt* gepStmt = SVFUtil::cast(gep->getPAGEdge()); if (gepStmt->isVariantFieldGep()) { setObjFieldInsensitive(ptd.get_id()); - CxtVar var(ptd.get_cond(),getFIObjVar(ptd.get_id())); + CxtVar var(ptd.get_cond(), getFIObjVar(ptd.get_id())); tmpDstPts.set(var); } else { - CxtVar var(ptd.get_cond(),getGepObjVar(ptd.get_id(), - gepStmt->getAccessPath().getConstantStructFldIdx())); + CxtVar var(ptd.get_cond(), + getGepObjVar(ptd.get_id(), gepStmt->getAccessPath().getConstantStructFldIdx())); tmpDstPts.set(var); } } @@ -188,15 +182,14 @@ CxtPtSet ContextDDA::processGepPts(const GepSVFGNode* gep, const CxtPtSet& srcPt bool ContextDDA::testIndCallReachability(CxtLocDPItem& dpm, const SVFFunction* callee, const CallICFGNode* cs) { - if(getPAG()->isIndirectCallSites(cs)) + if (getPAG()->isIndirectCallSites(cs)) { NodeID id = getPAG()->getFunPtr(cs); PAGNode* node = getPAG()->getGNode(id); CxtVar funptrVar(dpm.getCondVar().get_cond(), id); - CxtLocDPItem funptrDpm = getDPIm(funptrVar,getDefSVFGNode(node)); + CxtLocDPItem funptrDpm = getDPIm(funptrVar, getDefSVFGNode(node)); PointsTo pts = getBVPointsTo(findPT(funptrDpm)); - if(pts.test(getPAG()->getObjectNode(callee))) - return true; + if (pts.test(getPAG()->getObjectNode(callee))) return true; else return false; } @@ -219,9 +212,9 @@ CallSiteID ContextDDA::getCSIDAtCall(CxtLocDPItem&, const SVFGEdge* edge) const CallICFGNode* cbn = getSVFG()->getCallSite(svfg_csId); const SVFFunction* callee = edge->getDstNode()->getFun(); - if(getCallGraph()->hasCallSiteID(cbn,callee)) + if (getCallGraph()->hasCallSiteID(cbn, callee)) { - return getCallGraph()->getCallSiteID(cbn,callee); + return getCallGraph()->getCallSiteID(cbn, callee); } return 0; @@ -235,23 +228,21 @@ CallSiteID ContextDDA::getCSIDAtRet(CxtLocDPItem&, const SVFGEdge* edge) { CallSiteID svfg_csId = 0; - if (const RetDirSVFGEdge* retEdge = SVFUtil::dyn_cast(edge)) - svfg_csId = retEdge->getCallSiteId(); + if (const RetDirSVFGEdge* retEdge = SVFUtil::dyn_cast(edge)) svfg_csId = retEdge->getCallSiteId(); else svfg_csId = SVFUtil::cast(edge)->getCallSiteId(); const CallICFGNode* cbn = getSVFG()->getCallSite(svfg_csId); const SVFFunction* callee = edge->getSrcNode()->getFun(); - if(getCallGraph()->hasCallSiteID(cbn,callee)) + if (getCallGraph()->hasCallSiteID(cbn, callee)) { - return getCallGraph()->getCallSiteID(cbn,callee); + return getCallGraph()->getCallSiteID(cbn, callee); } return 0; } - /// Handle conditions during backward traversing bool ContextDDA::handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) { @@ -260,21 +251,21 @@ bool ContextDDA::handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) if (edge->isCallVFGEdge()) { /// we don't handle context in recursions, they treated as assignments - if(CallSiteID csId = getCSIDAtCall(dpm,edge)) + if (CallSiteID csId = getCSIDAtCall(dpm, edge)) { - if(isEdgeInRecursion(csId)) + if (isEdgeInRecursion(csId)) { - DBOUT(DDDA,outs() << "\t\t call edge " << getCallGraph()->getCallerOfCallSite(csId)->getName() << - "=>" << getCallGraph()->getCalleeOfCallSite(csId)->getName() << "in recursion \n"); + DBOUT(DDDA, outs() << "\t\t call edge " << getCallGraph()->getCallerOfCallSite(csId)->getName() << "=>" + << getCallGraph()->getCalleeOfCallSite(csId)->getName() << "in recursion \n"); popRecursiveCallSites(dpm); } else { if (dpm.matchContext(csId) == false) { - DBOUT(DDDA, outs() << "\t\t context not match, edge " - << edge->getDstID() << " --| " << edge->getSrcID() << " \t"); + DBOUT(DDDA, outs() << "\t\t context not match, edge " << edge->getDstID() << " --| " + << edge->getSrcID() << " \t"); DBOUT(DDDA, dumpContexts(dpm.getCond())); return false; } @@ -288,13 +279,14 @@ bool ContextDDA::handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) else if (edge->isRetVFGEdge()) { /// we don't handle context in recursions, they treated as assignments - if(CallSiteID csId = getCSIDAtRet(dpm,edge)) + if (CallSiteID csId = getCSIDAtRet(dpm, edge)) { - if(isEdgeInRecursion(csId)) + if (isEdgeInRecursion(csId)) { - DBOUT(DDDA,outs() << "\t\t return edge " << getCallGraph()->getCalleeOfCallSite(csId)->getName() << - "=>" << getCallGraph()->getCallerOfCallSite(csId)->getName() << "in recursion \n"); + DBOUT(DDDA, outs() << "\t\t return edge " << getCallGraph()->getCalleeOfCallSite(csId)->getName() + << "=>" << getCallGraph()->getCallerOfCallSite(csId)->getName() + << "in recursion \n"); popRecursiveCallSites(dpm); } else @@ -309,8 +301,8 @@ bool ContextDDA::handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) } else { - assert(dpm.getCond().containCallStr(csId) ==false && "contain visited call string ??"); - if(dpm.pushContext(csId)) + assert(dpm.getCond().containCallStr(csId) == false && "contain visited call string ??"); + if (dpm.pushContext(csId)) { DBOUT(DDDA, outs() << "\t\t push context "); DBOUT(DDDA, dumpContexts(dpm.getCond())); @@ -328,7 +320,6 @@ bool ContextDDA::handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) return true; } - /// we exclude concrete heap given the following conditions: /// (1) concrete calling context (not involved in recursion and not exceed the maximum context limit) /// (2) not inside loop @@ -340,29 +331,25 @@ bool ContextDDA::isHeapCondMemObj(const CxtVar& var, const StoreSVFGNode*) { if (!mem->getValue()) { - PAGNode *pnode = _pag->getGNode(getPtrNodeID(var)); + PAGNode* pnode = _pag->getGNode(getPtrNodeID(var)); GepObjVar* gepobj = SVFUtil::dyn_cast(pnode); if (gepobj != nullptr) { - assert(SVFUtil::isa(_pag->getGNode(gepobj->getBaseNode())) - && "empty refVal in a gep object whose base is a non-dummy object"); + assert(SVFUtil::isa(_pag->getGNode(gepobj->getBaseNode())) && + "empty refVal in a gep object whose base is a non-dummy object"); } else { - assert((SVFUtil::isa(pnode)) - && "empty refVal in non-dummy object"); + assert((SVFUtil::isa(pnode)) && "empty refVal in non-dummy object"); } return true; } - else if(const SVFInstruction* mallocSite = SVFUtil::dyn_cast(mem->getValue())) + else if (const SVFInstruction* mallocSite = SVFUtil::dyn_cast(mem->getValue())) { const SVFFunction* svfFun = mallocSite->getFunction(); - if(_ander->isInRecursion(svfFun)) - return true; - if(var.get_cond().isConcreteCxt() == false) - return true; - if(_pag->getICFG()->isInLoop(mallocSite)) - return true; + if (_ander->isInRecursion(svfFun)) return true; + if (var.get_cond().isConcreteCxt() == false) return true; + if (_pag->getICFG()->isInLoop(mallocSite)) return true; } } return false; diff --git a/svf/lib/DDA/DDAClient.cpp b/svf/lib/DDA/DDAClient.cpp index cb3bd58d7..b91278240 100644 --- a/svf/lib/DDA/DDAClient.cpp +++ b/svf/lib/DDA/DDAClient.cpp @@ -29,7 +29,6 @@ * */ - #include "Util/Options.h" #include "Util/SVFUtil.h" #include "MemoryModel/PointsTo.h" @@ -37,12 +36,11 @@ #include "DDA/DDAClient.h" #include "DDA/FlowDDA.h" #include -#include // for std::setw +#include // for std::setw using namespace SVF; using namespace SVFUtil; - void DDAClient::answerQueries(PointerAnalysis* pta) { @@ -55,16 +53,17 @@ void DDAClient::answerQueries(PointerAnalysis* pta) collectCandidateQueries(pta->getPAG()); u32_t count = 0; - for (OrderedNodeSet::iterator nIter = candidateQueries.begin(); - nIter != candidateQueries.end(); ++nIter,++count) + for (OrderedNodeSet::iterator nIter = candidateQueries.begin(); nIter != candidateQueries.end(); ++nIter, ++count) { PAGNode* node = pta->getPAG()->getGNode(*nIter); - if(pta->getPAG()->isValidTopLevelPtr(node)) + if (pta->getPAG()->isValidTopLevelPtr(node)) { - DBOUT(DGENERAL,outs() << "\n@@Computing PointsTo for :" << node->getId() << - " [" << count + 1<< "/" << candidateQueries.size() << "]" << " \n"); - DBOUT(DDDA,outs() << "\n@@Computing PointsTo for :" << node->getId() << - " [" << count + 1<< "/" << candidateQueries.size() << "]" << " \n"); + DBOUT(DGENERAL, outs() << "\n@@Computing PointsTo for :" << node->getId() << " [" << count + 1 << "/" + << candidateQueries.size() << "]" + << " \n"); + DBOUT(DDDA, outs() << "\n@@Computing PointsTo for :" << node->getId() << " [" << count + 1 << "/" + << candidateQueries.size() << "]" + << " \n"); setCurrentQueryPtr(node->getId()); pta->computeDDAPts(node->getId()); } @@ -78,8 +77,9 @@ void DDAClient::answerQueries(PointerAnalysis* pta) OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p) { setPAG(p); - for(SVFIR::CallSiteToFunPtrMap::const_iterator it = pag->getIndirectCallsites().begin(), - eit = pag->getIndirectCallsites().end(); it!=eit; ++it) + for (SVFIR::CallSiteToFunPtrMap::const_iterator it = pag->getIndirectCallsites().begin(), + eit = pag->getIndirectCallsites().end(); + it != eit; ++it) { if (SVFUtil::getSVFCallSite(it->first->getCallSite()).isVirtualCall()) { @@ -108,8 +108,8 @@ void FunptrDDAClient::performStat(PointerAnalysis* pta) u32_t twoTargetCallsites = 0; u32_t moreThanTwoCallsites = 0; - for (VTablePtrToCallSiteMap::iterator nIter = vtableToCallSiteMap.begin(); - nIter != vtableToCallSiteMap.end(); ++nIter) + for (VTablePtrToCallSiteMap::iterator nIter = vtableToCallSiteMap.begin(); nIter != vtableToCallSiteMap.end(); + ++nIter) { NodeID vtptr = nIter->first; const PointsTo& ddaPts = pta->getPts(vtptr); @@ -118,42 +118,40 @@ void FunptrDDAClient::performStat(PointerAnalysis* pta) CallGraph* callgraph = ander->getCallGraph(); const CallICFGNode* cbn = nIter->second; - if(!callgraph->hasIndCSCallees(cbn)) + if (!callgraph->hasIndCSCallees(cbn)) { - //outs() << "virtual callsite has no callee" << *(nIter->second.getInstruction()) << "\n"; + // outs() << "virtual callsite has no callee" << *(nIter->second.getInstruction()) << "\n"; continue; } const CallGraph::FunctionSet& callees = callgraph->getIndCSCallees(cbn); totalCallsites++; - if(callees.size() == 0) - zeroTargetCallsites++; - else if(callees.size() == 1) + if (callees.size() == 0) zeroTargetCallsites++; + else if (callees.size() == 1) oneTargetCallsites++; - else if(callees.size() == 2) + else if (callees.size() == 2) twoTargetCallsites++; else moreThanTwoCallsites++; - if(ddaPts.count() >= anderPts.count() || ddaPts.empty()) - continue; + if (ddaPts.count() >= anderPts.count() || ddaPts.empty()) continue; Set ander_vfns; Set dda_vfns; - ander->getVFnsFromPts(cbn,anderPts, ander_vfns); - pta->getVFnsFromPts(cbn,ddaPts, dda_vfns); + ander->getVFnsFromPts(cbn, anderPts, ander_vfns); + pta->getVFnsFromPts(cbn, ddaPts, dda_vfns); ++morePreciseCallsites; outs() << "============more precise callsite =================\n"; outs() << (nIter->second)->getCallSite()->toString() << "\n"; outs() << (nIter->second)->getCallSite()->getSourceLoc() << "\n"; outs() << "\n"; - outs() << "------ander pts or vtable num---(" << anderPts.count() << ")--\n"; + outs() << "------ander pts or vtable num---(" << anderPts.count() << ")--\n"; outs() << "------DDA vfn num---(" << ander_vfns.size() << ")--\n"; - //ander->dumpPts(vtptr, anderPts); + // ander->dumpPts(vtptr, anderPts); outs() << "------DDA pts or vtable num---(" << ddaPts.count() << ")--\n"; outs() << "------DDA vfn num---(" << dda_vfns.size() << ")--\n"; - //pta->dumpPts(vtptr, ddaPts); + // pta->dumpPts(vtptr, ddaPts); outs() << "-------------------------\n"; outs() << "\n"; outs() << "=================================================\n"; @@ -171,14 +169,12 @@ void FunptrDDAClient::performStat(PointerAnalysis* pta) outs() << "=================================================\n"; } - /// Only collect function pointers as query candidates. OrderedNodeSet& AliasDDAClient::collectCandidateQueries(SVFIR* pag) { setPAG(pag); SVFStmt::SVFStmtSetTy& loads = pag->getSVFStmtSet(SVFStmt::Load); - for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = - loads.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = loads.end(); iter != eiter; ++iter) { PAGNode* loadsrc = (*iter)->getSrcNode(); loadSrcNodes.insert(loadsrc); @@ -186,16 +182,14 @@ OrderedNodeSet& AliasDDAClient::collectCandidateQueries(SVFIR* pag) } SVFStmt::SVFStmtSetTy& stores = pag->getSVFStmtSet(SVFStmt::Store); - for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = - stores.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; ++iter) { PAGNode* storedst = (*iter)->getDstNode(); storeDstNodes.insert(storedst); addCandidate(storedst->getId()); } SVFStmt::SVFStmtSetTy& geps = pag->getSVFStmtSet(SVFStmt::Gep); - for (SVFStmt::SVFStmtSetTy::iterator iter = geps.begin(), eiter = - geps.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = geps.begin(), eiter = geps.end(); iter != eiter; ++iter) { PAGNode* gepsrc = (*iter)->getSrcNode(); gepSrcNodes.insert(gepsrc); @@ -207,24 +201,22 @@ OrderedNodeSet& AliasDDAClient::collectCandidateQueries(SVFIR* pag) void AliasDDAClient::performStat(PointerAnalysis* pta) { - for(PAGNodeSet::const_iterator lit = loadSrcNodes.begin(); lit!=loadSrcNodes.end(); lit++) + for (PAGNodeSet::const_iterator lit = loadSrcNodes.begin(); lit != loadSrcNodes.end(); lit++) { - for(PAGNodeSet::const_iterator sit = storeDstNodes.begin(); sit!=storeDstNodes.end(); sit++) + for (PAGNodeSet::const_iterator sit = storeDstNodes.begin(); sit != storeDstNodes.end(); sit++) { const PAGNode* node1 = *lit; const PAGNode* node2 = *sit; - if(node1->hasValue() && node2->hasValue()) + if (node1->hasValue() && node2->hasValue()) { - AliasResult result = pta->alias(node1->getId(),node2->getId()); + AliasResult result = pta->alias(node1->getId(), node2->getId()); outs() << "\n=================================================\n"; outs() << "Alias Query for (" << node1->getValue()->toString() << ","; outs() << node2->getValue()->toString() << ") \n"; - outs() << "[NodeID:" << node1->getId() << ", NodeID:" << node2->getId() << " " << result << "]\n"; + outs() << "[NodeID:" << node1->getId() << ", NodeID:" << node2->getId() << " " << result << "]\n"; outs() << "=================================================\n"; - } } } } - diff --git a/svf/lib/DDA/DDAPass.cpp b/svf/lib/DDA/DDAPass.cpp index ece82d950..7908c2e51 100644 --- a/svf/lib/DDA/DDAPass.cpp +++ b/svf/lib/DDA/DDAPass.cpp @@ -20,14 +20,12 @@ // //===----------------------------------------------------------------------===// - /* * @file: DDAPass.cpp * @author: Yulei Sui * @date: 01/07/2014 */ - #include "Util/Options.h" #include "MemoryModel/PointerAnalysisImpl.h" #include "DDA/DDAPass.h" @@ -47,24 +45,20 @@ char DDAPass::ID = 0; DDAPass::~DDAPass() { // _pta->dumpStat(); - if (_client != nullptr) - delete _client; + if (_client != nullptr) delete _client; } - void DDAPass::runOnModule(SVFIR* pag) { /// initialization for llvm alias analyzer - //InitializeAliasAnalysis(this, getDataLayout(&module)); + // InitializeAliasAnalysis(this, getDataLayout(&module)); selectClient(pag->getModule()); - for (u32_t i = PointerAnalysis::FlowS_DDA; - i < PointerAnalysis::Default_PTA; i++) + for (u32_t i = PointerAnalysis::FlowS_DDA; i < PointerAnalysis::Default_PTA; i++) { PointerAnalysis::PTATY iPtTy = static_cast(i); - if (Options::DDASelected(iPtTy)) - runPointerAnalysis(pag, i); + if (Options::DDASelected(iPtTy)) runPointerAnalysis(pag, i); } } @@ -89,10 +83,9 @@ void DDAPass::selectClient(SVFModule* module) _client = new DDAClient(module); if (Options::UserInputQuery() != "all") { - u32_t buf; // Have a buffer + u32_t buf; // Have a buffer stringstream ss(Options::UserInputQuery()); // Insert the user input string into a stream - while (ss >> buf) - _client->setQuery(buf); + while (ss >> buf) _client->setQuery(buf); } } } @@ -114,13 +107,11 @@ void DDAPass::runPointerAnalysis(SVFIR* pag, u32_t kind) /// Initialize pointer analysis. switch (kind) { - case PointerAnalysis::Cxt_DDA: - { + case PointerAnalysis::Cxt_DDA: { _pta = std::make_unique(pag, _client); break; } - case PointerAnalysis::FlowS_DDA: - { + case PointerAnalysis::FlowS_DDA: { _pta = std::make_unique(pag, _client); break; } @@ -129,45 +120,41 @@ void DDAPass::runPointerAnalysis(SVFIR* pag, u32_t kind) break; } - if(Options::WPANum()) + if (Options::WPANum()) { _client->collectWPANum(pag->getModule()); } else { - ///initialize + /// initialize _pta->initialize(); - ///compute points-to + /// compute points-to _client->answerQueries(_pta.get()); - ///finalize + /// finalize _pta->finalize(); - if(Options::PrintCPts()) - _pta->dumpCPts(); + if (Options::PrintCPts()) _pta->dumpCPts(); - if (_pta->printStat()) - _client->performStat(_pta.get()); + if (_pta->printStat()) _client->performStat(_pta.get()); - if (Options::PrintQueryPts()) - printQueryPTS(); + if (Options::PrintQueryPts()) printQueryPTS(); } } - /*! * Initialize context insensitive Edge for DDA */ -void DDAPass::initCxtInsensitiveEdges(PointerAnalysis* pta, const SVFG* svfg,const SVFGSCC* svfgSCC, SVFGEdgeSet& insensitveEdges) +void DDAPass::initCxtInsensitiveEdges(PointerAnalysis* pta, const SVFG* svfg, const SVFGSCC* svfgSCC, + SVFGEdgeSet& insensitveEdges) { - if(Options::InsenRecur()) - collectCxtInsenEdgeForRecur(pta,svfg,insensitveEdges); - else if(Options::InsenCycle()) - collectCxtInsenEdgeForVFCycle(pta,svfg,svfgSCC,insensitveEdges); + if (Options::InsenRecur()) collectCxtInsenEdgeForRecur(pta, svfg, insensitveEdges); + else if (Options::InsenCycle()) + collectCxtInsenEdgeForVFCycle(pta, svfg, svfgSCC, insensitveEdges); } /*! * Whether SVFG edge in a SCC cycle */ -bool DDAPass::edgeInSVFGSCC(const SVFGSCC* svfgSCC,const SVFGEdge* edge) +bool DDAPass::edgeInSVFGSCC(const SVFGSCC* svfgSCC, const SVFGEdge* edge) { return (svfgSCC->repNode(edge->getSrcID()) == svfgSCC->repNode(edge->getDstID())); } @@ -175,17 +162,17 @@ bool DDAPass::edgeInSVFGSCC(const SVFGSCC* svfgSCC,const SVFGEdge* edge) /*! * Whether call graph edge in SVFG SCC */ -bool DDAPass::edgeInCallGraphSCC(PointerAnalysis* pta,const SVFGEdge* edge) +bool DDAPass::edgeInCallGraphSCC(PointerAnalysis* pta, const SVFGEdge* edge) { const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun(); - if(srcFun && dstFun) + if (srcFun && dstFun) { - return pta->inSameCallGraphSCC(srcFun,dstFun); + return pta->inSameCallGraphSCC(srcFun, dstFun); } - assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge" ); + assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge"); return false; } @@ -193,10 +180,10 @@ bool DDAPass::edgeInCallGraphSCC(PointerAnalysis* pta,const SVFGEdge* edge) /*! * Mark insensitive edge for function recursions */ -void DDAPass::collectCxtInsenEdgeForRecur(PointerAnalysis* pta, const SVFG* svfg,SVFGEdgeSet& insensitveEdges) +void DDAPass::collectCxtInsenEdgeForRecur(PointerAnalysis* pta, const SVFG* svfg, SVFGEdgeSet& insensitveEdges) { - for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(),eit = svfg->end(); it != eit; ++it) + for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it) { SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin(); @@ -204,10 +191,9 @@ void DDAPass::collectCxtInsenEdgeForRecur(PointerAnalysis* pta, const SVFG* svfg for (; edgeIt != edgeEit; ++edgeIt) { const SVFGEdge* edge = *edgeIt; - if(edge->isCallVFGEdge() || edge->isRetVFGEdge()) + if (edge->isCallVFGEdge() || edge->isRetVFGEdge()) { - if(edgeInCallGraphSCC(pta,edge)) - insensitveEdges.insert(edge); + if (edgeInCallGraphSCC(pta, edge)) insensitveEdges.insert(edge); } } } @@ -216,12 +202,13 @@ void DDAPass::collectCxtInsenEdgeForRecur(PointerAnalysis* pta, const SVFG* svfg /*! * Mark insensitive edge for value-flow cycles */ -void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* svfg,const SVFGSCC* svfgSCC, SVFGEdgeSet& insensitveEdges) +void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* svfg, const SVFGSCC* svfgSCC, + SVFGEdgeSet& insensitveEdges) { OrderedSet insensitvefunPairs; - for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(),eit = svfg->end(); it != eit; ++it) + for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it) { SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin(); @@ -229,29 +216,29 @@ void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* sv for (; edgeIt != edgeEit; ++edgeIt) { const SVFGEdge* edge = *edgeIt; - if(edge->isCallVFGEdge() || edge->isRetVFGEdge()) + if (edge->isCallVFGEdge() || edge->isRetVFGEdge()) { - if(this->edgeInSVFGSCC(svfgSCC,edge)) + if (this->edgeInSVFGSCC(svfgSCC, edge)) { const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun(); - if(srcFun && dstFun) + if (srcFun && dstFun) { NodeID src = pta->getCallGraph()->getCallGraphNode(srcFun)->getId(); NodeID dst = pta->getCallGraph()->getCallGraphNode(dstFun)->getId(); - insensitvefunPairs.insert(std::make_pair(src,dst)); - insensitvefunPairs.insert(std::make_pair(dst,src)); + insensitvefunPairs.insert(std::make_pair(src, dst)); + insensitvefunPairs.insert(std::make_pair(dst, src)); } else - assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge" ); + assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge"); } } } } - for(SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(),eit = svfg->end(); it != eit; ++it) + for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it) { SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin(); SVFGEdge::SVFGEdgeSetTy::const_iterator edgeEit = it->second->InEdgeEnd(); @@ -259,18 +246,18 @@ void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* sv { const SVFGEdge* edge = *edgeIt; - if(edge->isCallVFGEdge() || edge->isRetVFGEdge()) + if (edge->isCallVFGEdge() || edge->isRetVFGEdge()) { const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun(); - if(srcFun && dstFun) + if (srcFun && dstFun) { NodeID src = pta->getCallGraph()->getCallGraphNode(srcFun)->getId(); NodeID dst = pta->getCallGraph()->getCallGraphNode(dstFun)->getId(); - if(insensitvefunPairs.find(std::make_pair(src,dst))!=insensitvefunPairs.end()) + if (insensitvefunPairs.find(std::make_pair(src, dst)) != insensitvefunPairs.end()) insensitveEdges.insert(edge); - else if(insensitvefunPairs.find(std::make_pair(dst,src))!=insensitvefunPairs.end()) + else if (insensitvefunPairs.find(std::make_pair(dst, src)) != insensitvefunPairs.end()) insensitveEdges.insert(edge); } } @@ -282,13 +269,11 @@ AliasResult DDAPass::alias(NodeID node1, NodeID node2) { SVFIR* pag = _pta->getPAG(); - if(pag->isValidTopLevelPtr(pag->getGNode(node1))) - _pta->computeDDAPts(node1); + if (pag->isValidTopLevelPtr(pag->getGNode(node1))) _pta->computeDDAPts(node1); - if(pag->isValidTopLevelPtr(pag->getGNode(node2))) - _pta->computeDDAPts(node2); + if (pag->isValidTopLevelPtr(pag->getGNode(node2))) _pta->computeDDAPts(node2); - return _pta->alias(node1,node2); + return _pta->alias(node1, node2); } /*! * Return alias results based on our points-to/alias analysis @@ -306,14 +291,12 @@ AliasResult DDAPass::alias(const SVFValue* V1, const SVFValue* V2) if (pag->hasValueNode(V1) && pag->hasValueNode(V2)) { PAGNode* node1 = pag->getGNode(pag->getValueNode(V1)); - if(pag->isValidTopLevelPtr(node1)) - _pta->computeDDAPts(node1->getId()); + if (pag->isValidTopLevelPtr(node1)) _pta->computeDDAPts(node1->getId()); PAGNode* node2 = pag->getGNode(pag->getValueNode(V2)); - if(pag->isValidTopLevelPtr(node2)) - _pta->computeDDAPts(node2->getId()); + if (pag->isValidTopLevelPtr(node2)) _pta->computeDDAPts(node2->getId()); - return _pta->alias(V1,V2); + return _pta->alias(V1, V2); } return AliasResult::MayAlias; @@ -328,6 +311,6 @@ void DDAPass::printQueryPTS() for (OrderedNodeSet::const_iterator it = candidates.begin(), eit = candidates.end(); it != eit; ++it) { const PointsTo& pts = _pta->getPts(*it); - _pta->dumpPts(*it,pts); + _pta->dumpPts(*it, pts); } } diff --git a/svf/lib/DDA/DDAStat.cpp b/svf/lib/DDA/DDAStat.cpp index e9c3a2bc3..4d3cbe735 100644 --- a/svf/lib/DDA/DDAStat.cpp +++ b/svf/lib/DDA/DDAStat.cpp @@ -71,7 +71,6 @@ void DDAStat::initDefault() _AnaTimePerQuery = 0; _AnaTimeCyclePerQuery = 0; - _NumOfDPM = 0; _NumOfStrongUpdates = 0; _NumOfMustAliases = 0; @@ -86,17 +85,14 @@ void DDAStat::initDefault() SVFG* DDAStat::getSVFG() const { - if(flowDDA) - return flowDDA->getSVFG(); + if (flowDDA) return flowDDA->getSVFG(); else return contextDDA->getSVFG(); - } PointerAnalysis* DDAStat::getPTA() const { - if(flowDDA) - return flowDDA; + if (flowDDA) return flowDDA; else return contextDDA; } @@ -109,59 +105,55 @@ void DDAStat::performStatPerQuery(NodeID ptr) u32_t maxNumOfDPMPerLoc = 0; u32_t cptsSize = 0; PointsTo pts; - if(flowDDA) + if (flowDDA) { - for(FlowDDA::LocToDPMVecMap::const_iterator it = flowDDA->getLocToDPMVecMap().begin(), - eit = flowDDA->getLocToDPMVecMap().end(); it!=eit; ++it) + for (FlowDDA::LocToDPMVecMap::const_iterator it = flowDDA->getLocToDPMVecMap().begin(), + eit = flowDDA->getLocToDPMVecMap().end(); + it != eit; ++it) { NumOfLoc++; u32_t num = it->second.size(); NumOfDPM += num; - if(num > maxNumOfDPMPerLoc) - maxNumOfDPMPerLoc = num; + if (num > maxNumOfDPMPerLoc) maxNumOfDPMPerLoc = num; } cptsSize = flowDDA->getPts(ptr).count(); pts = flowDDA->getPts(ptr); } - else if(contextDDA) + else if (contextDDA) { - for(ContextDDA::LocToDPMVecMap::const_iterator it = contextDDA->getLocToDPMVecMap().begin(), - eit = contextDDA->getLocToDPMVecMap().end(); it!=eit; ++it) + for (ContextDDA::LocToDPMVecMap::const_iterator it = contextDDA->getLocToDPMVecMap().begin(), + eit = contextDDA->getLocToDPMVecMap().end(); + it != eit; ++it) { NumOfLoc++; u32_t num = it->second.size(); NumOfDPM += num; - if(num > maxNumOfDPMPerLoc) - maxNumOfDPMPerLoc = num; + if (num > maxNumOfDPMPerLoc) maxNumOfDPMPerLoc = num; } ContextCond cxt; - CxtVar var(cxt,ptr); + CxtVar var(cxt, ptr); cptsSize = contextDDA->getPts(var).count(); pts = contextDDA->getBVPointsTo(contextDDA->getPts(var)); } u32_t ptsSize = pts.count(); - double avgDPMAtLoc = NumOfLoc!=0 ? (double)NumOfDPM/NumOfLoc : 0; + double avgDPMAtLoc = NumOfLoc != 0 ? (double)NumOfDPM / NumOfLoc : 0; _AvgNumOfDPMAtSVFGNode += avgDPMAtLoc; - if(maxNumOfDPMPerLoc > _MaxNumOfDPMAtSVFGNode) - _MaxNumOfDPMAtSVFGNode = maxNumOfDPMPerLoc; + if (maxNumOfDPMPerLoc > _MaxNumOfDPMAtSVFGNode) _MaxNumOfDPMAtSVFGNode = maxNumOfDPMPerLoc; _TotalCPtsSize += cptsSize; - if (_MaxCPtsSize < cptsSize) - _MaxCPtsSize = cptsSize; + if (_MaxCPtsSize < cptsSize) _MaxCPtsSize = cptsSize; _TotalPtsSize += ptsSize; - if(_MaxPtsSize < ptsSize) - _MaxPtsSize = ptsSize; + if (_MaxPtsSize < ptsSize) _MaxPtsSize = ptsSize; - if(cptsSize == 0) - _NumOfNullPtr++; + if (cptsSize == 0) _NumOfNullPtr++; - if(getPTA()->containBlackHoleNode(pts)) + if (getPTA()->containBlackHoleNode(pts)) { _NumOfConstantPtr++; } - if(getPTA()->containConstantNode(pts)) + if (getPTA()->containConstantNode(pts)) { _NumOfBlackholePtr++; } @@ -178,8 +170,8 @@ void DDAStat::performStatPerQuery(NodeID ptr) timeStatMap.clear(); NumPerQueryStatMap.clear(); - timeStatMap["TimePerQuery"] = _AnaTimePerQuery/TIMEINTERVAL; - timeStatMap["CyleTimePerQuery"] = _AnaTimeCyclePerQuery/TIMEINTERVAL; + timeStatMap["TimePerQuery"] = _AnaTimePerQuery / TIMEINTERVAL; + timeStatMap["CyleTimePerQuery"] = _AnaTimeCyclePerQuery / TIMEINTERVAL; NumPerQueryStatMap["CPtsSize"] = cptsSize; NumPerQueryStatMap["PtsSize"] = ptsSize; @@ -208,8 +200,7 @@ void DDAStat::performStatPerQuery(NodeID ptr) void DDAStat::getNumOfOOBQuery() { - if (flowDDA) - _TotalNumOfOutOfBudgetQuery = flowDDA->outOfBudgetDpms.size(); + if (flowDDA) _TotalNumOfOutOfBudgetQuery = flowDDA->outOfBudgetDpms.size(); else if (contextDDA) _TotalNumOfOutOfBudgetQuery = contextDDA->outOfBudgetDpms.size(); } @@ -225,37 +216,38 @@ void DDAStat::performStat() getNumOfOOBQuery(); - for (SVFIR::const_iterator nodeIt = SVFIR::getPAG()->begin(), nodeEit = SVFIR::getPAG()->end(); nodeIt != nodeEit; nodeIt++) + for (SVFIR::const_iterator nodeIt = SVFIR::getPAG()->begin(), nodeEit = SVFIR::getPAG()->end(); nodeIt != nodeEit; + nodeIt++) { PAGNode* pagNode = nodeIt->second; - if(SVFUtil::isa(pagNode)) + if (SVFUtil::isa(pagNode)) { - if(getPTA()->isLocalVarInRecursiveFun(nodeIt->first)) + if (getPTA()->isLocalVarInRecursiveFun(nodeIt->first)) { localVarInRecursion.set(nodeIt->first); } } } - timeStatMap["TotalQueryTime"] = _TotalTimeOfQueries/TIMEINTERVAL; - timeStatMap["AvgTimePerQuery"] = (_TotalTimeOfQueries/TIMEINTERVAL)/_TotalNumOfQuery; - timeStatMap["TotalBKCondTime"] = (_TotalTimeOfBKCondition/TIMEINTERVAL); + timeStatMap["TotalQueryTime"] = _TotalTimeOfQueries / TIMEINTERVAL; + timeStatMap["AvgTimePerQuery"] = (_TotalTimeOfQueries / TIMEINTERVAL) / _TotalNumOfQuery; + timeStatMap["TotalBKCondTime"] = (_TotalTimeOfBKCondition / TIMEINTERVAL); PTNumStatMap["NumOfQuery"] = _TotalNumOfQuery; PTNumStatMap["NumOfOOBQuery"] = _TotalNumOfOutOfBudgetQuery; PTNumStatMap["NumOfDPM"] = _TotalNumOfDPM; PTNumStatMap["NumOfSU"] = _TotalNumOfStrongUpdates; PTNumStatMap["NumOfStoreSU"] = _StrongUpdateStores.count(); - PTNumStatMap["NumOfStep"] = _TotalNumOfStep; - PTNumStatMap["NumOfStepInCycle"] = _TotalNumOfStepInCycle; - timeStatMap["AvgDPMAtLoc"] = (double)_AvgNumOfDPMAtSVFGNode/_TotalNumOfQuery; + PTNumStatMap["NumOfStep"] = _TotalNumOfStep; + PTNumStatMap["NumOfStepInCycle"] = _TotalNumOfStepInCycle; + timeStatMap["AvgDPMAtLoc"] = (double)_AvgNumOfDPMAtSVFGNode / _TotalNumOfQuery; PTNumStatMap["MaxDPMAtLoc"] = _MaxNumOfDPMAtSVFGNode; PTNumStatMap["MaxPathPerQuery"] = ContextCond::maximumPath; PTNumStatMap["MaxCxtPerQuery"] = ContextCond::maximumCxt; PTNumStatMap["MaxCPtsSize"] = _MaxCPtsSize; PTNumStatMap["MaxPtsSize"] = _MaxPtsSize; - timeStatMap["AvgCPtsSize"] = (double)_TotalCPtsSize/_TotalNumOfQuery; - timeStatMap["AvgPtsSize"] = (double)_TotalPtsSize/_TotalNumOfQuery; + timeStatMap["AvgCPtsSize"] = (double)_TotalCPtsSize / _TotalNumOfQuery; + timeStatMap["AvgPtsSize"] = (double)_TotalPtsSize / _TotalNumOfQuery; PTNumStatMap["IndEdgeSolved"] = getPTA()->getNumOfResolvedIndCallEdge(); PTNumStatMap["NumOfNullPtr"] = _NumOfNullPtr; PTNumStatMap["PointsToConstPtr"] = _NumOfConstantPtr; @@ -291,16 +283,15 @@ void DDAStat::printStatPerQuery(NodeID ptr, const PointsTo& pts) getPTA()->dumpPts(ptr, pts); } - void DDAStat::printStat(string str) { - if(flowDDA) + if (flowDDA) { FlowDDA::ConstSVFGEdgeSet edgeSet; flowDDA->getSVFG()->getStat()->performSCCStat(edgeSet); } - else if(contextDDA) + else if (contextDDA) { contextDDA->getSVFG()->getStat()->performSCCStat(contextDDA->getInsensitiveEdgeSet()); } diff --git a/svf/lib/DDA/FlowDDA.cpp b/svf/lib/DDA/FlowDDA.cpp index 96ceecab9..d8b492761 100644 --- a/svf/lib/DDA/FlowDDA.cpp +++ b/svf/lib/DDA/FlowDDA.cpp @@ -36,7 +36,6 @@ using namespace std; using namespace SVF; using namespace SVFUtil; - /*! * Compute points-to set for queries */ @@ -46,7 +45,7 @@ void FlowDDA::computeDDAPts(NodeID id) LocDPItem::setMaxBudget(Options::FlowBudget()); PAGNode* node = getPAG()->getGNode(id); - LocDPItem dpm = getDPIm(node->getId(),getDefSVFGNode(node)); + LocDPItem dpm = getDPIm(node->getId(), getDefSVFGNode(node)); /// start DDA analysis DOTIMESTAT(double start = DDAStat::getClk(true)); @@ -54,27 +53,24 @@ void FlowDDA::computeDDAPts(NodeID id) DOTIMESTAT(ddaStat->_AnaTimePerQuery = DDAStat::getClk(true) - start); DOTIMESTAT(ddaStat->_TotalTimeOfQueries += ddaStat->_AnaTimePerQuery); - if(isOutOfBudgetQuery() == false) - unionPts(node->getId(),pts); + if (isOutOfBudgetQuery() == false) unionPts(node->getId(), pts); else handleOutOfBudgetDpm(dpm); - if(this->printStat()) - DOSTAT(stat->performStatPerQuery(node->getId())); + if (this->printStat()) DOSTAT(stat->performStatPerQuery(node->getId())); - DBOUT(DGENERAL,stat->printStatPerQuery(id,getPts(id))); + DBOUT(DGENERAL, stat->printStatPerQuery(id, getPts(id))); } - /*! * Handle out-of-budget dpm */ void FlowDDA::handleOutOfBudgetDpm(const LocDPItem& dpm) { - DBOUT(DGENERAL,outs() << "~~~Out of budget query, downgrade to andersen analysis \n"); + DBOUT(DGENERAL, outs() << "~~~Out of budget query, downgrade to andersen analysis \n"); const PointsTo& anderPts = getAndersenAnalysis()->getPts(dpm.getCurNodeID()); - updateCachedPointsTo(dpm,anderPts); - unionPts(dpm.getCurNodeID(),anderPts); + updateCachedPointsTo(dpm, anderPts); + unionPts(dpm.getCurNodeID(), anderPts); addOutOfBudgetDpm(dpm); } @@ -83,54 +79,52 @@ bool FlowDDA::testIndCallReachability(LocDPItem&, const SVFFunction* callee, Cal const CallICFGNode* cbn = getSVFG()->getCallSite(csId); - if(getPAG()->isIndirectCallSites(cbn)) + if (getPAG()->isIndirectCallSites(cbn)) { - if(getCallGraph()->hasIndCSCallees(cbn)) + if (getCallGraph()->hasIndCSCallees(cbn)) { const FunctionSet& funset = getCallGraph()->getIndCSCallees(cbn); - if(funset.find(callee)!=funset.end()) - return true; + if (funset.find(callee) != funset.end()) return true; } return false; } - else // if this is an direct call + else // if this is an direct call return true; - } bool FlowDDA::handleBKCondition(LocDPItem& dpm, const SVFGEdge* edge) { _client->handleStatement(edge->getSrcNode(), dpm.getCurNodeID()); -// CallSiteID csId = 0; -// -// if (edge->isCallVFGEdge()) { -// /// we don't handle context in recursions, they treated as assignments -// if (const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) -// csId = callEdge->getCallSiteId(); -// else -// csId = SVFUtil::cast(edge)->getCallSiteId(); -// -// const SVFFunction* callee = edge->getDstNode()->getBB()->getParent(); -// if(testIndCallReachability(dpm,callee,csId)==false){ -// return false; -// } -// -// } -// -// else if (edge->isRetVFGEdge()) { -// /// we don't handle context in recursions, they treated as assignments -// if (const RetDirSVFGEdge* retEdge = SVFUtil::dyn_cast(edge)) -// csId = retEdge->getCallSiteId(); -// else -// csId = SVFUtil::cast(edge)->getCallSiteId(); -// -// const SVFFunction* callee = edge->getSrcNode()->getBB()->getParent(); -// if(testIndCallReachability(dpm,callee,csId)==false){ -// return false; -// } -// -// } + // CallSiteID csId = 0; + // + // if (edge->isCallVFGEdge()) { + // /// we don't handle context in recursions, they treated as assignments + // if (const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) + // csId = callEdge->getCallSiteId(); + // else + // csId = SVFUtil::cast(edge)->getCallSiteId(); + // + // const SVFFunction* callee = edge->getDstNode()->getBB()->getParent(); + // if(testIndCallReachability(dpm,callee,csId)==false){ + // return false; + // } + // + // } + // + // else if (edge->isRetVFGEdge()) { + // /// we don't handle context in recursions, they treated as assignments + // if (const RetDirSVFGEdge* retEdge = SVFUtil::dyn_cast(edge)) + // csId = retEdge->getCallSiteId(); + // else + // csId = SVFUtil::cast(edge)->getCallSiteId(); + // + // const SVFFunction* callee = edge->getSrcNode()->getBB()->getParent(); + // if(testIndCallReachability(dpm,callee,csId)==false){ + // return false; + // } + // + // } return true; } @@ -144,8 +138,7 @@ PointsTo FlowDDA::processGepPts(const GepSVFGNode* gep, const PointsTo& srcPts) for (PointsTo::iterator piter = srcPts.begin(); piter != srcPts.end(); ++piter) { NodeID ptd = *piter; - if (isBlkObjOrConstantObj(ptd)) - tmpDstPts.set(ptd); + if (isBlkObjOrConstantObj(ptd)) tmpDstPts.set(ptd); else { const GepStmt* gepStmt = SVFUtil::cast(gep->getPAGEdge()); @@ -178,20 +171,20 @@ bool FlowDDA::isHeapCondMemObj(const NodeID& var, const StoreSVFGNode*) { const MemObj* mem = _pag->getObject(getPtrNodeID(var)); assert(mem && "memory object is null??"); - if(mem->isHeap()) + if (mem->isHeap()) { -// if(const Instruction* mallocSite = SVFUtil::dyn_cast(mem->getValue())) { -// const SVFFunction* fun = mallocSite->getParent()->getParent(); -// const SVFFunction* curFun = store->getBB() ? store->getBB()->getParent() : nullptr; -// if(fun!=curFun) -// return true; -// if(_callGraphSCC->isInCycle(_callGraph->getCallGraphNode(fun)->getId())) -// return true; -// if(_pag->getICFG()->isInLoop(mallocSite)) -// return true; -// -// return false; -// } + // if(const Instruction* mallocSite = SVFUtil::dyn_cast(mem->getValue())) { + // const SVFFunction* fun = mallocSite->getParent()->getParent(); + // const SVFFunction* curFun = store->getBB() ? store->getBB()->getParent() : nullptr; + // if(fun!=curFun) + // return true; + // if(_callGraphSCC->isInCycle(_callGraph->getCallGraphNode(fun)->getId())) + // return true; + // if(_pag->getICFG()->isInLoop(mallocSite)) + // return true; + // + // return false; + // } return true; } return false; diff --git a/svf/lib/FastCluster/fastcluster.cpp b/svf/lib/FastCluster/fastcluster.cpp index ad79f6d08..e6106dd44 100644 --- a/svf/lib/FastCluster/fastcluster.cpp +++ b/svf/lib/FastCluster/fastcluster.cpp @@ -7,7 +7,6 @@ // (see the file LICENSE for details) // - #include #include #include @@ -37,56 +36,55 @@ bool fc_isnan(double x) void cutree_k(int n, const int* merge, int nclust, int* labels) { - int k,m1,m2,j,l; + int k, m1, m2, j, l; if (nclust > n || nclust < 2) { - for (j=0; j last_merge(n, 0); - for (k=1; k<=(n-nclust); k++) + for (k = 1; k <= (n - nclust); k++) { // (m1,m2) = merge[k,] - m1 = merge[k-1]; - m2 = merge[n-1+k-1]; - if (m1 < 0 && m2 < 0) // both single observables + m1 = merge[k - 1]; + m2 = merge[n - 1 + k - 1]; + if (m1 < 0 && m2 < 0) // both single observables { - last_merge[-m1-1] = last_merge[-m2-1] = k; + last_merge[-m1 - 1] = last_merge[-m2 - 1] = k; } - else if (m1 < 0 || m2 < 0) // one is a cluster + else if (m1 < 0 || m2 < 0) // one is a cluster { - if(m1 < 0) + if (m1 < 0) { j = -m1; m1 = m2; } - else j = -m2; + else + j = -m2; // merging single observable and cluster - for(l = 0; l < n; l++) - if (last_merge[l] == m1) - last_merge[l] = k; - last_merge[j-1] = k; + for (l = 0; l < n; l++) + if (last_merge[l] == m1) last_merge[l] = k; + last_merge[j - 1] = k; } - else // both cluster + else // both cluster { - for(l=0; l < n; l++) + for (l = 0; l < n; l++) { - if( last_merge[l] == m1 || last_merge[l] == m2 ) - last_merge[l] = k; + if (last_merge[l] == m1 || last_merge[l] == m2) last_merge[l] = k; } } } // assign cluster labels int label = 0; - std::vector z(n,-1); - for (j=0; j z(n, -1); + for (j = 0; j < n; j++) { - if (last_merge[j] == 0) // still singleton + if (last_merge[j] == 0) // still singleton { labels[j] = label++; } @@ -118,17 +116,16 @@ void cutree_cdist(int n, const int* merge, double* height, double cdist, int* la int k; - for (k=0; k<(n-1); k++) + for (k = 0; k < (n - 1); k++) { if (height[k] >= cdist) { break; } } - cutree_k(n, merge, n-k, labels); + cutree_k(n, merge, n - k, labels); } - // // Hierarchical clustering with one of Daniel Muellner's fast algorithms // @@ -157,7 +154,7 @@ int hclust_fast(int n, double* distmat, int method, int* merge, double* height) { // call appropriate clustering function - cluster_result Z2(n-1); + cluster_result Z2(n - 1); if (method == HCLUST_METHOD_SINGLE) { // single link @@ -172,7 +169,7 @@ int hclust_fast(int n, double* distmat, int method, int* merge, double* height) { // best average distance double* members = new double[n]; - for (int i=0; i(n, distmat, members, Z2); delete[] members; } diff --git a/svf/lib/Graphs/CDG.cpp b/svf/lib/Graphs/CDG.cpp index 806c2a3ee..f989cbc66 100644 --- a/svf/lib/Graphs/CDG.cpp +++ b/svf/lib/Graphs/CDG.cpp @@ -30,9 +30,9 @@ using namespace SVF; -CDG *CDG::controlDg = nullptr; +CDG* CDG::controlDg = nullptr; -void CDG::addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const SVFValue *pNode, s32_t branchID) +void CDG::addCDGEdgeFromSrcDst(const ICFGNode* src, const ICFGNode* dst, const SVFValue* pNode, s32_t branchID) { if (!hasCDGNode(src->getId())) { @@ -44,16 +44,14 @@ void CDG::addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const S } if (!hasCDGEdge(getCDGNode(src->getId()), getCDGNode(dst->getId()))) { - CDGEdge *pEdge = new CDGEdge(getCDGNode(src->getId()), - getCDGNode(dst->getId())); + CDGEdge* pEdge = new CDGEdge(getCDGNode(src->getId()), getCDGNode(dst->getId())); pEdge->insertBranchCondition(pNode, branchID); addCDGEdge(pEdge); incEdgeNum(); } else { - CDGEdge *pEdge = getCDGEdge(getCDGNode(src->getId()), - getCDGNode(dst->getId())); + CDGEdge* pEdge = getCDGEdge(getCDGNode(src->getId()), getCDGNode(dst->getId())); pEdge->insertBranchCondition(pNode, branchID); } } \ No newline at end of file diff --git a/svf/lib/Graphs/CFLGraph.cpp b/svf/lib/Graphs/CFLGraph.cpp index 9ae84f58c..0c8c5d058 100644 --- a/svf/lib/Graphs/CFLGraph.cpp +++ b/svf/lib/Graphs/CFLGraph.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * CFLGraph.cpp * @@ -46,8 +45,8 @@ void CFLGraph::addCFLNode(NodeID id, CFLNode* node) const CFLEdge* CFLGraph::addCFLEdge(CFLNode* src, CFLNode* dst, CFLEdge::GEdgeFlag label) { - CFLEdge* edge = new CFLEdge(src,dst,label); - if(cflEdgeSet.insert(edge).second) + CFLEdge* edge = new CFLEdge(src, dst, label); + if (cflEdgeSet.insert(edge).second) { src->addOutgoingEdge(edge); dst->addIngoingEdge(edge); @@ -62,10 +61,9 @@ const CFLEdge* CFLGraph::addCFLEdge(CFLNode* src, CFLNode* dst, CFLEdge::GEdgeFl const CFLEdge* CFLGraph::hasEdge(CFLNode* src, CFLNode* dst, CFLEdge::GEdgeFlag label) { - CFLEdge edge(src,dst,label); + CFLEdge edge(src, dst, label); auto it = cflEdgeSet.find(&edge); - if(it !=cflEdgeSet.end()) - return *it; + if (it != cflEdgeSet.end()) return *it; else return nullptr; } @@ -85,15 +83,12 @@ namespace SVF /*! * Write CFL graph into dot file for debugging */ -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits +template <> struct DOTGraphTraits : public DefaultDOTGraphTraits { typedef CFLNode NodeType; - DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(CFLGraph*) @@ -101,7 +96,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return "CFL Reachability Graph"; } /// Return function name; - static std::string getNodeLabel(CFLNode *node, CFLGraph*) + static std::string getNodeLabel(CFLNode* node, CFLGraph*) { std::string str; std::stringstream rawstr(str); @@ -109,13 +104,12 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return rawstr.str(); } - static std::string getNodeAttributes(CFLNode *node, CFLGraph*) + static std::string getNodeAttributes(CFLNode* node, CFLGraph*) { return "shape=box"; } - template - static std::string getEdgeAttributes(CFLNode*, EdgeIter EI, CFLGraph* graph) + template static std::string getEdgeAttributes(CFLNode*, EdgeIter EI, CFLGraph* graph) { CFLEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); @@ -151,13 +145,12 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits } else { - rawstr << "style=invis"; + rawstr << "style=invis"; } return rawstr.str(); } - template - static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) { CFLEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); @@ -168,4 +161,4 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits } }; -} \ No newline at end of file +} // namespace SVF \ No newline at end of file diff --git a/svf/lib/Graphs/CHG.cpp b/svf/lib/Graphs/CHG.cpp index 44c119478..43f99afb6 100644 --- a/svf/lib/Graphs/CHG.cpp +++ b/svf/lib/Graphs/CHG.cpp @@ -34,16 +34,14 @@ using namespace SVF; using namespace SVFUtil; using namespace std; -static bool hasEdge(const CHNode *src, const CHNode *dst, - CHEdge::CHEDGETYPE et) +static bool hasEdge(const CHNode* src, const CHNode* dst, CHEdge::CHEDGETYPE et) { - for (CHEdge::CHEdgeSetTy::const_iterator it = src->getOutEdges().begin(), - eit = src->getOutEdges().end(); it != eit; ++it) + for (CHEdge::CHEdgeSetTy::const_iterator it = src->getOutEdges().begin(), eit = src->getOutEdges().end(); it != eit; + ++it) { - CHNode *node = (*it)->getDstNode(); + CHNode* node = (*it)->getDstNode(); CHEdge::CHEDGETYPE edgeType = (*it)->getEdgeType(); - if (node == dst && edgeType == et) - return true; + if (node == dst && edgeType == et) return true; } return false; } @@ -52,8 +50,8 @@ static bool checkArgTypes(CallSite cs, const SVFFunction* fn) { // here we skip the first argument (i.e., this pointer) - u32_t arg_size = (fn->arg_size() > cs.arg_size()) ? cs.arg_size(): fn->arg_size(); - if(arg_size > 1) + u32_t arg_size = (fn->arg_size() > cs.arg_size()) ? cs.arg_size() : fn->arg_size(); + if (arg_size > 1) { for (unsigned i = 1; i < arg_size; i++) { @@ -69,59 +67,54 @@ static bool checkArgTypes(CallSite cs, const SVFFunction* fn) return true; } -void CHGraph::addEdge(const string className, const string baseClassName, - CHEdge::CHEDGETYPE edgeType) +void CHGraph::addEdge(const string className, const string baseClassName, CHEdge::CHEDGETYPE edgeType) { - CHNode *srcNode = getNode(className); - CHNode *dstNode = getNode(baseClassName); + CHNode* srcNode = getNode(className); + CHNode* dstNode = getNode(baseClassName); assert(srcNode && dstNode && "node not found?"); if (!hasEdge(srcNode, dstNode, edgeType)) { - CHEdge *edge = new CHEdge(srcNode, dstNode, edgeType); + CHEdge* edge = new CHEdge(srcNode, dstNode, edgeType); srcNode->addOutgoingEdge(edge); dstNode->addIncomingEdge(edge); } } -CHNode *CHGraph::getNode(const string name) const +CHNode* CHGraph::getNode(const string name) const { auto chNode = classNameToNodeMap.find(name); if (chNode != classNameToNodeMap.end()) return chNode->second; - else return nullptr; + else + return nullptr; } - /* * Get virtual functions for callsite "cs" based on vtbls (calculated * based on pointsto set) */ -void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) +void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet& vtbls, VFunSet& virtualFunctions) { /// get target virtual functions size_t idx = cs.getFunIdxInVtable(); /// get the function name of the virtual callsite string funName = cs.getFunNameOfVirtualCall(); - for (const SVFGlobalValue *vt : vtbls) + for (const SVFGlobalValue* vt : vtbls) { - const CHNode *child = getNode(vt->getName()); - if (child == nullptr) - continue; + const CHNode* child = getNode(vt->getName()); + if (child == nullptr) continue; CHNode::FuncVector vfns; child->getVirtualFunctions(idx, vfns); - for (CHNode::FuncVector::const_iterator fit = vfns.begin(), - feit = vfns.end(); fit != feit; ++fit) + for (CHNode::FuncVector::const_iterator fit = vfns.begin(), feit = vfns.end(); fit != feit; ++fit) { const SVFFunction* callee = *fit; - if (cs.arg_size() == callee->arg_size() || - (cs.isVarArg() && callee->isVarArg())) + if (cs.arg_size() == callee->arg_size() || (cs.isVarArg() && callee->isVarArg())) { // if argument types do not match // skip this one - if (!checkArgTypes(cs, callee)) - continue; + if (!checkArgTypes(cs, callee)) continue; string calleeName = callee->getName(); @@ -136,8 +129,7 @@ void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &vir */ const std::string suffix("[abi:cxx11]"); size_t suffix_pos = calleeName.rfind(suffix); - if (suffix_pos != string::npos) - calleeName.erase(suffix_pos, suffix.size()); + if (suffix_pos != string::npos) calleeName.erase(suffix_pos, suffix.size()); /* * if we can't get the function name of a virtual callsite, all virtual @@ -180,33 +172,28 @@ void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &vir } } - -void CHNode::getVirtualFunctions(u32_t idx, FuncVector &virtualFunctions) const +void CHNode::getVirtualFunctions(u32_t idx, FuncVector& virtualFunctions) const { - for (vector::const_iterator it = virtualFunctionVectors.begin(), - eit = virtualFunctionVectors.end(); it != eit; ++it) + for (vector::const_iterator it = virtualFunctionVectors.begin(), eit = virtualFunctionVectors.end(); + it != eit; ++it) { - if ((*it).size() > idx) - virtualFunctions.push_back((*it)[idx]); + if ((*it).size() > idx) virtualFunctions.push_back((*it)[idx]); } } void CHGraph::printCH() { - for (CHGraph::const_iterator it = this->begin(), eit = this->end(); - it != eit; ++it) + for (CHGraph::const_iterator it = this->begin(), eit = this->end(); it != eit; ++it) { - const CHNode *node = it->second; + const CHNode* node = it->second; outs() << "class: " << node->getName() << "\n"; - for (CHEdge::CHEdgeSetTy::const_iterator it = node->OutEdgeBegin(); - it != node->OutEdgeEnd(); ++it) + for (CHEdge::CHEdgeSetTy::const_iterator it = node->OutEdgeBegin(); it != node->OutEdgeEnd(); ++it) { if ((*it)->getEdgeType() == CHEdge::INHERITANCE) - outs() << (*it)->getDstNode()->getName() << " --inheritance--> " - << (*it)->getSrcNode()->getName() << "\n"; + outs() << (*it)->getDstNode()->getName() << " --inheritance--> " << (*it)->getSrcNode()->getName() + << "\n"; else - outs() << (*it)->getSrcNode()->getName() << " --instance--> " - << (*it)->getDstNode()->getName() << "\n"; + outs() << (*it)->getSrcNode()->getName() << " --instance--> " << (*it)->getDstNode()->getName() << "\n"; } } outs() << '\n'; @@ -232,15 +219,11 @@ namespace SVF /*! * Write value flow graph into dot file for debugging */ -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits +template <> struct DOTGraphTraits : public DefaultDOTGraphTraits { typedef CHNode NodeType; - DOTGraphTraits(bool isSimple = false) : - DefaultDOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(CHGraph*) @@ -248,12 +231,12 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return "Class Hierarchy Graph"; } /// Return function name; - static std::string getNodeLabel(CHNode *node, CHGraph*) + static std::string getNodeLabel(CHNode* node, CHGraph*) { return node->getName(); } - static std::string getNodeAttributes(CHNode *node, CHGraph*) + static std::string getNodeAttributes(CHNode* node, CHGraph*) { if (node->isPureAbstract()) { @@ -263,8 +246,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return "shape=box"; } - template - static std::string getEdgeAttributes(CHNode*, EdgeIter EI, CHGraph*) + template static std::string getEdgeAttributes(CHNode*, EdgeIter EI, CHGraph*) { CHEdge* edge = *(EI.getCurrent()); @@ -279,4 +261,4 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits } } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/Graphs/CallGraph.cpp b/svf/lib/Graphs/CallGraph.cpp index cad7a8863..ec54bbf63 100644 --- a/svf/lib/Graphs/CallGraph.cpp +++ b/svf/lib/Graphs/CallGraph.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * CallGraph.cpp * @@ -40,7 +39,6 @@ CallGraph::CallSiteToIdMap CallGraph::csToIdMap; CallGraph::IdToCallSiteMap CallGraph::idToCSMap; CallSiteID CallGraph::totalCallSiteNum = 1; - /// Add direct and indirect callsite //@{ void CallGraphEdge::addDirectCallSite(const CallICFGNode* call) @@ -51,7 +49,9 @@ void CallGraphEdge::addDirectCallSite(const CallICFGNode* call) void CallGraphEdge::addInDirectCallSite(const CallICFGNode* call) { - assert((nullptr == SVFUtil::getCallee(call->getCallSite()) || nullptr == SVFUtil::dyn_cast (SVFUtil::getForkedFun(call->getCallSite()))) && "not an indirect callsite??"); + assert((nullptr == SVFUtil::getCallee(call->getCallSite()) || + nullptr == SVFUtil::dyn_cast(SVFUtil::getForkedFun(call->getCallSite()))) && + "not an indirect callsite??"); indirectCalls.insert(call); } //@} @@ -59,10 +59,9 @@ void CallGraphEdge::addInDirectCallSite(const CallICFGNode* call) const std::string CallGraphEdge::toString() const { std::string str; - std::stringstream rawstr(str); + std::stringstream rawstr(str); rawstr << "CallSite ID: " << getCallSiteID(); - if(isDirectCallEdge()) - rawstr << "direct call"; + if (isDirectCallEdge()) rawstr << "direct call"; else rawstr << "indirect call"; rawstr << "[" << getDstID() << "<--" << getSrcID() << "]\t"; @@ -72,7 +71,7 @@ const std::string CallGraphEdge::toString() const const std::string CallGraphNode::toString() const { std::string str; - std::stringstream rawstr(str); + std::stringstream rawstr(str); rawstr << "CallGraphNode ID: " << getId() << " {fun: " << fun->getName() << "}"; return rawstr.str(); } @@ -89,23 +88,20 @@ bool CallGraphNode::isReachableFromProgEntry() const CallGraphNode* node = const_cast(nodeStack.top()); nodeStack.pop(); - if (SVFUtil::isProgEntryFunction(node->getFunction())) - return true; + if (SVFUtil::isProgEntryFunction(node->getFunction())) return true; for (const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) { CallGraphEdge* edge = *it; - if (visitedNodes.test_and_set(edge->getSrcID())) - nodeStack.push(edge->getSrcNode()); + if (visitedNodes.test_and_set(edge->getSrcID())) nodeStack.push(edge->getSrcNode()); } } return false; } - /// Constructor -CallGraph::CallGraph(CGEK k): kind(k) +CallGraph::CallGraph(CGEK k) : kind(k) { callGraphNodeNum = 0; numOfResolvedIndCallEdge = 0; @@ -114,9 +110,7 @@ CallGraph::CallGraph(CGEK k): kind(k) /*! * Memory has been cleaned up at GenericGraph */ -void CallGraph::destroy() -{ -} +void CallGraph::destroy() {} /*! * Add call graph node @@ -125,7 +119,7 @@ void CallGraph::addCallGraphNode(const SVFFunction* fun) { NodeID id = callGraphNodeNum; CallGraphNode* callGraphNode = new CallGraphNode(id, fun); - addGNode(id,callGraphNode); + addGNode(id, callGraphNode); funToCallGraphNodeMap[fun] = callGraphNode; callGraphNodeNum++; } @@ -133,9 +127,10 @@ void CallGraph::addCallGraphNode(const SVFFunction* fun) /*! * Whether we have already created this call graph edge */ -CallGraphEdge* CallGraph::hasGraphEdge(CallGraphNode* src, CallGraphNode* dst,CallGraphEdge::CEDGEK kind, CallSiteID csId) const +CallGraphEdge* CallGraph::hasGraphEdge(CallGraphNode* src, CallGraphNode* dst, CallGraphEdge::CEDGEK kind, + CallSiteID csId) const { - CallGraphEdge edge(src,dst,kind,csId); + CallGraphEdge edge(src, dst, kind, csId); CallGraphEdge* outEdge = src->hasOutgoingEdge(&edge); CallGraphEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -150,14 +145,12 @@ CallGraphEdge* CallGraph::hasGraphEdge(CallGraphNode* src, CallGraphNode* dst,Ca /*! * get CallGraph edge via nodes */ -CallGraphEdge* CallGraph::getGraphEdge(CallGraphNode* src, CallGraphNode* dst,CallGraphEdge::CEDGEK kind, CallSiteID) +CallGraphEdge* CallGraph::getGraphEdge(CallGraphNode* src, CallGraphNode* dst, CallGraphEdge::CEDGEK kind, CallSiteID) { - for (CallGraphEdge::CallGraphEdgeSet::iterator iter = src->OutEdgeBegin(); - iter != src->OutEdgeEnd(); ++iter) + for (CallGraphEdge::CallGraphEdgeSet::iterator iter = src->OutEdgeBegin(); iter != src->OutEdgeEnd(); ++iter) { CallGraphEdge* edge = (*iter); - if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId()) - return edge; + if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId()) return edge; } return nullptr; } @@ -165,7 +158,8 @@ CallGraphEdge* CallGraph::getGraphEdge(CallGraphNode* src, CallGraphNode* dst,Ca /*! * Add direct call edges */ -void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun) +void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs, const SVFFunction* callerFun, + const SVFFunction* calleeFun) { CallGraphNode* caller = getCallGraphNode(callerFun); @@ -173,9 +167,9 @@ void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* CallSiteID csId = addCallSite(cs, callee->getFunction()); - if(!hasGraphEdge(caller,callee, CallGraphEdge::CallRetEdge,csId)) + if (!hasGraphEdge(caller, callee, CallGraphEdge::CallRetEdge, csId)) { - CallGraphEdge* edge = new CallGraphEdge(caller,callee,CallGraphEdge::CallRetEdge,csId); + CallGraphEdge* edge = new CallGraphEdge(caller, callee, CallGraphEdge::CallRetEdge, csId); edge->addDirectCallSite(cs); addEdge(edge); callinstToCallGraphEdgesMap[cs].insert(edge); @@ -185,7 +179,8 @@ void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* /*! * Add indirect call edge to update call graph */ -void CallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun) +void CallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs, const SVFFunction* callerFun, + const SVFFunction* calleeFun) { CallGraphNode* caller = getCallGraphNode(callerFun); @@ -195,9 +190,9 @@ void CallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunctio CallSiteID csId = addCallSite(cs, callee->getFunction()); - if(!hasGraphEdge(caller,callee, CallGraphEdge::CallRetEdge,csId)) + if (!hasGraphEdge(caller, callee, CallGraphEdge::CallRetEdge, csId)) { - CallGraphEdge* edge = new CallGraphEdge(caller,callee,CallGraphEdge::CallRetEdge, csId); + CallGraphEdge* edge = new CallGraphEdge(caller, callee, CallGraphEdge::CallRetEdge, csId); edge->addInDirectCallSite(cs); addEdge(edge); callinstToCallGraphEdgesMap[cs].insert(edge); @@ -210,16 +205,16 @@ void CallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunctio void CallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet) { CallGraphNode* callGraphNode = getCallGraphNode(callee); - for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); - it!=eit; ++it) + for (CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it != eit; ++it) { - for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->directCallsBegin(), - ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*it)->directCallsBegin(), ecit = (*it)->directCallsEnd(); + cit != ecit; ++cit) { csSet.insert((*cit)); } - for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->indirectCallsBegin(), - ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*it)->indirectCallsBegin(), + ecit = (*it)->indirectCallsEnd(); + cit != ecit; ++cit) { csSet.insert((*cit)); } @@ -232,11 +227,10 @@ void CallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, CallGra void CallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet) { CallGraphNode* callGraphNode = getCallGraphNode(callee); - for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); - it!=eit; ++it) + for (CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it != eit; ++it) { - for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->directCallsBegin(), - ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*it)->directCallsBegin(), ecit = (*it)->directCallsEnd(); + cit != ecit; ++cit) { csSet.insert((*cit)); } @@ -249,11 +243,11 @@ void CallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, CallGra void CallGraph::getIndCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet) { CallGraphNode* callGraphNode = getCallGraphNode(callee); - for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); - it!=eit; ++it) + for (CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it != eit; ++it) { - for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->indirectCallsBegin(), - ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*it)->indirectCallsBegin(), + ecit = (*it)->indirectCallsEnd(); + cit != ecit; ++cit) { csSet.insert((*cit)); } @@ -297,14 +291,12 @@ bool CallGraph::isReachableBetweenFunctions(const SVFFunction* srcFn, const SVFF CallGraphNode* node = const_cast(nodeStack.top()); nodeStack.pop(); - if (node->getFunction() == srcFn) - return true; + if (node->getFunction() == srcFn) return true; for (CallGraphEdgeConstIter it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) { CallGraphEdge* edge = *it; - if (visitedNodes.test_and_set(edge->getSrcID())) - nodeStack.push(edge->getSrcNode()); + if (visitedNodes.test_and_set(edge->getSrcID())) nodeStack.push(edge->getSrcNode()); } } @@ -330,16 +322,12 @@ namespace SVF /*! * Write value flow graph into dot file for debugging */ -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits +template <> struct DOTGraphTraits : public DefaultDOTGraphTraits { typedef CallGraphNode NodeType; typedef NodeType::iterator ChildIteratorType; - DOTGraphTraits(bool isSimple = false) : - DefaultDOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(CallGraph*) @@ -347,12 +335,12 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return "Call Graph"; } /// Return function name; - static std::string getNodeLabel(CallGraphNode *node, CallGraph*) + static std::string getNodeLabel(CallGraphNode* node, CallGraph*) { return node->toString(); } - static std::string getNodeAttributes(CallGraphNode *node, CallGraph*) + static std::string getNodeAttributes(CallGraphNode* node, CallGraph*) { const SVFFunction* fun = node->getFunction(); if (!SVFUtil::isExtCall(fun)) @@ -363,11 +351,10 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return "shape=Mrecord"; } - template - static std::string getEdgeAttributes(CallGraphNode*, EdgeIter EI, CallGraph*) + template static std::string getEdgeAttributes(CallGraphNode*, EdgeIter EI, CallGraph*) { - //TODO: mark indirect call of Fork with different color + // TODO: mark indirect call of Fork with different color CallGraphEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); @@ -392,8 +379,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return color; } - template - static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) { CallGraphEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); @@ -405,4 +391,4 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return rawstr.str(); } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/Graphs/ConsG.cpp b/svf/lib/Graphs/ConsG.cpp index 27bb70ed5..2f02bd071 100644 --- a/svf/lib/Graphs/ConsG.cpp +++ b/svf/lib/Graphs/ConsG.cpp @@ -33,7 +33,6 @@ using namespace SVF; using namespace SVFUtil; - /*! * Start building constraint graph */ @@ -41,104 +40,89 @@ void ConstraintGraph::buildCG() { // initialize nodes - for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; ++it) + for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; ++it) { addConstraintNode(new ConstraintNode(it->first), it->first); } // initialize edges SVFStmt::SVFStmtSetTy& addrs = getPAGEdgeSet(SVFStmt::Addr); - for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter = - addrs.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter = addrs.end(); iter != eiter; ++iter) { const AddrStmt* edge = SVFUtil::cast(*iter); - addAddrCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addAddrCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& copys = getPAGEdgeSet(SVFStmt::Copy); - for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter = - copys.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter = copys.end(); iter != eiter; ++iter) { const CopyStmt* edge = SVFUtil::cast(*iter); - if(edge->isBitCast() || edge->isValueCopy()) - addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + if (edge->isBitCast() || edge->isValueCopy()) addCopyCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& phis = getPAGEdgeSet(SVFStmt::Phi); - for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter = - phis.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter = phis.end(); iter != eiter; ++iter) { const PhiStmt* edge = SVFUtil::cast(*iter); - for(const auto opVar : edge->getOpndVars()) - addCopyCGEdge(opVar->getId(),edge->getResID()); + for (const auto opVar : edge->getOpndVars()) addCopyCGEdge(opVar->getId(), edge->getResID()); } SVFStmt::SVFStmtSetTy& selects = getPAGEdgeSet(SVFStmt::Select); - for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter = - selects.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter = selects.end(); iter != eiter; ++iter) { const SelectStmt* edge = SVFUtil::cast(*iter); - for(const auto opVar : edge->getOpndVars()) - addCopyCGEdge(opVar->getId(),edge->getResID()); + for (const auto opVar : edge->getOpndVars()) addCopyCGEdge(opVar->getId(), edge->getResID()); } SVFStmt::SVFStmtSetTy& calls = getPAGEdgeSet(SVFStmt::Call); - for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter = - calls.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter = calls.end(); iter != eiter; ++iter) { const CallPE* edge = SVFUtil::cast(*iter); - addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addCopyCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& rets = getPAGEdgeSet(SVFStmt::Ret); - for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter = - rets.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter = rets.end(); iter != eiter; ++iter) { const RetPE* edge = SVFUtil::cast(*iter); - addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addCopyCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& tdfks = getPAGEdgeSet(SVFStmt::ThreadFork); - for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter = - tdfks.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter = tdfks.end(); iter != eiter; ++iter) { const TDForkPE* edge = SVFUtil::cast(*iter); - addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addCopyCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& tdjns = getPAGEdgeSet(SVFStmt::ThreadJoin); - for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter = - tdjns.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter = tdjns.end(); iter != eiter; ++iter) { const TDJoinPE* edge = SVFUtil::cast(*iter); - addCopyCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addCopyCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& ngeps = getPAGEdgeSet(SVFStmt::Gep); - for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter = - ngeps.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter = ngeps.end(); iter != eiter; ++iter) { GepStmt* edge = SVFUtil::cast(*iter); - if(edge->isVariantFieldGep()) - addVariantGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + if (edge->isVariantFieldGep()) addVariantGepCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); else - addNormalGepCGEdge(edge->getRHSVarID(),edge->getLHSVarID(),edge->getAccessPath()); + addNormalGepCGEdge(edge->getRHSVarID(), edge->getLHSVarID(), edge->getAccessPath()); } SVFStmt::SVFStmtSetTy& loads = getPAGEdgeSet(SVFStmt::Load); - for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = - loads.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = loads.end(); iter != eiter; ++iter) { LoadStmt* edge = SVFUtil::cast(*iter); - addLoadCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addLoadCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } SVFStmt::SVFStmtSetTy& stores = getPAGEdgeSet(SVFStmt::Store); - for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = - stores.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; ++iter) { StoreStmt* edge = SVFUtil::cast(*iter); - addStoreCGEdge(edge->getRHSVarID(),edge->getLHSVarID()); + addStoreCGEdge(edge->getRHSVarID(), edge->getLHSVarID()); } clearSolitaries(); @@ -152,29 +136,23 @@ void ConstraintGraph::clearSolitaries() Set nodesToRemove; for (auto it = this->begin(); it != this->end(); ++it) { - if (it->second->hasIncomingEdge() || it->second->hasOutgoingEdge()) - continue; - if (pag->getGNode(it->first)->isPointer()) - continue; + if (it->second->hasIncomingEdge() || it->second->hasOutgoingEdge()) continue; + if (pag->getGNode(it->first)->isPointer()) continue; nodesToRemove.insert(it->second); } - for (auto node : nodesToRemove) - removeConstraintNode(node); + for (auto node : nodesToRemove) removeConstraintNode(node); } /*! * Memory has been cleaned up at GenericGraph */ -void ConstraintGraph::destroy() -{ -} +void ConstraintGraph::destroy() {} /*! * Constructor for address constraint graph edge */ -AddrCGEdge::AddrCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) - : ConstraintEdge(s,d,Addr,id) +AddrCGEdge::AddrCGEdge(ConstraintNode* s, ConstraintNode* d, EdgeID id) : ConstraintEdge(s, d, Addr, id) { // Retarget addr edges may lead s to be a dummy node PAGNode* node = SVFIR::getPAG()->getGNode(s->getId()); @@ -192,8 +170,7 @@ AddrCGEdge* ConstraintGraph::addAddrCGEdge(NodeID src, NodeID dst) { ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); - if (hasEdge(srcNode, dstNode, ConstraintEdge::Addr)) - return nullptr; + if (hasEdge(srcNode, dstNode, ConstraintEdge::Addr)) return nullptr; AddrCGEdge* edge = new AddrCGEdge(srcNode, dstNode, edgeIndex++); bool inserted = AddrCGEdgeSet.insert(edge).second; @@ -213,8 +190,7 @@ CopyCGEdge* ConstraintGraph::addCopyCGEdge(NodeID src, NodeID dst) ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); - if (hasEdge(srcNode, dstNode, ConstraintEdge::Copy) || srcNode == dstNode) - return nullptr; + if (hasEdge(srcNode, dstNode, ConstraintEdge::Copy) || srcNode == dstNode) return nullptr; CopyCGEdge* edge = new CopyCGEdge(srcNode, dstNode, edgeIndex++); @@ -227,19 +203,16 @@ CopyCGEdge* ConstraintGraph::addCopyCGEdge(NodeID src, NodeID dst) return edge; } - /*! * Add Gep edge */ -NormalGepCGEdge* ConstraintGraph::addNormalGepCGEdge(NodeID src, NodeID dst, const AccessPath& ap) +NormalGepCGEdge* ConstraintGraph::addNormalGepCGEdge(NodeID src, NodeID dst, const AccessPath& ap) { ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); - if (hasEdge(srcNode, dstNode, ConstraintEdge::NormalGep)) - return nullptr; + if (hasEdge(srcNode, dstNode, ConstraintEdge::NormalGep)) return nullptr; - NormalGepCGEdge* edge = - new NormalGepCGEdge(srcNode, dstNode, ap, edgeIndex++); + NormalGepCGEdge* edge = new NormalGepCGEdge(srcNode, dstNode, ap, edgeIndex++); bool inserted = directEdgeSet.insert(edge).second; (void)inserted; // Suppress warning of unused variable under release build @@ -257,8 +230,7 @@ VariantGepCGEdge* ConstraintGraph::addVariantGepCGEdge(NodeID src, NodeID dst) { ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); - if (hasEdge(srcNode, dstNode, ConstraintEdge::VariantGep)) - return nullptr; + if (hasEdge(srcNode, dstNode, ConstraintEdge::VariantGep)) return nullptr; VariantGepCGEdge* edge = new VariantGepCGEdge(srcNode, dstNode, edgeIndex++); @@ -278,8 +250,7 @@ LoadCGEdge* ConstraintGraph::addLoadCGEdge(NodeID src, NodeID dst) { ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); - if (hasEdge(srcNode, dstNode, ConstraintEdge::Load)) - return nullptr; + if (hasEdge(srcNode, dstNode, ConstraintEdge::Load)) return nullptr; LoadCGEdge* edge = new LoadCGEdge(srcNode, dstNode, edgeIndex++); @@ -299,8 +270,7 @@ StoreCGEdge* ConstraintGraph::addStoreCGEdge(NodeID src, NodeID dst) { ConstraintNode* srcNode = getConstraintNode(src); ConstraintNode* dstNode = getConstraintNode(dst); - if (hasEdge(srcNode, dstNode, ConstraintEdge::Store)) - return nullptr; + if (hasEdge(srcNode, dstNode, ConstraintEdge::Store)) return nullptr; StoreCGEdge* edge = new StoreCGEdge(srcNode, dstNode, edgeIndex++); @@ -313,7 +283,6 @@ StoreCGEdge* ConstraintGraph::addStoreCGEdge(NodeID src, NodeID dst) return edge; } - /*! * Re-target dst node of an edge * @@ -325,33 +294,33 @@ void ConstraintGraph::reTargetDstOfEdge(ConstraintEdge* edge, ConstraintNode* ne { NodeID newDstNodeID = newDstNode->getId(); NodeID srcId = edge->getSrcID(); - if(LoadCGEdge* load = SVFUtil::dyn_cast(edge)) + if (LoadCGEdge* load = SVFUtil::dyn_cast(edge)) { removeLoadEdge(load); - addLoadCGEdge(srcId,newDstNodeID); + addLoadCGEdge(srcId, newDstNodeID); } - else if(StoreCGEdge* store = SVFUtil::dyn_cast(edge)) + else if (StoreCGEdge* store = SVFUtil::dyn_cast(edge)) { removeStoreEdge(store); - addStoreCGEdge(srcId,newDstNodeID); + addStoreCGEdge(srcId, newDstNodeID); } - else if(CopyCGEdge* copy = SVFUtil::dyn_cast(edge)) + else if (CopyCGEdge* copy = SVFUtil::dyn_cast(edge)) { removeDirectEdge(copy); - addCopyCGEdge(srcId,newDstNodeID); + addCopyCGEdge(srcId, newDstNodeID); } - else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast(edge)) + else if (NormalGepCGEdge* gep = SVFUtil::dyn_cast(edge)) { const AccessPath ap = gep->getAccessPath(); removeDirectEdge(gep); - addNormalGepCGEdge(srcId,newDstNodeID, ap); + addNormalGepCGEdge(srcId, newDstNodeID, ap); } - else if(VariantGepCGEdge* gep = SVFUtil::dyn_cast(edge)) + else if (VariantGepCGEdge* gep = SVFUtil::dyn_cast(edge)) { removeDirectEdge(gep); - addVariantGepCGEdge(srcId,newDstNodeID); + addVariantGepCGEdge(srcId, newDstNodeID); } - else if(AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) + else if (AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) { removeAddrEdge(addr); } @@ -369,33 +338,33 @@ void ConstraintGraph::reTargetSrcOfEdge(ConstraintEdge* edge, ConstraintNode* ne { NodeID newSrcNodeID = newSrcNode->getId(); NodeID dstId = edge->getDstID(); - if(LoadCGEdge* load = SVFUtil::dyn_cast(edge)) + if (LoadCGEdge* load = SVFUtil::dyn_cast(edge)) { removeLoadEdge(load); - addLoadCGEdge(newSrcNodeID,dstId); + addLoadCGEdge(newSrcNodeID, dstId); } - else if(StoreCGEdge* store = SVFUtil::dyn_cast(edge)) + else if (StoreCGEdge* store = SVFUtil::dyn_cast(edge)) { removeStoreEdge(store); - addStoreCGEdge(newSrcNodeID,dstId); + addStoreCGEdge(newSrcNodeID, dstId); } - else if(CopyCGEdge* copy = SVFUtil::dyn_cast(edge)) + else if (CopyCGEdge* copy = SVFUtil::dyn_cast(edge)) { removeDirectEdge(copy); - addCopyCGEdge(newSrcNodeID,dstId); + addCopyCGEdge(newSrcNodeID, dstId); } - else if(NormalGepCGEdge* gep = SVFUtil::dyn_cast(edge)) + else if (NormalGepCGEdge* gep = SVFUtil::dyn_cast(edge)) { const AccessPath ap = gep->getAccessPath(); removeDirectEdge(gep); addNormalGepCGEdge(newSrcNodeID, dstId, ap); } - else if(VariantGepCGEdge* gep = SVFUtil::dyn_cast(edge)) + else if (VariantGepCGEdge* gep = SVFUtil::dyn_cast(edge)) { removeDirectEdge(gep); - addVariantGepCGEdge(newSrcNodeID,dstId); + addVariantGepCGEdge(newSrcNodeID, dstId); } - else if(AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) + else if (AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) { removeAddrEdge(addr); } @@ -460,38 +429,35 @@ void ConstraintGraph::removeDirectEdge(ConstraintEdge* edge) * Move incoming direct edges of a sub node which is outside SCC to its rep node * Remove incoming direct edges of a sub node which is inside SCC from its rep node */ -bool ConstraintGraph::moveInEdgesToRepNode(ConstraintNode* node, ConstraintNode* rep ) +bool ConstraintGraph::moveInEdgesToRepNode(ConstraintNode* node, ConstraintNode* rep) { std::vector sccEdges; std::vector nonSccEdges; - for (ConstraintNode::const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; - ++it) + for (ConstraintNode::const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) { ConstraintEdge* subInEdge = *it; - if(sccRepNode(subInEdge->getSrcID()) != rep->getId()) - nonSccEdges.push_back(subInEdge); + if (sccRepNode(subInEdge->getSrcID()) != rep->getId()) nonSccEdges.push_back(subInEdge); else { sccEdges.push_back(subInEdge); } } // if this edge is outside scc, then re-target edge dst to rep - while(!nonSccEdges.empty()) + while (!nonSccEdges.empty()) { ConstraintEdge* edge = nonSccEdges.back(); nonSccEdges.pop_back(); - reTargetDstOfEdge(edge,rep); + reTargetDstOfEdge(edge, rep); } bool criticalGepInsideSCC = false; // if this edge is inside scc, then remove this edge and two end nodes - while(!sccEdges.empty()) + while (!sccEdges.empty()) { ConstraintEdge* edge = sccEdges.back(); sccEdges.pop_back(); /// only copy and gep edge can be removed - if(SVFUtil::isa(edge)) - removeDirectEdge(edge); + if (SVFUtil::isa(edge)) removeDirectEdge(edge); else if (SVFUtil::isa(edge)) { // If the GEP is critical (i.e. may have a non-zero offset), @@ -502,9 +468,9 @@ bool ConstraintGraph::moveInEdgesToRepNode(ConstraintNode* node, ConstraintNode* } removeDirectEdge(edge); } - else if(SVFUtil::isa(edge)) - reTargetDstOfEdge(edge,rep); - else if(AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) + else if (SVFUtil::isa(edge)) + reTargetDstOfEdge(edge, rep); + else if (AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) { removeAddrEdge(addr); } @@ -518,39 +484,36 @@ bool ConstraintGraph::moveInEdgesToRepNode(ConstraintNode* node, ConstraintNode* * Move outgoing direct edges of a sub node which is outside SCC to its rep node * Remove outgoing direct edges of a sub node which is inside SCC from its rep node */ -bool ConstraintGraph::moveOutEdgesToRepNode(ConstraintNode*node, ConstraintNode* rep ) +bool ConstraintGraph::moveOutEdgesToRepNode(ConstraintNode* node, ConstraintNode* rep) { std::vector sccEdges; std::vector nonSccEdges; - for (ConstraintNode::const_iterator it = node->OutEdgeBegin(), eit = node->OutEdgeEnd(); it != eit; - ++it) + for (ConstraintNode::const_iterator it = node->OutEdgeBegin(), eit = node->OutEdgeEnd(); it != eit; ++it) { ConstraintEdge* subOutEdge = *it; - if(sccRepNode(subOutEdge->getDstID()) != rep->getId()) - nonSccEdges.push_back(subOutEdge); + if (sccRepNode(subOutEdge->getDstID()) != rep->getId()) nonSccEdges.push_back(subOutEdge); else { sccEdges.push_back(subOutEdge); } } // if this edge is outside scc, then re-target edge src to rep - while(!nonSccEdges.empty()) + while (!nonSccEdges.empty()) { ConstraintEdge* edge = nonSccEdges.back(); nonSccEdges.pop_back(); - reTargetSrcOfEdge(edge,rep); + reTargetSrcOfEdge(edge, rep); } bool criticalGepInsideSCC = false; // if this edge is inside scc, then remove this edge and two end nodes - while(!sccEdges.empty()) + while (!sccEdges.empty()) { ConstraintEdge* edge = sccEdges.back(); sccEdges.pop_back(); /// only copy and gep edge can be removed - if(SVFUtil::isa(edge)) - removeDirectEdge(edge); + if (SVFUtil::isa(edge)) removeDirectEdge(edge); else if (SVFUtil::isa(edge)) { // If the GEP is critical (i.e. may have a non-zero offset), @@ -561,9 +524,9 @@ bool ConstraintGraph::moveOutEdgesToRepNode(ConstraintNode*node, ConstraintNode* } removeDirectEdge(edge); } - else if(SVFUtil::isa(edge)) - reTargetSrcOfEdge(edge,rep); - else if(AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) + else if (SVFUtil::isa(edge)) + reTargetSrcOfEdge(edge, rep); + else if (AddrCGEdge* addr = SVFUtil::dyn_cast(edge)) { removeAddrEdge(addr); } @@ -573,7 +536,6 @@ bool ConstraintGraph::moveOutEdgesToRepNode(ConstraintNode*node, ConstraintNode* return criticalGepInsideSCC; } - /*! * Dump constraint graph */ @@ -591,55 +553,46 @@ void ConstraintGraph::print() outs() << "-----------------ConstraintGraph--------------------------------------\n"; ConstraintEdge::ConstraintEdgeSetTy& addrs = this->getAddrCGEdges(); - for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = addrs.begin(), - eiter = addrs.end(); iter != eiter; ++iter) + for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = addrs.begin(), eiter = addrs.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID() << "\n"; } ConstraintEdge::ConstraintEdgeSetTy& directs = this->getDirectCGEdges(); - for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = directs.begin(), - eiter = directs.end(); iter != eiter; ++iter) + for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = directs.begin(), eiter = directs.end(); iter != eiter; + ++iter) { if (CopyCGEdge* copy = SVFUtil::dyn_cast(*iter)) { - outs() << copy->getSrcID() << " -- Copy --> " << copy->getDstID() - << "\n"; + outs() << copy->getSrcID() << " -- Copy --> " << copy->getDstID() << "\n"; } else if (NormalGepCGEdge* ngep = SVFUtil::dyn_cast(*iter)) { - outs() << ngep->getSrcID() << " -- NormalGep (" << ngep->getConstantFieldIdx() - << ") --> " << ngep->getDstID() << "\n"; + outs() << ngep->getSrcID() << " -- NormalGep (" << ngep->getConstantFieldIdx() << ") --> " + << ngep->getDstID() << "\n"; } else if (VariantGepCGEdge* vgep = SVFUtil::dyn_cast(*iter)) { - outs() << vgep->getSrcID() << " -- VarintGep --> " - << vgep->getDstID() << "\n"; + outs() << vgep->getSrcID() << " -- VarintGep --> " << vgep->getDstID() << "\n"; } else assert(false && "wrong constraint edge kind!"); } ConstraintEdge::ConstraintEdgeSetTy& loads = this->getLoadCGEdges(); - for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = loads.begin(), - eiter = loads.end(); iter != eiter; ++iter) + for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = loads.begin(), eiter = loads.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID() << "\n"; } ConstraintEdge::ConstraintEdgeSetTy& stores = this->getStoreCGEdges(); - for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = stores.begin(), - eiter = stores.end(); iter != eiter; ++iter) + for (ConstraintEdge::ConstraintEdgeSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; + ++iter) { - outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID() << "\n"; } - outs() - << "--------------------------------------------------------------\n"; - + outs() << "--------------------------------------------------------------\n"; } /*! @@ -654,64 +607,56 @@ void ConstraintGraph::view() //@{ ConstraintNode::iterator ConstraintNode::directOutEdgeBegin() { - if (Options::DetectPWC()) - return directOutEdges.begin(); + if (Options::DetectPWC()) return directOutEdges.begin(); else return copyOutEdges.begin(); } ConstraintNode::iterator ConstraintNode::directOutEdgeEnd() { - if (Options::DetectPWC()) - return directOutEdges.end(); + if (Options::DetectPWC()) return directOutEdges.end(); else return copyOutEdges.end(); } ConstraintNode::iterator ConstraintNode::directInEdgeBegin() { - if (Options::DetectPWC()) - return directInEdges.begin(); + if (Options::DetectPWC()) return directInEdges.begin(); else return copyInEdges.begin(); } ConstraintNode::iterator ConstraintNode::directInEdgeEnd() { - if (Options::DetectPWC()) - return directInEdges.end(); + if (Options::DetectPWC()) return directInEdges.end(); else return copyInEdges.end(); } ConstraintNode::const_iterator ConstraintNode::directOutEdgeBegin() const { - if (Options::DetectPWC()) - return directOutEdges.begin(); + if (Options::DetectPWC()) return directOutEdges.begin(); else return copyOutEdges.begin(); } ConstraintNode::const_iterator ConstraintNode::directOutEdgeEnd() const { - if (Options::DetectPWC()) - return directOutEdges.end(); + if (Options::DetectPWC()) return directOutEdges.end(); else return copyOutEdges.end(); } ConstraintNode::const_iterator ConstraintNode::directInEdgeBegin() const { - if (Options::DetectPWC()) - return directInEdges.begin(); + if (Options::DetectPWC()) return directInEdges.begin(); else return copyInEdges.begin(); } ConstraintNode::const_iterator ConstraintNode::directInEdgeEnd() const { - if (Options::DetectPWC()) - return directInEdges.end(); + if (Options::DetectPWC()) return directInEdges.end(); else return copyInEdges.end(); } @@ -727,15 +672,11 @@ const std::string ConstraintNode::toString() const */ namespace SVF { -template<> -struct DOTGraphTraits : public DOTGraphTraits +template <> struct DOTGraphTraits : public DOTGraphTraits { typedef ConstraintNode NodeType; - DOTGraphTraits(bool isSimple = false) : - DOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(ConstraintGraph*) @@ -743,15 +684,16 @@ struct DOTGraphTraits : public DOTGraphTraits return "ConstraintG"; } - static bool isNodeHidden(NodeType *n, ConstraintGraph *) + static bool isNodeHidden(NodeType* n, ConstraintGraph*) { if (Options::ShowHiddenNode()) return false; - else return (n->getInEdges().empty() && n->getOutEdges().empty()); + else + return (n->getInEdges().empty() && n->getOutEdges().empty()); } /// Return label of a VFG node with two display mode /// Either you can choose to display the name of the value or the whole instruction - static std::string getNodeLabel(NodeType *n, ConstraintGraph*) + static std::string getNodeLabel(NodeType* n, ConstraintGraph*) { PAGNode* node = SVFIR::getPAG()->getGNode(n->getId()); bool briefDisplay = Options::BriefConsCGDotGraph(); @@ -763,8 +705,7 @@ struct DOTGraphTraits : public DOTGraphTraits { if (SVFUtil::isa(node)) { - if (nameDisplay) - rawstr << node->getId() << ":" << node->getValueName(); + if (nameDisplay) rawstr << node->getId() << ":" << node->getValueName(); else rawstr << node->getId(); } @@ -778,19 +719,17 @@ struct DOTGraphTraits : public DOTGraphTraits rawstr << node->getId() << ":" << node->getValue()->toString(); else rawstr << node->getId() << ":"; - } return rawstr.str(); } - static std::string getNodeAttributes(NodeType *n, ConstraintGraph*) + static std::string getNodeAttributes(NodeType* n, ConstraintGraph*) { PAGNode* node = SVFIR::getPAG()->getGNode(n->getId()); if (SVFUtil::isa(node)) { - if(SVFUtil::isa(node)) - return "shape=hexagon"; + if (SVFUtil::isa(node)) return "shape=hexagon"; else if (SVFUtil::isa(node)) return "shape=diamond"; else @@ -798,9 +737,8 @@ struct DOTGraphTraits : public DOTGraphTraits } else if (SVFUtil::isa(node)) { - if(SVFUtil::isa(node)) - return "shape=doubleoctagon"; - else if(SVFUtil::isa(node)) + if (SVFUtil::isa(node)) return "shape=doubleoctagon"; + else if (SVFUtil::isa(node)) return "shape=box3d"; else if (SVFUtil::isa(node)) return "shape=tab"; @@ -822,8 +760,7 @@ struct DOTGraphTraits : public DOTGraphTraits return ""; } - template - static std::string getEdgeAttributes(NodeType*, EdgeIter EI, ConstraintGraph*) + template static std::string getEdgeAttributes(NodeType*, EdgeIter EI, ConstraintGraph*) { ConstraintEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); @@ -835,8 +772,7 @@ struct DOTGraphTraits : public DOTGraphTraits { return "color=black"; } - else if (edge->getEdgeKind() == ConstraintEdge::NormalGep - || edge->getEdgeKind() == ConstraintEdge::VariantGep) + else if (edge->getEdgeKind() == ConstraintEdge::NormalGep || edge->getEdgeKind() == ConstraintEdge::VariantGep) { return "color=purple"; } @@ -855,10 +791,9 @@ struct DOTGraphTraits : public DOTGraphTraits return ""; } - template - static std::string getEdgeSourceLabel(NodeType*, EdgeIter) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter) { return ""; } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/Graphs/GraphWriter.cpp b/svf/lib/Graphs/GraphWriter.cpp index 47130c94a..153391a5a 100644 --- a/svf/lib/Graphs/GraphWriter.cpp +++ b/svf/lib/Graphs/GraphWriter.cpp @@ -9,32 +9,30 @@ #include -std::string SVF::DOT::EscapeStr(const std::string &Label) +std::string SVF::DOT::EscapeStr(const std::string& Label) { std::string Str(Label); - for (unsigned i = 0; i != Str.length(); ++i) - switch (Str[i]) + for (unsigned i = 0; i != Str.length(); ++i) switch (Str[i]) { case '\n': - Str.insert(Str.begin()+i, '\\'); // Escape character... + Str.insert(Str.begin() + i, '\\'); // Escape character... ++i; Str[i] = 'n'; break; case '\t': - Str.insert(Str.begin()+i, ' '); // Convert to two spaces + Str.insert(Str.begin() + i, ' '); // Convert to two spaces ++i; Str[i] = ' '; break; case '\\': - if (i+1 != Str.length()) - switch (Str[i+1]) + if (i + 1 != Str.length()) switch (Str[i + 1]) { case 'l': continue; // don't disturb \l case '|': case '{': case '}': - Str.erase(Str.begin()+i); + Str.erase(Str.begin() + i); continue; default: break; @@ -45,8 +43,8 @@ std::string SVF::DOT::EscapeStr(const std::string &Label) case '>': case '|': case '"': - Str.insert(Str.begin()+i, '\\'); // Escape character... - ++i; // don't infinite loop + Str.insert(Str.begin() + i, '\\'); // Escape character... + ++i; // don't infinite loop break; } return Str; diff --git a/svf/lib/Graphs/ICFG.cpp b/svf/lib/Graphs/ICFG.cpp index 6fb1f329d..f86c89ae9 100644 --- a/svf/lib/Graphs/ICFG.cpp +++ b/svf/lib/Graphs/ICFG.cpp @@ -36,7 +36,6 @@ using namespace SVF; using namespace SVFUtil; - FunEntryICFGNode::FunEntryICFGNode(NodeID id, const SVFFunction* f) : InterICFGNode(id, FunEntryBlock) { fun = f; @@ -47,8 +46,7 @@ FunEntryICFGNode::FunEntryICFGNode(NodeID id, const SVFFunction* f) : InterICFGN } } -FunExitICFGNode::FunExitICFGNode(NodeID id, const SVFFunction* f) - : InterICFGNode(id, FunExitBlock), formalRet(nullptr) +FunExitICFGNode::FunExitICFGNode(NodeID id, const SVFFunction* f) : InterICFGNode(id, FunExitBlock), formalRet(nullptr) { fun = f; // if function is implemented @@ -76,67 +74,55 @@ const std::string GlobalICFGNode::toString() const std::string str; std::stringstream rawstr(str); rawstr << "GlobalICFGNode" << getId(); - for (const SVFStmt *stmt : getSVFStmts()) - rawstr << "\n" << stmt->toString(); + for (const SVFStmt* stmt : getSVFStmts()) rawstr << "\n" << stmt->toString(); return rawstr.str(); } - const std::string IntraICFGNode::toString() const { std::string str; std::stringstream rawstr(str); rawstr << "IntraICFGNode" << getId(); rawstr << " {fun: " << getFun()->getName() << getInst()->getSourceLoc() << "}"; - for (const SVFStmt *stmt : getSVFStmts()) - rawstr << "\n" << stmt->toString(); - if(getSVFStmts().empty()) - rawstr << "\n" << getInst()->toString(); + for (const SVFStmt* stmt : getSVFStmts()) rawstr << "\n" << stmt->toString(); + if (getSVFStmts().empty()) rawstr << "\n" << getInst()->toString(); return rawstr.str(); } - const std::string FunEntryICFGNode::toString() const { std::string str; std::stringstream rawstr(str); rawstr << "FunEntryICFGNode" << getId(); rawstr << " {fun: " << getFun()->getName(); - if (isExtCall(getFun())==false) - rawstr << getFun()->getSourceLoc(); + if (isExtCall(getFun()) == false) rawstr << getFun()->getSourceLoc(); rawstr << "}"; - for (const SVFStmt *stmt : getSVFStmts()) - rawstr << "\n" << stmt->toString(); + for (const SVFStmt* stmt : getSVFStmts()) rawstr << "\n" << stmt->toString(); return rawstr.str(); } const std::string FunExitICFGNode::toString() const { - const SVFFunction *fun = getFun(); + const SVFFunction* fun = getFun(); std::string str; std::stringstream rawstr(str); rawstr << "FunExitICFGNode" << getId(); rawstr << " {fun: " << fun->getName(); // ensure the enclosing function has exit basic block - if (!isExtCall(fun) && fun->hasReturn()) - rawstr << fun->getExitBB()->front()->getSourceLoc(); + if (!isExtCall(fun) && fun->hasReturn()) rawstr << fun->getExitBB()->front()->getSourceLoc(); rawstr << "}"; - for (const SVFStmt *stmt : getSVFStmts()) - rawstr << "\n" << stmt->toString(); + for (const SVFStmt* stmt : getSVFStmts()) rawstr << "\n" << stmt->toString(); return rawstr.str(); } - const std::string CallICFGNode::toString() const { std::string str; std::stringstream rawstr(str); rawstr << "CallICFGNode" << getId(); rawstr << " {fun: " << getFun()->getName() << getCallSite()->getSourceLoc() << "}"; - for (const SVFStmt *stmt : getSVFStmts()) - rawstr << "\n" << stmt->toString(); - if(getSVFStmts().empty() && cs) - rawstr << "\n" << cs->toString(); + for (const SVFStmt* stmt : getSVFStmts()) rawstr << "\n" << stmt->toString(); + if (getSVFStmts().empty() && cs) rawstr << "\n" << cs->toString(); return rawstr.str(); } @@ -146,10 +132,8 @@ const std::string RetICFGNode::toString() const std::stringstream rawstr(str); rawstr << "RetICFGNode" << getId(); rawstr << " {fun: " << getFun()->getName() << getCallSite()->getSourceLoc() << "}"; - for (const SVFStmt *stmt : getSVFStmts()) - rawstr << "\n" << stmt->toString(); - if(getSVFStmts().empty() && cs) - rawstr << "\n" << cs->toString(); + for (const SVFStmt* stmt : getSVFStmts()) rawstr << "\n" << stmt->toString(); + if (getSVFStmts().empty() && cs) rawstr << "\n" << cs->toString(); return rawstr.str(); } @@ -165,10 +149,12 @@ const std::string IntraCFGEdge::toString() const { std::string str; std::stringstream rawstr(str); - if(getCondition() == nullptr) + if (getCondition() == nullptr) rawstr << "IntraCFGEdge: [ICFGNode" << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t"; else - rawstr << "IntraCFGEdge: [ICFGNode" << getDstID() << " <-- ICFGNode" << getSrcID() << "] (branchCondition:" << getCondition()->toString() << ") (succCondValue: " << getSuccessorCondValue() << ") \t"; + rawstr << "IntraCFGEdge: [ICFGNode" << getDstID() << " <-- ICFGNode" << getSrcID() + << "] (branchCondition:" << getCondition()->toString() << ") (succCondValue: " << getSuccessorCondValue() + << ") \t"; return rawstr.str(); } @@ -177,7 +163,8 @@ const std::string CallCFGEdge::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "CallCFGEdge " << " [ICFGNode"; + rawstr << "CallCFGEdge " + << " [ICFGNode"; rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << cs->toString() << "\t"; return rawstr.str(); } @@ -186,7 +173,8 @@ const std::string RetCFGEdge::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "RetCFGEdge " << " [ICFGNode"; + rawstr << "RetCFGEdge " + << " [ICFGNode"; rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << cs->toString() << "\t"; return rawstr.str(); } @@ -199,22 +187,20 @@ const std::string RetCFGEdge::toString() const * 2) connect ICFG edges * between two statements (PAGEdges) */ -ICFG::ICFG(): totalICFGNode(0), globalBlockNode(nullptr) -{ -} +ICFG::ICFG() : totalICFGNode(0), globalBlockNode(nullptr) {} ICFG::~ICFG() { Set loops; - for (const auto &it: icfgNodeToSVFLoopVec) + for (const auto& it : icfgNodeToSVFLoopVec) { - for (const auto &loop: it.second) + for (const auto& loop : it.second) { loops.insert(loop); } } - for (const auto &it: loops) + for (const auto& it : loops) { delete it; } @@ -225,29 +211,25 @@ ICFG::~ICFG() ICFGNode* ICFG::getICFGNode(const SVFInstruction* inst) { ICFGNode* node; - if(SVFUtil::isNonInstricCallSite(inst)) - node = getCallICFGNode(inst); - else if(SVFUtil::isIntrinsicInst(inst)) + if (SVFUtil::isNonInstricCallSite(inst)) node = getCallICFGNode(inst); + else if (SVFUtil::isIntrinsicInst(inst)) node = getIntraICFGNode(inst); -// assert (false && "associating an intrinsic instruction with an ICFGNode!"); + // assert (false && "associating an intrinsic instruction with an ICFGNode!"); else node = getIntraICFGNode(inst); - assert (node!=nullptr && "no ICFGNode for this instruction?"); + assert(node != nullptr && "no ICFGNode for this instruction?"); return node; } - CallICFGNode* ICFG::getCallICFGNode(const SVFInstruction* inst) { - if(SVFUtil::isCallSite(inst) ==false) - outs() << inst->toString() << "\n"; + if (SVFUtil::isCallSite(inst) == false) outs() << inst->toString() << "\n"; assert(SVFUtil::isCallSite(inst) && "not a call instruction?"); assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!"); CallICFGNode* node = getCallBlock(inst); - if(node==nullptr) - node = addCallBlock(inst); - assert (node!=nullptr && "no CallICFGNode for this instruction?"); + if (node == nullptr) node = addCallBlock(inst); + assert(node != nullptr && "no CallICFGNode for this instruction?"); return node; } @@ -256,35 +238,31 @@ RetICFGNode* ICFG::getRetICFGNode(const SVFInstruction* inst) assert(SVFUtil::isCallSite(inst) && "not a call instruction?"); assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!"); RetICFGNode* node = getRetBlock(inst); - if(node==nullptr) - node = addRetBlock(inst); - assert (node!=nullptr && "no RetICFGNode for this instruction?"); + if (node == nullptr) node = addRetBlock(inst); + assert(node != nullptr && "no RetICFGNode for this instruction?"); return node; } IntraICFGNode* ICFG::getIntraICFGNode(const SVFInstruction* inst) { IntraICFGNode* node = getIntraBlock(inst); - if(node==nullptr) - node = addIntraBlock(inst); + if (node == nullptr) node = addIntraBlock(inst); return node; } /// Add a function entry node -FunEntryICFGNode* ICFG::getFunEntryICFGNode(const SVFFunction* fun) +FunEntryICFGNode* ICFG::getFunEntryICFGNode(const SVFFunction* fun) { FunEntryICFGNode* b = getFunEntryBlock(fun); - if (b == nullptr) - return addFunEntryBlock(fun); + if (b == nullptr) return addFunEntryBlock(fun); else return b; } /// Add a function exit node -FunExitICFGNode* ICFG::getFunExitICFGNode(const SVFFunction* fun) +FunExitICFGNode* ICFG::getFunExitICFGNode(const SVFFunction* fun) { FunExitICFGNode* b = getFunExitBlock(fun); - if (b == nullptr) - return addFunExitBlock(fun); + if (b == nullptr) return addFunExitBlock(fun); else return b; } @@ -294,7 +272,7 @@ FunExitICFGNode* ICFG::getFunExitICFGNode(const SVFFunction* fun) */ ICFGEdge* ICFG::hasIntraICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEdgeK kind) { - ICFGEdge edge(src,dst,kind); + ICFGEdge edge(src, dst, kind); ICFGEdge* outEdge = src->hasOutgoingEdge(&edge); ICFGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -311,7 +289,7 @@ ICFGEdge* ICFG::hasIntraICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEdg */ ICFGEdge* ICFG::hasInterICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEdgeK kind) { - ICFGEdge edge(src,dst, kind); + ICFGEdge edge(src, dst, kind); ICFGEdge* outEdge = src->hasOutgoingEdge(&edge); ICFGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -328,7 +306,7 @@ ICFGEdge* ICFG::hasInterICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEdg */ ICFGEdge* ICFG::hasThreadICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEdgeK kind) { - ICFGEdge edge(src,dst,kind); + ICFGEdge edge(src, dst, kind); ICFGEdge* outEdge = src->hasOutgoingEdge(&edge); ICFGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -340,17 +318,15 @@ ICFGEdge* ICFG::hasThreadICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEd return nullptr; } - /*! * Return the corresponding ICFGEdge */ ICFGEdge* ICFG::getICFGEdge(const ICFGNode* src, const ICFGNode* dst, ICFGEdge::ICFGEdgeK kind) { - ICFGEdge * edge = nullptr; + ICFGEdge* edge = nullptr; u32_t counter = 0; - for (ICFGEdge::ICFGEdgeSetTy::iterator iter = src->OutEdgeBegin(); - iter != src->OutEdgeEnd(); ++iter) + for (ICFGEdge::ICFGEdgeSetTy::iterator iter = src->OutEdgeBegin(); iter != src->OutEdgeEnd(); ++iter) { if ((*iter)->getDstID() == dst->getId() && (*iter)->getEdgeKind() == kind) { @@ -360,7 +336,6 @@ ICFGEdge* ICFG::getICFGEdge(const ICFGNode* src, const ICFGNode* dst, ICFGEdge:: } assert(counter <= 1 && "there's more than one edge between two ICFG nodes"); return edge; - } /*! @@ -377,7 +352,7 @@ ICFGEdge* ICFG::addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode) } else { - IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode,dstNode); + IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode, dstNode); return (addICFGEdge(intraEdge) ? intraEdge : nullptr); } } @@ -385,7 +360,8 @@ ICFGEdge* ICFG::addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode) /*! * Add conditional intraprocedural edges between two nodes */ -ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, s32_t branchCondVal) +ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, + s32_t branchCondVal) { checkIntraEdgeParents(srcNode, dstNode); @@ -397,19 +373,18 @@ ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, co } else { - IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode,dstNode); - intraEdge->setBranchCondition(condition,branchCondVal); + IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode, dstNode); + intraEdge->setBranchCondition(condition, branchCondVal); return (addICFGEdge(intraEdge) ? intraEdge : nullptr); } } - /*! * Add interprocedural call edges between two nodes */ -ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs) +ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs) { - ICFGEdge* edge = hasInterICFGEdge(srcNode,dstNode, ICFGEdge::CallCF); + ICFGEdge* edge = hasInterICFGEdge(srcNode, dstNode, ICFGEdge::CallCF); if (edge != nullptr) { assert(edge->isCallCFGEdge() && "this should be a call CFG edge!"); @@ -417,7 +392,7 @@ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstr } else { - CallCFGEdge* callEdge = new CallCFGEdge(srcNode,dstNode,cs); + CallCFGEdge* callEdge = new CallCFGEdge(srcNode, dstNode, cs); return (addICFGEdge(callEdge) ? callEdge : nullptr); } } @@ -425,7 +400,7 @@ ICFGEdge* ICFG::addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstr /*! * Add interprocedural return edges between two nodes */ -ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs) +ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstruction* cs) { ICFGEdge* edge = hasInterICFGEdge(srcNode, dstNode, ICFGEdge::RetCF); if (edge != nullptr) @@ -435,12 +410,11 @@ ICFGEdge* ICFG::addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFInstru } else { - RetCFGEdge* retEdge = new RetCFGEdge(srcNode,dstNode,cs); + RetCFGEdge* retEdge = new RetCFGEdge(srcNode, dstNode, cs); return (addICFGEdge(retEdge) ? retEdge : nullptr); } } - /*! * Dump ICFG */ @@ -469,47 +443,46 @@ void ICFG::updateCallGraph(CallGraph* callgraph) const CallICFGNode* callBlock = iter->first; const SVFInstruction* cs = callBlock->getCallSite(); assert(callBlock->isIndirectCall() && "this is not an indirect call?"); - const CallGraph::FunctionSet & functions = iter->second; - for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) + const CallGraph::FunctionSet& functions = iter->second; + for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); + func_iter++) { - const SVFFunction* callee = *func_iter; + const SVFFunction* callee = *func_iter; CallICFGNode* callBlockNode = getCallICFGNode(cs); RetICFGNode* retBlockNode = getRetICFGNode(cs); /// if this is an external function (no function body), connect calleeEntryNode to calleeExitNode - if (isExtCall(callee)) - addIntraEdge(callBlockNode, retBlockNode); + if (isExtCall(callee)) addIntraEdge(callBlockNode, retBlockNode); else { FunEntryICFGNode* calleeEntryNode = getFunEntryBlock(callee); FunExitICFGNode* calleeExitNode = getFunExitBlock(callee); - if(ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode, cs)) + if (ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode, cs)) { - for (const SVFStmt *stmt : callBlockNode->getSVFStmts()) + for (const SVFStmt* stmt : callBlockNode->getSVFStmts()) { - if(const CallPE *callPE = SVFUtil::dyn_cast(stmt)) + if (const CallPE* callPE = SVFUtil::dyn_cast(stmt)) { - if(callPE->getFunEntryICFGNode() == calleeEntryNode) + if (callPE->getFunEntryICFGNode() == calleeEntryNode) SVFUtil::cast(callEdge)->addCallPE(callPE); } } } - if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode, cs)) + if (ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode, cs)) { - for (const SVFStmt *stmt : retBlockNode->getSVFStmts()) + for (const SVFStmt* stmt : retBlockNode->getSVFStmts()) { - if(const RetPE *retPE = SVFUtil::dyn_cast(stmt)) + if (const RetPE* retPE = SVFUtil::dyn_cast(stmt)) { - if(retPE->getFunExitICFGNode() == calleeExitNode) + if (retPE->getFunExitICFGNode() == calleeExitNode) SVFUtil::cast(retEdge)->addRetPE(retPE); } } } /// Remove callBlockNode to retBlockNode intraICFGEdge since we found at least one inter procedural edge - if(ICFGEdge* edge = hasIntraICFGEdge(callBlockNode,retBlockNode, ICFGEdge::IntraCF)) + if (ICFGEdge* edge = hasIntraICFGEdge(callBlockNode, retBlockNode, ICFGEdge::IntraCF)) removeICFGEdge(edge); } - } } // dump ICFG @@ -524,15 +497,11 @@ void ICFG::updateCallGraph(CallGraph* callgraph) */ namespace SVF { -template<> -struct DOTGraphTraits : public DOTGraphTraits +template <> struct DOTGraphTraits : public DOTGraphTraits { typedef ICFGNode NodeType; - DOTGraphTraits(bool isSimple = false) : - DOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(ICFG*) @@ -540,69 +509,66 @@ struct DOTGraphTraits : public DOTGraphTraits return "ICFG"; } - std::string getNodeLabel(NodeType *node, ICFG *graph) + std::string getNodeLabel(NodeType* node, ICFG* graph) { return getSimpleNodeLabel(node, graph); } /// Return the label of an ICFG node - static std::string getSimpleNodeLabel(NodeType *node, ICFG*) + static std::string getSimpleNodeLabel(NodeType* node, ICFG*) { return node->toString(); } - static bool isNodeHidden(ICFGNode *node, ICFG *) + static bool isNodeHidden(ICFGNode* node, ICFG*) { - if (Options::ShowHiddenNode()) - return false; + if (Options::ShowHiddenNode()) return false; else return node->getInEdges().empty() && node->getOutEdges().empty(); } - static std::string getNodeAttributes(NodeType *node, ICFG*) + static std::string getNodeAttributes(NodeType* node, ICFG*) { std::string str; std::stringstream rawstr(str); - if(SVFUtil::isa(node)) + if (SVFUtil::isa(node)) { - rawstr << "color=black"; + rawstr << "color=black"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow"; + rawstr << "color=yellow"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=green"; + rawstr << "color=green"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=red"; + rawstr << "color=red"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=blue"; + rawstr << "color=blue"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=purple"; + rawstr << "color=purple"; } else assert(false && "no such kind of node!!"); - rawstr << ""; + rawstr << ""; return rawstr.str(); } - template - static std::string getEdgeAttributes(NodeType*, EdgeIter EI, ICFG*) + template static std::string getEdgeAttributes(NodeType*, EdgeIter EI, ICFG*) { ICFGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); - if (SVFUtil::isa(edge)) - return "style=solid,color=red"; + if (SVFUtil::isa(edge)) return "style=solid,color=red"; else if (SVFUtil::isa(edge)) return "style=solid,color=blue"; else @@ -610,20 +576,18 @@ struct DOTGraphTraits : public DOTGraphTraits return ""; } - template - static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) { ICFGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); std::string str; std::stringstream rawstr(str); - if (CallCFGEdge* dirCall = SVFUtil::dyn_cast(edge)) - rawstr << dirCall->getCallSite(); + if (CallCFGEdge* dirCall = SVFUtil::dyn_cast(edge)) rawstr << dirCall->getCallSite(); else if (RetCFGEdge* dirRet = SVFUtil::dyn_cast(edge)) rawstr << dirRet->getCallSite(); return rawstr.str(); } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/Graphs/IRGraph.cpp b/svf/lib/Graphs/IRGraph.cpp index 824eba71e..ed773a8d8 100644 --- a/svf/lib/Graphs/IRGraph.cpp +++ b/svf/lib/Graphs/IRGraph.cpp @@ -45,10 +45,8 @@ IRGraph::~IRGraph() bool IRGraph::addEdge(SVFVar* src, SVFVar* dst, SVFStmt* edge) { - DBOUT(DPAGBuild, - outs() << "add edge from " << src->getId() << " kind :" - << src->getNodeKind() << " to " << dst->getId() - << " kind :" << dst->getNodeKind() << "\n"); + DBOUT(DPAGBuild, outs() << "add edge from " << src->getId() << " kind :" << src->getNodeKind() << " to " + << dst->getId() << " kind :" << dst->getNodeKind() << "\n"); src->addOutEdge(edge); dst->addInEdge(edge); return true; @@ -59,7 +57,7 @@ bool IRGraph::addEdge(SVFVar* src, SVFVar* dst, SVFStmt* edge) */ SVFStmt* IRGraph::hasNonlabeledEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind) { - SVFStmt edge(src,dst,kind, false); + SVFStmt edge(src, dst, kind, false); SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge); if (it != KindToSVFStmtSetMap[kind].end()) { @@ -73,7 +71,7 @@ SVFStmt* IRGraph::hasNonlabeledEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK ki */ SVFStmt* IRGraph::hasLabeledEdge(SVFVar* src, SVFVar* op1, SVFStmt::PEDGEK kind, const SVFVar* op2) { - SVFStmt edge(src,op1,SVFStmt::makeEdgeFlagWithAddionalOpnd(kind,op2), false); + SVFStmt edge(src, op1, SVFStmt::makeEdgeFlagWithAddionalOpnd(kind, op2), false); SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge); if (it != KindToSVFStmtSetMap[kind].end()) { @@ -87,7 +85,7 @@ SVFStmt* IRGraph::hasLabeledEdge(SVFVar* src, SVFVar* op1, SVFStmt::PEDGEK kind, */ SVFStmt* IRGraph::hasLabeledEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind, const ICFGNode* callInst) { - SVFStmt edge(src,dst,SVFStmt::makeEdgeFlagWithCallInst(kind,callInst), false); + SVFStmt edge(src, dst, SVFStmt::makeEdgeFlagWithCallInst(kind, callInst), false); SVFStmt::SVFStmtSetTy::iterator it = KindToSVFStmtSetMap[kind].find(&edge); if (it != KindToSVFStmtSetMap[kind].end()) { @@ -112,59 +110,52 @@ void IRGraph::view() SVF::ViewGraph(this, "ProgramAssignmentGraph"); } - namespace SVF { /*! * Write value flow graph into dot file for debugging */ -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits +template <> struct DOTGraphTraits : public DefaultDOTGraphTraits { typedef SVFVar NodeType; typedef NodeType::iterator ChildIteratorType; - DOTGraphTraits(bool isSimple = false) : - DefaultDOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} /// Return name of the graph - static std::string getGraphName(IRGraph *graph) + static std::string getGraphName(IRGraph* graph) { return graph->getGraphName(); } /// isNodeHidden - If the function returns true, the given node is not /// displayed in the graph - static bool isNodeHidden(SVFVar *node, IRGraph *) + static bool isNodeHidden(SVFVar* node, IRGraph*) { if (Options::ShowHiddenNode()) return false; - else return node->isIsolatedNode(); + else + return node->isIsolatedNode(); } /// Return label of a VFG node with two display mode /// Either you can choose to display the name of the value or the whole instruction - static std::string getNodeLabel(SVFVar *node, IRGraph*) + static std::string getNodeLabel(SVFVar* node, IRGraph*) { std::string str; std::stringstream rawstr(str); // print function info - if (node->getFunction()) - rawstr << "[" << node->getFunction()->getName() << "] "; + if (node->getFunction()) rawstr << "[" << node->getFunction()->getName() << "] "; rawstr << node->toString(); return rawstr.str(); - } - static std::string getNodeAttributes(SVFVar *node, IRGraph*) + static std::string getNodeAttributes(SVFVar* node, IRGraph*) { if (SVFUtil::isa(node)) { - if(SVFUtil::isa(node)) - return "shape=hexagon"; + if (SVFUtil::isa(node)) return "shape=hexagon"; else if (SVFUtil::isa(node)) return "shape=diamond"; else @@ -172,9 +163,8 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits } else if (SVFUtil::isa(node)) { - if(SVFUtil::isa(node)) - return "shape=doubleoctagon"; - else if(SVFUtil::isa(node)) + if (SVFUtil::isa(node)) return "shape=doubleoctagon"; + else if (SVFUtil::isa(node)) return "shape=box3d"; else if (SVFUtil::isa(node)) return "shape=tab"; @@ -196,8 +186,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return ""; } - template - static std::string getEdgeAttributes(SVFVar*, EdgeIter EI, IRGraph*) + template static std::string getEdgeAttributes(SVFVar*, EdgeIter EI, IRGraph*) { const SVFStmt* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); @@ -266,22 +255,21 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits exit(1); } - template - static std::string getEdgeSourceLabel(SVFVar*, EdgeIter EI) + template static std::string getEdgeSourceLabel(SVFVar*, EdgeIter EI) { const SVFStmt* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); - if(const CallPE* calledge = SVFUtil::dyn_cast(edge)) + if (const CallPE* calledge = SVFUtil::dyn_cast(edge)) { - const SVFInstruction* callInst= calledge->getCallSite()->getCallSite(); + const SVFInstruction* callInst = calledge->getCallSite()->getCallSite(); return callInst->getSourceLoc(); } - else if(const RetPE* retedge = SVFUtil::dyn_cast(edge)) + else if (const RetPE* retedge = SVFUtil::dyn_cast(edge)) { - const SVFInstruction* callInst= retedge->getCallSite()->getCallSite(); + const SVFInstruction* callInst = retedge->getCallSite()->getCallSite(); return callInst->getSourceLoc(); } return ""; } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/Graphs/SVFG.cpp b/svf/lib/Graphs/SVFG.cpp index 603debb0d..0ae635c5f 100644 --- a/svf/lib/Graphs/SVFG.cpp +++ b/svf/lib/Graphs/SVFG.cpp @@ -49,7 +49,7 @@ const NodeBS MRSVFGNode::getDefSVFVars() const const std::string MRSVFGNode::toString() const { std::string str; - std::stringstream rawstr(str); + std::stringstream rawstr(str); rawstr << "MRSVFGNode ID: " << getId(); return rawstr.str(); } @@ -59,8 +59,8 @@ const std::string FormalINSVFGNode::toString() const std::string str; std::stringstream rawstr(str); rawstr << "FormalINSVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}"; - rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << - " = ENCHI(MR_" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n"; + rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << " = ENCHI(MR_" + << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n"; rawstr << getMRVer()->getMR()->dumpStr() << "\n"; return rawstr.str(); } @@ -71,7 +71,7 @@ const std::string FormalOUTSVFGNode::toString() const std::stringstream rawstr(str); rawstr << "FormalOUTSVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}"; rawstr << "RETMU(" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n"; - rawstr << getMRVer()->getMR()->dumpStr() << "\n"; + rawstr << getMRVer()->getMR()->dumpStr() << "\n"; return rawstr.str(); } @@ -79,7 +79,8 @@ const std::string ActualINSVFGNode::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "ActualINSVFGNode ID: " << getId() << " at callsite: " << getCallSite()->getCallSite()->toString() << " {fun: " << getFun()->getName() << "}"; + rawstr << "ActualINSVFGNode ID: " << getId() << " at callsite: " << getCallSite()->getCallSite()->toString() + << " {fun: " << getFun()->getName() << "}"; rawstr << "CSMU(" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n"; rawstr << getMRVer()->getMR()->dumpStr() << "\n"; rawstr << "CS[" << getCallSite()->getCallSite()->getSourceLoc() << "]"; @@ -90,11 +91,12 @@ const std::string ActualOUTSVFGNode::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "ActualOUTSVFGNode ID: " << getId() << " at callsite: " << getCallSite()->getCallSite()->toString() << " {fun: " << getFun()->getName() << "}"; - rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << - " = CSCHI(MR_" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n"; + rawstr << "ActualOUTSVFGNode ID: " << getId() << " at callsite: " << getCallSite()->getCallSite()->toString() + << " {fun: " << getFun()->getName() << "}"; + rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << " = CSCHI(MR_" + << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n"; rawstr << getMRVer()->getMR()->dumpStr() << "\n"; - rawstr << "CS[" << getCallSite()->getCallSite()->getSourceLoc() << "]" ; + rawstr << "CS[" << getCallSite()->getCallSite()->getSourceLoc() << "]"; return rawstr.str(); } @@ -103,10 +105,8 @@ const std::string MSSAPHISVFGNode::toString() const std::string str; std::stringstream rawstr(str); rawstr << "MSSAPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}"; - rawstr << "MR_" << getResVer()->getMR()->getMRID() - << "V_" << getResVer()->getSSAVersion() << " = PHI("; - for (MemSSA::PHI::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); - it != eit; it++) + rawstr << "MR_" << getResVer()->getMR()->getMRID() << "V_" << getResVer()->getSSAVersion() << " = PHI("; + for (MemSSA::PHI::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); it != eit; it++) rawstr << "MR_" << it->second->getMR()->getMRID() << "V_" << it->second->getSSAVersion() << ", "; rawstr << ")\n"; @@ -135,10 +135,10 @@ const std::string InterMSSAPHISVFGNode::toString() const { std::string str; std::stringstream rawstr(str); - if(isFormalINPHI()) - rawstr << "FormalINPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}"; + if (isFormalINPHI()) rawstr << "FormalINPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}"; else - rawstr << "ActualOUTPHISVFGNode ID: " << getId() << " at callsite: " << getCallSite()->getCallSite()->toString() << " {fun: " << getFun()->getName() << "}"; + rawstr << "ActualOUTPHISVFGNode ID: " << getId() << " at callsite: " << getCallSite()->getCallSite()->toString() + << " {fun: " << getFun()->getName() << "}"; rawstr << MSSAPHISVFGNode::toString(); return rawstr.str(); } @@ -177,7 +177,6 @@ const std::string RetIndSVFGEdge::toString() const return rawstr.str(); } - const std::string ThreadMHPIndSVFGEdge::toString() const { std::string str; @@ -186,8 +185,8 @@ const std::string ThreadMHPIndSVFGEdge::toString() const return rawstr.str(); } - -FormalOUTSVFGNode::FormalOUTSVFGNode(NodeID id, const MRVer* mrVer, const FunExitICFGNode* funExit): MRSVFGNode(id, FPOUT) +FormalOUTSVFGNode::FormalOUTSVFGNode(NodeID id, const MRVer* mrVer, const FunExitICFGNode* funExit) + : MRSVFGNode(id, FPOUT) { cpts = mrVer->getMR()->getPointsTo(); ver = mrVer; @@ -197,7 +196,8 @@ FormalOUTSVFGNode::FormalOUTSVFGNode(NodeID id, const MRVer* mrVer, const FunExi /*! * Constructor */ -SVFG::SVFG(std::unique_ptr mssa, VFGK k): VFG(mssa->getPTA()->getCallGraph(),k),mssa(std::move(mssa)), pta(this->mssa->getPTA()) +SVFG::SVFG(std::unique_ptr mssa, VFGK k) + : VFG(mssa->getPTA()->getCallGraph(), k), mssa(std::move(mssa)), pta(this->mssa->getPTA()) { stat = new SVFGStat(this); } @@ -240,8 +240,7 @@ void SVFG::buildSVFG() stat->indVFEdgeStart(); connectIndirectSVFGEdges(); stat->indVFEdgeEnd(); - if (!Options::WriteSVFG().empty()) - writeToFile(Options::WriteSVFG()); + if (!Options::WriteSVFG().empty()) writeToFile(Options::WriteSVFG()); } } @@ -253,70 +252,72 @@ void SVFG::addSVFGNodesForAddrTakenVars() // set defs for address-taken vars defined at store statements SVFStmt::SVFStmtSetTy& stores = getPAGEdgeSet(SVFStmt::Store); - for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = - stores.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; ++iter) { StoreStmt* store = SVFUtil::cast(*iter); const StmtSVFGNode* sNode = getStmtVFGNode(store); - for(CHISet::iterator pi = mssa->getCHISet(store).begin(), epi = mssa->getCHISet(store).end(); pi!=epi; ++pi) - setDef((*pi)->getResVer(),sNode); + for (CHISet::iterator pi = mssa->getCHISet(store).begin(), epi = mssa->getCHISet(store).end(); pi != epi; ++pi) + setDef((*pi)->getResVer(), sNode); } /// set defs for address-taken vars defined at phi/chi/call /// create corresponding def and use nodes for address-taken vars (a.k.a MRVers) /// initialize memory SSA phi nodes (phi of address-taken variables) - for(MemSSA::BBToPhiSetMap::iterator it = mssa->getBBToPhiSetMap().begin(), - eit = mssa->getBBToPhiSetMap().end(); it!=eit; ++it) + for (MemSSA::BBToPhiSetMap::iterator it = mssa->getBBToPhiSetMap().begin(), eit = mssa->getBBToPhiSetMap().end(); + it != eit; ++it) { - for(PHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi) + for (PHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi != epi; ++pi) { - MemSSA::PHI* phi = *pi; + MemSSA::PHI* phi = *pi; const SVFInstruction* inst = phi->getBasicBlock()->front(); - addIntraMSSAPHISVFGNode(pag->getICFG()->getICFGNode(inst), phi->opVerBegin(), phi->opVerEnd(),phi->getResVer(), totalVFGNode++); + addIntraMSSAPHISVFGNode(pag->getICFG()->getICFGNode(inst), phi->opVerBegin(), phi->opVerEnd(), + phi->getResVer(), totalVFGNode++); } } /// initialize memory SSA entry chi nodes - for(MemSSA::FunToEntryChiSetMap::iterator it = mssa->getFunToEntryChiSetMap().begin(), - eit = mssa->getFunToEntryChiSetMap().end(); it!=eit; ++it) + for (MemSSA::FunToEntryChiSetMap::iterator it = mssa->getFunToEntryChiSetMap().begin(), + eit = mssa->getFunToEntryChiSetMap().end(); + it != eit; ++it) { - for(CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi) + for (CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi != epi; ++pi) { const MemSSA::ENTRYCHI* chi = SVFUtil::cast(*pi); - addFormalINSVFGNode(pag->getICFG()->getFunEntryICFGNode(chi->getFunction()), chi->getResVer(), totalVFGNode++); + addFormalINSVFGNode(pag->getICFG()->getFunEntryICFGNode(chi->getFunction()), chi->getResVer(), + totalVFGNode++); } } /// initialize memory SSA return mu nodes - for(MemSSA::FunToReturnMuSetMap::iterator it = mssa->getFunToRetMuSetMap().begin(), - eit = mssa->getFunToRetMuSetMap().end(); it!=eit; ++it) + for (MemSSA::FunToReturnMuSetMap::iterator it = mssa->getFunToRetMuSetMap().begin(), + eit = mssa->getFunToRetMuSetMap().end(); + it != eit; ++it) { - for(MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi) + for (MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi != epi; ++pi) { const MemSSA::RETMU* mu = SVFUtil::cast(*pi); addFormalOUTSVFGNode(pag->getICFG()->getFunExitICFGNode(mu->getFunction()), mu->getMRVer(), totalVFGNode++); } } /// initialize memory SSA callsite mu nodes - for(MemSSA::CallSiteToMUSetMap::iterator it = mssa->getCallSiteToMuSetMap().begin(), - eit = mssa->getCallSiteToMuSetMap().end(); - it!=eit; ++it) + for (MemSSA::CallSiteToMUSetMap::iterator it = mssa->getCallSiteToMuSetMap().begin(), + eit = mssa->getCallSiteToMuSetMap().end(); + it != eit; ++it) { - for(MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi) + for (MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi != epi; ++pi) { const MemSSA::CALLMU* mu = SVFUtil::cast(*pi); addActualINSVFGNode(mu->getCallSite(), mu->getMRVer(), totalVFGNode++); } } /// initialize memory SSA callsite chi nodes - for(MemSSA::CallSiteToCHISetMap::iterator it = mssa->getCallSiteToChiSetMap().begin(), - eit = mssa->getCallSiteToChiSetMap().end(); - it!=eit; ++it) + for (MemSSA::CallSiteToCHISetMap::iterator it = mssa->getCallSiteToChiSetMap().begin(), + eit = mssa->getCallSiteToChiSetMap().end(); + it != eit; ++it) { - for(CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi) + for (CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi != epi; ++pi) { const MemSSA::CALLCHI* chi = SVFUtil::cast(*pi); addActualOUTSVFGNode(chi->getCallSite(), chi->getResVer(), totalVFGNode++); } - } } @@ -326,127 +327,122 @@ void SVFG::addSVFGNodesForAddrTakenVars() void SVFG::connectIndirectSVFGEdges() { - for(iterator it = begin(), eit = end(); it!=eit; ++it) + for (iterator it = begin(), eit = end(); it != eit; ++it) { NodeID nodeId = it->first; const SVFGNode* node = it->second; - if(const LoadSVFGNode* loadNode = SVFUtil::dyn_cast(node)) + if (const LoadSVFGNode* loadNode = SVFUtil::dyn_cast(node)) { MUSet& muSet = mssa->getMUSet(SVFUtil::cast(loadNode->getPAGEdge())); - for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it) + for (MUSet::iterator it = muSet.begin(), eit = muSet.end(); it != eit; ++it) { - if(LOADMU* mu = SVFUtil::dyn_cast(*it)) + if (LOADMU* mu = SVFUtil::dyn_cast(*it)) { NodeID def = getDef(mu->getMRVer()); - addIntraIndirectVFEdge(def,nodeId, mu->getMRVer()->getMR()->getPointsTo()); + addIntraIndirectVFEdge(def, nodeId, mu->getMRVer()->getMR()->getPointsTo()); } } } - else if(const StoreSVFGNode* storeNode = SVFUtil::dyn_cast(node)) + else if (const StoreSVFGNode* storeNode = SVFUtil::dyn_cast(node)) { CHISet& chiSet = mssa->getCHISet(SVFUtil::cast(storeNode->getPAGEdge())); - for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it) + for (CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it != eit; ++it) { - if(STORECHI* chi = SVFUtil::dyn_cast(*it)) + if (STORECHI* chi = SVFUtil::dyn_cast(*it)) { NodeID def = getDef(chi->getOpVer()); - addIntraIndirectVFEdge(def,nodeId, chi->getOpVer()->getMR()->getPointsTo()); + addIntraIndirectVFEdge(def, nodeId, chi->getOpVer()->getMR()->getPointsTo()); } } } - else if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast(node)) + else if (const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast(node)) { CallGraphEdge::CallInstSet callInstSet; - mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet); - for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it) + mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(), callInstSet); + for (CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it != eit; + ++it) { const CallICFGNode* cs = *it; - if(!mssa->hasMU(cs)) - continue; + if (!mssa->hasMU(cs)) continue; ActualINSVFGNodeSet& actualIns = getActualINSVFGNodes(cs); - for(ActualINSVFGNodeSet::iterator ait = actualIns.begin(), aeit = actualIns.end(); ait!=aeit; ++ait) + for (ActualINSVFGNodeSet::iterator ait = actualIns.begin(), aeit = actualIns.end(); ait != aeit; ++ait) { const ActualINSVFGNode* actualIn = SVFUtil::cast(getSVFGNode(*ait)); - addInterIndirectVFCallEdge(actualIn,formalIn,getCallSiteID(cs, formalIn->getFun())); + addInterIndirectVFCallEdge(actualIn, formalIn, getCallSiteID(cs, formalIn->getFun())); } } } - else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast(node)) + else if (const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast(node)) { CallGraphEdge::CallInstSet callInstSet; // const MemSSA::RETMU* retMu = formalOut->getRetMU(); - mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet); - for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it) + mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(), callInstSet); + for (CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it != eit; + ++it) { const CallICFGNode* cs = *it; - if(!mssa->hasCHI(cs)) - continue; + if (!mssa->hasCHI(cs)) continue; ActualOUTSVFGNodeSet& actualOuts = getActualOUTSVFGNodes(cs); - for(ActualOUTSVFGNodeSet::iterator ait = actualOuts.begin(), aeit = actualOuts.end(); ait!=aeit; ++ait) + for (ActualOUTSVFGNodeSet::iterator ait = actualOuts.begin(), aeit = actualOuts.end(); ait != aeit; + ++ait) { const ActualOUTSVFGNode* actualOut = SVFUtil::cast(getSVFGNode(*ait)); - addInterIndirectVFRetEdge(formalOut,actualOut,getCallSiteID(cs, formalOut->getFun())); + addInterIndirectVFRetEdge(formalOut, actualOut, getCallSiteID(cs, formalOut->getFun())); } } NodeID def = getDef(formalOut->getMRVer()); - addIntraIndirectVFEdge(def,nodeId, formalOut->getMRVer()->getMR()->getPointsTo()); + addIntraIndirectVFEdge(def, nodeId, formalOut->getMRVer()->getMR()->getPointsTo()); } - else if(const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast(node)) + else if (const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast(node)) { const MRVer* ver = actualIn->getMRVer(); NodeID def = getDef(ver); - addIntraIndirectVFEdge(def,nodeId, ver->getMR()->getPointsTo()); + addIntraIndirectVFEdge(def, nodeId, ver->getMR()->getPointsTo()); } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { /// There's no need to connect actual out node to its definition site in the same function. } - else if(const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast(node)) + else if (const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast(node)) { - for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); - it != eit; it++) + for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; + it++) { const MRVer* op = it->second; NodeID def = getDef(op); - addIntraIndirectVFEdge(def,nodeId, op->getMR()->getPointsTo()); + addIntraIndirectVFEdge(def, nodeId, op->getMR()->getPointsTo()); } } } - connectFromGlobalToProgEntry(); } - /*! * Connect indirect SVFG edges from global initializers (store) to main function entry */ void SVFG::connectFromGlobalToProgEntry() { SVFModule* svfModule = mssa->getPTA()->getModule(); - const SVFFunction* mainFunc = - SVFUtil::getProgEntryFunction(svfModule); + const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction(svfModule); FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc); - if (formalIns.empty()) - return; + if (formalIns.empty()) return; for (GlobalVFGNodeSet::const_iterator storeIt = globalVFGNodes.begin(), storeEit = globalVFGNodes.end(); - storeIt != storeEit; ++storeIt) + storeIt != storeEit; ++storeIt) { if (const StoreSVFGNode* store = SVFUtil::dyn_cast(*storeIt)) { /// connect this store to main function entry const NodeBS& storePts = mssa->getPTA()->getPts(store->getPAGDstNodeID()).toNodeBS(); - for (FormalINSVFGNodeSet::iterator fiIt = formalIns.begin(), fiEit = - formalIns.end(); fiIt != fiEit; ++fiIt) + for (FormalINSVFGNodeSet::iterator fiIt = formalIns.begin(), fiEit = formalIns.end(); fiIt != fiEit; ++fiIt) { NodeID formalInID = *fiIt; - NodeBS formalInPts = ((FormalINSVFGNode*) getSVFGNode(formalInID))->getPointsTo(); + NodeBS formalInPts = ((FormalINSVFGNode*)getSVFGNode(formalInID))->getPointsTo(); formalInPts &= storePts; - if (formalInPts.empty()) - continue; + if (formalInPts.empty()) continue; /// add indirect value flow edge addIntraIndirectVFEdge(store->getId(), formalInID, formalInPts); @@ -463,20 +459,19 @@ SVFGEdge* SVFG::addIntraIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& SVFGNode* srcNode = getSVFGNode(srcId); SVFGNode* dstNode = getSVFGNode(dstId); checkIntraEdgeParents(srcNode, dstNode); - if(SVFGEdge* edge = hasIntraVFGEdge(srcNode,dstNode,SVFGEdge::IntraIndirectVF)) + if (SVFGEdge* edge = hasIntraVFGEdge(srcNode, dstNode, SVFGEdge::IntraIndirectVF)) { assert(SVFUtil::isa(edge) && "this should be a indirect value flow edge!"); return (SVFUtil::cast(edge)->addPointsTo(cpts) ? edge : nullptr); } else { - IntraIndSVFGEdge* indirectEdge = new IntraIndSVFGEdge(srcNode,dstNode); + IntraIndSVFGEdge* indirectEdge = new IntraIndSVFGEdge(srcNode, dstNode); indirectEdge->addPointsTo(cpts); return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr); } } - /*! * Add def-use edges of a memory region between two may-happen-in-parallel statements for multithreaded program */ @@ -484,14 +479,14 @@ SVFGEdge* SVFG::addThreadMHPIndirectVFEdge(NodeID srcId, NodeID dstId, const Nod { SVFGNode* srcNode = getSVFGNode(srcId); SVFGNode* dstNode = getSVFGNode(dstId); - if(SVFGEdge* edge = hasThreadVFGEdge(srcNode,dstNode,SVFGEdge::TheadMHPIndirectVF)) + if (SVFGEdge* edge = hasThreadVFGEdge(srcNode, dstNode, SVFGEdge::TheadMHPIndirectVF)) { assert(SVFUtil::isa(edge) && "this should be a indirect value flow edge!"); return (SVFUtil::cast(edge)->addPointsTo(cpts) ? edge : nullptr); } else { - ThreadMHPIndSVFGEdge* indirectEdge = new ThreadMHPIndSVFGEdge(srcNode,dstNode); + ThreadMHPIndSVFGEdge* indirectEdge = new ThreadMHPIndSVFGEdge(srcNode, dstNode); indirectEdge->addPointsTo(cpts); return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr); } @@ -500,18 +495,18 @@ SVFGEdge* SVFG::addThreadMHPIndirectVFEdge(NodeID srcId, NodeID dstId, const Nod /* * Add def-use call edges of a memory region between two statements */ -SVFGEdge* SVFG::addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts,CallSiteID csId) +SVFGEdge* SVFG::addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts, CallSiteID csId) { SVFGNode* srcNode = getSVFGNode(srcId); SVFGNode* dstNode = getSVFGNode(dstId); - if(SVFGEdge* edge = hasInterVFGEdge(srcNode,dstNode,SVFGEdge::CallIndVF,csId)) + if (SVFGEdge* edge = hasInterVFGEdge(srcNode, dstNode, SVFGEdge::CallIndVF, csId)) { assert(SVFUtil::isa(edge) && "this should be a indirect value flow edge!"); return (SVFUtil::cast(edge)->addPointsTo(cpts) ? edge : nullptr); } else { - CallIndSVFGEdge* callEdge = new CallIndSVFGEdge(srcNode,dstNode,csId); + CallIndSVFGEdge* callEdge = new CallIndSVFGEdge(srcNode, dstNode, csId); callEdge->addPointsTo(cpts); return (addSVFGEdge(callEdge) ? callEdge : nullptr); } @@ -520,18 +515,18 @@ SVFGEdge* SVFG::addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& /* * Add def-use return edges of a memory region between two statements */ -SVFGEdge* SVFG::addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts,CallSiteID csId) +SVFGEdge* SVFG::addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& cpts, CallSiteID csId) { SVFGNode* srcNode = getSVFGNode(srcId); SVFGNode* dstNode = getSVFGNode(dstId); - if(SVFGEdge* edge = hasInterVFGEdge(srcNode,dstNode,SVFGEdge::RetIndVF,csId)) + if (SVFGEdge* edge = hasInterVFGEdge(srcNode, dstNode, SVFGEdge::RetIndVF, csId)) { assert(SVFUtil::isa(edge) && "this should be a indirect value flow edge!"); return (SVFUtil::cast(edge)->addPointsTo(cpts) ? edge : nullptr); } else { - RetIndSVFGEdge* retEdge = new RetIndSVFGEdge(srcNode,dstNode,csId); + RetIndSVFGEdge* retEdge = new RetIndSVFGEdge(srcNode, dstNode, csId); retEdge->addPointsTo(cpts); return (addSVFGEdge(retEdge) ? retEdge : nullptr); } @@ -540,14 +535,14 @@ SVFGEdge* SVFG::addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS& c /*! * */ -SVFGEdge* SVFG::addInterIndirectVFCallEdge(const ActualINSVFGNode* src, const FormalINSVFGNode* dst,CallSiteID csId) +SVFGEdge* SVFG::addInterIndirectVFCallEdge(const ActualINSVFGNode* src, const FormalINSVFGNode* dst, CallSiteID csId) { NodeBS cpts1 = src->getPointsTo(); NodeBS cpts2 = dst->getPointsTo(); - if(cpts1.intersects(cpts2)) + if (cpts1.intersects(cpts2)) { cpts1 &= cpts2; - return addCallIndirectVFEdge(src->getId(),dst->getId(),cpts1,csId); + return addCallIndirectVFEdge(src->getId(), dst->getId(), cpts1, csId); } return nullptr; } @@ -555,15 +550,15 @@ SVFGEdge* SVFG::addInterIndirectVFCallEdge(const ActualINSVFGNode* src, const Fo /*! * Add inter VF edge from function exit mu to callsite chi */ -SVFGEdge* SVFG::addInterIndirectVFRetEdge(const FormalOUTSVFGNode* src, const ActualOUTSVFGNode* dst,CallSiteID csId) +SVFGEdge* SVFG::addInterIndirectVFRetEdge(const FormalOUTSVFGNode* src, const ActualOUTSVFGNode* dst, CallSiteID csId) { NodeBS cpts1 = src->getPointsTo(); NodeBS cpts2 = dst->getPointsTo(); - if(cpts1.intersects(cpts2)) + if (cpts1.intersects(cpts2)) { cpts1 &= cpts2; - return addRetIndirectVFEdge(src->getId(),dst->getId(),cpts1,csId); + return addRetIndirectVFEdge(src->getId(), dst->getId(), cpts1, csId); } return nullptr; } @@ -579,7 +574,8 @@ void SVFG::dump(const std::string& file, bool simple) /** * Get all inter value flow edges at this indirect call site, including call and return edges. */ -void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, const SVFFunction* callee, SVFGEdgeSetTy& edges) +void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, const SVFFunction* callee, + SVFGEdgeSetTy& edges) { CallSiteID csId = getCallSiteID(callICFGNode, callee); RetICFGNode* retICFGNode = pag->getICFG()->getRetICFGNode(callICFGNode->getCallSite()); @@ -593,8 +589,8 @@ void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end(); for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++) { - const PAGNode *cs_arg = *csArgIt; - const PAGNode *fun_arg = *funArgIt; + const PAGNode* cs_arg = *csArgIt; + const PAGNode* fun_arg = *funArgIt; if (isInterestedPAGNode(fun_arg) && isInterestedPAGNode(cs_arg)) getInterVFEdgeAtIndCSFromAPToFP(cs_arg, fun_arg, callICFGNode, csId, edges); } @@ -607,7 +603,7 @@ void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, { for (; csArgIt != csArgEit; csArgIt++) { - const PAGNode *cs_arg = *csArgIt; + const PAGNode* cs_arg = *csArgIt; if (isInterestedPAGNode(cs_arg)) getInterVFEdgeAtIndCSFromAPToFP(cs_arg, varFunArgNode, callICFGNode, csId, edges); } @@ -628,10 +624,10 @@ void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, if (hasFuncEntryChi(callee) && hasCallSiteMu(callICFGNode)) { SVFG::ActualINSVFGNodeSet& actualInNodes = getActualINSVFGNodes(callICFGNode); - for(SVFG::ActualINSVFGNodeSet::iterator ai_it = actualInNodes.begin(), - ai_eit = actualInNodes.end(); ai_it!=ai_eit; ++ai_it) + for (SVFG::ActualINSVFGNodeSet::iterator ai_it = actualInNodes.begin(), ai_eit = actualInNodes.end(); + ai_it != ai_eit; ++ai_it) { - ActualINSVFGNode * actualIn = SVFUtil::cast(getSVFGNode(*ai_it)); + ActualINSVFGNode* actualIn = SVFUtil::cast(getSVFGNode(*ai_it)); getInterVFEdgeAtIndCSFromAInToFIn(actualIn, callee, edges); } } @@ -640,8 +636,8 @@ void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, if (hasFuncRetMu(callee) && hasCallSiteChi(callICFGNode)) { SVFG::ActualOUTSVFGNodeSet& actualOutNodes = getActualOUTSVFGNodes(callICFGNode); - for(SVFG::ActualOUTSVFGNodeSet::iterator ao_it = actualOutNodes.begin(), - ao_eit = actualOutNodes.end(); ao_it!=ao_eit; ++ao_it) + for (SVFG::ActualOUTSVFGNodeSet::iterator ao_it = actualOutNodes.begin(), ao_eit = actualOutNodes.end(); + ao_it != ao_eit; ++ao_it) { ActualOUTSVFGNode* actualOut = SVFUtil::cast(getSVFGNode(*ao_it)); getInterVFEdgeAtIndCSFromFOutToAOut(actualOut, callee, edges); @@ -655,7 +651,7 @@ void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, */ void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* callee, SVFGEdgeSetTy& edges) { - VFG::connectCallerAndCallee(cs,callee,edges); + VFG::connectCallerAndCallee(cs, callee, edges); CallSiteID csId = getCallSiteID(cs, callee); @@ -664,12 +660,12 @@ void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* cal { SVFG::ActualINSVFGNodeSet& actualInNodes = getActualINSVFGNodes(cs); const SVFG::FormalINSVFGNodeSet& formalInNodes = getFormalINSVFGNodes(callee); - for(SVFG::ActualINSVFGNodeSet::iterator ai_it = actualInNodes.begin(), - ai_eit = actualInNodes.end(); ai_it!=ai_eit; ++ai_it) + for (SVFG::ActualINSVFGNodeSet::iterator ai_it = actualInNodes.begin(), ai_eit = actualInNodes.end(); + ai_it != ai_eit; ++ai_it) { - const ActualINSVFGNode * actualIn = SVFUtil::cast(getSVFGNode(*ai_it)); - for(SVFG::FormalINSVFGNodeSet::iterator fi_it = formalInNodes.begin(), - fi_eit = formalInNodes.end(); fi_it!=fi_eit; ++fi_it) + const ActualINSVFGNode* actualIn = SVFUtil::cast(getSVFGNode(*ai_it)); + for (SVFG::FormalINSVFGNodeSet::iterator fi_it = formalInNodes.begin(), fi_eit = formalInNodes.end(); + fi_it != fi_eit; ++fi_it) { const FormalINSVFGNode* formalIn = SVFUtil::cast(getSVFGNode(*fi_it)); connectAInAndFIn(actualIn, formalIn, csId, edges); @@ -683,12 +679,12 @@ void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* cal // connect formal out and actual out const SVFG::FormalOUTSVFGNodeSet& formalOutNodes = getFormalOUTSVFGNodes(callee); SVFG::ActualOUTSVFGNodeSet& actualOutNodes = getActualOUTSVFGNodes(cs); - for(SVFG::FormalOUTSVFGNodeSet::iterator fo_it = formalOutNodes.begin(), - fo_eit = formalOutNodes.end(); fo_it!=fo_eit; ++fo_it) + for (SVFG::FormalOUTSVFGNodeSet::iterator fo_it = formalOutNodes.begin(), fo_eit = formalOutNodes.end(); + fo_it != fo_eit; ++fo_it) { - const FormalOUTSVFGNode * formalOut = SVFUtil::cast(getSVFGNode(*fo_it)); - for(SVFG::ActualOUTSVFGNodeSet::iterator ao_it = actualOutNodes.begin(), - ao_eit = actualOutNodes.end(); ao_it!=ao_eit; ++ao_it) + const FormalOUTSVFGNode* formalOut = SVFUtil::cast(getSVFGNode(*fo_it)); + for (SVFG::ActualOUTSVFGNodeSet::iterator ao_it = actualOutNodes.begin(), ao_eit = actualOutNodes.end(); + ao_it != ao_eit; ++ao_it) { const ActualOUTSVFGNode* actualOut = SVFUtil::cast(getSVFGNode(*ao_it)); connectFOutAndAOut(formalOut, actualOut, csId, edges); @@ -697,29 +693,26 @@ void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* cal } } - /*! * Whether this is an function entry SVFGNode (formal parameter, formal In) */ const SVFFunction* SVFG::isFunEntrySVFGNode(const SVFGNode* node) const { - if(const FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) + if (const FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) { return fp->getFun(); } - else if(const InterPHISVFGNode* phi = SVFUtil::dyn_cast(node)) + else if (const InterPHISVFGNode* phi = SVFUtil::dyn_cast(node)) { - if(phi->isFormalParmPHI()) - return phi->getFun(); + if (phi->isFormalParmPHI()) return phi->getFun(); } - else if(const FormalINSVFGNode* fi = SVFUtil::dyn_cast(node)) + else if (const FormalINSVFGNode* fi = SVFUtil::dyn_cast(node)) { return fi->getFun(); } - else if(const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) + else if (const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) { - if(mphi->isFormalINPHI()) - return mphi->getFun(); + if (mphi->isFormalINPHI()) return mphi->getFun(); } return nullptr; } @@ -729,23 +722,21 @@ const SVFFunction* SVFG::isFunEntrySVFGNode(const SVFGNode* node) const */ const CallICFGNode* SVFG::isCallSiteRetSVFGNode(const SVFGNode* node) const { - if(const ActualRetSVFGNode* ar = SVFUtil::dyn_cast(node)) + if (const ActualRetSVFGNode* ar = SVFUtil::dyn_cast(node)) { return ar->getCallSite(); } - else if(const InterPHISVFGNode* phi = SVFUtil::dyn_cast(node)) + else if (const InterPHISVFGNode* phi = SVFUtil::dyn_cast(node)) { - if(phi->isActualRetPHI()) - return phi->getCallSite(); + if (phi->isActualRetPHI()) return phi->getCallSite(); } - else if(const ActualOUTSVFGNode* ao = SVFUtil::dyn_cast(node)) + else if (const ActualOUTSVFGNode* ao = SVFUtil::dyn_cast(node)) { return ao->getCallSite(); } - else if(const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) + else if (const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) { - if(mphi->isActualOUTPHI()) - return mphi->getCallSite(); + if (mphi->isActualOUTPHI()) return mphi->getCallSite(); } return nullptr; } @@ -763,15 +754,11 @@ void SVFG::performStat() */ namespace SVF { -template<> -struct DOTGraphTraits : public DOTGraphTraits +template <> struct DOTGraphTraits : public DOTGraphTraits { typedef SVFGNode NodeType; - DOTGraphTraits(bool isSimple = false) : - DOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(SVFG*) @@ -781,38 +768,38 @@ struct DOTGraphTraits : public DOTGraphTraits /// isNodeHidden - If the function returns true, the given node is not /// displayed in the graph - static bool isNodeHidden(SVFGNode *node, SVFG *) + static bool isNodeHidden(SVFGNode* node, SVFG*) { if (Options::ShowHiddenNode()) return false; - else return node->getInEdges().empty() && node->getOutEdges().empty(); + else + return node->getInEdges().empty() && node->getOutEdges().empty(); } - std::string getNodeLabel(NodeType *node, SVFG *graph) + std::string getNodeLabel(NodeType* node, SVFG* graph) { - if (isSimple()) - return getSimpleNodeLabel(node, graph); + if (isSimple()) return getSimpleNodeLabel(node, graph); else return getCompleteNodeLabel(node, graph); } /// Return label of a VFG node without MemSSA information - static std::string getSimpleNodeLabel(NodeType *node, SVFG*) + static std::string getSimpleNodeLabel(NodeType* node, SVFG*) { std::string str; std::stringstream rawstr(str); - if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { rawstr << stmtNode->toString(); } - else if(PHISVFGNode* tphi = SVFUtil::dyn_cast(node)) + else if (PHISVFGNode* tphi = SVFUtil::dyn_cast(node)) { rawstr << tphi->toString(); } - else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) + else if (FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) { rawstr << fp->toString(); } - else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast(node)) + else if (ActualParmSVFGNode* ap = SVFUtil::dyn_cast(node)) { rawstr << ap->toString(); } @@ -824,39 +811,39 @@ struct DOTGraphTraits : public DOTGraphTraits { rawstr << fr->toString(); } - else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast(node)) + else if (FormalINSVFGNode* fi = SVFUtil::dyn_cast(node)) { rawstr << fi->toString(); } - else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast(node)) + else if (FormalOUTSVFGNode* fo = SVFUtil::dyn_cast(node)) { rawstr << fo->toString(); } - else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast(node)) + else if (ActualINSVFGNode* ai = SVFUtil::dyn_cast(node)) { rawstr << ai->toString(); } - else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast(node)) + else if (ActualOUTSVFGNode* ao = SVFUtil::dyn_cast(node)) { rawstr << ao->toString(); } - else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) + else if (MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) { rawstr << mphi->toString(); } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { rawstr << "NullPtr"; } - else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) + else if (BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) { rawstr << bop->toString(); } - else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) + else if (UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) { rawstr << uop->toString(); } - else if(CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) + else if (CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) { rawstr << cmp->toString(); } @@ -867,60 +854,60 @@ struct DOTGraphTraits : public DOTGraphTraits } /// Return label of a VFG node with MemSSA information - static std::string getCompleteNodeLabel(NodeType *node, SVFG*) + static std::string getCompleteNodeLabel(NodeType* node, SVFG*) { std::string str; std::stringstream rawstr(str); - if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { rawstr << stmtNode->toString(); } - else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) + else if (BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) { rawstr << bop->toString(); } - else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) + else if (UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) { rawstr << uop->toString(); } - else if(CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) + else if (CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) { rawstr << cmp->toString(); } - else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) + else if (MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast(node)) { rawstr << mphi->toString(); } - else if(PHISVFGNode* tphi = SVFUtil::dyn_cast(node)) + else if (PHISVFGNode* tphi = SVFUtil::dyn_cast(node)) { rawstr << tphi->toString(); } - else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast(node)) + else if (FormalINSVFGNode* fi = SVFUtil::dyn_cast(node)) { - rawstr << fi->toString(); + rawstr << fi->toString(); } - else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast(node)) + else if (FormalOUTSVFGNode* fo = SVFUtil::dyn_cast(node)) { rawstr << fo->toString(); } - else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) + else if (FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) { - rawstr << fp->toString(); + rawstr << fp->toString(); } - else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast(node)) + else if (ActualINSVFGNode* ai = SVFUtil::dyn_cast(node)) { rawstr << ai->toString(); } - else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast(node)) + else if (ActualOUTSVFGNode* ao = SVFUtil::dyn_cast(node)) { - rawstr << ao->toString(); + rawstr << ao->toString(); } - else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast(node)) + else if (ActualParmSVFGNode* ap = SVFUtil::dyn_cast(node)) { rawstr << ap->toString(); } - else if(NullPtrSVFGNode* nptr = SVFUtil::dyn_cast(node)) + else if (NullPtrSVFGNode* nptr = SVFUtil::dyn_cast(node)) { rawstr << nptr->toString(); } @@ -942,137 +929,135 @@ struct DOTGraphTraits : public DOTGraphTraits return rawstr.str(); } - static std::string getNodeAttributes(NodeType *node, SVFG *graph) + static std::string getNodeAttributes(NodeType* node, SVFG* graph) { std::string str; std::stringstream rawstr(str); - if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { const PAGEdge* edge = stmtNode->getPAGEdge(); if (SVFUtil::isa(edge)) { - rawstr << "color=green"; + rawstr << "color=green"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=black"; + rawstr << "color=black"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=black,style=dotted"; + rawstr << "color=black,style=dotted"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=purple"; + rawstr << "color=purple"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=blue"; + rawstr << "color=blue"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=red"; + rawstr << "color=red"; } else { assert(0 && "No such kind edge!!"); } - rawstr << ""; + rawstr << ""; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=black"; + rawstr << "color=black"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=black"; + rawstr << "color=black"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=grey"; + rawstr << "color=grey"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=black,penwidth=2"; + rawstr << "color=black,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=black,penwidth=2"; + rawstr << "color=black,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=black,penwidth=2"; + rawstr << "color=black,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=gold,penwidth=2"; + rawstr << "color=gold,penwidth=2"; } else assert(false && "no such kind of node!!"); /// dump slice information - if(graph->getStat()->isSource(node)) + if (graph->getStat()->isSource(node)) { rawstr << ",style=filled, fillcolor=red"; } - else if(graph->getStat()->isSink(node)) + else if (graph->getStat()->isSink(node)) { rawstr << ",style=filled, fillcolor=blue"; } - else if(graph->getStat()->inBackwardSlice(node)) + else if (graph->getStat()->inBackwardSlice(node)) { rawstr << ",style=filled, fillcolor=yellow"; } - else if(graph->getStat()->inForwardSlice(node)) + else if (graph->getStat()->inForwardSlice(node)) rawstr << ",style=filled, fillcolor=gray"; - rawstr << ""; + rawstr << ""; return rawstr.str(); } - template - static std::string getEdgeAttributes(NodeType*, EdgeIter EI, SVFG*) + template static std::string getEdgeAttributes(NodeType*, EdgeIter EI, SVFG*) { SVFGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); if (SVFUtil::isa(edge)) { - if (SVFUtil::isa(edge)) - return "style=solid,color=red"; + if (SVFUtil::isa(edge)) return "style=solid,color=red"; else if (SVFUtil::isa(edge)) return "style=solid,color=blue"; else @@ -1080,8 +1065,7 @@ struct DOTGraphTraits : public DOTGraphTraits } else if (SVFUtil::isa(edge)) { - if (SVFUtil::isa(edge)) - return "style=dashed,color=red"; + if (SVFUtil::isa(edge)) return "style=dashed,color=red"; else if (SVFUtil::isa(edge)) return "style=dashed,color=blue"; else @@ -1090,16 +1074,14 @@ struct DOTGraphTraits : public DOTGraphTraits return ""; } - template - static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) { SVFGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); std::string str; std::stringstream rawstr(str); - if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast(edge)) - rawstr << dirCall->getCallSiteId(); + if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast(edge)) rawstr << dirCall->getCallSiteId(); else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast(edge)) rawstr << dirRet->getCallSiteId(); else if (CallIndSVFGEdge* indCall = SVFUtil::dyn_cast(edge)) @@ -1110,4 +1092,4 @@ struct DOTGraphTraits : public DOTGraphTraits return rawstr.str(); } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/Graphs/SVFGOPT.cpp b/svf/lib/Graphs/SVFGOPT.cpp index 0fb9e1df7..6572b65ba 100644 --- a/svf/lib/Graphs/SVFGOPT.cpp +++ b/svf/lib/Graphs/SVFGOPT.cpp @@ -43,13 +43,11 @@ static std::string KeepAllSelfCycle = "all"; static std::string KeepContextSelfCycle = "context"; static std::string KeepNoneSelfCycle = "none"; - void SVFGOPT::buildSVFG() { SVFG::buildSVFG(); - if(Options::DumpVFG()) - dump("SVFG_before_opt"); + if (Options::DumpVFG()) dump("SVFG_before_opt"); DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("\tSVFG Optimisation\n")); @@ -60,15 +58,13 @@ void SVFGOPT::buildSVFG() handleIntraValueFlow(); stat->sfvgOptEnd(); - } /*! * */ SVFGEdge* SVFGOPT::addCallIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS& cpts) { - if (Options::ContextInsensitive()) - return addIntraIndirectVFEdge(srcId, dstId, cpts); + if (Options::ContextInsensitive()) return addIntraIndirectVFEdge(srcId, dstId, cpts); else return addCallIndirectVFEdge(srcId, dstId, cpts, csid); } @@ -78,8 +74,7 @@ SVFGEdge* SVFGOPT::addCallIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteI */ SVFGEdge* SVFGOPT::addRetIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID csid, const NodeBS& cpts) { - if (Options::ContextInsensitive()) - return addIntraIndirectVFEdge(srcId, dstId, cpts); + if (Options::ContextInsensitive()) return addIntraIndirectVFEdge(srcId, dstId, cpts); else return addRetIndirectVFEdge(srcId, dstId, cpts, csid); } @@ -90,19 +85,16 @@ SVFGEdge* SVFGOPT::addRetIndirectSVFGEdge(NodeID srcId, NodeID dstId, CallSiteID void SVFGOPT::handleInterValueFlow() { SVFGNodeSet candidates; - for (SVFGNodeIDToNodeMapTy::iterator it = SVFG::begin(), eit = SVFG::end(); - it!=eit; ++it) + for (SVFGNodeIDToNodeMapTy::iterator it = SVFG::begin(), eit = SVFG::end(); it != eit; ++it) { SVFGNode* node = it->second; - if (SVFUtil::isa(node)) + if (SVFUtil::isa(node)) candidates.insert(node); } SVFGNodeSet nodesToBeDeleted; - for (SVFGNodeSet::const_iterator it = candidates.begin(), eit = candidates.end(); - it!=eit; ++it) + for (SVFGNodeSet::const_iterator it = candidates.begin(), eit = candidates.end(); it != eit; ++it) { SVFGNode* node = *it; if (FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) @@ -126,8 +118,7 @@ void SVFGOPT::handleInterValueFlow() } else if (SVFUtil::isa(node)) { - if(keepActualOutFormalIn == false) - nodesToBeDeleted.insert(node); + if (keepActualOutFormalIn == false) nodesToBeDeleted.insert(node); } } @@ -137,7 +128,7 @@ void SVFGOPT::handleInterValueFlow() if (canBeRemoved(node)) { if (SVFUtil::isa(node)) - retargetEdgesOfAOutFIn(node); /// reset def of address-taken variable + retargetEdgesOfAOutFIn(node); /// reset def of address-taken variable removeAllEdges(node); removeSVFGNode(node); @@ -150,14 +141,13 @@ void SVFGOPT::handleInterValueFlow() */ void SVFGOPT::replaceFParamARetWithPHI(PHISVFGNode* phi, SVFGNode* svfgNode) { - assert((SVFUtil::isa(svfgNode)) - && "expecting a formal param or actual ret svfg node"); + assert((SVFUtil::isa(svfgNode)) && + "expecting a formal param or actual ret svfg node"); /// create a new PHISVFGNode. NodeID phiId = phi->getId(); /// migrate formal-param's edges to phi node. - for (SVFGNode::const_iterator it = svfgNode->OutEdgeBegin(), eit = svfgNode->OutEdgeEnd(); - it != eit; ++it) + for (SVFGNode::const_iterator it = svfgNode->OutEdgeBegin(), eit = svfgNode->OutEdgeEnd(); it != eit; ++it) { const SVFGEdge* outEdge = *it; SVFGNode* dstNode = outEdge->getDstNode(); @@ -173,8 +163,7 @@ void SVFGOPT::replaceFParamARetWithPHI(PHISVFGNode* phi, SVFGNode* svfgNode) /// add actual-param/formal-ret into phi's operand list if (FormalParmSVFGNode* fp = SVFUtil::dyn_cast(svfgNode)) { - for (SVFGNode::iterator it = svfgNode->InEdgeBegin(), eit = svfgNode->InEdgeEnd(); - it != eit; ++it) + for (SVFGNode::iterator it = svfgNode->InEdgeBegin(), eit = svfgNode->InEdgeEnd(); it != eit; ++it) { ActualParmSVFGNode* ap = SVFUtil::cast((*it)->getSrcNode()); addInterPHIOperands(phi, ap->getParam()); @@ -184,8 +173,7 @@ void SVFGOPT::replaceFParamARetWithPHI(PHISVFGNode* phi, SVFGNode* svfgNode) } else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast(svfgNode)) { - for (SVFGNode::iterator it = svfgNode->InEdgeBegin(), eit = svfgNode->InEdgeEnd(); - it != eit; ++it) + for (SVFGNode::iterator it = svfgNode->InEdgeBegin(), eit = svfgNode->InEdgeEnd(); it != eit; ++it) { FormalRetSVFGNode* fr = SVFUtil::cast((*it)->getSrcNode()); addInterPHIOperands(phi, fr->getRet()); @@ -216,8 +204,7 @@ void SVFGOPT::retargetEdgesOfAInFOut(SVFGNode* node) inPointsTo = inEdge->getPointsTo(); def = inEdge->getSrcNode(); - if (SVFUtil::isa(node)) - setActualINDef(node->getId(), def->getId()); + if (SVFUtil::isa(node)) setActualINDef(node->getId(), def->getId()); else if (SVFUtil::isa(node)) setFormalOUTDef(node->getId(), def->getId()); } @@ -229,8 +216,7 @@ void SVFGOPT::retargetEdgesOfAInFOut(SVFGNode* node) NodeBS intersection = inPointsTo; intersection &= outEdge->getPointsTo(); - if (intersection.empty()) - continue; + if (intersection.empty()) continue; SVFGNode* dstNode = outEdge->getDstNode(); if (const CallIndSVFGEdge* callEdge = SVFUtil::dyn_cast(outEdge)) @@ -264,8 +250,7 @@ void SVFGOPT::retargetEdgesOfAOutFIn(SVFGNode* node) NodeBS intersection = inEdge->getPointsTo(); intersection &= outEdge->getPointsTo(); - if (intersection.empty()) - continue; + if (intersection.empty()) continue; NodeID dstId = outEdge->getDstID(); if (const RetIndSVFGEdge* retEdge = SVFUtil::dyn_cast(inEdge)) @@ -316,8 +301,7 @@ bool SVFGOPT::isConnectingTwoCallSites(const SVFGNode* node) const } } - if (hasInCallRet && hasOutCallRet) - return true; + if (hasInCallRet && hasOutCallRet) return true; else return false; } @@ -331,19 +315,16 @@ bool SVFGOPT::isConnectingTwoCallSites(const SVFGNode* node) const /// 4. ActualOUT if it doesn't reside at indirect call site and it's not definition site /// of FormalOUT /// 5. FormalOUT if it doesn't reside at the exit of address-taken function -bool SVFGOPT::canBeRemoved(const SVFGNode * node) +bool SVFGOPT::canBeRemoved(const SVFGNode* node) { - if (SVFUtil::isa(node)) - return true; - else if (SVFUtil::isa(node)) + if (SVFUtil::isa(node)) return true; + else if (SVFUtil::isa( + node)) { /// Now each SVFG edge can only be associated with one call site id, /// so if this node has both incoming call/ret and outgoing call/ret /// edges, we don't remove this node. - if (isConnectingTwoCallSites(node)) - return false; + if (isConnectingTwoCallSites(node)) return false; if (const ActualINSVFGNode* ai = SVFUtil::dyn_cast(node)) { @@ -372,8 +353,7 @@ bool SVFGOPT::canBeRemoved(const SVFGNode * node) void SVFGOPT::parseSelfCycleHandleOption() { std::string choice = (Options::SelfCycle().empty()) ? "" : Options::SelfCycle(); - if (choice.empty() || choice == KeepAllSelfCycle) - keepAllSelfCycle = true; + if (choice.empty() || choice == KeepAllSelfCycle) keepAllSelfCycle = true; else if (choice == KeepContextSelfCycle) keepContextSelfCycle = true; else if (choice == KeepNoneSelfCycle) @@ -399,11 +379,9 @@ void SVFGOPT::handleIntraValueFlow() const MSSAPHISVFGNode* node = worklist.pop(); /// Skip nodes which have self cycle - if (checkSelfCycleEdges(node)) - continue; + if (checkSelfCycleEdges(node)) continue; - if (node->hasOutgoingEdge() && node->hasIncomingEdge()) - bypassMSSAPHINode(node); + if (node->hasOutgoingEdge() && node->hasIncomingEdge()) bypassMSSAPHINode(node); /// remove node's edges if it only has incoming or outgoing edges. if (node->hasIncomingEdge() && node->hasOutgoingEdge() == false) @@ -411,8 +389,7 @@ void SVFGOPT::handleIntraValueFlow() /// remove all the incoming edges; SVFGNode::const_iterator edgeIt = node->InEdgeBegin(); SVFGNode::const_iterator edgeEit = node->InEdgeEnd(); - for (; edgeIt != edgeEit; ++edgeIt) - addIntoWorklist((*edgeIt)->getSrcNode()); + for (; edgeIt != edgeEit; ++edgeIt) addIntoWorklist((*edgeIt)->getSrcNode()); removeInEdges(node); } @@ -421,8 +398,7 @@ void SVFGOPT::handleIntraValueFlow() /// remove all the outgoing edges; SVFGNode::const_iterator edgeIt = node->OutEdgeBegin(); SVFGNode::const_iterator edgeEit = node->OutEdgeEnd(); - for (; edgeIt != edgeEit; ++edgeIt) - addIntoWorklist((*edgeIt)->getDstNode()); + for (; edgeIt != edgeEit; ++edgeIt) addIntoWorklist((*edgeIt)->getDstNode()); removeOutEdges(node); } @@ -433,7 +409,6 @@ void SVFGOPT::handleIntraValueFlow() } } - /// Remove self cycle edges according to specified options: /// 1. keepAllSelfCycle = TRUE: all self cycle edges are kept; /// 2. keepContextSelfCycle = TRUE: all self cycle edges related-to context are kept; @@ -455,13 +430,12 @@ bool SVFGOPT::checkSelfCycleEdges(const MSSAPHISVFGNode* node) if (keepAllSelfCycle) { hasSelfCycle = true; - break; /// There's no need to check other edge if we do not remove self cycle + break; /// There's no need to check other edge if we do not remove self cycle } - else if (keepContextSelfCycle && - SVFUtil::isa(preEdge)) + else if (keepContextSelfCycle && SVFUtil::isa(preEdge)) { hasSelfCycle = true; - continue; /// Continue checking and remove other self cycle which are NOT context-related + continue; /// Continue checking and remove other self cycle which are NOT context-related } else { @@ -494,8 +468,8 @@ void SVFGOPT::bypassMSSAPHINode(const MSSAPHISVFGNode* node) { const SVFGEdge* succEdge = *outEdgeIt; const SVFGNode* dstNode = (*outEdgeIt)->getDstNode(); - if (srcNode->getId() != dstNode->getId() - && addNewSVFGEdge(srcNode->getId(), dstNode->getId(), preEdge, succEdge)) + if (srcNode->getId() != dstNode->getId() && + addNewSVFGEdge(srcNode->getId(), dstNode->getId(), preEdge, succEdge)) added = true; else { @@ -522,8 +496,8 @@ void SVFGOPT::bypassMSSAPHINode(const MSSAPHISVFGNode* node) */ bool SVFGOPT::addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge* preEdge, const SVFGEdge* succEdge) { - assert(SVFUtil::isa(preEdge) && SVFUtil::isa(succEdge) - && "either pre or succ edge is not indirect SVFG edge"); + assert(SVFUtil::isa(preEdge) && SVFUtil::isa(succEdge) && + "either pre or succ edge is not indirect SVFG edge"); const IndirectSVFGEdge* preIndEdge = SVFUtil::cast(preEdge); const IndirectSVFGEdge* succIndEdge = SVFUtil::cast(succEdge); @@ -531,8 +505,7 @@ bool SVFGOPT::addNewSVFGEdge(NodeID srcId, NodeID dstId, const SVFGEdge* preEdge NodeBS intersection = preIndEdge->getPointsTo(); intersection &= succIndEdge->getPointsTo(); - if (intersection.empty()) - return false; + if (intersection.empty()) return false; assert(bothInterEdges(preEdge, succEdge) == false && "both edges are inter edges"); diff --git a/svf/lib/Graphs/SVFGReadWrite.cpp b/svf/lib/Graphs/SVFGReadWrite.cpp index c6950715a..e3ed84d08 100644 --- a/svf/lib/Graphs/SVFGReadWrite.cpp +++ b/svf/lib/Graphs/SVFGReadWrite.cpp @@ -41,9 +41,11 @@ using namespace std; // Format of file // __Nodes__ -// SVFGNodeID: >= >= MVER: {MRVERID: MemRegion: pts{ } MRVERSION: MSSADef: , pts{ }} >= ICFGNodeID: +// SVFGNodeID: >= >= MVER: {MRVERID: MemRegion: pts{ } MRVERSION: MSSADef: +// , pts{ }} >= ICFGNodeID: // __Edges__ -// srcSVFGNodeID: => dstSVFGNodeID: >= | MVER: {MRVERID: MemRegion: pts{ } MRVERSION: MSSADef: , pts{ }} +// srcSVFGNodeID: => dstSVFGNodeID: >= | MVER: {MRVERID: MemRegion: pts{ } MRVERSION: +// MSSADef: , pts{ }} void SVFG::writeToFile(const string& filename) { outs() << "Writing SVFG analysis to '" << filename << "'..."; @@ -56,44 +58,50 @@ void SVFG::writeToFile(const string& filename) } f << "__Nodes__\n"; // Iterate over nodes and write to file - for(iterator it = begin(), eit = end(); it!=eit; ++it) + for (iterator it = begin(), eit = end(); it != eit; ++it) { NodeID nodeId = it->first; const SVFGNode* node = it->second; - if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast(node)) + if (const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast(node)) { - //node - f << "SVFGNodeID: " << nodeId << " >= " << "FormalINSVFGNode"; + // node + f << "SVFGNodeID: " << nodeId << " >= " + << "FormalINSVFGNode"; f << " >= MVER: {"; f << *formalIn->getMRVer() << "} >= ICFGNodeID: " << formalIn->getFunEntryNode()->getId() << "\n"; } - else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast(node)) + else if (const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast(node)) { - //node - f << "SVFGNodeID: " << nodeId << " >= " << "FormalOUTSVFGNode"; + // node + f << "SVFGNodeID: " << nodeId << " >= " + << "FormalOUTSVFGNode"; f << " >= MVER: {"; - f << *formalOut->getMRVer() << "} >= ICFGNodeID: " << formalOut->getFunExitNode()->getId() << "\n"; + f << *formalOut->getMRVer() << "} >= ICFGNodeID: " << formalOut->getFunExitNode()->getId() << "\n"; } - else if(const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast(node)) + else if (const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast(node)) { - //node - f << "SVFGNodeID: " << nodeId << " >= " << "ActualINSVFGNode"; + // node + f << "SVFGNodeID: " << nodeId << " >= " + << "ActualINSVFGNode"; f << " >= MVER: {"; f << *actualIn->getMRVer() << "} >= ICFGNodeID: " << actualIn->getCallSite()->getId() << "\n"; } - else if(const ActualOUTSVFGNode* actualOut = SVFUtil::dyn_cast(node)) + else if (const ActualOUTSVFGNode* actualOut = SVFUtil::dyn_cast(node)) { - //node - f << "SVFGNodeID: " << nodeId << " >= " << "ActualOUTSVFGNode" << " >= MVER: {"; - f << *actualOut->getMRVer() << "} >= ICFGNodeID: " << actualOut->getCallSite()->getId() << "\n"; + // node + f << "SVFGNodeID: " << nodeId << " >= " + << "ActualOUTSVFGNode" + << " >= MVER: {"; + f << *actualOut->getMRVer() << "} >= ICFGNodeID: " << actualOut->getCallSite()->getId() << "\n"; } - else if(const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast(node)) + else if (const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast(node)) { - //node - f << "SVFGNodeID: " << nodeId << " >= " << "PHISVFGNode"; - unordered_map opvers; - for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); - it != eit; it++) + // node + f << "SVFGNodeID: " << nodeId << " >= " + << "PHISVFGNode"; + unordered_map opvers; + for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; + it++) { opvers.insert(make_pair(it->first, it->second)); } @@ -103,10 +111,11 @@ void SVFG::writeToFile(const string& filename) const SVFInstruction* inst = phiNode->getICFGNode()->getBB()->front(); f << "} >= ICFGNodeID: " << pag->getICFG()->getICFGNode(inst)->getId(); f << " >= OPVers: {"; - for (auto x: opvers) + for (auto x : opvers) { const MRVer* op = x.second; - f << "{" << *op << "}" << ","; + f << "{" << *op << "}" + << ","; } f << "}\n"; } @@ -114,84 +123,98 @@ void SVFG::writeToFile(const string& filename) f << "\n\n__Edges__\n"; // Iterate over edges and write to file - for(iterator it = begin(), eit = end(); it!=eit; ++it) + for (iterator it = begin(), eit = end(); it != eit; ++it) { NodeID nodeId = it->first; const SVFGNode* node = it->second; - if(const LoadSVFGNode* loadNode = SVFUtil::dyn_cast(node)) + if (const LoadSVFGNode* loadNode = SVFUtil::dyn_cast(node)) { MUSet& muSet = mssa->getMUSet(SVFUtil::cast(loadNode->getPAGEdge())); - for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it) + for (MUSet::iterator it = muSet.begin(), eit = muSet.end(); it != eit; ++it) { - if(LOADMU* mu = SVFUtil::dyn_cast(*it)) + if (LOADMU* mu = SVFUtil::dyn_cast(*it)) { NodeID def = getDef(mu->getMRVer()); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << def << " >= LoadNode | MVER: {" << *mu->getMRVer() << "}" << "\n"; + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << def << " >= LoadNode | MVER: {" << *mu->getMRVer() << "}" + << "\n"; } } } - else if(const StoreSVFGNode* storeNode = SVFUtil::dyn_cast(node)) + else if (const StoreSVFGNode* storeNode = SVFUtil::dyn_cast(node)) { CHISet& chiSet = mssa->getCHISet(SVFUtil::cast(storeNode->getPAGEdge())); - for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it) + for (CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it != eit; ++it) { - if(STORECHI* chi = SVFUtil::dyn_cast(*it)) + if (STORECHI* chi = SVFUtil::dyn_cast(*it)) { NodeID def = getDef(chi->getOpVer()); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << def << " >= StoreNode | MVER: {" << *chi->getOpVer() << "}" << "\n"; + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << def << " >= StoreNode | MVER: {" << *chi->getOpVer() << "}" + << "\n"; } } } - else if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast(node)) + else if (const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast(node)) { CallGraphEdge::CallInstSet callInstSet; - mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet); - for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it) + mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(), callInstSet); + for (CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it != eit; + ++it) { const CallICFGNode* cs = *it; - if(!mssa->hasMU(cs)) - continue; + if (!mssa->hasMU(cs)) continue; ActualINSVFGNodeSet& actualIns = getActualINSVFGNodes(cs); - for(ActualINSVFGNodeSet::iterator ait = actualIns.begin(), aeit = actualIns.end(); ait!=aeit; ++ait) + for (ActualINSVFGNodeSet::iterator ait = actualIns.begin(), aeit = actualIns.end(); ait != aeit; ++ait) { const ActualINSVFGNode* actualIn = SVFUtil::cast(getSVFGNode(*ait)); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << actualIn->getId() << " >= FormalINSVFGNode" << "\n"; + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << actualIn->getId() << " >= FormalINSVFGNode" + << "\n"; } } } - else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast(node)) + else if (const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast(node)) { CallGraphEdge::CallInstSet callInstSet; - mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet); - for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it) + mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(), callInstSet); + for (CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it != eit; + ++it) { const CallICFGNode* cs = *it; - if(!mssa->hasCHI(cs)) - continue; + if (!mssa->hasCHI(cs)) continue; ActualOUTSVFGNodeSet& actualOuts = getActualOUTSVFGNodes(cs); - for(ActualOUTSVFGNodeSet::iterator ait = actualOuts.begin(), aeit = actualOuts.end(); ait!=aeit; ++ait) + for (ActualOUTSVFGNodeSet::iterator ait = actualOuts.begin(), aeit = actualOuts.end(); ait != aeit; + ++ait) { const ActualOUTSVFGNode* actualOut = SVFUtil::cast(getSVFGNode(*ait)); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << actualOut->getId() << " >= FormalOUTSVFGNode" << "\n"; + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << actualOut->getId() << " >= FormalOUTSVFGNode" + << "\n"; } } NodeID def = getDef(formalOut->getMRVer()); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << def << " >= FormalOUTSVFGNode | intra" << "\n"; + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << def << " >= FormalOUTSVFGNode | intra" + << "\n"; } - else if(const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast(node)) + else if (const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast(node)) { NodeID def = getDef(actualIn->getMRVer()); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << def << " >= ActualINSVFGNode" << "\n"; - + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << def << " >= ActualINSVFGNode" + << "\n"; } - else if(const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast(node)) + else if (const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast(node)) { - for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); - it != eit; it++) + for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; + it++) { const MRVer* op = it->second; NodeID def = getDef(op); - f << "srcSVFGNodeID: " << nodeId << " => " << "dstSVFGNodeID: " << def << " >= PHISVFGNode | MVER: {" << *op << "}" << "\n"; + f << "srcSVFGNodeID: " << nodeId << " => " + << "dstSVFGNodeID: " << def << " >= PHISVFGNode | MVER: {" << *op << "}" + << "\n"; } } } @@ -215,62 +238,59 @@ void SVFG::readFile(const string& filename) } PAGEdge::PAGEdgeSetTy& stores = getPAGEdgeSet(PAGEdge::Store); - for (PAGEdge::PAGEdgeSetTy::iterator iter = stores.begin(), eiter = - stores.end(); iter != eiter; ++iter) + for (PAGEdge::PAGEdgeSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; ++iter) { StoreStmt* store = SVFUtil::cast(*iter); const StmtSVFGNode* sNode = getStmtVFGNode(store); - for(CHISet::iterator pi = mssa->getCHISet(store).begin(), epi = mssa->getCHISet(store).end(); pi!=epi; ++pi) - setDef((*pi)->getResVer(),sNode); + for (CHISet::iterator pi = mssa->getCHISet(store).begin(), epi = mssa->getCHISet(store).end(); pi != epi; ++pi) + setDef((*pi)->getResVer(), sNode); } - //outer loop through each line in the file + // outer loop through each line in the file string line; // add nodes stat->ATVFNodeStart(); while (F.good()) { getline(F, line); - if (line.empty()) - continue; - if (line.find("__Edges__") != std::string::npos) - break; + if (line.empty()) continue; + if (line.find("__Edges__") != std::string::npos) break; std::string s = line; std::string delimiter = " >= "; string temp; int index = 0; - //implement delimiter to split string using ">=" + // implement delimiter to split string using ">=" size_t next = 0; size_t last = 0; size_t outer_last = 0; - size_t nextTemp; //size_t lastTemp; + size_t nextTemp; // size_t lastTemp; NodeID id = 0; string type; string MR; string basicBlock; string opVer; - //inner loop through to get each element in the line + // inner loop through to get each element in the line while ((next = s.find(delimiter, last)) != string::npos) { - temp = s.substr(last, next-last); + temp = s.substr(last, next - last); last = next + 4; outer_last = next + 4; - if(index == 0) + if (index == 0) { nextTemp = temp.find("SVFGNodeID: ") + 12; id = atoi(temp.substr(nextTemp).c_str()); } - if(index == 1) + if (index == 1) { type = temp; } - if(index > 1) + if (index > 1) { - if(index == 2) + if (index == 2) { MR = temp; } - if(index == 3) + if (index == 3) { basicBlock = temp; } @@ -278,7 +298,7 @@ void SVFG::readFile(const string& filename) index++; } MRVer* tempMRVer; - if(!MR.empty()) + if (!MR.empty()) { tempMRVer = getMRVERFromString(MR); } @@ -286,46 +306,47 @@ void SVFG::readFile(const string& filename) { tempMRVer = getMRVERFromString(""); } - //add nodes using the variables we extracted - if(type == "FormalINSVFGNode") + // add nodes using the variables we extracted + if (type == "FormalINSVFGNode") { outer_last = s.find("ICFGNodeID: ") + 12; NodeID FunID = atoi(s.substr(outer_last).c_str()); addFormalINSVFGNode(SVFUtil::dyn_cast(pag->getICFG()->getICFGNode(FunID)), tempMRVer, id); } - else if(type == "FormalOUTSVFGNode") + else if (type == "FormalOUTSVFGNode") { outer_last = s.find("ICFGNodeID: ") + 12; - NodeID FunID = atoi(s.substr(outer_last).c_str()); + NodeID FunID = atoi(s.substr(outer_last).c_str()); addFormalOUTSVFGNode(SVFUtil::dyn_cast(pag->getICFG()->getICFGNode(FunID)), tempMRVer, id); } - else if(type == "ActualINSVFGNode") + else if (type == "ActualINSVFGNode") { outer_last = s.find("ICFGNodeID: ") + 12; NodeID CallSiteID = atoi(s.substr(outer_last).c_str()); - addActualINSVFGNode(SVFUtil::dyn_cast(pag->getICFG()->getICFGNode(CallSiteID)), tempMRVer, id); + addActualINSVFGNode(SVFUtil::dyn_cast(pag->getICFG()->getICFGNode(CallSiteID)), tempMRVer, + id); } - else if(type == "ActualOUTSVFGNode") + else if (type == "ActualOUTSVFGNode") { outer_last = s.find("ICFGNodeID: ") + 12; NodeID CallSiteID = atoi(s.substr(outer_last).c_str()); - addActualOUTSVFGNode(SVFUtil::dyn_cast(pag->getICFG()->getICFGNode(CallSiteID)), tempMRVer, id); + addActualOUTSVFGNode(SVFUtil::dyn_cast(pag->getICFG()->getICFGNode(CallSiteID)), tempMRVer, + id); } else if (type == "PHISVFGNode") { - opVer = s.substr(outer_last); + opVer = s.substr(outer_last); next = opVer.find("{") + 1; last = opVer.find(",}"); temp = opVer.substr(next, last); - Map OPVers; + Map OPVers; int index = 0; while ((next = temp.find("{") + 1) != string::npos) { - if (temp == ",}") - break; + if (temp == ",}") break; last = temp.find("},"); string temp1; - temp1 = temp.substr(next, last-next); + temp1 = temp.substr(next, last - next); MRVer* tempOPVer = getMRVERFromString(temp1); OPVers.insert(make_pair(index, tempOPVer)); temp = temp.substr(last + 1); @@ -333,14 +354,14 @@ void SVFG::readFile(const string& filename) } next = basicBlock.find("ICFGNodeID: ") + 12; temp = basicBlock.substr(next); - addIntraMSSAPHISVFGNode(pag->getICFG()->getICFGNode(atoi(temp.c_str())), OPVers.begin(), OPVers.end(), tempMRVer, id); + addIntraMSSAPHISVFGNode(pag->getICFG()->getICFGNode(atoi(temp.c_str())), OPVers.begin(), OPVers.end(), + tempMRVer, id); } else { } - if (totalVFGNode < id) - totalVFGNode = id + 1; + if (totalVFGNode < id) totalVFGNode = id + 1; } stat->ATVFNodeEnd(); @@ -349,8 +370,7 @@ void SVFG::readFile(const string& filename) while (F.good()) { getline(F, line); - if (line.empty()) - continue; + if (line.empty()) continue; std::string s = line; std::string delimiter = " >= "; @@ -371,14 +391,13 @@ void SVFG::readFile(const string& filename) NodeID dst; next = edge.find("srcSVFGNodeID: ") + 15; last = edge.find(" => "); - src = atoi(edge.substr(next, last-next).c_str()); + src = atoi(edge.substr(next, last - next).c_str()); next = edge.find("dstSVFGNodeID: ") + 15; dst = atoi(edge.substr(next).c_str()); string type; string attribute; - if (attributes.find(" | ") == string::npos) - type = attributes; + if (attributes.find(" | ") == string::npos) type = attributes; else { next = attributes.find(" | "); @@ -386,13 +405,13 @@ void SVFG::readFile(const string& filename) attribute = attributes.substr(next + 3); } - if(type == "FormalINSVFGNode") + if (type == "FormalINSVFGNode") { const FormalINSVFGNode* formalIn = SVFUtil::cast(getSVFGNode(src)); const ActualINSVFGNode* actualIn = SVFUtil::cast(getSVFGNode(dst)); - addInterIndirectVFCallEdge(actualIn,formalIn, getCallSiteID(actualIn->getCallSite(), formalIn->getFun())); + addInterIndirectVFCallEdge(actualIn, formalIn, getCallSiteID(actualIn->getCallSite(), formalIn->getFun())); } - else if(type == "FormalOUTSVFGNode") + else if (type == "FormalOUTSVFGNode") { const FormalOUTSVFGNode* formalOut = SVFUtil::cast(getSVFGNode(src)); if (attribute.find("intra") != string::npos) @@ -402,15 +421,16 @@ void SVFG::readFile(const string& filename) else { const ActualOUTSVFGNode* actualOut = SVFUtil::cast(getSVFGNode(dst)); - addInterIndirectVFRetEdge(formalOut,actualOut,getCallSiteID(actualOut->getCallSite(), formalOut->getFun())); + addInterIndirectVFRetEdge(formalOut, actualOut, + getCallSiteID(actualOut->getCallSite(), formalOut->getFun())); } } - else if(type == "ActualINSVFGNode") + else if (type == "ActualINSVFGNode") { const ActualINSVFGNode* actualIn = SVFUtil::cast(getSVFGNode(src)); - addIntraIndirectVFEdge(dst,src, actualIn->getMRVer()->getMR()->getPointsTo()); + addIntraIndirectVFEdge(dst, src, actualIn->getMRVer()->getMR()->getPointsTo()); } - else if(type == "ActualOUTSVFGNode") + else if (type == "ActualOUTSVFGNode") { // There's no need to connect actual out node to its definition site in the same function. } @@ -418,7 +438,7 @@ void SVFG::readFile(const string& filename) { MRVer* tempMRVer; tempMRVer = getMRVERFromString(attribute); - addIntraIndirectVFEdge(dst,src, tempMRVer->getMR()->getPointsTo()); + addIntraIndirectVFEdge(dst, src, tempMRVer->getMR()->getPointsTo()); } else { @@ -430,7 +450,7 @@ void SVFG::readFile(const string& filename) MRVer* SVFG::getMRVERFromString(const string& s) { - if(s == "") + if (s == "") { return NULL; } @@ -443,7 +463,7 @@ MRVer* SVFG::getMRVERFromString(const string& s) //{create Memory Region object next = s.find("MemRegion: pts{") + 15; last = s.find("} MRVERSION: "); - temp = s.substr(next, last-next); + temp = s.substr(next, last - next); // convert string to PointsTo NodeBS dstPts; string point; @@ -459,7 +479,7 @@ MRVer* SVFG::getMRVERFromString(const string& s) // create mssdef next = s.find("MSSADef: ") + 9; last = s.find("} >="); - temp = s.substr(next, last-next); + temp = s.substr(next, last - next); // convert string to deftype istringstream ss1(temp.substr(0, temp.find(", "))); int obj1; @@ -469,7 +489,7 @@ MRVer* SVFG::getMRVERFromString(const string& s) // mrversion next = s.find("MRVERSION: ") + 11; last = s.find(" MSSADef:"); - temp = s.substr(next, last-next); + temp = s.substr(next, last - next); // convert mrversion to nodeid istringstream ss2(temp); NodeID obj2; diff --git a/svf/lib/Graphs/SVFGStat.cpp b/svf/lib/Graphs/SVFGStat.cpp index bd6d7ef27..bf7ce3d8b 100644 --- a/svf/lib/Graphs/SVFGStat.cpp +++ b/svf/lib/Graphs/SVFGStat.cpp @@ -34,30 +34,30 @@ using namespace SVF; using namespace std; -const char* MemSSAStat::TotalTimeOfConstructMemSSA = "TotalMSSATime"; ///< Total time for constructing memory SSA -const char* MemSSAStat::TimeOfGeneratingMemRegions = "GenRegionTime"; ///< Time for allocating regions -const char* MemSSAStat::TimeOfCreateMUCHI = "GenMUCHITime"; ///< Time for generating mu/chi for load/store/calls -const char* MemSSAStat::TimeOfInsertingPHI = "InsertPHITime"; ///< Time for inserting phis -const char* MemSSAStat::TimeOfSSARenaming = "SSARenameTime"; ///< Time for SSA rename - -const char* MemSSAStat::NumOfMaxRegion = "MaxRegSize"; ///< Number of max points-to set in region. -const char* MemSSAStat::NumOfAveragePtsInRegion = "AverageRegSize"; ///< Number of average points-to set in region. -const char* MemSSAStat::NumOfMemRegions = "MemRegions"; ///< Number of memory regions -const char* MemSSAStat::NumOfEntryChi = "FunEntryChi"; ///< Number of function entry chi -const char* MemSSAStat::NumOfRetMu = "FunRetMu"; ///< Number of function return mu -const char* MemSSAStat::NumOfCSChi = "CSChiNode"; ///< Number of call site chi -const char* MemSSAStat::NumOfCSMu = "CSMuNode"; ///< Number of call site mu -const char* MemSSAStat::NumOfLoadMu = "LoadMuNode"; ///< Number of load mu -const char* MemSSAStat::NumOfStoreChi = "StoreChiNode"; ///< Number of store chi -const char* MemSSAStat::NumOfMSSAPhi = "MSSAPhi"; ///< Number of non-top level ptr phi - -const char* MemSSAStat::NumOfFunHasEntryChi = "FunHasEntryChi"; ///< Number of functions which have entry chi -const char* MemSSAStat::NumOfFunHasRetMu = "FunHasRetMu"; ///< Number of functions which have return mu -const char* MemSSAStat::NumOfCSHasChi = "CSHasChi"; ///< Number of call sites which have chi -const char* MemSSAStat::NumOfCSHasMu = "CSHasMu"; ///< Number of call sites which have mu -const char* MemSSAStat::NumOfLoadHasMu = "LoadHasMu"; ///< Number of loads which have mu -const char* MemSSAStat::NumOfStoreHasChi = "StoreHasChi"; ///< Number of stores which have chi -const char* MemSSAStat::NumOfBBHasMSSAPhi = "BBHasMSSAPhi"; ///< Number of basic blocks which have mssa phi +const char* MemSSAStat::TotalTimeOfConstructMemSSA = "TotalMSSATime"; ///< Total time for constructing memory SSA +const char* MemSSAStat::TimeOfGeneratingMemRegions = "GenRegionTime"; ///< Time for allocating regions +const char* MemSSAStat::TimeOfCreateMUCHI = "GenMUCHITime"; ///< Time for generating mu/chi for load/store/calls +const char* MemSSAStat::TimeOfInsertingPHI = "InsertPHITime"; ///< Time for inserting phis +const char* MemSSAStat::TimeOfSSARenaming = "SSARenameTime"; ///< Time for SSA rename + +const char* MemSSAStat::NumOfMaxRegion = "MaxRegSize"; ///< Number of max points-to set in region. +const char* MemSSAStat::NumOfAveragePtsInRegion = "AverageRegSize"; ///< Number of average points-to set in region. +const char* MemSSAStat::NumOfMemRegions = "MemRegions"; ///< Number of memory regions +const char* MemSSAStat::NumOfEntryChi = "FunEntryChi"; ///< Number of function entry chi +const char* MemSSAStat::NumOfRetMu = "FunRetMu"; ///< Number of function return mu +const char* MemSSAStat::NumOfCSChi = "CSChiNode"; ///< Number of call site chi +const char* MemSSAStat::NumOfCSMu = "CSMuNode"; ///< Number of call site mu +const char* MemSSAStat::NumOfLoadMu = "LoadMuNode"; ///< Number of load mu +const char* MemSSAStat::NumOfStoreChi = "StoreChiNode"; ///< Number of store chi +const char* MemSSAStat::NumOfMSSAPhi = "MSSAPhi"; ///< Number of non-top level ptr phi + +const char* MemSSAStat::NumOfFunHasEntryChi = "FunHasEntryChi"; ///< Number of functions which have entry chi +const char* MemSSAStat::NumOfFunHasRetMu = "FunHasRetMu"; ///< Number of functions which have return mu +const char* MemSSAStat::NumOfCSHasChi = "CSHasChi"; ///< Number of call sites which have chi +const char* MemSSAStat::NumOfCSHasMu = "CSHasMu"; ///< Number of call sites which have mu +const char* MemSSAStat::NumOfLoadHasMu = "LoadHasMu"; ///< Number of loads which have mu +const char* MemSSAStat::NumOfStoreHasChi = "StoreHasChi"; ///< Number of stores which have chi +const char* MemSSAStat::NumOfBBHasMSSAPhi = "BBHasMSSAPhi"; ///< Number of basic blocks which have mssa phi /*! * Constructor @@ -81,23 +81,22 @@ void MemSSAStat::performStat() u32_t maxRegionSize = 0; u32_t totalRegionPtsNum = 0; - MRGenerator::MRSet & mrSet = mrGenerator->getMRSet(); + MRGenerator::MRSet& mrSet = mrGenerator->getMRSet(); MRGenerator::MRSet::const_iterator it = mrSet.begin(); MRGenerator::MRSet::const_iterator eit = mrSet.end(); for (; it != eit; it++) { const MemRegion* region = *it; u32_t regionSize = region->getRegionSize(); - if (regionSize > maxRegionSize) - maxRegionSize = regionSize; + if (regionSize > maxRegionSize) maxRegionSize = regionSize; totalRegionPtsNum += regionSize; } - timeStatMap[TotalTimeOfConstructMemSSA] = (endTime - startTime)/TIMEINTERVAL; + timeStatMap[TotalTimeOfConstructMemSSA] = (endTime - startTime) / TIMEINTERVAL; timeStatMap[TimeOfGeneratingMemRegions] = MemSSA::timeOfGeneratingMemRegions; - timeStatMap[TimeOfCreateMUCHI] = MemSSA::timeOfCreateMUCHI; - timeStatMap[TimeOfInsertingPHI] = MemSSA::timeOfInsertingPHI; - timeStatMap[TimeOfSSARenaming] = MemSSA::timeOfSSARenaming; + timeStatMap[TimeOfCreateMUCHI] = MemSSA::timeOfCreateMUCHI; + timeStatMap[TimeOfInsertingPHI] = MemSSA::timeOfInsertingPHI; + timeStatMap[TimeOfSSARenaming] = MemSSA::timeOfSSARenaming; PTNumStatMap[NumOfMaxRegion] = maxRegionSize; timeStatMap[NumOfAveragePtsInRegion] = (regionNumber == 0) ? 0 : ((double)totalRegionPtsNum / regionNumber); @@ -119,7 +118,6 @@ void MemSSAStat::performStat() PTNumStatMap[NumOfBBHasMSSAPhi] = mssa->getBBToPhiSetMap().size(); printStat(); - } /*! @@ -183,17 +181,17 @@ void SVFGStat::performStat() processGraph(); - timeStatMap["TotalTime"] = (endTime - startTime)/TIMEINTERVAL; + timeStatMap["TotalTime"] = (endTime - startTime) / TIMEINTERVAL; - timeStatMap["ConnDirEdgeTime"] = (connectDirSVFGEdgeTimeEnd - connectDirSVFGEdgeTimeStart)/TIMEINTERVAL; + timeStatMap["ConnDirEdgeTime"] = (connectDirSVFGEdgeTimeEnd - connectDirSVFGEdgeTimeStart) / TIMEINTERVAL; - timeStatMap["ConnIndEdgeTime"] = (connectIndSVFGEdgeTimeEnd - connectIndSVFGEdgeTimeStart)/TIMEINTERVAL; + timeStatMap["ConnIndEdgeTime"] = (connectIndSVFGEdgeTimeEnd - connectIndSVFGEdgeTimeStart) / TIMEINTERVAL; - timeStatMap["TLNodeTime"] = (addTopLevelNodeTimeEnd - addTopLevelNodeTimeStart)/TIMEINTERVAL; + timeStatMap["TLNodeTime"] = (addTopLevelNodeTimeEnd - addTopLevelNodeTimeStart) / TIMEINTERVAL; - timeStatMap["ATNodeTime"] = (addAddrTakenNodeTimeEnd - addAddrTakenNodeTimeStart)/TIMEINTERVAL; + timeStatMap["ATNodeTime"] = (addAddrTakenNodeTimeEnd - addAddrTakenNodeTimeStart) / TIMEINTERVAL; - timeStatMap["OptTime"] = (svfgOptTimeEnd - svfgOptTimeStart)/TIMEINTERVAL; + timeStatMap["OptTime"] = (svfgOptTimeEnd - svfgOptTimeStart) / TIMEINTERVAL; PTNumStatMap["TotalNode"] = numOfNodes; @@ -251,8 +249,7 @@ void SVFGStat::processGraph() for (; it != eit; ++it) { numOfNodes++; - if (SVFUtil::isa(it->second)) - numOfFormalIn++; + if (SVFUtil::isa(it->second)) numOfFormalIn++; else if (SVFUtil::isa(it->second)) numOfFormalOut++; else if (SVFUtil::isa(it->second)) @@ -292,11 +289,9 @@ void SVFGStat::processGraph() avgOutDegree = totalOutEdge / numOfNodes; } - if (!nodeHasIndInEdge.empty()) - avgIndInDegree = totalIndInEdge / nodeHasIndInEdge.size(); + if (!nodeHasIndInEdge.empty()) avgIndInDegree = totalIndInEdge / nodeHasIndInEdge.size(); - if (!nodeHasIndOutEdge.empty()) - avgIndOutDegree = totalIndOutEdge / nodeHasIndOutEdge.size(); + if (!nodeHasIndOutEdge.empty()) avgIndOutDegree = totalIndOutEdge / nodeHasIndOutEdge.size(); } void SVFGStat::calculateNodeDegrees(SVFGNode* node, NodeSet& nodeHasIndInEdge, NodeSet& nodeHasIndOutEdge) @@ -304,8 +299,7 @@ void SVFGStat::calculateNodeDegrees(SVFGNode* node, NodeSet& nodeHasIndInEdge, N // Incoming edge const SVFGEdge::SVFGEdgeSetTy& inEdges = node->getInEdges(); // total in edge - if (inEdges.size() > maxInDegree) - maxInDegree = inEdges.size(); + if (inEdges.size() > maxInDegree) maxInDegree = inEdges.size(); totalInEdge += inEdges.size(); // indirect in edge @@ -325,8 +319,7 @@ void SVFGStat::calculateNodeDegrees(SVFGNode* node, NodeSet& nodeHasIndInEdge, N totalIndEdgeLabels += cpts.count(); } - if (SVFUtil::isa(*edgeIt)) - totalDirCallEdge++; + if (SVFUtil::isa(*edgeIt)) totalDirCallEdge++; else if (SVFUtil::isa(*edgeIt)) totalIndCallEdge++; else if (SVFUtil::isa(*edgeIt)) @@ -335,8 +328,7 @@ void SVFGStat::calculateNodeDegrees(SVFGNode* node, NodeSet& nodeHasIndInEdge, N totalIndRetEdge++; } - if (indInEdges > maxIndInDegree) - maxIndInDegree = indInEdges; + if (indInEdges > maxIndInDegree) maxIndInDegree = indInEdges; totalIndInEdge += indInEdges; /*-----------------------------------------------------*/ @@ -344,8 +336,7 @@ void SVFGStat::calculateNodeDegrees(SVFGNode* node, NodeSet& nodeHasIndInEdge, N // Outgoing edge const SVFGEdge::SVFGEdgeSetTy& outEdges = node->getOutEdges(); // total out edge - if (outEdges.size() > maxOutDegree) - maxOutDegree = outEdges.size(); + if (outEdges.size() > maxOutDegree) maxOutDegree = outEdges.size(); totalOutEdge += outEdges.size(); // indirect out edge @@ -361,8 +352,7 @@ void SVFGStat::calculateNodeDegrees(SVFGNode* node, NodeSet& nodeHasIndInEdge, N } } - if (indOutEdges > maxIndOutDegree) - maxIndOutDegree = indOutEdges; + if (indOutEdges > maxIndOutDegree) maxIndOutDegree = indOutEdges; totalIndOutEdge += indOutEdges; } @@ -400,13 +390,12 @@ void SVFGStat::performSCCStat(SVFGEdgeSet insensitiveCalRetEdges) for (; it != eit; ++it) { totalNode++; - if(svfgSCC->isInCycle(it->first)) + if (svfgSCC->isInCycle(it->first)) { nodeInCycle++; sccRepNodeSet.insert(svfgSCC->repNode(it->first)); const NodeBS& subNodes = svfgSCC->subNodes(it->first); - if(subNodes.count() > maxNodeInCycle) - maxNodeInCycle = subNodes.count(); + if (subNodes.count() > maxNodeInCycle) maxNodeInCycle = subNodes.count(); } SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin(); @@ -414,10 +403,10 @@ void SVFGStat::performSCCStat(SVFGEdgeSet insensitiveCalRetEdges) for (; edgeIt != edgeEit; ++edgeIt) { - const SVFGEdge *edge = *edgeIt; + const SVFGEdge* edge = *edgeIt; totalEdge++; bool eCycle = false; - if(getSCCRep(svfgSCC,edge->getSrcID()) == getSCCRep(svfgSCC,edge->getDstID())) + if (getSCCRep(svfgSCC, edge->getSrcID()) == getSCCRep(svfgSCC, edge->getDstID())) { edgeInCycle++; eCycle = true; @@ -426,25 +415,22 @@ void SVFGStat::performSCCStat(SVFGEdgeSet insensitiveCalRetEdges) if (edge->isDirectVFGEdge()) { totalDirectEdge++; - if(eCycle) - directEdgeInCycle++; - + if (eCycle) directEdgeInCycle++; } if (edge->isIndirectVFGEdge()) { totalIndirectEdge++; - if(eCycle) - indirectEdgeInCycle++; + if (eCycle) indirectEdgeInCycle++; } if (edge->isCallVFGEdge()) { totalCallEdge++; - if(eCycle) + if (eCycle) { callEdgeInCycle++; } - if(insensitiveCalRetEdges.find(edge)!=insensitiveCalRetEdges.end()) + if (insensitiveCalRetEdges.find(edge) != insensitiveCalRetEdges.end()) { insensitiveCallEdge++; } @@ -452,12 +438,12 @@ void SVFGStat::performSCCStat(SVFGEdgeSet insensitiveCalRetEdges) if (edge->isRetVFGEdge()) { totalRetEdge++; - if(eCycle) + if (eCycle) { retEdgeInCycle++; } - if(insensitiveCalRetEdges.find(edge)!=insensitiveCalRetEdges.end()) + if (insensitiveCalRetEdges.find(edge) != insensitiveCalRetEdges.end()) { insensitiveRetEdge++; } @@ -465,10 +451,8 @@ void SVFGStat::performSCCStat(SVFGEdgeSet insensitiveCalRetEdges) } } - totalCycle = sccRepNodeSet.size(); - PTNumStatMap["TotalNode"] = totalNode; PTNumStatMap["TotalCycle"] = totalCycle; PTNumStatMap["NodeInCycle"] = nodeInCycle; @@ -489,11 +473,9 @@ void SVFGStat::performSCCStat(SVFGEdgeSet insensitiveCalRetEdges) PTNumStatMap["RetEdgeInCycle"] = retEdgeInCycle; PTNumStatMap["InsenRetEdge"] = insensitiveRetEdge; - PTAStat::printStat("SVFG SCC Stat"); delete svfgSCC; - } void SVFGStat::printStat(string str) diff --git a/svf/lib/Graphs/ThreadCallGraph.cpp b/svf/lib/Graphs/ThreadCallGraph.cpp index d2b2c2732..6495b977f 100644 --- a/svf/lib/Graphs/ThreadCallGraph.cpp +++ b/svf/lib/Graphs/ThreadCallGraph.cpp @@ -37,13 +37,11 @@ using namespace SVFUtil; /*! * Constructor */ -ThreadCallGraph::ThreadCallGraph() : - CallGraph(ThdCallGraph), tdAPI(ThreadAPI::getThreadAPI()) +ThreadCallGraph::ThreadCallGraph() : CallGraph(ThdCallGraph), tdAPI(ThreadAPI::getThreadAPI()) { DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Building ThreadCallGraph\n")); } - /* * Update call graph using pointer analysis results * (1) resolve function pointers for non-fork calls @@ -58,9 +56,9 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta) for (; iter != eiter; iter++) { const CallICFGNode* cs = iter->first; - const CallGraph::FunctionSet &functions = iter->second; - for (CallGraph::FunctionSet::const_iterator func_iter = - functions.begin(); func_iter != functions.end(); func_iter++) + const CallGraph::FunctionSet& functions = iter->second; + for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); + func_iter++) { const SVFFunction* callee = *func_iter; this->addIndirectCallGraphEdge(cs, cs->getCaller(), callee); @@ -71,16 +69,16 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta) for (CallSiteSet::const_iterator it = forksitesBegin(), eit = forksitesEnd(); it != eit; ++it) { const SVFValue* forkedval = tdAPI->getForkedFun((*it)->getCallSite()); - if(SVFUtil::dyn_cast(forkedval)==nullptr) + if (SVFUtil::dyn_cast(forkedval) == nullptr) { SVFIR* pag = pta->getPAG(); const NodeBS targets = pta->getPts(pag->getValueNode(forkedval)).toNodeBS(); for (NodeBS::iterator ii = targets.begin(), ie = targets.end(); ii != ie; ii++) { - if(ObjVar* objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) + if (ObjVar* objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) { const MemObj* obj = pag->getObject(objPN); - if(obj->isFunction()) + if (obj->isFunction()) { const SVFFunction* svfCallee = SVFUtil::cast(obj->getValue()); this->addIndirectForkEdge(*it, svfCallee); @@ -91,7 +89,6 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta) } } - /*! * Update join edge using pointer analysis results */ @@ -112,7 +109,7 @@ void ThreadCallGraph::updateJoinEdge(PointerAnalysis* pta) } } assert(!forkset.empty() && "Can't find a forksite for this join!!"); - addDirectJoinEdge(*it,forkset); + addDirectJoinEdge(*it, forkset); } } @@ -168,7 +165,7 @@ void ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunct * A ThreadJoinEdge is created from the functions where join sites reside in to the start routine function * But we don't invoke addEdge() method to add the edge to src and dst, otherwise it makes a scc cycle */ -void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forkset) +void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs, const CallSiteSet& forkset) { CallGraphNode* joinFunNode = getCallGraphNode(cs->getCaller()); @@ -181,10 +178,10 @@ void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet CallGraphNode* threadRoutineFunNode = getCallGraphNode(threadRoutineFun); CallSiteID csId = addCallSite(cs, threadRoutineFun); - if (!hasThreadJoinEdge(cs,joinFunNode,threadRoutineFunNode, csId)) + if (!hasThreadJoinEdge(cs, joinFunNode, threadRoutineFunNode, csId)) { assert(cs->getCaller() == joinFunNode->getFunction() && "callee instruction not inside caller??"); - ThreadJoinEdge* edge = new ThreadJoinEdge(joinFunNode,threadRoutineFunNode,csId); + ThreadJoinEdge* edge = new ThreadJoinEdge(joinFunNode, threadRoutineFunNode, csId); edge->addDirectCallSite(cs); addThreadJoinEdgeSetMap(cs, edge); diff --git a/svf/lib/Graphs/VFG.cpp b/svf/lib/Graphs/VFG.cpp index 915d7df4f..2135f9712 100644 --- a/svf/lib/Graphs/VFG.cpp +++ b/svf/lib/Graphs/VFG.cpp @@ -27,7 +27,6 @@ * Author: Yulei Sui */ - #include #include "Util/Options.h" #include "Graphs/VFG.h" @@ -40,7 +39,7 @@ using namespace SVFUtil; const std::string VFGNode::toString() const { std::string str; - std::stringstream rawstr(str); + std::stringstream rawstr(str); rawstr << "VFGNode ID: " << getId() << " "; return rawstr.str(); } @@ -48,7 +47,7 @@ const std::string VFGNode::toString() const const std::string StmtVFGNode::toString() const { std::string str; - std::stringstream rawstr(str); + std::stringstream rawstr(str); rawstr << "StmtVFGNode ID: " << getId() << " "; rawstr << getPAGEdge()->toString(); return rawstr.str(); @@ -73,9 +72,9 @@ const std::string LoadVFGNode::toString() const const NodeBS StoreVFGNode::getDefSVFVars() const { NodeBS nb; - for (auto edge: getOutEdges()) + for (auto edge : getOutEdges()) { - if (IndirectSVFGEdge *iedge = SVFUtil::dyn_cast(edge)) + if (IndirectSVFGEdge* iedge = SVFUtil::dyn_cast(edge)) { nb |= iedge->getPointsTo(); } @@ -121,11 +120,10 @@ const std::string CmpVFGNode::toString() const std::stringstream rawstr(str); rawstr << "CmpVFGNode ID: " << getId() << " "; rawstr << "PAGEdge: [" << res->getId() << " = cmp("; - for(CmpVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); - it != eit; it++) + for (CmpVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); it != eit; it++) rawstr << it->second->getId() << ", "; rawstr << ")]\n"; - if(res->hasValue()) + if (res->hasValue()) { rawstr << " " << res->getValue()->toString(); } @@ -145,11 +143,10 @@ const std::string BinaryOPVFGNode::toString() const std::stringstream rawstr(str); rawstr << "BinaryOPVFGNode ID: " << getId() << " "; rawstr << "PAGEdge: [" << res->getId() << " = Binary("; - for(BinaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); - it != eit; it++) + for (BinaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); it != eit; it++) rawstr << it->second->getId() << ", "; rawstr << ")]\t"; - if(res->hasValue()) + if (res->hasValue()) { rawstr << " " << res->getValue()->toString(); } @@ -169,11 +166,10 @@ const std::string UnaryOPVFGNode::toString() const std::stringstream rawstr(str); rawstr << "UnaryOPVFGNode ID: " << getId() << " "; rawstr << "PAGEdge: [" << res->getId() << " = Unary("; - for(UnaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); - it != eit; it++) + for (UnaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); it != eit; it++) rawstr << it->second->getId() << ", "; rawstr << ")]\t"; - if(res->hasValue()) + if (res->hasValue()) { rawstr << " " << res->getValue()->toString(); } @@ -223,29 +219,26 @@ const std::string PHIVFGNode::toString() const std::stringstream rawstr(str); rawstr << "PHIVFGNode ID: " << getId() << " "; rawstr << "PAGNode: [" << res->getId() << " = PHI("; - for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); - it != eit; it++) + for (PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); it != eit; it++) rawstr << it->second->getId() << ", "; rawstr << ")]\t"; - if(res->hasValue()) + if (res->hasValue()) { rawstr << " " << res->getValue()->toString(); } return rawstr.str(); } - const std::string IntraPHIVFGNode::toString() const { std::string str; std::stringstream rawstr(str); rawstr << "IntraPHIVFGNode ID: " << getId() << " "; rawstr << "PAGNode: [" << res->getId() << " = PHI("; - for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); - it != eit; it++) + for (PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd(); it != eit; it++) rawstr << it->second->getId() << ", "; rawstr << ")]\t"; - if(res->hasValue()) + if (res->hasValue()) { rawstr << " " << res->getValue()->toString(); } @@ -268,7 +261,6 @@ const std::string AddrVFGNode::toString() const return rawstr.str(); } - const std::string ArgumentVFGNode::toString() const { std::string str; @@ -329,7 +321,6 @@ const std::string ActualRetVFGNode::toString() const return rawstr.str(); } - const NodeBS FormalRetVFGNode::getDefSVFVars() const { NodeBS nb; @@ -347,15 +338,16 @@ const std::string FormalRetVFGNode::toString() const return rawstr.str(); } - const std::string InterPHIVFGNode::toString() const { std::string str; std::stringstream rawstr(str); - if(isFormalParmPHI()) - rawstr << "FormalParmPHI ID: " << getId() << " PAGNode ID: " << res->getId() << "\n" << res->getValue()->toString(); + if (isFormalParmPHI()) + rawstr << "FormalParmPHI ID: " << getId() << " PAGNode ID: " << res->getId() << "\n" + << res->getValue()->toString(); else - rawstr << "ActualRetPHI ID: " << getId() << " PAGNode ID: " << res->getId() << "\n" << res->getValue()->toString(); + rawstr << "ActualRetPHI ID: " << getId() << " PAGNode ID: " << res->getId() << "\n" + << res->getValue()->toString(); return rawstr.str(); } @@ -375,7 +367,6 @@ const std::string NullPtrVFGNode::toString() const return rawstr.str(); } - const std::string VFGEdge::toString() const { std::string str; @@ -418,17 +409,12 @@ const std::string RetDirSVFGEdge::toString() const return rawstr.str(); } - - -FormalRetVFGNode::FormalRetVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f) : - ArgumentVFGNode(id, n, FRet), fun(f) +FormalRetVFGNode::FormalRetVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f) + : ArgumentVFGNode(id, n, FRet), fun(f) { } -PHIVFGNode::PHIVFGNode(NodeID id, const PAGNode* r,VFGNodeK k): VFGNode(id, k), res(r) -{ - -} +PHIVFGNode::PHIVFGNode(NodeID id, const PAGNode* r, VFGNodeK k) : VFGNode(id, k), res(r) {} /*! * Constructor @@ -438,7 +424,7 @@ PHIVFGNode::PHIVFGNode(NodeID id, const PAGNode* r,VFGNodeK k): VFGNode(id, k), * 2) connect VFG edges * between two statements (PAGEdges) */ -VFG::VFG(CallGraph* cg, VFGK k): totalVFGNode(0), callgraph(cg), pag(SVFIR::getPAG()), kind(k) +VFG::VFG(CallGraph* cg, VFGK k) : totalVFGNode(0), callgraph(cg), pag(SVFIR::getPAG()), kind(k) { DBOUT(DGENERAL, outs() << pasMsg("\tCreate VFG Top Level Node\n")); @@ -456,7 +442,6 @@ void VFG::destroy() pag = nullptr; } - /*! * Create VFG nodes for top level pointers */ @@ -470,16 +455,14 @@ void VFG::addVFGNodes() // initialize address nodes SVFStmt::SVFStmtSetTy& addrs = getPAGEdgeSet(SVFStmt::Addr); - for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter = - addrs.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter = addrs.end(); iter != eiter; ++iter) { addAddrVFGNode(SVFUtil::cast(*iter)); } // initialize copy nodes SVFStmt::SVFStmtSetTy& copys = getPAGEdgeSet(SVFStmt::Copy); - for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter = - copys.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter = copys.end(); iter != eiter; ++iter) { const CopyStmt* edge = SVFUtil::cast(*iter); assert(!isPhiCopyEdge(edge) && "Copy edges can not be a PhiNode (or from PhiNode)"); @@ -488,104 +471,99 @@ void VFG::addVFGNodes() // initialize gep nodes SVFStmt::SVFStmtSetTy& ngeps = getPAGEdgeSet(SVFStmt::Gep); - for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter = - ngeps.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter = ngeps.end(); iter != eiter; ++iter) { addGepVFGNode(SVFUtil::cast(*iter)); } // initialize load nodes SVFStmt::SVFStmtSetTy& loads = getPAGEdgeSet(SVFStmt::Load); - for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = - loads.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = loads.end(); iter != eiter; ++iter) { addLoadVFGNode(SVFUtil::cast(*iter)); } // initialize store nodes SVFStmt::SVFStmtSetTy& stores = getPAGEdgeSet(SVFStmt::Store); - for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = - stores.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; ++iter) { addStoreVFGNode(SVFUtil::cast(*iter)); } SVFStmt::SVFStmtSetTy& forks = getPAGEdgeSet(SVFStmt::ThreadFork); - for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter = - forks.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter = forks.end(); iter != eiter; ++iter) { TDForkPE* forkedge = SVFUtil::cast(*iter); - addActualParmVFGNode(forkedge->getRHSVar(),forkedge->getCallSite()); + addActualParmVFGNode(forkedge->getRHSVar(), forkedge->getCallSite()); } // initialize actual parameter nodes - for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); it !=eit; ++it) + for (SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); + it != eit; ++it) { - for(SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit) + for (SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit != epit; ++pit) { const PAGNode* pagNode = *pit; - if (isInterestedPAGNode(pagNode)) - addActualParmVFGNode(pagNode,it->first); + if (isInterestedPAGNode(pagNode)) addActualParmVFGNode(pagNode, it->first); } } // initialize actual return nodes (callsite return) - for(SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), eit = pag->getCallSiteRets().end(); it !=eit; ++it) + for (SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), eit = pag->getCallSiteRets().end(); it != eit; + ++it) { /// for external function we do not create acutalRet VFGNode /// they are in the formal of AddrVFGNode if the external function returns an allocated memory /// if fun has body, it may also exist in isExtCall, e.g., xmalloc() in bzip2, spec2000. - if(isInterestedPAGNode(it->second) == false || hasDef(it->second)) - continue; + if (isInterestedPAGNode(it->second) == false || hasDef(it->second)) continue; - addActualRetVFGNode(it->second,it->first->getCallICFGNode()); + addActualRetVFGNode(it->second, it->first->getCallICFGNode()); } // initialize formal parameter nodes - for(SVFIR::FunToArgsListMap::iterator it = pag->getFunArgsMap().begin(), eit = pag->getFunArgsMap().end(); it !=eit; ++it) + for (SVFIR::FunToArgsListMap::iterator it = pag->getFunArgsMap().begin(), eit = pag->getFunArgsMap().end(); + it != eit; ++it) { const SVFFunction* func = it->first; - for(SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit) + for (SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit != epit; ++pit) { const PAGNode* param = *pit; - if (isInterestedPAGNode(param) == false || hasBlackHoleConstObjAddrAsDef(param)) - continue; + if (isInterestedPAGNode(param) == false || hasBlackHoleConstObjAddrAsDef(param)) continue; CallPESet callPEs; if (param->hasIncomingEdges(SVFStmt::Call)) { - for (SVFStmt::SVFStmtSetTy::const_iterator cit = param->getIncomingEdgesBegin(SVFStmt::Call), ecit = - param->getIncomingEdgesEnd(SVFStmt::Call); cit != ecit; ++cit) + for (SVFStmt::SVFStmtSetTy::const_iterator cit = param->getIncomingEdgesBegin(SVFStmt::Call), + ecit = param->getIncomingEdgesEnd(SVFStmt::Call); + cit != ecit; ++cit) { CallPE* callPE = SVFUtil::cast(*cit); - if (isInterestedPAGNode(callPE->getRHSVar())) - callPEs.insert(callPE); + if (isInterestedPAGNode(callPE->getRHSVar())) callPEs.insert(callPE); } } - addFormalParmVFGNode(param,func,callPEs); + addFormalParmVFGNode(param, func, callPEs); } if (func->isVarArg()) { const PAGNode* varParam = pag->getGNode(pag->getVarargNode(func)); - if (isInterestedPAGNode(varParam) == false || hasBlackHoleConstObjAddrAsDef(varParam)) - continue; + if (isInterestedPAGNode(varParam) == false || hasBlackHoleConstObjAddrAsDef(varParam)) continue; CallPESet callPEs; if (varParam->hasIncomingEdges(SVFStmt::Call)) { - for(SVFStmt::SVFStmtSetTy::const_iterator cit = varParam->getIncomingEdgesBegin(SVFStmt::Call), - ecit = varParam->getIncomingEdgesEnd(SVFStmt::Call); cit!=ecit; ++cit) + for (SVFStmt::SVFStmtSetTy::const_iterator cit = varParam->getIncomingEdgesBegin(SVFStmt::Call), + ecit = varParam->getIncomingEdgesEnd(SVFStmt::Call); + cit != ecit; ++cit) { CallPE* callPE = SVFUtil::cast(*cit); - if(isInterestedPAGNode(callPE->getRHSVar())) - callPEs.insert(callPE); + if (isInterestedPAGNode(callPE->getRHSVar())) callPEs.insert(callPE); } } - addFormalParmVFGNode(varParam,func,callPEs); + addFormalParmVFGNode(varParam, func, callPEs); } } @@ -600,72 +578,58 @@ void VFG::addVFGNodes() if (uniqueFunRetNode->hasOutgoingEdges(SVFStmt::Ret)) { for (SVFStmt::SVFStmtSetTy::const_iterator cit = uniqueFunRetNode->getOutgoingEdgesBegin(SVFStmt::Ret), - ecit = uniqueFunRetNode->getOutgoingEdgesEnd(SVFStmt::Ret); - cit != ecit; ++cit) + ecit = uniqueFunRetNode->getOutgoingEdgesEnd(SVFStmt::Ret); + cit != ecit; ++cit) { const RetPE* retPE = SVFUtil::cast(*cit); - if (isInterestedPAGNode(retPE->getLHSVar())) - retPEs.insert(retPE); + if (isInterestedPAGNode(retPE->getLHSVar())) retPEs.insert(retPE); } } - if(isInterestedPAGNode(uniqueFunRetNode)) - addFormalRetVFGNode(uniqueFunRetNode, func, retPEs); + if (isInterestedPAGNode(uniqueFunRetNode)) addFormalRetVFGNode(uniqueFunRetNode, func, retPEs); } // initialize llvm phi nodes (phi of top level pointers) SVFStmt::SVFStmtSetTy& phis = getPAGEdgeSet(SVFStmt::Phi); - for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter = - phis.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter = phis.end(); iter != eiter; ++iter) { const PhiStmt* edge = SVFUtil::cast(*iter); - if(isInterestedPAGNode(edge->getRes())) - addIntraPHIVFGNode(edge); + if (isInterestedPAGNode(edge->getRes())) addIntraPHIVFGNode(edge); } // initialize select statement SVFStmt::SVFStmtSetTy& selects = getPAGEdgeSet(SVFStmt::Select); - for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter = - selects.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter = selects.end(); iter != eiter; ++iter) { const MultiOpndStmt* edge = SVFUtil::cast(*iter); - if(isInterestedPAGNode(edge->getRes())) - addIntraPHIVFGNode(edge); + if (isInterestedPAGNode(edge->getRes())) addIntraPHIVFGNode(edge); } // initialize llvm binary nodes (binary operators) SVFStmt::SVFStmtSetTy& binaryops = getPAGEdgeSet(SVFStmt::BinaryOp); - for (SVFStmt::SVFStmtSetTy::iterator iter = binaryops.begin(), eiter = - binaryops.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = binaryops.begin(), eiter = binaryops.end(); iter != eiter; ++iter) { const BinaryOPStmt* edge = SVFUtil::cast(*iter); - if(isInterestedPAGNode(edge->getRes())) - addBinaryOPVFGNode(edge); + if (isInterestedPAGNode(edge->getRes())) addBinaryOPVFGNode(edge); } // initialize llvm unary nodes (unary operators) SVFStmt::SVFStmtSetTy& unaryops = getPAGEdgeSet(SVFStmt::UnaryOp); - for (SVFStmt::SVFStmtSetTy::iterator iter = unaryops.begin(), eiter = - unaryops.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = unaryops.begin(), eiter = unaryops.end(); iter != eiter; ++iter) { const UnaryOPStmt* edge = SVFUtil::cast(*iter); - if(isInterestedPAGNode(edge->getRes())) - addUnaryOPVFGNode(edge); + if (isInterestedPAGNode(edge->getRes())) addUnaryOPVFGNode(edge); } // initialize llvm unary nodes (unary operators) SVFStmt::SVFStmtSetTy& brs = getPAGEdgeSet(SVFStmt::Branch); - for (SVFStmt::SVFStmtSetTy::iterator iter = brs.begin(), eiter = - brs.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = brs.begin(), eiter = brs.end(); iter != eiter; ++iter) { const BranchStmt* edge = SVFUtil::cast(*iter); - if(isInterestedPAGNode(edge->getBranchInst())) - addBranchVFGNode(edge); + if (isInterestedPAGNode(edge->getBranchInst())) addBranchVFGNode(edge); } // initialize llvm cmp nodes (comparison) SVFStmt::SVFStmtSetTy& cmps = getPAGEdgeSet(SVFStmt::Cmp); - for (SVFStmt::SVFStmtSetTy::iterator iter = cmps.begin(), eiter = - cmps.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = cmps.begin(), eiter = cmps.end(); iter != eiter; ++iter) { const CmpStmt* edge = SVFUtil::cast(*iter); - if(isInterestedPAGNode(edge->getRes())) - addCmpVFGNode(edge); + if (isInterestedPAGNode(edge->getRes())) addCmpVFGNode(edge); } } @@ -685,9 +649,9 @@ VFGEdge* VFG::addIntraDirectVFEdge(NodeID srcId, NodeID dstId) } else { - if(srcNode!=dstNode) + if (srcNode != dstNode) { - IntraDirSVFGEdge* directEdge = new IntraDirSVFGEdge(srcNode,dstNode); + IntraDirSVFGEdge* directEdge = new IntraDirSVFGEdge(srcNode, dstNode); return (addVFGEdge(directEdge) ? directEdge : nullptr); } else @@ -710,7 +674,7 @@ VFGEdge* VFG::addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId) } else { - CallDirSVFGEdge* callEdge = new CallDirSVFGEdge(srcNode,dstNode,csId); + CallDirSVFGEdge* callEdge = new CallDirSVFGEdge(srcNode, dstNode, csId); return (addVFGEdge(callEdge) ? callEdge : nullptr); } } @@ -730,114 +694,116 @@ VFGEdge* VFG::addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId) } else { - RetDirSVFGEdge* retEdge = new RetDirSVFGEdge(srcNode,dstNode,csId); + RetDirSVFGEdge* retEdge = new RetDirSVFGEdge(srcNode, dstNode, csId); return (addVFGEdge(retEdge) ? retEdge : nullptr); } } - /*! * Connect def-use chains for direct value-flow, (value-flow of top level pointers) */ void VFG::connectDirectVFGEdges() { - for(iterator it = begin(), eit = end(); it!=eit; ++it) + for (iterator it = begin(), eit = end(); it != eit; ++it) { NodeID nodeId = it->first; VFGNode* node = it->second; - if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { /// do not handle AddrSVFG node, as it is already the source of a definition - if(SVFUtil::isa(stmtNode)) - continue; + if (SVFUtil::isa(stmtNode)) continue; /// for all other cases, like copy/gep/load/ret, connect the RHS pointer to its def if (stmtNode->getPAGSrcNode()->isConstDataOrAggDataButNotNullPtr() == false) // for ptr vfg, we skip src node of integer type if it is at a int2ptr copystmt - if(isInterestedPAGNode(stmtNode->getPAGSrcNode())) + if (isInterestedPAGNode(stmtNode->getPAGSrcNode())) addIntraDirectVFEdge(getDef(stmtNode->getPAGSrcNode()), nodeId); if (const GepStmt* gepStmt = SVFUtil::dyn_cast(stmtNode->getPAGEdge())) { - for (const auto &varType: gepStmt->getOffsetVarAndGepTypePairVec()) + for (const auto& varType : gepStmt->getOffsetVarAndGepTypePairVec()) { - if(varType.first->isConstDataOrAggDataButNotNullPtr() || isInterestedPAGNode(varType.first) == false) + if (varType.first->isConstDataOrAggDataButNotNullPtr() || + isInterestedPAGNode(varType.first) == false) continue; addIntraDirectVFEdge(getDef(varType.first), nodeId); } } /// for store, connect the RHS/LHS pointer to its def - if(SVFUtil::isa(stmtNode) && (stmtNode->getPAGDstNode()->isConstDataOrAggDataButNotNullPtr() == false)) + if (SVFUtil::isa(stmtNode) && + (stmtNode->getPAGDstNode()->isConstDataOrAggDataButNotNullPtr() == false)) { addIntraDirectVFEdge(getDef(stmtNode->getPAGDstNode()), nodeId); } - } - else if(PHIVFGNode* phiNode = SVFUtil::dyn_cast(node)) + else if (PHIVFGNode* phiNode = SVFUtil::dyn_cast(node)) { - for (PHIVFGNode::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; it++) + for (PHIVFGNode::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; + it++) { if (it->second->isConstDataOrAggDataButNotNullPtr() == false) addIntraDirectVFEdge(getDef(it->second), nodeId); } } - else if(BinaryOPVFGNode* binaryNode = SVFUtil::dyn_cast(node)) + else if (BinaryOPVFGNode* binaryNode = SVFUtil::dyn_cast(node)) { - for (BinaryOPVFGNode::OPVers::const_iterator it = binaryNode->opVerBegin(), eit = binaryNode->opVerEnd(); it != eit; it++) + for (BinaryOPVFGNode::OPVers::const_iterator it = binaryNode->opVerBegin(), eit = binaryNode->opVerEnd(); + it != eit; it++) { if (it->second->isConstDataOrAggDataButNotNullPtr() == false) addIntraDirectVFEdge(getDef(it->second), nodeId); } } - else if(UnaryOPVFGNode* unaryNode = SVFUtil::dyn_cast(node)) + else if (UnaryOPVFGNode* unaryNode = SVFUtil::dyn_cast(node)) { - for (UnaryOPVFGNode::OPVers::const_iterator it = unaryNode->opVerBegin(), eit = unaryNode->opVerEnd(); it != eit; it++) + for (UnaryOPVFGNode::OPVers::const_iterator it = unaryNode->opVerBegin(), eit = unaryNode->opVerEnd(); + it != eit; it++) { if (it->second->isConstDataOrAggDataButNotNullPtr() == false) addIntraDirectVFEdge(getDef(it->second), nodeId); } } - else if(CmpVFGNode* cmpNode = SVFUtil::dyn_cast(node)) + else if (CmpVFGNode* cmpNode = SVFUtil::dyn_cast(node)) { - for (CmpVFGNode::OPVers::const_iterator it = cmpNode->opVerBegin(), eit = cmpNode->opVerEnd(); it != eit; it++) + for (CmpVFGNode::OPVers::const_iterator it = cmpNode->opVerBegin(), eit = cmpNode->opVerEnd(); it != eit; + it++) { if (it->second->isConstDataOrAggDataButNotNullPtr() == false) addIntraDirectVFEdge(getDef(it->second), nodeId); } } - else if(BranchVFGNode* branchNode = SVFUtil::dyn_cast(node)) + else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast(node)) { const SVFVar* cond = branchNode->getBranchStmt()->getCondition(); - if (cond->isConstDataOrAggDataButNotNullPtr() == false) - addIntraDirectVFEdge(getDef(cond), nodeId); + if (cond->isConstDataOrAggDataButNotNullPtr() == false) addIntraDirectVFEdge(getDef(cond), nodeId); } - else if(ActualParmVFGNode* actualParm = SVFUtil::dyn_cast(node)) + else if (ActualParmVFGNode* actualParm = SVFUtil::dyn_cast(node)) { if (actualParm->getParam()->isConstDataOrAggDataButNotNullPtr() == false) addIntraDirectVFEdge(getDef(actualParm->getParam()), nodeId); } - else if(FormalParmVFGNode* formalParm = SVFUtil::dyn_cast(node)) + else if (FormalParmVFGNode* formalParm = SVFUtil::dyn_cast(node)) { - for(CallPESet::const_iterator it = formalParm->callPEBegin(), eit = formalParm->callPEEnd(); - it!=eit; ++it) + for (CallPESet::const_iterator it = formalParm->callPEBegin(), eit = formalParm->callPEEnd(); it != eit; + ++it) { const CallICFGNode* cs = (*it)->getCallSite(); - ActualParmVFGNode* acutalParm = getActualParmVFGNode((*it)->getRHSVar(),cs); - addInterEdgeFromAPToFP(acutalParm,formalParm,getCallSiteID(cs, formalParm->getFun())); + ActualParmVFGNode* acutalParm = getActualParmVFGNode((*it)->getRHSVar(), cs); + addInterEdgeFromAPToFP(acutalParm, formalParm, getCallSiteID(cs, formalParm->getFun())); } } - else if(FormalRetVFGNode* calleeRet = SVFUtil::dyn_cast(node)) + else if (FormalRetVFGNode* calleeRet = SVFUtil::dyn_cast(node)) { /// connect formal ret to its definition node addIntraDirectVFEdge(getDef(calleeRet->getRet()), nodeId); /// connect formal ret to actual ret - for(RetPESet::const_iterator it = calleeRet->retPEBegin(), eit = calleeRet->retPEEnd(); it!=eit; ++it) + for (RetPESet::const_iterator it = calleeRet->retPEBegin(), eit = calleeRet->retPEEnd(); it != eit; ++it) { ActualRetVFGNode* callsiteRev = getActualRetVFGNode((*it)->getLHSVar()); const CallICFGNode* retBlockNode = (*it)->getCallSite(); CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(retBlockNode->getCallSite()); - addInterEdgeFromFRToAR(calleeRet,callsiteRev, getCallSiteID(callBlockNode, calleeRet->getFun())); + addInterEdgeFromFRToAR(calleeRet, callsiteRev, getCallSiteID(callBlockNode, calleeRet->getFun())); } } /// Do not process FormalRetVFGNode, as they are connected by copy within callee @@ -845,27 +811,26 @@ void VFG::connectDirectVFGEdges() } /// connect direct value-flow edges (parameter passing) for thread fork/join - if(Options::EnableThreadCallGraph()) + if (Options::EnableThreadCallGraph()) { /// add fork edge SVFStmt::SVFStmtSetTy& forks = getPAGEdgeSet(SVFStmt::ThreadFork); - for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter = - forks.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter = forks.end(); iter != eiter; ++iter) { TDForkPE* forkedge = SVFUtil::cast(*iter); - ActualParmVFGNode* acutalParm = getActualParmVFGNode(forkedge->getRHSVar(),forkedge->getCallSite()); + ActualParmVFGNode* acutalParm = getActualParmVFGNode(forkedge->getRHSVar(), forkedge->getCallSite()); FormalParmVFGNode* formalParm = getFormalParmVFGNode(forkedge->getLHSVar()); - addInterEdgeFromAPToFP(acutalParm,formalParm,getCallSiteID(forkedge->getCallSite(), formalParm->getFun())); + addInterEdgeFromAPToFP(acutalParm, formalParm, + getCallSiteID(forkedge->getCallSite(), formalParm->getFun())); } /// add join edge SVFStmt::SVFStmtSetTy& joins = getPAGEdgeSet(SVFStmt::ThreadJoin); - for (SVFStmt::SVFStmtSetTy::iterator iter = joins.begin(), eiter = - joins.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = joins.begin(), eiter = joins.end(); iter != eiter; ++iter) { TDJoinPE* joinedge = SVFUtil::cast(*iter); NodeID callsiteRev = getDef(joinedge->getLHSVar()); FormalRetVFGNode* calleeRet = getFormalRetVFGNode(joinedge->getRHSVar()); - addRetEdge(calleeRet->getId(),callsiteRev, getCallSiteID(joinedge->getCallSite(), calleeRet->getFun())); + addRetEdge(calleeRet->getId(), callsiteRev, getCallSiteID(joinedge->getCallSite(), calleeRet->getFun())); } } } @@ -875,7 +840,7 @@ void VFG::connectDirectVFGEdges() */ VFGEdge* VFG::hasIntraVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kind) { - VFGEdge edge(src,dst,kind); + VFGEdge edge(src, dst, kind); VFGEdge* outEdge = src->hasOutgoingEdge(&edge); VFGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -887,13 +852,12 @@ VFGEdge* VFG::hasIntraVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kind return nullptr; } - /*! * Whether we has an thread VFG edge */ VFGEdge* VFG::hasThreadVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kind) { - VFGEdge edge(src,dst,kind); + VFGEdge edge(src, dst, kind); VFGEdge* outEdge = src->hasOutgoingEdge(&edge); VFGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -908,9 +872,9 @@ VFGEdge* VFG::hasThreadVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kin /*! * Whether we has an inter VFG edge */ -VFGEdge* VFG::hasInterVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kind,CallSiteID csId) +VFGEdge* VFG::hasInterVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kind, CallSiteID csId) { - VFGEdge edge(src,dst,VFGEdge::makeEdgeFlagWithInvokeID(kind,csId)); + VFGEdge edge(src, dst, VFGEdge::makeEdgeFlagWithInvokeID(kind, csId)); VFGEdge* outEdge = src->hasOutgoingEdge(&edge); VFGEdge* inEdge = dst->hasIncomingEdge(&edge); if (outEdge && inEdge) @@ -922,16 +886,14 @@ VFGEdge* VFG::hasInterVFGEdge(VFGNode* src, VFGNode* dst, VFGEdge::VFGEdgeK kind return nullptr; } - /*! * Return the corresponding VFGEdge */ VFGEdge* VFG::getIntraVFGEdge(const VFGNode* src, const VFGNode* dst, VFGEdge::VFGEdgeK kind) { - return hasIntraVFGEdge(const_cast(src),const_cast(dst),kind); + return hasIntraVFGEdge(const_cast(src), const_cast(dst), kind); } - /*! * Dump VFG */ @@ -948,7 +910,6 @@ void VFG::view() SVF::ViewGraph(this, "Value Flow Graph"); } - void VFG::updateCallGraph(PointerAnalysis* pta) { VFGEdgeSetTy vfEdgesAtIndCallSite; @@ -958,10 +919,11 @@ void VFG::updateCallGraph(PointerAnalysis* pta) { const CallICFGNode* newcs = iter->first; assert(newcs->isIndirectCall() && "this is not an indirect call?"); - const PointerAnalysis::FunctionSet & functions = iter->second; - for (PointerAnalysis::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) + const PointerAnalysis::FunctionSet& functions = iter->second; + for (PointerAnalysis::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); + func_iter++) { - const SVFFunction* func = *func_iter; + const SVFFunction* func = *func_iter; connectCallerAndCallee(newcs, func, vfEdgesAtIndCallSite); } } @@ -973,13 +935,13 @@ void VFG::updateCallGraph(PointerAnalysis* pta) */ void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFunction* callee, VFGEdgeSetTy& edges) { - SVFIR * pag = SVFIR::getPAG(); - ICFG * icfg = pag->getICFG(); + SVFIR* pag = SVFIR::getPAG(); + ICFG* icfg = pag->getICFG(); CallSiteID csId = getCallSiteID(callBlockNode, callee); RetICFGNode* retBlockNode = icfg->getRetICFGNode(callBlockNode->getCallSite()); // connect actual and formal param if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(callee) && - matchArgs(callBlockNode->getCallSite(), callee)) + matchArgs(callBlockNode->getCallSite(), callee)) { const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode); const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(callee); @@ -987,8 +949,8 @@ void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFun SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end(); for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++) { - const PAGNode *cs_arg = *csArgIt; - const PAGNode *fun_arg = *funArgIt; + const PAGNode* cs_arg = *csArgIt; + const PAGNode* fun_arg = *funArgIt; if (isInterestedPAGNode(cs_arg) && isInterestedPAGNode(fun_arg)) connectAParamAndFParam(cs_arg, fun_arg, callBlockNode, csId, edges); } @@ -1002,7 +964,7 @@ void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFun { for (; csArgIt != csArgEit; csArgIt++) { - const PAGNode *cs_arg = *csArgIt; + const PAGNode* cs_arg = *csArgIt; if (isInterestedPAGNode(cs_arg)) connectAParamAndFParam(cs_arg, varFunArgNode, callBlockNode, csId, edges); } @@ -1026,31 +988,30 @@ void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFun const PAGNode* VFG::getLHSTopLevPtr(const VFGNode* node) const { - if(const AddrVFGNode* addr = SVFUtil::dyn_cast(node)) - return addr->getPAGDstNode(); - else if(const CopyVFGNode* copy = SVFUtil::dyn_cast(node)) + if (const AddrVFGNode* addr = SVFUtil::dyn_cast(node)) return addr->getPAGDstNode(); + else if (const CopyVFGNode* copy = SVFUtil::dyn_cast(node)) return copy->getPAGDstNode(); - else if(const GepVFGNode* gep = SVFUtil::dyn_cast(node)) + else if (const GepVFGNode* gep = SVFUtil::dyn_cast(node)) return gep->getPAGDstNode(); - else if(const LoadVFGNode* load = SVFUtil::dyn_cast(node)) + else if (const LoadVFGNode* load = SVFUtil::dyn_cast(node)) return load->getPAGDstNode(); - else if(const PHIVFGNode* phi = SVFUtil::dyn_cast(node)) + else if (const PHIVFGNode* phi = SVFUtil::dyn_cast(node)) return phi->getRes(); - else if(const CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) + else if (const CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) return cmp->getRes(); - else if(const BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) + else if (const BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) return bop->getRes(); - else if(const UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) + else if (const UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) return uop->getRes(); - else if(const ActualParmVFGNode* ap = SVFUtil::dyn_cast(node)) + else if (const ActualParmVFGNode* ap = SVFUtil::dyn_cast(node)) return ap->getParam(); - else if(const FormalParmVFGNode*fp = SVFUtil::dyn_cast(node)) + else if (const FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) return fp->getParam(); - else if(const ActualRetVFGNode* ar = SVFUtil::dyn_cast(node)) + else if (const ActualRetVFGNode* ar = SVFUtil::dyn_cast(node)) return ar->getRev(); - else if(const FormalRetVFGNode* fr = SVFUtil::dyn_cast(node)) + else if (const FormalRetVFGNode* fr = SVFUtil::dyn_cast(node)) return fr->getRet(); - else if(const NullPtrVFGNode* nullVFG = SVFUtil::dyn_cast(node)) + else if (const NullPtrVFGNode* nullVFG = SVFUtil::dyn_cast(node)) return nullVFG->getPAGNode(); else assert(false && "unexpected node kind!"); @@ -1062,19 +1023,17 @@ const PAGNode* VFG::getLHSTopLevPtr(const VFGNode* node) const */ const SVFFunction* VFG::isFunEntryVFGNode(const VFGNode* node) const { - if(const FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) + if (const FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) { return fp->getFun(); } - else if(const InterPHIVFGNode* phi = SVFUtil::dyn_cast(node)) + else if (const InterPHIVFGNode* phi = SVFUtil::dyn_cast(node)) { - if(phi->isFormalParmPHI()) - return phi->getFun(); + if (phi->isFormalParmPHI()) return phi->getFun(); } return nullptr; } - const SVFValue* StmtVFGNode::getValue() const { return getPAGEdge()->getValue(); @@ -1105,15 +1064,11 @@ const SVFValue* ArgumentVFGNode::getValue() const */ namespace SVF { -template<> -struct DOTGraphTraits : public DOTGraphTraits +template <> struct DOTGraphTraits : public DOTGraphTraits { typedef VFGNode NodeType; - DOTGraphTraits(bool isSimple = false) : - DOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DOTGraphTraits(isSimple) {} /// Return name of the graph static std::string getGraphName(VFG*) @@ -1121,32 +1076,31 @@ struct DOTGraphTraits : public DOTGraphTraits return "VFG"; } - std::string getNodeLabel(NodeType *node, VFG *graph) + std::string getNodeLabel(NodeType* node, VFG* graph) { - if (isSimple()) - return getSimpleNodeLabel(node, graph); + if (isSimple()) return getSimpleNodeLabel(node, graph); else return getCompleteNodeLabel(node, graph); } /// Return label of a VFG node without MemSSA information - static std::string getSimpleNodeLabel(NodeType *node, VFG*) + static std::string getSimpleNodeLabel(NodeType* node, VFG*) { std::string str; std::stringstream rawstr(str); - if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { rawstr << stmtNode->toString(); } - else if(PHIVFGNode* tphi = SVFUtil::dyn_cast(node)) + else if (PHIVFGNode* tphi = SVFUtil::dyn_cast(node)) { rawstr << tphi->toString(); } - else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) + else if (FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) { rawstr << fp->toString(); } - else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast(node)) + else if (ActualParmVFGNode* ap = SVFUtil::dyn_cast(node)) { rawstr << ap->toString(); } @@ -1158,21 +1112,22 @@ struct DOTGraphTraits : public DOTGraphTraits { rawstr << fr->toString(); } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { rawstr << "NullPtr"; } - else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) + else if (BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) { rawstr << bop->toString(); } - else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) + else if (UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) { rawstr << uop->toString(); } - else if(CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) + else if (CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) { - rawstr << cmp->toString();; + rawstr << cmp->toString(); + ; } else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast(node)) { @@ -1185,40 +1140,40 @@ struct DOTGraphTraits : public DOTGraphTraits } /// Return label of a VFG node with MemSSA information - static std::string getCompleteNodeLabel(NodeType *node, VFG*) + static std::string getCompleteNodeLabel(NodeType* node, VFG*) { std::string str; std::stringstream rawstr(str); - if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { rawstr << stmtNode->toString(); } - else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) + else if (BinaryOPVFGNode* bop = SVFUtil::dyn_cast(node)) { rawstr << bop->toString(); } - else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) + else if (UnaryOPVFGNode* uop = SVFUtil::dyn_cast(node)) { rawstr << uop->toString(); } - else if(CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) + else if (CmpVFGNode* cmp = SVFUtil::dyn_cast(node)) { rawstr << cmp->toString(); } - else if(PHIVFGNode* phi = SVFUtil::dyn_cast(node)) + else if (PHIVFGNode* phi = SVFUtil::dyn_cast(node)) { rawstr << phi->toString(); } - else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) + else if (FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) { rawstr << fp->toString(); } - else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast(node)) + else if (ActualParmVFGNode* ap = SVFUtil::dyn_cast(node)) { rawstr << ap->toString(); } - else if(NullPtrVFGNode* nptr = SVFUtil::dyn_cast(node)) + else if (NullPtrVFGNode* nptr = SVFUtil::dyn_cast(node)) { rawstr << nptr->toString(); } @@ -1244,33 +1199,33 @@ struct DOTGraphTraits : public DOTGraphTraits return rawstr.str(); } - static std::string getNodeAttributes(NodeType *node, VFG*) + static std::string getNodeAttributes(NodeType* node, VFG*) { std::string str; std::stringstream rawstr(str); - if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (StmtVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { const PAGEdge* edge = stmtNode->getPAGEdge(); if (SVFUtil::isa(edge)) { - rawstr << "color=green"; + rawstr << "color=green"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=black"; + rawstr << "color=black"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=black,style=dotted"; + rawstr << "color=black,style=dotted"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=purple"; + rawstr << "color=purple"; } else if (SVFUtil::isa(edge)) { - rawstr << "color=blue"; + rawstr << "color=blue"; } else if (SVFUtil::isa(edge)) { @@ -1280,7 +1235,7 @@ struct DOTGraphTraits : public DOTGraphTraits { assert(0 && "No such kind edge!!"); } - rawstr << ""; + rawstr << ""; } else if (SVFUtil::isa(node)) { @@ -1294,55 +1249,53 @@ struct DOTGraphTraits : public DOTGraphTraits { rawstr << "color=grey"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=black"; + rawstr << "color=black"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=grey"; + rawstr << "color=grey"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } - else if(SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=yellow,penwidth=2"; + rawstr << "color=yellow,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=orange,penwidth=2"; + rawstr << "color=orange,penwidth=2"; } else if (SVFUtil::isa(node)) { - rawstr << "color=gold,penwidth=2"; + rawstr << "color=gold,penwidth=2"; } else assert(false && "no such kind of node!!"); - rawstr << ""; + rawstr << ""; return rawstr.str(); } - template - static std::string getEdgeAttributes(NodeType*, EdgeIter EI, VFG*) + template static std::string getEdgeAttributes(NodeType*, EdgeIter EI, VFG*) { VFGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); if (SVFUtil::isa(edge)) { - if (SVFUtil::isa(edge)) - return "style=solid,color=red"; + if (SVFUtil::isa(edge)) return "style=solid,color=red"; else if (SVFUtil::isa(edge)) return "style=solid,color=blue"; else @@ -1350,8 +1303,7 @@ struct DOTGraphTraits : public DOTGraphTraits } else if (SVFUtil::isa(edge)) { - if (SVFUtil::isa(edge)) - return "style=dashed,color=red"; + if (SVFUtil::isa(edge)) return "style=dashed,color=red"; else if (SVFUtil::isa(edge)) return "style=dashed,color=blue"; else @@ -1364,20 +1316,18 @@ struct DOTGraphTraits : public DOTGraphTraits return ""; } - template - static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) + template static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI) { VFGEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); std::string str; std::stringstream rawstr(str); - if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast(edge)) - rawstr << dirCall->getCallSiteId(); + if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast(edge)) rawstr << dirCall->getCallSiteId(); else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast(edge)) rawstr << dirRet->getCallSiteId(); return rawstr.str(); } }; -} // End namespace llvm +} // namespace SVF diff --git a/svf/lib/MSSA/MemPartition.cpp b/svf/lib/MSSA/MemPartition.cpp index 48a481048..3ff5c4d5f 100644 --- a/svf/lib/MSSA/MemPartition.cpp +++ b/svf/lib/MSSA/MemPartition.cpp @@ -41,13 +41,13 @@ using namespace SVF; */ void DistinctMRG::partitionMRs() { - for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); - it!=eit; ++it) + for (FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it != eit; + ++it) { const SVFFunction* fun = it->first; /// Collect all points-to target in a function scope. NodeBS mergePts; - for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) + for (PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { const NodeBS& pts = *cit; mergePts |= pts; @@ -103,7 +103,7 @@ void DistinctMRG::getMRsForLoad(MRSet& mrs, const NodeBS& pts, const SVFFunction MemRegion mr(newPts); MRSet::iterator mit = memRegSet.find(&mr); - assert(mit!=memRegSet.end() && "memory region not found!!"); + assert(mit != memRegSet.end() && "memory region not found!!"); mrs.insert(*mit); } } @@ -121,13 +121,12 @@ void DistinctMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, cons void IntraDisjointMRG::partitionMRs() { - for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), - eit = getFunToPointsToList().end(); it!=eit; ++it) + for (FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it != eit; + ++it) { const SVFFunction* fun = it->first; - for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); - cit!=ecit; ++cit) + for (PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { const NodeBS& cpts = *cit; @@ -137,8 +136,8 @@ void IntraDisjointMRG::partitionMRs() /// Create memory regions. const PointsToList& inters = getIntersList(fun); - for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end(); - interIt != interEit; ++interIt) + for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end(); interIt != interEit; + ++interIt) { const NodeBS& inter = *interIt; createDisjointMR(fun, inter); @@ -168,11 +167,11 @@ void IntraDisjointMRG::computeIntersections(const NodeBS& cpts, PointsToList& in PointsToList toBeDeleted; PointsToList newInters; - NodeBS cpts_copy = cpts; // make a copy since cpts may be changed. + NodeBS cpts_copy = cpts; // make a copy since cpts may be changed. // check intersections with existing cpts in subSetMap - for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end(); - interIt != interEit; ++interIt) + for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end(); interIt != interEit; + ++interIt) { const NodeBS& inter = *interIt; @@ -199,30 +198,26 @@ void IntraDisjointMRG::computeIntersections(const NodeBS& cpts, PointsToList& in cpts_copy.intersectWithComplement(new_inter); - if (cpts_copy.empty()) - break; + if (cpts_copy.empty()) break; } } // remove old intersections - for (PointsToList::const_iterator it = toBeDeleted.begin(), eit = toBeDeleted.end(); - it != eit; ++it) + for (PointsToList::const_iterator it = toBeDeleted.begin(), eit = toBeDeleted.end(); it != eit; ++it) { const NodeBS& temp_cpts = *it; inters.erase(temp_cpts); } // add new intersections - for (PointsToList::const_iterator it = newInters.begin(), eit = newInters.end(); - it != eit; ++it) + for (PointsToList::const_iterator it = newInters.begin(), eit = newInters.end(); it != eit; ++it) { const NodeBS& temp_cpts = *it; inters.insert(temp_cpts); } // add remaining set into inters - if (cpts_copy.empty() == false) - inters.insert(cpts_copy); + if (cpts_copy.empty() == false) inters.insert(cpts_copy); } } @@ -249,7 +244,7 @@ void IntraDisjointMRG::getMRsForLoadFromInterList(MRSet& mrs, const NodeBS& cpts { MemRegion mr(inter); MRSet::iterator mit = memRegSet.find(&mr); - assert(mit!=memRegSet.end() && "memory region not found!!"); + assert(mit != memRegSet.end() && "memory region not found!!"); mrs.insert(*mit); } } @@ -269,11 +264,10 @@ void IntraDisjointMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, void InterDisjointMRG::partitionMRs() { /// Generate disjoint cpts. - for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), - eit = getFunToPointsToList().end(); it!=eit; ++it) + for (FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it != eit; + ++it) { - for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); - cit!=ecit; ++cit) + for (PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { const NodeBS& cpts = *cit; @@ -282,22 +276,20 @@ void InterDisjointMRG::partitionMRs() } /// Create memory regions. - for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), - eit = getFunToPointsToList().end(); it!=eit; ++it) + for (FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it != eit; + ++it) { const SVFFunction* fun = it->first; - for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); - cit!=ecit; ++cit) + for (PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { const NodeBS& cpts = *cit; - for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end(); - interIt != interEit; ++interIt) + for (PointsToList::const_iterator interIt = inters.begin(), interEit = inters.end(); interIt != interEit; + ++interIt) { const NodeBS& inter = *interIt; - if (cpts.contains(inter)) - createDisjointMR(fun, inter); + if (cpts.contains(inter)) createDisjointMR(fun, inter); } } } diff --git a/svf/lib/MSSA/MemRegion.cpp b/svf/lib/MSSA/MemRegion.cpp index 1a4b38f31..3718232c3 100644 --- a/svf/lib/MSSA/MemRegion.cpp +++ b/svf/lib/MSSA/MemRegion.cpp @@ -38,8 +38,7 @@ using namespace SVFUtil; u32_t MemRegion::totalMRNum = 0; u32_t MRVer::totalVERNum = 0; -MRGenerator::MRGenerator(BVDataPTAImpl* p, bool ptrOnly) : - pta(p), ptrOnlyMSSA(ptrOnly) +MRGenerator::MRGenerator(BVDataPTAImpl* p, bool ptrOnly) : pta(p), ptrOnlyMSSA(ptrOnly) { callGraph = pta->getCallGraph(); callGraphSCC = new SCC(callGraph); @@ -51,8 +50,7 @@ MRGenerator::MRGenerator(BVDataPTAImpl* p, bool ptrOnly) : void MRGenerator::destroy() { - for (MRSet::iterator it = memRegSet.begin(), eit = memRegSet.end(); - it != eit; ++it) + for (MRSet::iterator it = memRegSet.begin(), eit = memRegSet.end(); it != eit; ++it) { delete *it; } @@ -71,12 +69,11 @@ void MRGenerator::createMR(const SVFFunction* fun, const NodeBS& cpts) const NodeBS& repCPts = getRepPointsTo(cpts); MemRegion mr(repCPts); MRSet::const_iterator mit = memRegSet.find(&mr); - if(mit!=memRegSet.end()) + if (mit != memRegSet.end()) { const MemRegion* mr = *mit; MRSet& mrs = funToMRsMap[fun]; - if(mrs.find(mr)==mrs.end()) - mrs.insert(mr); + if (mrs.find(mr) == mrs.end()) mrs.insert(mr); } else { @@ -93,11 +90,10 @@ const MemRegion* MRGenerator::getMR(const NodeBS& cpts) const { MemRegion mr(getRepPointsTo(cpts)); MRSet::iterator mit = memRegSet.find(&mr); - assert(mit!=memRegSet.end() && "memory region not found!!"); + assert(mit != memRegSet.end() && "memory region not found!!"); return *mit; } - /*! * Collect globals for escape analysis */ @@ -106,7 +102,7 @@ void MRGenerator::collectGlobals() SVFIR* pag = pta->getPAG(); for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter) { - if(ObjVar* obj = SVFUtil::dyn_cast(nIter->second)) + if (ObjVar* obj = SVFUtil::dyn_cast(nIter->second)) { if (obj->getMemObj()->isGlobalObj()) { @@ -150,8 +146,7 @@ void MRGenerator::generateMRs() bool MRGenerator::hasSVFStmtList(const SVFInstruction* inst) { SVFIR* pag = pta->getPAG(); - if (ptrOnlyMSSA) - return pag->hasPTASVFStmtList(pag->getICFG()->getICFGNode(inst)); + if (ptrOnlyMSSA) return pag->hasPTASVFStmtList(pag->getICFG()->getICFGNode(inst)); else return pag->hasSVFStmtList(pag->getICFG()->getICFGNode(inst)); } @@ -159,8 +154,7 @@ bool MRGenerator::hasSVFStmtList(const SVFInstruction* inst) SVFIR::SVFStmtList& MRGenerator::getPAGEdgesFromInst(const SVFInstruction* inst) { SVFIR* pag = pta->getPAG(); - if (ptrOnlyMSSA) - return pag->getPTASVFStmtList(pag->getICFG()->getICFGNode(inst)); + if (ptrOnlyMSSA) return pag->getPTASVFStmtList(pag->getICFG()->getICFGNode(inst)); else return pag->getSVFStmtList(pag->getICFG()->getICFGNode(inst)); } @@ -172,45 +166,38 @@ void MRGenerator::collectModRefForLoadStore() { SVFModule* svfModule = pta->getModule(); - for (SVFModule::const_iterator fi = svfModule->begin(), efi = svfModule->end(); fi != efi; - ++fi) + for (SVFModule::const_iterator fi = svfModule->begin(), efi = svfModule->end(); fi != efi; ++fi) { const SVFFunction& fun = **fi; /// if this function does not have any caller, then we do not care its MSSA - if (Options::IgnoreDeadFun() && fun.isUncalledFunction()) - continue; + if (Options::IgnoreDeadFun() && fun.isUncalledFunction()) continue; - for (SVFFunction::const_iterator iter = fun.begin(), eiter = fun.end(); - iter != eiter; ++iter) + for (SVFFunction::const_iterator iter = fun.begin(), eiter = fun.end(); iter != eiter; ++iter) { const SVFBasicBlock* bb = *iter; - for (SVFBasicBlock::const_iterator bit = bb->begin(), ebit = bb->end(); - bit != ebit; ++bit) + for (SVFBasicBlock::const_iterator bit = bb->begin(), ebit = bb->end(); bit != ebit; ++bit) { const SVFInstruction* svfInst = *bit; SVFStmtList& pagEdgeList = getPAGEdgesFromInst(svfInst); - for (SVFStmtList::iterator bit = pagEdgeList.begin(), ebit = - pagEdgeList.end(); bit != ebit; ++bit) + for (SVFStmtList::iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; ++bit) { const PAGEdge* inst = *bit; pagEdgeToFunMap[inst] = &fun; - if (const StoreStmt *st = SVFUtil::dyn_cast(inst)) + if (const StoreStmt* st = SVFUtil::dyn_cast(inst)) { NodeBS cpts(pta->getPts(st->getLHSVarID()).toNodeBS()); // TODO: change this assertion check later when we have conditional points-to set - if (cpts.empty()) - continue; + if (cpts.empty()) continue; assert(!cpts.empty() && "null pointer!!"); addCPtsToStore(cpts, st, &fun); } - else if (const LoadStmt *ld = SVFUtil::dyn_cast(inst)) + else if (const LoadStmt* ld = SVFUtil::dyn_cast(inst)) { NodeBS cpts(pta->getPts(ld->getRHSVarID()).toNodeBS()); // TODO: change this assertion check later when we have conditional points-to set - if (cpts.empty()) - continue; + if (cpts.empty()) continue; assert(!cpts.empty() && "null pointer!!"); addCPtsToLoad(cpts, ld, &fun); } @@ -220,7 +207,6 @@ void MRGenerator::collectModRefForLoadStore() } } - /*! * Generate memory regions for calls */ @@ -230,8 +216,9 @@ void MRGenerator::collectModRefForCall() DBOUT(DGENERAL, outs() << pasMsg("\t\tCollect Callsite PointsTo \n")); /// collect points-to information for callsites - for(SVFIR::CallSiteSet::const_iterator it = pta->getPAG()->getCallSiteSet().begin(), - eit = pta->getPAG()->getCallSiteSet().end(); it!=eit; ++it) + for (SVFIR::CallSiteSet::const_iterator it = pta->getPAG()->getCallSiteSet().begin(), + eit = pta->getPAG()->getCallSiteSet().end(); + it != eit; ++it) { collectCallSitePts((*it)); } @@ -241,16 +228,16 @@ void MRGenerator::collectModRefForCall() WorkList worklist; getCallGraphSCCRevTopoOrder(worklist); - while(!worklist.empty()) + while (!worklist.empty()) { NodeID callGraphNodeID = worklist.pop(); /// handle all sub scc nodes of this rep node const NodeBS& subNodes = callGraphSCC->subNodes(callGraphNodeID); - for(NodeBS::iterator it = subNodes.begin(), eit = subNodes.end(); it!=eit; ++it) + for (NodeBS::iterator it = subNodes.begin(), eit = subNodes.end(); it != eit; ++it) { CallGraphNode* subCallGraphNode = callGraph->getCallGraphNode(*it); /// Get mod-ref of all callsites calling callGraphNode - modRefAnalysis(subCallGraphNode,worklist); + modRefAnalysis(subCallGraphNode, worklist); } } @@ -258,17 +245,17 @@ void MRGenerator::collectModRefForCall() for (const CallICFGNode* callBlockNode : pta->getPAG()->getCallSiteSet()) { - if(hasRefSideEffectOfCallSite(callBlockNode)) + if (hasRefSideEffectOfCallSite(callBlockNode)) { NodeBS refs = getRefSideEffectOfCallSite(callBlockNode); - addCPtsToCallSiteRefs(refs,callBlockNode); + addCPtsToCallSiteRefs(refs, callBlockNode); } - if(hasModSideEffectOfCallSite(callBlockNode)) + if (hasModSideEffectOfCallSite(callBlockNode)) { NodeBS mods = getModSideEffectOfCallSite(callBlockNode); /// mods are treated as both def and use of memory objects - addCPtsToCallSiteMods(mods,callBlockNode); - addCPtsToCallSiteRefs(mods,callBlockNode); + addCPtsToCallSiteMods(mods, callBlockNode); + addCPtsToCallSiteRefs(mods, callBlockNode); } } } @@ -282,26 +269,24 @@ void MRGenerator::collectModRefForCall() void MRGenerator::sortPointsTo(const NodeBS& cpts) { - if(cptsToRepCPtsMap.find(cpts)!=cptsToRepCPtsMap.end()) - return; + if (cptsToRepCPtsMap.find(cpts) != cptsToRepCPtsMap.end()) return; PointsToList subSetList; NodeBS repCPts = cpts; - for(PtsToRepPtsSetMap::iterator it = cptsToRepCPtsMap.begin(), - eit = cptsToRepCPtsMap.end(); it!=eit; ++it) + for (PtsToRepPtsSetMap::iterator it = cptsToRepCPtsMap.begin(), eit = cptsToRepCPtsMap.end(); it != eit; ++it) { NodeBS& existCPts = it->second; - if(cpts.contains(existCPts)) + if (cpts.contains(existCPts)) { subSetList.insert(it->first); } - else if(existCPts.contains(cpts)) + else if (existCPts.contains(cpts)) { repCPts = existCPts; } } - for(PointsToList::iterator it = subSetList.begin(), eit = subSetList.end(); it!=eit; ++it) + for (PointsToList::iterator it = subSetList.begin(), eit = subSetList.end(); it != eit; ++it) { cptsToRepCPtsMap[*it] = cpts; } @@ -319,25 +304,24 @@ void MRGenerator::partitionMRs() /// TODO: we may need some refined region partitioning algorithm here /// For now, we just collapse all refs/mods objects at callsites into one region /// Consider modularly partition memory regions to speed up analysis (only partition regions within function scope) - for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); - it!=eit; ++it) + for (FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it != eit; + ++it) { - for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) + for (PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { sortPointsTo(*cit); } } /// Generate memory regions according to condition pts after computing superset - for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); - it!=eit; ++it) + for (FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it != eit; + ++it) { const SVFFunction* fun = it->first; - for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) + for (PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { - createMR(fun,*cit); + createMR(fun, *cit); } } - } /*! @@ -347,67 +331,69 @@ void MRGenerator::updateAliasMRs() { /// update stores with its aliased regions - for(StoresToPointsToMap::const_iterator it = storesToPointsToMap.begin(), eit = storesToPointsToMap.end(); it!=eit; ++it) + for (StoresToPointsToMap::const_iterator it = storesToPointsToMap.begin(), eit = storesToPointsToMap.end(); + it != eit; ++it) { MRSet aliasMRs; const SVFFunction* fun = getFunction(it->first); const NodeBS& storeCPts = it->second; - getAliasMemRegions(aliasMRs,storeCPts,fun); - for(MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait!=eait; ++ait) + getAliasMemRegions(aliasMRs, storeCPts, fun); + for (MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait != eait; ++ait) { storesToMRsMap[it->first].insert(*ait); } } - for(LoadsToPointsToMap::const_iterator it = loadsToPointsToMap.begin(), eit = loadsToPointsToMap.end(); it!=eit; ++it) + for (LoadsToPointsToMap::const_iterator it = loadsToPointsToMap.begin(), eit = loadsToPointsToMap.end(); it != eit; + ++it) { MRSet aliasMRs; const SVFFunction* fun = getFunction(it->first); const NodeBS& loadCPts = it->second; getMRsForLoad(aliasMRs, loadCPts, fun); - for(MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait!=eait; ++ait) + for (MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait != eait; ++ait) { loadsToMRsMap[it->first].insert(*ait); } } /// update callsites with its aliased regions - for(CallSiteToPointsToMap::const_iterator it = callsiteToModPointsToMap.begin(), - eit = callsiteToModPointsToMap.end(); it!=eit; ++it) + for (CallSiteToPointsToMap::const_iterator it = callsiteToModPointsToMap.begin(), + eit = callsiteToModPointsToMap.end(); + it != eit; ++it) { const SVFFunction* fun = it->first->getCaller(); MRSet aliasMRs; const NodeBS& callsiteModCPts = it->second; - getAliasMemRegions(aliasMRs,callsiteModCPts,fun); - for(MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait!=eait; ++ait) + getAliasMemRegions(aliasMRs, callsiteModCPts, fun); + for (MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait != eait; ++ait) { callsiteToModMRsMap[it->first].insert(*ait); } } - for(CallSiteToPointsToMap::const_iterator it = callsiteToRefPointsToMap.begin(), - eit = callsiteToRefPointsToMap.end(); it!=eit; ++it) + for (CallSiteToPointsToMap::const_iterator it = callsiteToRefPointsToMap.begin(), + eit = callsiteToRefPointsToMap.end(); + it != eit; ++it) { const SVFFunction* fun = it->first->getCaller(); MRSet aliasMRs; const NodeBS& callsiteRefCPts = it->second; getMRsForCallSiteRef(aliasMRs, callsiteRefCPts, fun); - for(MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait!=eait; ++ait) + for (MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait != eait; ++ait) { callsiteToRefMRsMap[it->first].insert(*ait); } } } - /*! * Add indirect uses an memory object in the function */ void MRGenerator::addRefSideEffectOfFunction(const SVFFunction* fun, const NodeBS& refs) { - for(NodeBS::iterator it = refs.begin(), eit = refs.end(); it!=eit; ++it) + for (NodeBS::iterator it = refs.begin(), eit = refs.end(); it != eit; ++it) { - if(isNonLocalObject(*it,fun)) - funToRefsMap[fun].set(*it); + if (isNonLocalObject(*it, fun)) funToRefsMap[fun].set(*it); } } @@ -416,10 +402,9 @@ void MRGenerator::addRefSideEffectOfFunction(const SVFFunction* fun, const NodeB */ void MRGenerator::addModSideEffectOfFunction(const SVFFunction* fun, const NodeBS& mods) { - for(NodeBS::iterator it = mods.begin(), eit = mods.end(); it!=eit; ++it) + for (NodeBS::iterator it = mods.begin(), eit = mods.end(); it != eit; ++it) { - if(isNonLocalObject(*it,fun)) - funToModsMap[fun].set(*it); + if (isNonLocalObject(*it, fun)) funToModsMap[fun].set(*it); } } @@ -428,12 +413,12 @@ void MRGenerator::addModSideEffectOfFunction(const SVFFunction* fun, const NodeB */ bool MRGenerator::addRefSideEffectOfCallSite(const CallICFGNode* cs, const NodeBS& refs) { - if(!refs.empty()) + if (!refs.empty()) { NodeBS refset = refs; refset &= getCallSiteArgsPts(cs); - getEscapObjviaGlobals(refset,refs); - addRefSideEffectOfFunction(cs->getCaller(),refset); + getEscapObjviaGlobals(refset, refs); + addRefSideEffectOfFunction(cs->getCaller(), refset); return csToRefsMap[cs] |= refset; } return false; @@ -444,18 +429,17 @@ bool MRGenerator::addRefSideEffectOfCallSite(const CallICFGNode* cs, const NodeB */ bool MRGenerator::addModSideEffectOfCallSite(const CallICFGNode* cs, const NodeBS& mods) { - if(!mods.empty()) + if (!mods.empty()) { NodeBS modset = mods; modset &= (getCallSiteArgsPts(cs) | getCallSiteRetPts(cs)); - getEscapObjviaGlobals(modset,mods); - addModSideEffectOfFunction(cs->getCaller(),modset); + getEscapObjviaGlobals(modset, mods); + addModSideEffectOfFunction(cs->getCaller(), modset); return csToModsMap[cs] |= modset; } return false; } - /*! * Get the reverse topo order of scc call graph */ @@ -463,7 +447,7 @@ void MRGenerator::getCallGraphSCCRevTopoOrder(WorkList& worklist) { NodeStack& topoOrder = callGraphSCC->topoNodeStack(); - while(!topoOrder.empty()) + while (!topoOrder.empty()) { NodeID callgraphNodeID = topoOrder.top(); topoOrder.pop(); @@ -486,20 +470,18 @@ void MRGenerator::collectCallSitePts(const CallICFGNode* cs) if (pag->hasCallSiteArgsMap(callBlockNode)) { const SVFIR::SVFVarList& args = pta->getPAG()->getCallSiteArgsList(callBlockNode); - for(SVFIR::SVFVarList::const_iterator itA = args.begin(), ieA = args.end(); itA!=ieA; ++itA) + for (SVFIR::SVFVarList::const_iterator itA = args.begin(), ieA = args.end(); itA != ieA; ++itA) { const PAGNode* node = *itA; - if(node->isPointer()) - worklist.push(node->getId()); + if (node->isPointer()) worklist.push(node->getId()); } } - while(!worklist.empty()) + while (!worklist.empty()) { NodeID nodeId = worklist.pop(); const NodeBS& tmp = pta->getPts(nodeId).toNodeBS(); - for(NodeBS::iterator it = tmp.begin(), eit = tmp.end(); it!=eit; ++it) - argsPts |= CollectPtsChain(*it); + for (NodeBS::iterator it = tmp.begin(), eit = tmp.end(); it != eit; ++it) argsPts |= CollectPtsChain(*it); } /// collect the pts chain of the return argument @@ -508,17 +490,14 @@ void MRGenerator::collectCallSitePts(const CallICFGNode* cs) if (pta->getPAG()->callsiteHasRet(retBlockNode)) { const PAGNode* node = pta->getPAG()->getCallSiteRet(retBlockNode); - if(node->isPointer()) + if (node->isPointer()) { const NodeBS& tmp = pta->getPts(node->getId()).toNodeBS(); - for(NodeBS::iterator it = tmp.begin(), eit = tmp.end(); it!=eit; ++it) - retPts |= CollectPtsChain(*it); + for (NodeBS::iterator it = tmp.begin(), eit = tmp.end(); it != eit; ++it) retPts |= CollectPtsChain(*it); } } - } - /*! * Recursively collect all points-to of the whole struct fields */ @@ -526,29 +505,26 @@ NodeBS& MRGenerator::CollectPtsChain(NodeID id) { NodeID baseId = pta->getPAG()->getBaseObjVar(id); NodeToPTSSMap::iterator it = cachedPtsChainMap.find(baseId); - if(it!=cachedPtsChainMap.end()) - return it->second; + if (it != cachedPtsChainMap.end()) return it->second; else { NodeBS& pts = cachedPtsChainMap[baseId]; pts |= pta->getPAG()->getFieldsAfterCollapse(baseId); WorkList worklist; - for(NodeBS::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it) - worklist.push(*it); + for (NodeBS::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) worklist.push(*it); - while(!worklist.empty()) + while (!worklist.empty()) { NodeID nodeId = worklist.pop(); const NodeBS& tmp = pta->getPts(nodeId).toNodeBS(); - for(NodeBS::iterator it = tmp.begin(), eit = tmp.end(); it!=eit; ++it) + for (NodeBS::iterator it = tmp.begin(), eit = tmp.end(); it != eit; ++it) { pts |= CollectPtsChain(*it); } } return pts; } - } /*! @@ -558,13 +534,12 @@ NodeBS& MRGenerator::CollectPtsChain(NodeID id) void MRGenerator::getEscapObjviaGlobals(NodeBS& globs, const NodeBS& calleeModRef) { - for(NodeBS::iterator it = calleeModRef.begin(), eit = calleeModRef.end(); it!=eit; ++it) + for (NodeBS::iterator it = calleeModRef.begin(), eit = calleeModRef.end(); it != eit; ++it) { const MemObj* obj = pta->getPAG()->getObject(*it); (void)obj; // Suppress warning of unused variable under release build assert(obj && "object not found!!"); - if(allGlobals.test(*it)) - globs.set(*it); + if (allGlobals.test(*it)) globs.set(*it); } } @@ -577,16 +552,14 @@ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const const MemObj* obj = pta->getPAG()->getObject(id); assert(obj && "object not found!!"); /// if the object is heap or global - if(obj->isGlobalObj() || obj->isHeap()) - return true; + if (obj->isGlobalObj() || obj->isHeap()) return true; /// or if the local variable of its callers /// or a local variable is in function recursion cycles - else if(obj->isStack()) + else if (obj->isStack()) { - if(const SVFFunction* svffun = pta->getPAG()->getGNode(id)->getFunction()) + if (const SVFFunction* svffun = pta->getPAG()->getGNode(id)->getFunction()) { - if(svffun!=curFun) - return true; + if (svffun != curFun) return true; else return callGraphSCC->isInCycle(callGraph->getCallGraphNode(svffun)->getId()); } @@ -601,15 +574,13 @@ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const SVFFunction* callee) { /// if a callee is a heap allocator function, then its mod set of this callsite is the heap object. - if(isHeapAllocExtCall(cs->getCallSite())) + if (isHeapAllocExtCall(cs->getCallSite())) { SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs->getCallSite()); - for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), - ebit = pagEdgeList.end(); bit != ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; ++bit) { const PAGEdge* edge = *bit; - if (const AddrStmt* addr = SVFUtil::dyn_cast(edge)) - mod.set(addr->getRHSVarID()); + if (const AddrStmt* addr = SVFUtil::dyn_cast(edge)) mod.set(addr->getRHSVarID()); } } /// otherwise, we find the mod/ref sets from the callee function, who has definition and been processed @@ -634,30 +605,29 @@ void MRGenerator::modRefAnalysis(CallGraphNode* callGraphNode, WorkList& worklis { /// add ref/mod set of callee to its invocation callsites at caller - for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); - it!=eit; ++it) + for (CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it != eit; ++it) { CallGraphEdge* edge = *it; /// handle direct callsites - for(CallGraphEdge::CallInstSet::iterator cit = edge->getDirectCalls().begin(), - ecit = edge->getDirectCalls().end(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::iterator cit = edge->getDirectCalls().begin(), + ecit = edge->getDirectCalls().end(); + cit != ecit; ++cit) { NodeBS mod, ref; const CallICFGNode* cs = (*cit); bool modrefchanged = handleCallsiteModRef(mod, ref, cs, callGraphNode->getFunction()); - if(modrefchanged) - worklist.push(edge->getSrcID()); + if (modrefchanged) worklist.push(edge->getSrcID()); } /// handle indirect callsites - for(CallGraphEdge::CallInstSet::iterator cit = edge->getIndirectCalls().begin(), - ecit = edge->getIndirectCalls().end(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::iterator cit = edge->getIndirectCalls().begin(), + ecit = edge->getIndirectCalls().end(); + cit != ecit; ++cit) { NodeBS mod, ref; const CallICFGNode* cs = (*cit); bool modrefchanged = handleCallsiteModRef(mod, ref, cs, callGraphNode->getFunction()); - if(modrefchanged) - worklist.push(edge->getSrcID()); + if (modrefchanged) worklist.push(edge->getSrcID()); } } } @@ -671,8 +641,7 @@ NodeBS MRGenerator::getModInfoForCall(const CallICFGNode* cs) { SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs->getCallSite()); NodeBS mods; - for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = - pagEdgeList.end(); bit != ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; ++bit) { const PAGEdge* edge = *bit; if (const StoreStmt* st = SVFUtil::dyn_cast(edge)) @@ -695,8 +664,7 @@ NodeBS MRGenerator::getRefInfoForCall(const CallICFGNode* cs) { SVFStmtList& pagEdgeList = getPAGEdgesFromInst(cs->getCallSite()); NodeBS refs; - for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = - pagEdgeList.end(); bit != ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; ++bit) { const PAGEdge* edge = *bit; if (const LoadStmt* ld = SVFUtil::dyn_cast(edge)) @@ -719,8 +687,7 @@ ModRefInfo MRGenerator::getModRefInfo(const CallICFGNode* cs) bool ref = !getRefInfoForCall(cs).empty(); bool mod = !getModInfoForCall(cs).empty(); - if (mod && ref) - return ModRefInfo::ModRef; + if (mod && ref) return ModRefInfo::ModRef; else if (ref) return ModRefInfo::Ref; else if (mod) @@ -748,14 +715,11 @@ ModRefInfo MRGenerator::getModRefInfo(const CallICFGNode* cs, const SVFValue* V) pta->expandFIObjs(csRef, csRefExpanded); pta->expandFIObjs(csMod, csModExpanded); - if (csRefExpanded.intersects(ptsExpanded)) - ref = true; - if (csModExpanded.intersects(ptsExpanded)) - mod = true; + if (csRefExpanded.intersects(ptsExpanded)) ref = true; + if (csModExpanded.intersects(ptsExpanded)) mod = true; } - if (mod && ref) - return ModRefInfo::ModRef; + if (mod && ref) return ModRefInfo::ModRef; else if (ref) return ModRefInfo::Ref; else if (mod) @@ -787,17 +751,13 @@ ModRefInfo MRGenerator::getModRefInfo(const CallICFGNode* cs1, const CallICFGNod pta->expandFIObjs(cs2Mod, cs2ModExpanded); /// Ref: cs1 ref memory mod by cs2 - if (cs1RefExpanded.intersects(cs2ModExpanded)) - ref = true; + if (cs1RefExpanded.intersects(cs2ModExpanded)) ref = true; /// Mod: cs1 mod memory ref or mod by cs2 - if (cs1ModExpanded.intersects(cs2RefExpanded) || cs1ModExpanded.intersects(cs2ModExpanded)) - mod = true; + if (cs1ModExpanded.intersects(cs2RefExpanded) || cs1ModExpanded.intersects(cs2ModExpanded)) mod = true; /// ModRef: cs1 ref and mod memory mod by cs2 - if (cs1RefExpanded.intersects(cs2ModExpanded) && cs1ModExpanded.intersects(cs2ModExpanded)) - ref = mod = true; + if (cs1RefExpanded.intersects(cs2ModExpanded) && cs1ModExpanded.intersects(cs2ModExpanded)) ref = mod = true; - if (ref && mod) - return ModRefInfo::ModRef; + if (ref && mod) return ModRefInfo::ModRef; else if (ref) return ModRefInfo::Ref; else if (mod) @@ -806,9 +766,10 @@ ModRefInfo MRGenerator::getModRefInfo(const CallICFGNode* cs1, const CallICFGNod return ModRefInfo::NoModRef; } -std::ostream& SVF::operator<<(std::ostream &o, const MRVer& mrver) +std::ostream& SVF::operator<<(std::ostream& o, const MRVer& mrver) { - o << "MRVERID: " << mrver.getID() <<" MemRegion: " << mrver.getMR()->dumpStr() << " MRVERSION: " << mrver.getSSAVersion() << " MSSADef: " << mrver.getDef()->getType() << ", " - << mrver.getDef()->getMR()->dumpStr() ; + o << "MRVERID: " << mrver.getID() << " MemRegion: " << mrver.getMR()->dumpStr() + << " MRVERSION: " << mrver.getSSAVersion() << " MSSADef: " << mrver.getDef()->getType() << ", " + << mrver.getDef()->getMR()->dumpStr(); return o; } diff --git a/svf/lib/MSSA/MemSSA.cpp b/svf/lib/MSSA/MemSSA.cpp index 5f5b5622e..cee51b8f2 100644 --- a/svf/lib/MSSA/MemSSA.cpp +++ b/svf/lib/MSSA/MemSSA.cpp @@ -35,10 +35,10 @@ using namespace SVF; using namespace SVFUtil; -double MemSSA::timeOfGeneratingMemRegions = 0; ///< Time for allocating regions -double MemSSA::timeOfCreateMUCHI = 0; ///< Time for generating mu/chi for load/store/calls -double MemSSA::timeOfInsertingPHI = 0; ///< Time for inserting phis -double MemSSA::timeOfSSARenaming = 0; ///< Time for SSA rename +double MemSSA::timeOfGeneratingMemRegions = 0; ///< Time for allocating regions +double MemSSA::timeOfCreateMUCHI = 0; ///< Time for generating mu/chi for load/store/calls +double MemSSA::timeOfInsertingPHI = 0; ///< Time for inserting phis +double MemSSA::timeOfSSARenaming = 0; ///< Time for SSA rename /*! * Constructor @@ -46,11 +46,9 @@ double MemSSA::timeOfSSARenaming = 0; ///< Time for SSA rename MemSSA::MemSSA(BVDataPTAImpl* p, bool ptrOnlyMSSA) { pta = p; - assert((pta->getAnalysisTy()!=PointerAnalysis::Default_PTA) - && "please specify a pointer analysis"); + assert((pta->getAnalysisTy() != PointerAnalysis::Default_PTA) && "please specify a pointer analysis"); - if (Options::MemPar() == MemPartition::Distinct) - mrGen = new DistinctMRG(pta, ptrOnlyMSSA); + if (Options::MemPar() == MemPartition::Distinct) mrGen = new DistinctMRG(pta, ptrOnlyMSSA); else if (Options::MemPar() == MemPartition::IntraDisjoint) mrGen = new IntraDisjointMRG(pta, ptrOnlyMSSA); else if (Options::MemPar() == MemPartition::InterDisjoint) @@ -58,14 +56,13 @@ MemSSA::MemSSA(BVDataPTAImpl* p, bool ptrOnlyMSSA) else assert(false && "unrecognised memory partition strategy"); - stat = new MemSSAStat(this); /// Generate whole program memory regions double mrStart = stat->getClk(true); mrGen->generateMRs(); double mrEnd = stat->getClk(true); - timeOfGeneratingMemRegions = (mrEnd - mrStart)/TIMEINTERVAL; + timeOfGeneratingMemRegions = (mrEnd - mrStart) / TIMEINTERVAL; } SVFIR* MemSSA::getPAG() @@ -81,8 +78,7 @@ void MemSSA::buildMemSSA(const SVFFunction& fun) assert(!isExtCall(&fun) && "we do not build memory ssa for external functions"); - DBOUT(DMSSA, outs() << "Building Memory SSA for function " << fun.getName() - << " \n"); + DBOUT(DMSSA, outs() << "Building Memory SSA for function " << fun.getName() << " \n"); usedRegs.clear(); reg2BBMap.clear(); @@ -91,20 +87,19 @@ void MemSSA::buildMemSSA(const SVFFunction& fun) double muchiStart = stat->getClk(true); createMUCHI(fun); double muchiEnd = stat->getClk(true); - timeOfCreateMUCHI += (muchiEnd - muchiStart)/TIMEINTERVAL; + timeOfCreateMUCHI += (muchiEnd - muchiStart) / TIMEINTERVAL; /// Insert PHI for memory regions double phiStart = stat->getClk(true); insertPHI(fun); double phiEnd = stat->getClk(true); - timeOfInsertingPHI += (phiEnd - phiStart)/TIMEINTERVAL; + timeOfInsertingPHI += (phiEnd - phiStart) / TIMEINTERVAL; /// SSA rename for memory regions double renameStart = stat->getClk(true); SSARename(fun); double renameEnd = stat->getClk(true); - timeOfSSARenaming += (renameEnd - renameStart)/TIMEINTERVAL; - + timeOfSSARenaming += (renameEnd - renameStart) / TIMEINTERVAL; } /*! @@ -116,9 +111,7 @@ void MemSSA::createMUCHI(const SVFFunction& fun) SVFIR* pag = pta->getPAG(); - DBOUT(DMSSA, - outs() << "\t creating mu chi for function " << fun.getName() - << "\n"); + DBOUT(DMSSA, outs() << "\t creating mu chi for function " << fun.getName() << "\n"); // 1. create mu/chi // insert a set of mus for memory regions at each load // inset a set of chis for memory regions at each store @@ -137,19 +130,18 @@ void MemSSA::createMUCHI(const SVFFunction& fun) /// ignore dead basic blocks BBList reachableBBs = fun.getReachableBBs(); - for (BBList::const_iterator iter = reachableBBs.begin(), eiter = reachableBBs.end(); - iter != eiter; ++iter) + for (BBList::const_iterator iter = reachableBBs.begin(), eiter = reachableBBs.end(); iter != eiter; ++iter) { const SVFBasicBlock* bb = *iter; varKills.clear(); for (SVFBasicBlock::const_iterator it = bb->begin(), eit = bb->end(); it != eit; ++it) { const SVFInstruction* inst = *it; - if(mrGen->hasSVFStmtList(inst)) + if (mrGen->hasSVFStmtList(inst)) { SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst); - for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), - ebit = pagEdgeList.end(); bit != ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; + ++bit) { const PAGEdge* inst = *bit; if (const LoadStmt* load = SVFUtil::dyn_cast(inst)) @@ -161,39 +153,34 @@ void MemSSA::createMUCHI(const SVFFunction& fun) if (isNonInstricCallSite(inst)) { const CallICFGNode* cs = pag->getICFG()->getCallICFGNode(inst); - if(mrGen->hasRefMRSet(cs)) - AddCallSiteMU(cs,mrGen->getCallSiteRefMRSet(cs)); + if (mrGen->hasRefMRSet(cs)) AddCallSiteMU(cs, mrGen->getCallSiteRefMRSet(cs)); - if(mrGen->hasModMRSet(cs)) - AddCallSiteCHI(cs,mrGen->getCallSiteModMRSet(cs)); + if (mrGen->hasModMRSet(cs)) AddCallSiteCHI(cs, mrGen->getCallSiteModMRSet(cs)); } } } // create entry chi for this function including all memory regions // initialize them with version 0 and 1 r_1 = chi (r_0) - for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end(); - iter != eiter; ++iter) + for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end(); iter != eiter; ++iter) { const MemRegion* mr = *iter; // initialize mem region version and stack for renaming phase mr2CounterMap[mr] = 0; mr2VerStackMap[mr].clear(); ENTRYCHI* chi = new ENTRYCHI(&fun, mr); - chi->setOpVer(newSSAName(mr,chi)); - chi->setResVer(newSSAName(mr,chi)); + chi->setOpVer(newSSAName(mr, chi)); + chi->setResVer(newSSAName(mr, chi)); funToEntryChiSetMap[&fun].insert(chi); /// if the function does not have a reachable return instruction from function entry /// then we won't create return mu for it - if(fun.hasReturn()) + if (fun.hasReturn()) { RETMU* mu = new RETMU(&fun, mr); funToReturnMuSetMap[&fun].insert(mu); } - } - } /* @@ -202,16 +189,14 @@ void MemSSA::createMUCHI(const SVFFunction& fun) void MemSSA::insertPHI(const SVFFunction& fun) { - DBOUT(DMSSA, - outs() << "\t insert phi for function " << fun.getName() << "\n"); + DBOUT(DMSSA, outs() << "\t insert phi for function " << fun.getName() << "\n"); - const Map>& df = fun.getDomFrontierMap(); + const Map>& df = fun.getDomFrontierMap(); // record whether a phi of mr has already been inserted into the bb. BBToMRSetMap bb2MRSetMap; // start inserting phi node - for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end(); - iter != eiter; ++iter) + for (MRSet::iterator iter = usedRegs.begin(), eiter = usedRegs.end(); iter != eiter; ++iter) { const MemRegion* mr = *iter; @@ -220,8 +205,8 @@ void MemSSA::insertPHI(const SVFFunction& fun) { const SVFBasicBlock* bb = bbs.back(); bbs.pop_back(); - Map>::const_iterator it = df.find(bb); - if(it == df.end()) + Map>::const_iterator it = df.find(bb); + if (it == df.end()) { writeWrnMsg("bb not in the dominance frontier map??"); continue; @@ -234,14 +219,13 @@ void MemSSA::insertPHI(const SVFFunction& fun) { bb2MRSetMap[pbb].insert(mr); // insert phi node - AddMSSAPHI(pbb,mr); + AddMSSAPHI(pbb, mr); // continue to insert phi in its iterative dominate frontiers bbs.push_back(pbb); } } } } - } /*! @@ -250,8 +234,7 @@ void MemSSA::insertPHI(const SVFFunction& fun) void MemSSA::SSARename(const SVFFunction& fun) { - DBOUT(DMSSA, - outs() << "\t ssa rename for function " << fun.getName() << "\n"); + DBOUT(DMSSA, outs() << "\t ssa rename for function " << fun.getName() << "\n"); SSARenameBB(*fun.getEntryBlock()); } @@ -270,9 +253,7 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb) // rename phi result op // for each r = phi (...) // rewrite r as new name - if (hasPHISet(&bb)) - RenamePhiRes(getPHISet(&bb),memRegs); - + if (hasPHISet(&bb)) RenamePhiRes(getPHISet(&bb), memRegs); // process mu and chi // for each mu(r) @@ -281,54 +262,46 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb) // rewrite r' with top mrver of stack(r) // rewrite r with new name - for (SVFBasicBlock::const_iterator it = bb.begin(), eit = bb.end(); - it != eit; ++it) + for (SVFBasicBlock::const_iterator it = bb.begin(), eit = bb.end(); it != eit; ++it) { const SVFInstruction* inst = *it; - if(mrGen->hasSVFStmtList(inst)) + if (mrGen->hasSVFStmtList(inst)) { SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst); - for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end(); - bit!=ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; ++bit) { const PAGEdge* inst = *bit; - if (const LoadStmt* load = SVFUtil::dyn_cast(inst)) - RenameMuSet(getMUSet(load)); + if (const LoadStmt* load = SVFUtil::dyn_cast(inst)) RenameMuSet(getMUSet(load)); else if (const StoreStmt* store = SVFUtil::dyn_cast(inst)) - RenameChiSet(getCHISet(store),memRegs); - + RenameChiSet(getCHISet(store), memRegs); } } if (isNonInstricCallSite(inst)) { const CallICFGNode* cs = pag->getICFG()->getCallICFGNode(inst); - if(mrGen->hasRefMRSet(cs)) - RenameMuSet(getMUSet(cs)); + if (mrGen->hasRefMRSet(cs)) RenameMuSet(getMUSet(cs)); - if(mrGen->hasModMRSet(cs)) - RenameChiSet(getCHISet(cs),memRegs); + if (mrGen->hasModMRSet(cs)) RenameChiSet(getCHISet(cs), memRegs); } - else if(inst->isRetInst()) + else if (inst->isRetInst()) { const SVFFunction* fun = bb.getParent(); RenameMuSet(getReturnMuSet(fun)); } } - // fill phi operands of succ basic blocks for (const SVFBasicBlock* succ : bb.getSuccessors()) { u32_t pos = bb.getBBPredecessorPos(succ); - if (hasPHISet(succ)) - RenamePhiOps(getPHISet(succ),pos,memRegs); + if (hasPHISet(succ)) RenamePhiOps(getPHISet(succ), pos, memRegs); } // for succ basic block in dominator tree const SVFFunction* fun = bb.getParent(); - const Map>& dtBBsMap = fun->getDomTreeMap(); - Map>::const_iterator mapIter = dtBBsMap.find(&bb); + const Map>& dtBBsMap = fun->getDomTreeMap(); + Map>::const_iterator mapIter = dtBBsMap.find(&bb); if (mapIter != dtBBsMap.end()) { const Set& dtBBs = mapIter->second; @@ -345,15 +318,12 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb) memRegs.pop_back(); mr2VerStackMap[mr].pop_back(); } - } MRVer* MemSSA::newSSAName(const MemRegion* mr, MSSADEF* def) { - assert(0 != mr2CounterMap.count(mr) - && "did not find initial version in map? "); - assert(0 != mr2VerStackMap.count(mr) - && "did not find initial stack in map? "); + assert(0 != mr2CounterMap.count(mr) && "did not find initial version in map? "); + assert(0 != mr2VerStackMap.count(mr) && "did not find initial stack in map? "); MRVERSION version = mr2CounterMap[mr]; mr2CounterMap[mr] = version + 1; @@ -370,71 +340,62 @@ MRVer* MemSSA::newSSAName(const MemRegion* mr, MSSADEF* def) void MemSSA::destroy() { - for (LoadToMUSetMap::iterator iter = load2MuSetMap.begin(), eiter = - load2MuSetMap.end(); iter != eiter; ++iter) + for (LoadToMUSetMap::iterator iter = load2MuSetMap.begin(), eiter = load2MuSetMap.end(); iter != eiter; ++iter) { - for (MUSet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (MUSet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } } - for (StoreToChiSetMap::iterator iter = store2ChiSetMap.begin(), eiter = - store2ChiSetMap.end(); iter != eiter; ++iter) + for (StoreToChiSetMap::iterator iter = store2ChiSetMap.begin(), eiter = store2ChiSetMap.end(); iter != eiter; + ++iter) { - for (CHISet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (CHISet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } } - for (CallSiteToMUSetMap::iterator iter = callsiteToMuSetMap.begin(), - eiter = callsiteToMuSetMap.end(); iter != eiter; ++iter) + for (CallSiteToMUSetMap::iterator iter = callsiteToMuSetMap.begin(), eiter = callsiteToMuSetMap.end(); + iter != eiter; ++iter) { - for (MUSet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (MUSet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } } - for (CallSiteToCHISetMap::iterator iter = callsiteToChiSetMap.begin(), - eiter = callsiteToChiSetMap.end(); iter != eiter; ++iter) + for (CallSiteToCHISetMap::iterator iter = callsiteToChiSetMap.begin(), eiter = callsiteToChiSetMap.end(); + iter != eiter; ++iter) { - for (CHISet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (CHISet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } } - for (FunToEntryChiSetMap::iterator iter = funToEntryChiSetMap.begin(), - eiter = funToEntryChiSetMap.end(); iter != eiter; ++iter) + for (FunToEntryChiSetMap::iterator iter = funToEntryChiSetMap.begin(), eiter = funToEntryChiSetMap.end(); + iter != eiter; ++iter) { - for (CHISet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (CHISet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } } - for (FunToReturnMuSetMap::iterator iter = funToReturnMuSetMap.begin(), - eiter = funToReturnMuSetMap.end(); iter != eiter; ++iter) + for (FunToReturnMuSetMap::iterator iter = funToReturnMuSetMap.begin(), eiter = funToReturnMuSetMap.end(); + iter != eiter; ++iter) { - for (MUSet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (MUSet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } } - for (BBToPhiSetMap::iterator iter = bb2PhiSetMap.begin(), eiter = - bb2PhiSetMap.end(); iter != eiter; ++iter) + for (BBToPhiSetMap::iterator iter = bb2PhiSetMap.begin(), eiter = bb2PhiSetMap.end(); iter != eiter; ++iter) { - for (PHISet::iterator it = iter->second.begin(), eit = - iter->second.end(); it != eit; ++it) + for (PHISet::iterator it = iter->second.begin(), eit = iter->second.end(); it != eit; ++it) { delete *it; } @@ -452,8 +413,7 @@ void MemSSA::destroy() */ void MemSSA::performStat() { - if(pta->printStat()) - stat->performStat(); + if (pta->printStat()) stat->performStat(); } /*! @@ -466,13 +426,12 @@ u32_t MemSSA::getLoadMuNum() const LoadToMUSetMap::const_iterator eit = load2MuSetMap.end(); for (; it != eit; it++) { - const MUSet & muSet = it->second; - num+= muSet.size(); + const MUSet& muSet = it->second; + num += muSet.size(); } return num; } - /*! * Get StoreCHI numbers */ @@ -489,7 +448,6 @@ u32_t MemSSA::getStoreChiNum() const return num; } - /*! * Get EntryCHI numbers */ @@ -506,7 +464,6 @@ u32_t MemSSA::getFunEntryChiNum() const return num; } - /*! * Get RetMU numbers */ @@ -517,13 +474,12 @@ u32_t MemSSA::getFunRetMuNum() const FunToReturnMuSetMap::const_iterator eit = funToReturnMuSetMap.end(); for (; it != eit; it++) { - const MUSet & muSet = it->second; - num+= muSet.size(); + const MUSet& muSet = it->second; + num += muSet.size(); } return num; } - /*! * Get CallMU numbers */ @@ -534,13 +490,12 @@ u32_t MemSSA::getCallSiteMuNum() const CallSiteToMUSetMap::const_iterator eit = callsiteToMuSetMap.end(); for (; it != eit; it++) { - const MUSet & muSet = it->second; - num+= muSet.size(); + const MUSet& muSet = it->second; + num += muSet.size(); } return num; } - /*! * Get CallCHI numbers */ @@ -551,13 +506,12 @@ u32_t MemSSA::getCallSiteChiNum() const CallSiteToCHISetMap::const_iterator eit = callsiteToChiSetMap.end(); for (; it != eit; it++) { - const CHISet & chiSet = it->second; - num+= chiSet.size(); + const CHISet& chiSet = it->second; + num += chiSet.size(); } return num; } - /*! * Get PHI numbers */ @@ -568,8 +522,8 @@ u32_t MemSSA::getBBPhiNum() const BBToPhiSetMap::const_iterator eit = bb2PhiSetMap.end(); for (; it != eit; it++) { - const PHISet & phiSet = it->second; - num+= phiSet.size(); + const PHISet& phiSet = it->second; + num += phiSet.size(); } return num; } @@ -581,52 +535,47 @@ void MemSSA::dumpMSSA(OutStream& Out) { SVFIR* pag = pta->getPAG(); - for (SVFModule::iterator fit = pta->getModule()->begin(), efit = pta->getModule()->end(); - fit != efit; ++fit) + for (SVFModule::iterator fit = pta->getModule()->begin(), efit = pta->getModule()->end(); fit != efit; ++fit) { const SVFFunction* fun = *fit; - if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName()) - continue; + if (Options::MSSAFun() != "" && Options::MSSAFun() != fun->getName()) continue; Out << "==========FUNCTION: " << fun->getName() << "==========\n"; // dump function entry chi nodes if (hasFuncEntryChi(fun)) { - CHISet & entry_chis = getFuncEntryChiSet(fun); + CHISet& entry_chis = getFuncEntryChiSet(fun); for (CHISet::iterator chi_it = entry_chis.begin(); chi_it != entry_chis.end(); chi_it++) { (*chi_it)->dump(); } } - for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); - bit != ebit; ++bit) + for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = *bit; Out << bb->getName() << "\n"; PHISet& phiSet = getPHISet(bb); - for(PHISet::iterator pi = phiSet.begin(), epi = phiSet.end(); pi !=epi; ++pi) + for (PHISet::iterator pi = phiSet.begin(), epi = phiSet.end(); pi != epi; ++pi) { (*pi)->dump(); } bool last_is_chi = false; - for (SVFBasicBlock::const_iterator it = bb->begin(), eit = bb->end(); - it != eit; ++it) + for (SVFBasicBlock::const_iterator it = bb->begin(), eit = bb->end(); it != eit; ++it) { const SVFInstruction* inst = *it; bool isAppCall = isNonInstricCallSite(inst) && !isExtCall(inst); if (isAppCall || isHeapAllocExtCall(inst)) { const CallICFGNode* cs = pag->getICFG()->getCallICFGNode(inst); - if(hasMU(cs)) + if (hasMU(cs)) { if (!last_is_chi) { Out << "\n"; } - for (MUSet::iterator mit = getMUSet(cs).begin(), emit = getMUSet(cs).end(); - mit != emit; ++mit) + for (MUSet::iterator mit = getMUSet(cs).begin(), emit = getMUSet(cs).end(); mit != emit; ++mit) { (*mit)->dump(); } @@ -634,10 +583,10 @@ void MemSSA::dumpMSSA(OutStream& Out) Out << inst->toString() << "\n"; - if(hasCHI(cs)) + if (hasCHI(cs)) { - for (CHISet::iterator cit = getCHISet(cs).begin(), ecit = getCHISet(cs).end(); - cit != ecit; ++cit) + for (CHISet::iterator cit = getCHISet(cs).begin(), ecit = getCHISet(cs).end(); cit != ecit; + ++cit) { (*cit)->dump(); } @@ -651,14 +600,14 @@ void MemSSA::dumpMSSA(OutStream& Out) { bool dump_preamble = false; SVFStmtList& pagEdgeList = mrGen->getPAGEdgesFromInst(inst); - for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end(); - bit!=ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; + ++bit) { const PAGEdge* edge = *bit; if (const LoadStmt* load = SVFUtil::dyn_cast(edge)) { MUSet& muSet = getMUSet(load); - for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it) + for (MUSet::iterator it = muSet.begin(), eit = muSet.end(); it != eit; ++it) { if (!dump_preamble && !last_is_chi) { @@ -673,14 +622,14 @@ void MemSSA::dumpMSSA(OutStream& Out) Out << inst->toString() << "\n"; bool has_chi = false; - for(SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit= pagEdgeList.end(); - bit!=ebit; ++bit) + for (SVFStmtList::const_iterator bit = pagEdgeList.begin(), ebit = pagEdgeList.end(); bit != ebit; + ++bit) { const PAGEdge* edge = *bit; if (const StoreStmt* store = SVFUtil::dyn_cast(edge)) { CHISet& chiSet = getCHISet(store); - for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it) + for (CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it != eit; ++it) { has_chi = true; (*it)->dump(); @@ -701,7 +650,7 @@ void MemSSA::dumpMSSA(OutStream& Out) // dump return mu nodes if (hasReturnMu(fun)) { - MUSet & return_mus = getReturnMuSet(fun); + MUSet& return_mus = getReturnMuSet(fun); for (MUSet::iterator mu_it = return_mus.begin(); mu_it != return_mus.end(); mu_it++) { (*mu_it)->dump(); diff --git a/svf/lib/MSSA/SVFGBuilder.cpp b/svf/lib/MSSA/SVFGBuilder.cpp index 33974d24a..0022763b0 100644 --- a/svf/lib/MSSA/SVFGBuilder.cpp +++ b/svf/lib/MSSA/SVFGBuilder.cpp @@ -37,11 +37,9 @@ using namespace SVF; using namespace SVFUtil; - SVFG* SVFGBuilder::buildPTROnlySVFG(BVDataPTAImpl* pta) { - if(Options::OPTSVFG()) - return build(pta, VFG::PTRONLYSVFG_OPT); + if (Options::OPTSVFG()) return build(pta, VFG::PTRONLYSVFG_OPT); else return build(pta, VFG::PTRONLYSVFG); } @@ -51,7 +49,6 @@ SVFG* SVFGBuilder::buildFullSVFG(BVDataPTAImpl* pta) return build(pta, VFG::FULLSVFG); } - /*! * Create SVFG */ @@ -64,24 +61,21 @@ void SVFGBuilder::buildSVFG() SVFG* SVFGBuilder::build(BVDataPTAImpl* pta, VFG::VFGK kind) { - auto mssa = buildMSSA(pta, (VFG::PTRONLYSVFG==kind || VFG::PTRONLYSVFG_OPT==kind)); + auto mssa = buildMSSA(pta, (VFG::PTRONLYSVFG == kind || VFG::PTRONLYSVFG_OPT == kind)); DBOUT(DGENERAL, outs() << pasMsg("Build Sparse Value-Flow Graph \n")); - if(kind == VFG::FULLSVFG_OPT || kind == VFG::PTRONLYSVFG_OPT) + if (kind == VFG::FULLSVFG_OPT || kind == VFG::PTRONLYSVFG_OPT) svfg = std::make_unique(std::move(mssa), kind); else - svfg = std::unique_ptr(new SVFG(std::move(mssa),kind)); + svfg = std::unique_ptr(new SVFG(std::move(mssa), kind)); buildSVFG(); /// Update call graph using pre-analysis results - if(Options::SVFGWithIndirectCall() || SVFGWithIndCall) - svfg->updateCallGraph(pta); + if (Options::SVFGWithIndirectCall() || SVFGWithIndCall) svfg->updateCallGraph(pta); - if(svfg->getMSSA()->getPTA()->printStat()) - svfg->performStat(); + if (svfg->getMSSA()->getPTA()->printStat()) svfg->performStat(); - if(Options::DumpVFG()) - svfg->dump("svfg_final"); + if (Options::DumpVFG()) svfg->dump("svfg_final"); return svfg.get(); } @@ -102,13 +96,11 @@ std::unique_ptr SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM auto mssa = std::make_unique(pta, ptrOnlyMSSA); SVFModule* svfModule = mssa->getPTA()->getModule(); - for (SVFModule::const_iterator iter = svfModule->begin(), eiter = svfModule->end(); - iter != eiter; ++iter) + for (SVFModule::const_iterator iter = svfModule->begin(), eiter = svfModule->end(); iter != eiter; ++iter) { - const SVFFunction *fun = *iter; - if (isExtCall(fun)) - continue; + const SVFFunction* fun = *iter; + if (isExtCall(fun)) continue; mssa->buildMemSSA(*fun); } @@ -121,5 +113,3 @@ std::unique_ptr SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM return mssa; } - - diff --git a/svf/lib/MTA/LockAnalysis.cpp b/svf/lib/MTA/LockAnalysis.cpp index 431d0eb18..06c9c90e6 100644 --- a/svf/lib/MTA/LockAnalysis.cpp +++ b/svf/lib/MTA/LockAnalysis.cpp @@ -33,11 +33,9 @@ #include "Util/SVFUtil.h" #include "Util/PTAStat.h" - using namespace SVF; using namespace SVFUtil; - void LockAnalysis::analyze() { @@ -62,13 +60,12 @@ void LockAnalysis::analyze() DOTIMESTAT(lockTime += (lockEnd - lockStart) / TIMEINTERVAL); } - /*! * Collect lock/unlock sites */ void LockAnalysis::collectLockUnlocksites() { - ThreadCallGraph* tcg=tct->getThreadCallGraph(); + ThreadCallGraph* tcg = tct->getThreadCallGraph(); for (const SVFFunction* F : tct->getSVFModule()->getFunctionSet()) { @@ -96,14 +93,14 @@ void LockAnalysis::collectLockUnlocksites() void LockAnalysis::buildCandidateFuncSetforLock() { - ThreadCallGraph* tcg=tct->getThreadCallGraph(); + ThreadCallGraph* tcg = tct->getThreadCallGraph(); TCT::PTACGNodeSet visited; FIFOWorkList worklist; for (InstSet::iterator it = locksites.begin(), eit = locksites.end(); it != eit; ++it) { - const SVFFunction* fun=(*it)->getFun(); + const SVFFunction* fun = (*it)->getFun(); CallGraphNode* cgnode = tcg->getCallGraphNode(fun); if (visited.find(cgnode) == visited.end()) { @@ -155,14 +152,13 @@ void LockAnalysis::analyzeIntraProcedualLock() InstSet backwardInsts; InstSet unlockSet; - bool forward = intraForwardTraverse(lockSite,unlockSet,forwardInsts); - bool backward = intraBackwardTraverse(unlockSet,backwardInsts); + bool forward = intraForwardTraverse(lockSite, unlockSet, forwardInsts); + bool backward = intraBackwardTraverse(unlockSet, backwardInsts); /// FIXME:Should we intersect forwardInsts and backwardInsts? - if(forward && backward) - addIntraLock(lockSite,forwardInsts); - else if(forward && !backward) - addCondIntraLock(lockSite,forwardInsts); + if (forward && backward) addIntraLock(lockSite, forwardInsts); + else if (forward && !backward) + addCondIntraLock(lockSite, forwardInsts); } } @@ -178,28 +174,26 @@ bool LockAnalysis::intraForwardTraverse(const ICFGNode* lockSite, InstSet& unloc worklist.push_back(lockSite); while (!worklist.empty()) { - const ICFGNode *I = worklist.back(); + const ICFGNode* I = worklist.back(); worklist.pop_back(); const SVFInstruction* exitInst = svfFun->getExitBB()->back(); - if(tct->getICFGNode(exitInst) == I) - return false; + if (tct->getICFGNode(exitInst) == I) return false; // Skip the visited Instructions. - if (forwardInsts.find(I)!=forwardInsts.end()) - continue; + if (forwardInsts.find(I) != forwardInsts.end()) continue; forwardInsts.insert(I); if (isTDRelease(I) && isAliasedLocks(lockSite, I)) { unlockSet.insert(I); - DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << lockSite->getSourceLoc()<<"\n"); - DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << I->getSourceLoc()<<"\n"); + DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << lockSite->getSourceLoc() << "\n"); + DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << I->getSourceLoc() << "\n"); continue; } - for(const ICFGEdge* outEdge : I->getOutEdges()) + for (const ICFGEdge* outEdge : I->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == I->getFun()) + if (outEdge->getDstNode()->getFun() == I->getFun()) { worklist.push_back(outEdge->getDstNode()); } @@ -209,7 +203,6 @@ bool LockAnalysis::intraForwardTraverse(const ICFGNode* lockSite, InstSet& unloc return true; } - /*! * Intra-procedural backward traversal */ @@ -217,7 +210,7 @@ bool LockAnalysis::intraBackwardTraverse(const InstSet& unlockSet, InstSet& back { InstVec worklist; - for(InstSet::const_iterator it = unlockSet.begin(), eit = unlockSet.end(); it!=eit; ++it) + for (InstSet::const_iterator it = unlockSet.begin(), eit = unlockSet.end(); it != eit; ++it) { const ICFGNode* unlockSite = *it; const SVFInstruction* entryInst = unlockSite->getFun()->getEntryBlock()->back(); @@ -225,27 +218,25 @@ bool LockAnalysis::intraBackwardTraverse(const InstSet& unlockSet, InstSet& back while (!worklist.empty()) { - const ICFGNode *I = worklist.back(); + const ICFGNode* I = worklist.back(); worklist.pop_back(); - if(tct->getICFGNode(entryInst) == I) - return false; + if (tct->getICFGNode(entryInst) == I) return false; // Skip the visited Instructions. - if (backwardInsts.find(I)!=backwardInsts.end()) - continue; + if (backwardInsts.find(I) != backwardInsts.end()) continue; backwardInsts.insert(I); if (isTDAcquire(I) && isAliasedLocks(unlockSite, I)) { - DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << I->getSourceLoc()<<"\n"); - DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << unlockSite->getSourceLoc()<<"\n"); + DBOUT(DMTA, outs() << "LockAnalysis ci lock -- " << I->getSourceLoc() << "\n"); + DBOUT(DMTA, outs() << "LockAnalysis ci unlock -- " << unlockSite->getSourceLoc() << "\n"); continue; } - for(const ICFGEdge* inEdge : I->getInEdges()) + for (const ICFGEdge* inEdge : I->getInEdges()) { - if(inEdge->getSrcNode()->getFun() == I->getFun()) + if (inEdge->getSrcNode()->getFun() == I->getFun()) { worklist.push_back(inEdge->getSrcNode()); } @@ -256,14 +247,12 @@ bool LockAnalysis::intraBackwardTraverse(const InstSet& unlockSet, InstSet& back return true; } - void LockAnalysis::collectCxtLock() { FunSet entryFuncSet = tct->getEntryProcs(); for (FunSet::const_iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it) { - if (!isLockCandidateFun(*it)) - continue; + if (!isLockCandidateFun(*it)) continue; CallStrCxt cxt; CxtLockProc t(cxt, *it); pushToCTPWorkList(t); @@ -274,35 +263,35 @@ void LockAnalysis::collectCxtLock() CxtLockProc clp = popFromCTPWorkList(); CallGraphNode* cgNode = getTCG()->getCallGraphNode(clp.getProc()); // lzh TODO. - if (!isLockCandidateFun(cgNode->getFunction())) - continue; + if (!isLockCandidateFun(cgNode->getFunction())) continue; - for (CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit != neit; nit++) + for (CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit != neit; + nit++) { const CallGraphEdge* cgEdge = (*nit); - for (CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(), ecit = cgEdge->directCallsEnd(); - cit != ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(), + ecit = cgEdge->directCallsEnd(); + cit != ecit; ++cit) { - DBOUT(DMTA, - outs() << "\nCollecting CxtLocks: handling direct call:" << **cit << "\t" << cgEdge->getSrcNode()->getFunction()->getName() - << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n"); + DBOUT(DMTA, outs() << "\nCollecting CxtLocks: handling direct call:" << **cit << "\t" + << cgEdge->getSrcNode()->getFunction()->getName() << "-->" + << cgEdge->getDstNode()->getFunction()->getName() << "\n"); handleCallRelation(clp, cgEdge, getSVFCallSite((*cit)->getCallSite())); } - for (CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(), eind = cgEdge->indirectCallsEnd(); - ind != eind; ++ind) + for (CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(), + eind = cgEdge->indirectCallsEnd(); + ind != eind; ++ind) { - DBOUT(DMTA, - outs() << "\nCollecting CxtLocks: handling indirect call:" << **ind << "\t" - << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() - << "\n"); + DBOUT(DMTA, outs() << "\nCollecting CxtLocks: handling indirect call:" << **ind << "\t" + << cgEdge->getSrcNode()->getFunction()->getName() << "-->" + << cgEdge->getDstNode()->getFunction()->getName() << "\n"); handleCallRelation(clp, cgEdge, getSVFCallSite((*ind)->getCallSite())); } } } } - /*! * Handling call relations when collecting context-sensitive locks */ @@ -313,7 +302,7 @@ void LockAnalysis::handleCallRelation(CxtLockProc& clp, const CallGraphEdge* cgE const ICFGNode* curNode = tct->getICFGNode(cs.getInstruction()); if (isTDAcquire(curNode)) { - addCxtLock(cxt,curNode); + addCxtLock(cxt, curNode); return; } const SVFFunction* svfcallee = cgEdge->getDstNode()->getFunction(); @@ -325,7 +314,6 @@ void LockAnalysis::handleCallRelation(CxtLockProc& clp, const CallGraphEdge* cgE DBOUT(DMTA, outs() << "LockAnalysis Process CallRet old clp --"; clp.dump()); DBOUT(DMTA, outs() << "LockAnalysis Process CallRet new clp --"; newclp.dump()); } - } void LockAnalysis::analyzeLockSpanCxtStmt() @@ -334,8 +322,7 @@ void LockAnalysis::analyzeLockSpanCxtStmt() FunSet entryFuncSet = tct->getEntryProcs(); for (FunSet::const_iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it) { - if (!isLockCandidateFun(*it)) - continue; + if (!isLockCandidateFun(*it)) continue; CallStrCxt cxt; const SVFInstruction* frontInst = (*it)->getEntryBlock()->front(); CxtStmt cxtstmt(cxt, tct->getICFGNode(frontInst)); @@ -363,13 +350,11 @@ void LockAnalysis::analyzeLockSpanCxtStmt() else if (isTDAcquire(curInst)) { assert(hasCxtLock(cts) && "context-sensitive lock not found!!"); - if(addCxtStmtToSpan(cts,cts)) - handleIntra(cts); + if (addCxtStmtToSpan(cts, cts)) handleIntra(cts); } else if (isTDRelease(curInst)) { - if(removeCxtStmtToSpan(cts,cts)) - handleIntra(cts); + if (removeCxtStmtToSpan(cts, cts)) handleIntra(cts); } else if (isCallSite(curInst) && !isExtCall(curInst)) { @@ -383,18 +368,15 @@ void LockAnalysis::analyzeLockSpanCxtStmt() { handleIntra(cts); } - } - } - /*! * Print context-insensitive and context-sensitive locks */ void LockAnalysis::printLocks(const CxtStmt& cts) { - const CxtLockSet & lockset = getCxtLockfromCxtStmt(cts); + const CxtLockSet& lockset = getCxtLockfromCxtStmt(cts); outs() << "\nlock sets size = " << lockset.size() << "\n"; for (CxtLockSet::const_iterator it = lockset.begin(), eit = lockset.end(); it != eit; ++it) { @@ -402,21 +384,20 @@ void LockAnalysis::printLocks(const CxtStmt& cts) } } - - /// Handle fork void LockAnalysis::handleFork(const CxtStmt& cts) { const CallStrCxt& curCxt = cts.getContext(); const CallICFGNode* call = SVFUtil::dyn_cast(cts.getStmt()); - if(getTCG()->hasThreadForkEdge(call)) + if (getTCG()->hasThreadForkEdge(call)) { for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(call), - ecgIt = getTCG()->getForkEdgeEnd(call); cgIt != ecgIt; ++cgIt) + ecgIt = getTCG()->getForkEdgeEnd(call); + cgIt != ecgIt; ++cgIt) { const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); CallStrCxt newCxt = curCxt; - pushCxt(newCxt,call,svfcallee); + pushCxt(newCxt, call, svfcallee); const SVFInstruction* svfInst = svfcallee->getEntryBlock()->front(); CxtStmt newCts(newCxt, tct->getICFGNode(svfInst)); markCxtStmtFlag(newCts, cts); @@ -433,12 +414,12 @@ void LockAnalysis::handleCall(const CxtStmt& cts) const CallICFGNode* call = SVFUtil::dyn_cast(cts.getStmt()); if (getTCG()->hasCallGraphEdge(call)) { - for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(call), ecgIt = getTCG()->getCallEdgeEnd(call); - cgIt != ecgIt; ++cgIt) + for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(call), + ecgIt = getTCG()->getCallEdgeEnd(call); + cgIt != ecgIt; ++cgIt) { const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); - if (SVFUtil::isExtCall(svfcallee)) - continue; + if (SVFUtil::isExtCall(svfcallee)) continue; CallStrCxt newCxt = curCxt; pushCxt(newCxt, call, svfcallee); const SVFInstruction* svfInst = svfcallee->getEntryBlock()->front(); @@ -457,21 +438,22 @@ void LockAnalysis::handleRet(const CxtStmt& cts) const SVFFunction* svffun = curInst->getFun(); CallGraphNode* curFunNode = getTCG()->getCallGraphNode(svffun); - for (CallGraphNode::const_iterator it = curFunNode->getInEdges().begin(), eit = curFunNode->getInEdges().end(); it != eit; ++it) + for (CallGraphNode::const_iterator it = curFunNode->getInEdges().begin(), eit = curFunNode->getInEdges().end(); + it != eit; ++it) { CallGraphEdge* edge = *it; - if (SVFUtil::isa(edge)) - continue; - for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(), ecit = (edge)->directCallsEnd(); cit != ecit; - ++cit) + if (SVFUtil::isa(edge)) continue; + for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(), + ecit = (edge)->directCallsEnd(); + cit != ecit; ++cit) { CallStrCxt newCxt = curCxt; const ICFGNode* inst = *cit; if (matchCxt(newCxt, SVFUtil::cast(inst), curFunNode->getFunction())) { - for(const ICFGEdge* outEdge : curInst->getOutEdges()) + for (const ICFGEdge* outEdge : curInst->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == curInst->getFun()) + if (outEdge->getDstNode()->getFun() == curInst->getFun()) { CxtStmt newCts(newCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, cts); @@ -479,16 +461,17 @@ void LockAnalysis::handleRet(const CxtStmt& cts) } } } - for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(), ecit = (edge)->indirectCallsEnd(); - cit != ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(), + ecit = (edge)->indirectCallsEnd(); + cit != ecit; ++cit) { CallStrCxt newCxt = curCxt; const ICFGNode* inst = *cit; if (matchCxt(newCxt, SVFUtil::cast(inst), curFunNode->getFunction())) { - for(const ICFGEdge* outEdge : curInst->getOutEdges()) + for (const ICFGEdge* outEdge : curInst->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == curInst->getFun()) + if (outEdge->getDstNode()->getFun() == curInst->getFun()) { CxtStmt newCts(newCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, cts); @@ -506,9 +489,9 @@ void LockAnalysis::handleIntra(const CxtStmt& cts) const ICFGNode* curInst = cts.getStmt(); const CallStrCxt& curCxt = cts.getContext(); - for(const ICFGEdge* outEdge : curInst->getOutEdges()) + for (const ICFGEdge* outEdge : curInst->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == curInst->getFun()) + if (outEdge->getDstNode()->getFun() == curInst->getFun()) { CxtStmt newCts(curCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, cts); @@ -516,19 +499,18 @@ void LockAnalysis::handleIntra(const CxtStmt& cts) } } - void LockAnalysis::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) { const SVFFunction* svfcaller = call->getFun(); CallSiteID csId = getTCG()->getCallSiteID(call, callee); -// /// handle calling context for candidate functions only -// if (isLockCandidateFun(caller) == false) -// return; + // /// handle calling context for candidate functions only + // if (isLockCandidateFun(caller) == false) + // return; if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false) { - tct->pushCxt(cxt,csId); + tct->pushCxt(cxt, csId); DBOUT(DMTA, tct->dumpCxt(cxt)); } } @@ -538,18 +520,16 @@ bool LockAnalysis::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVF const SVFFunction* svfcaller = call->getFun(); CallSiteID csId = getTCG()->getCallSiteID(call, callee); -// /// handle calling context for candidate functions only -// if (isLockCandidateFun(caller) == false) -// return true; + // /// handle calling context for candidate functions only + // if (isLockCandidateFun(caller) == false) + // return true; /// partial match - if (cxt.empty()) - return true; + if (cxt.empty()) return true; if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false) { - if (cxt.back() == csId) - cxt.pop_back(); + if (cxt.back() == csId) cxt.pop_back(); else return false; DBOUT(DMTA, tct->dumpCxt(cxt)); @@ -557,19 +537,17 @@ bool LockAnalysis::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVF return true; } - /*! * Protected by at least one common lock under every context */ -bool LockAnalysis::isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2) +bool LockAnalysis::isProtectedByCommonLock(const ICFGNode* i1, const ICFGNode* i2) { numOfTotalQueries++; bool commonlock = false; DOTIMESTAT(double queryStart = PTAStat::getClk(true)); - if (isInsideIntraLock(i1) && isInsideIntraLock(i2)) - commonlock = isProtectedByCommonCILock(i1,i2) ; + if (isInsideIntraLock(i1) && isInsideIntraLock(i2)) commonlock = isProtectedByCommonCILock(i1, i2); else - commonlock = isProtectedByCommonCxtLock(i1,i2); + commonlock = isProtectedByCommonCxtLock(i1, i2); DOTIMESTAT(double queryEnd = PTAStat::getClk(true)); DOTIMESTAT(lockQueriesTime += (queryEnd - queryStart) / TIMEINTERVAL); return commonlock; @@ -578,19 +556,18 @@ bool LockAnalysis::isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i /*! * Protected by at least one common context-insensitive lock */ -bool LockAnalysis::isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode *i2) +bool LockAnalysis::isProtectedByCommonCILock(const ICFGNode* i1, const ICFGNode* i2) { - if(!isInsideCondIntraLock(i1) && !isInsideCondIntraLock(i2)) + if (!isInsideCondIntraLock(i1) && !isInsideCondIntraLock(i2)) { const InstSet& lockset1 = getIntraLockSet(i1); const InstSet& lockset2 = getIntraLockSet(i2); - for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1!=ecil1; ++cil1) + for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1 != ecil1; ++cil1) { - for (InstSet::const_iterator cil2=lockset2.begin(), ecil2=lockset2.end(); cil2!=ecil2; ++cil2) + for (InstSet::const_iterator cil2 = lockset2.begin(), ecil2 = lockset2.end(); cil2 != ecil2; ++cil2) { - if (isAliasedLocks(*cil1, *cil2)) - return true; + if (isAliasedLocks(*cil1, *cil2)) return true; } } } @@ -602,20 +579,18 @@ bool LockAnalysis::isProtectedByCommonCILock(const ICFGNode *i1, const ICFGNode */ bool LockAnalysis::isProtectedByCommonCxtLock(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2) { - if(!hasCxtLockfromCxtStmt(cxtStmt1) || !hasCxtLockfromCxtStmt(cxtStmt2)) - return true; + if (!hasCxtLockfromCxtStmt(cxtStmt1) || !hasCxtLockfromCxtStmt(cxtStmt2)) return true; const CxtLockSet& lockset1 = getCxtLockfromCxtStmt(cxtStmt1); const CxtLockSet& lockset2 = getCxtLockfromCxtStmt(cxtStmt2); - return alias(lockset1,lockset2); + return alias(lockset1, lockset2); } /*! * Protected by at least one common context-sensitive lock under each context */ -bool LockAnalysis::isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode *i2) +bool LockAnalysis::isProtectedByCommonCxtLock(const ICFGNode* i1, const ICFGNode* i2) { - if(!hasCxtStmtfromInst(i1) || !hasCxtStmtfromInst(i2)) - return false; + if (!hasCxtStmtfromInst(i1) || !hasCxtStmtfromInst(i2)) return false; const CxtStmtSet& ctsset1 = getCxtStmtfromInst(i1); const CxtStmtSet& ctsset2 = getCxtStmtfromInst(i2); for (CxtStmtSet::const_iterator cts1 = ctsset1.begin(), ects1 = ctsset1.end(); cts1 != ects1; cts1++) @@ -624,25 +599,22 @@ bool LockAnalysis::isProtectedByCommonCxtLock(const ICFGNode *i1, const ICFGNode for (CxtStmtSet::const_iterator cts2 = ctsset2.begin(), ects2 = ctsset2.end(); cts2 != ects2; cts2++) { const CxtStmt& cxtStmt2 = *cts2; - if(cxtStmt1==cxtStmt2) continue; - if(isProtectedByCommonCxtLock(cxtStmt1,cxtStmt2)==false) - return false; + if (cxtStmt1 == cxtStmt2) continue; + if (isProtectedByCommonCxtLock(cxtStmt1, cxtStmt2) == false) return false; } } return true; } - /*! * Return true if two instructions are inside at least one common lock span */ -bool LockAnalysis::isInSameSpan(const ICFGNode *i1, const ICFGNode *i2) +bool LockAnalysis::isInSameSpan(const ICFGNode* i1, const ICFGNode* i2) { DOTIMESTAT(double queryStart = PTAStat::getClk(true)); bool sameSpan = false; - if (isInsideIntraLock(i1) && isInsideIntraLock(i2)) - sameSpan = isInSameCISpan(i1, i2); + if (isInsideIntraLock(i1) && isInsideIntraLock(i2)) sameSpan = isInSameCISpan(i1, i2); else sameSpan = isInSameCSSpan(i1, i2); @@ -654,18 +626,17 @@ bool LockAnalysis::isInSameSpan(const ICFGNode *i1, const ICFGNode *i2) /*! * Return true if two instructions are inside same context-insensitive lock span */ -bool LockAnalysis::isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const +bool LockAnalysis::isInSameCISpan(const ICFGNode* i1, const ICFGNode* i2) const { - if(!isInsideCondIntraLock(i1) && !isInsideCondIntraLock(i2)) + if (!isInsideCondIntraLock(i1) && !isInsideCondIntraLock(i2)) { const InstSet& lockset1 = getIntraLockSet(i1); const InstSet& lockset2 = getIntraLockSet(i2); - for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1!=ecil1; ++cil1) + for (InstSet::const_iterator cil1 = lockset1.begin(), ecil1 = lockset1.end(); cil1 != ecil1; ++cil1) { - for (InstSet::const_iterator cil2=lockset2.begin(), ecil2=lockset2.end(); cil2!=ecil2; ++cil2) + for (InstSet::const_iterator cil2 = lockset2.begin(), ecil2 = lockset2.end(); cil2 != ecil2; ++cil2) { - if (*cil1==*cil2) - return true; + if (*cil1 == *cil2) return true; } } } @@ -677,19 +648,17 @@ bool LockAnalysis::isInSameCISpan(const ICFGNode *i1, const ICFGNode *i2) const */ bool LockAnalysis::isInSameCSSpan(const CxtStmt& cxtStmt1, const CxtStmt& cxtStmt2) const { - if(!hasCxtLockfromCxtStmt(cxtStmt1) || !hasCxtLockfromCxtStmt(cxtStmt2)) - return true; + if (!hasCxtLockfromCxtStmt(cxtStmt1) || !hasCxtLockfromCxtStmt(cxtStmt2)) return true; const CxtLockSet& lockset1 = getCxtLockfromCxtStmt(cxtStmt1); const CxtLockSet& lockset2 = getCxtLockfromCxtStmt(cxtStmt2); - return intersects(lockset1,lockset2); + return intersects(lockset1, lockset2); } /*! * Return true if two instructions are inside at least one common context-sensitive lock span */ -bool LockAnalysis::isInSameCSSpan(const ICFGNode *I1, const ICFGNode *I2) const +bool LockAnalysis::isInSameCSSpan(const ICFGNode* I1, const ICFGNode* I2) const { - if(!hasCxtStmtfromInst(I1) || !hasCxtStmtfromInst(I2)) - return false; + if (!hasCxtStmtfromInst(I1) || !hasCxtStmtfromInst(I2)) return false; const CxtStmtSet& ctsset1 = getCxtStmtfromInst(I1); const CxtStmtSet& ctsset2 = getCxtStmtfromInst(I2); @@ -699,9 +668,8 @@ bool LockAnalysis::isInSameCSSpan(const ICFGNode *I1, const ICFGNode *I2) const for (CxtStmtSet::const_iterator cts2 = ctsset2.begin(), ects2 = ctsset2.end(); cts2 != ects2; cts2++) { const CxtStmt& cxtStmt2 = *cts2; - if(cxtStmt1==cxtStmt2) continue; - if(isInSameCSSpan(cxtStmt1,cxtStmt2)==false) - return false; + if (cxtStmt1 == cxtStmt2) continue; + if (isInSameCSSpan(cxtStmt1, cxtStmt2) == false) return false; } } return true; diff --git a/svf/lib/MTA/MHP.cpp b/svf/lib/MTA/MHP.cpp index 9ef4b10d5..578528886 100644 --- a/svf/lib/MTA/MHP.cpp +++ b/svf/lib/MTA/MHP.cpp @@ -37,12 +37,12 @@ using namespace SVF; using namespace SVFUtil; - /*! * Constructor */ -MHP::MHP(TCT* t) : tcg(t->getThreadCallGraph()), tct(t), numOfTotalQueries(0), numOfMHPQueries(0), - interleavingTime(0), interleavingQueriesTime(0) +MHP::MHP(TCT* t) + : tcg(t->getThreadCallGraph()), tct(t), numOfTotalQueries(0), numOfMHPQueries(0), interleavingTime(0), + interleavingQueriesTime(0) { fja = new ForkJoinAnalysis(tct); fja->analyzeForkJoinPair(); @@ -134,8 +134,7 @@ void MHP::analyzeInterleaving() /// update non-candidate functions' interleaving updateNonCandidateFunInterleaving(); - if (Options::PrintInterLev()) - printInterleaving(); + if (Options::PrintInterLev()) printInterleaving(); } /*! @@ -151,8 +150,7 @@ void MHP::updateNonCandidateFunInterleaving() const SVFInstruction* entryinst = fun->getEntryBlock()->front(); const ICFGNode* entryNode = tct->getICFGNode(entryinst); - if (!hasThreadStmtSet(entryNode)) - continue; + if (!hasThreadStmtSet(entryNode)) continue; const CxtThreadStmtSet& tsSet = getThreadStmtSet(entryNode); @@ -164,8 +162,7 @@ void MHP::updateNonCandidateFunInterleaving() { for (const SVFInstruction* svfInst : svfbb->getInstructionList()) { - if (svfInst == entryinst) - continue; + if (svfInst == entryinst) continue; const ICFGNode* curNode = tct->getICFGNode(svfInst); CxtThreadStmt newCts(cts.getTid(), curCxt, curNode); threadStmtToTheadInterLeav[newCts] |= threadStmtToTheadInterLeav[cts]; @@ -184,7 +181,8 @@ void MHP::handleNonCandidateFun(const CxtThreadStmt& cts) { const ICFGNode* curInst = cts.getStmt(); const SVFFunction* curfun = curInst->getFun(); - assert((curInst == tct->getICFGNode(curfun->getEntryBlock()->front())) && "curInst is not the entry of non candidate function."); + assert((curInst == tct->getICFGNode(curfun->getEntryBlock()->front())) && + "curInst is not the entry of non candidate function."); const CallStrCxt& curCxt = cts.getContext(); CallGraphNode* node = tcg->getCallGraphNode(curfun); for (CallGraphNode::const_iterator nit = node->OutEdgeBegin(), neit = node->OutEdgeEnd(); nit != neit; nit++) @@ -214,8 +212,8 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid) { for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(cbn), - ecgIt = tcg->getForkEdgeEnd(cbn); - cgIt != ecgIt; ++cgIt) + ecgIt = tcg->getForkEdgeEnd(cbn); + cgIt != ecgIt; ++cgIt) { const SVFFunction* svfroutine = (*cgIt)->getDstNode()->getFunction(); CallStrCxt newCxt = curCxt; @@ -254,8 +252,7 @@ void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid) const SVFInstruction* svfEntryInst = eb->front(); CxtThreadStmt newCts(cts.getTid(), curCxt, tct->getICFGNode(svfEntryInst)); addInterleavingThread(newCts, cts); - if (hasJoinInSymmetricLoop(curCxt, call)) - rmInterleavingThread(newCts, joinedTids, call); + if (hasJoinInSymmetricLoop(curCxt, call)) rmInterleavingThread(newCts, joinedTids, call); } } else @@ -297,13 +294,12 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid) if (tct->getThreadCallGraph()->hasCallGraphEdge(cbn)) { for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = tcg->getCallEdgeBegin(cbn), - ecgIt = tcg->getCallEdgeEnd(cbn); - cgIt != ecgIt; ++cgIt) + ecgIt = tcg->getCallEdgeEnd(cbn); + cgIt != ecgIt; ++cgIt) { const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); - if (isExtCall(svfcallee)) - continue; + if (isExtCall(svfcallee)) continue; CallStrCxt newCxt = curCxt; const CallICFGNode* callicfgnode = SVFUtil::cast(call); pushCxt(newCxt, callicfgnode, svfcallee); @@ -322,18 +318,17 @@ void MHP::handleRet(const CxtThreadStmt& cts) CallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getFun()); for (CallGraphEdge* edge : curFunNode->getInEdges()) { - if (SVFUtil::isa(edge)) - continue; + if (SVFUtil::isa(edge)) continue; for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->directCallsBegin(), - ecit = (edge)->directCallsEnd(); - cit != ecit; ++cit) + ecit = (edge)->directCallsEnd(); + cit != ecit; ++cit) { CallStrCxt newCxt = cts.getContext(); if (matchCxt(newCxt, *cit, curFunNode->getFunction())) { - for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) + for (const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun()) + if (outEdge->getDstNode()->getFun() == cts.getStmt()->getFun()) { CxtThreadStmt newCts(cts.getTid(), newCxt, outEdge->getDstNode()); addInterleavingThread(newCts, cts); @@ -342,15 +337,15 @@ void MHP::handleRet(const CxtThreadStmt& cts) } } for (CallGraphEdge::CallInstSet::const_iterator cit = (edge)->indirectCallsBegin(), - ecit = (edge)->indirectCallsEnd(); - cit != ecit; ++cit) + ecit = (edge)->indirectCallsEnd(); + cit != ecit; ++cit) { CallStrCxt newCxt = cts.getContext(); if (matchCxt(newCxt, *cit, curFunNode->getFunction())) { - for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) + for (const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun()) + if (outEdge->getDstNode()->getFun() == cts.getStmt()->getFun()) { CxtThreadStmt newCts(cts.getTid(), newCxt, outEdge->getDstNode()); addInterleavingThread(newCts, cts); @@ -367,9 +362,9 @@ void MHP::handleRet(const CxtThreadStmt& cts) void MHP::handleIntra(const CxtThreadStmt& cts) { - for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) + for (const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == cts.getStmt()->getFun()) + if (outEdge->getDstNode()->getFun() == cts.getStmt()->getFun()) { CxtThreadStmt newCts(cts.getTid(), cts.getContext(), outEdge->getDstNode()); addInterleavingThread(newCts, cts); @@ -394,9 +389,9 @@ void MHP::updateAncestorThreads(NodeID curTid) if (const ICFGNode* forkInst = ct.getThread()) { CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct); - for(const ICFGEdge* outEdge : forkInst->getOutEdges()) + for (const ICFGEdge* outEdge : forkInst->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == forkInst->getFun()) + if (outEdge->getDstNode()->getFun() == forkInst->getFun()) { CxtThreadStmt cts(tct->getParentThread(i), forkSiteCxt, outEdge->getDstNode()); addInterleavingThread(cts, curTid); @@ -425,8 +420,7 @@ void MHP::updateSiblingThreads(NodeID curTid) NodeBS siblingTds = tct->getSiblingThread(tid); for (const unsigned stid : siblingTds) { - if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid)) - continue; + if ((isHBPair(tid, stid) && isRecurFullJoin(tid, curTid)) || isHBPair(stid, tid)) continue; const CxtThread& ct = tct->getTCTNode(stid)->getCxtThread(); const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct); @@ -446,8 +440,7 @@ void MHP::updateSiblingThreads(NodeID curTid) */ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid) { - if (parentTid == curTid) - return true; + if (parentTid == curTid) return true; const TCTNode* curNode = tct->getTCTNode(curTid); FIFOWorkList worklist; @@ -460,8 +453,7 @@ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid) NodeID srcID = edge->getSrcID(); if (fja->isFullJoin(srcID, node->getId())) { - if (srcID == parentTid) - return true; + if (srcID == parentTid) return true; else worklist.push(edge->getSrcNode()); } @@ -528,8 +520,7 @@ bool MHP::isConnectedfromMain(const SVFFunction* fun) while (!worklist.empty()) { const CallGraphNode* node = worklist.pop(); - if ("main" == node->getFunction()->getName()) - return true; + if ("main" == node->getFunction()->getName()) return true; for (CallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++) { const CallGraphNode* srcNode = (*nit)->getSrcNode(); @@ -557,8 +548,7 @@ bool MHP::mayHappenInParallelInst(const ICFGNode* i1, const ICFGNode* i2) { /// TODO: Any instruction in dead function is assumed no MHP with others - if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2)) - return false; + if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2)) return false; const CxtThreadStmtSet& tsSet1 = getThreadStmtSet(i1); const CxtThreadStmtSet& tsSet2 = getThreadStmtSet(i2); @@ -603,8 +593,7 @@ bool MHP::mayHappenInParallelCache(const ICFGNode* i1, const ICFGNode* i2) } else { - if (it->second) - numOfMHPQueries++; + if (it->second) numOfMHPQueries++; return it->second; } } @@ -625,17 +614,15 @@ bool MHP::mayHappenInParallel(const ICFGNode* i1, const ICFGNode* i2) bool MHP::executedByTheSameThread(const ICFGNode* i1, const ICFGNode* i2) { - if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2)) - return true; + if (!hasThreadStmtSet(i1) || !hasThreadStmtSet(i2)) return true; const CxtThreadStmtSet& tsSet1 = getThreadStmtSet(i1); const CxtThreadStmtSet& tsSet2 = getThreadStmtSet(i2); - for (const CxtThreadStmt&ts1 : tsSet1) + for (const CxtThreadStmt& ts1 : tsSet1) { for (const CxtThreadStmt& ts2 : tsSet2) { - if (ts1.getTid() != ts2.getTid() || isMultiForkedThread(ts1.getTid())) - return false; + if (ts1.getTid() != ts2.getTid() || isMultiForkedThread(ts1.getTid())) return false; } } return true; @@ -648,8 +635,7 @@ void MHP::printInterleaving() { for (const auto& pair : threadStmtToTheadInterLeav) { - outs() << "( t" << pair.first.getTid() - << pair.first.getStmt()->toString() << " ) ==> ["; + outs() << "( t" << pair.first.getTid() << pair.first.getStmt()->toString() << " ) ==> ["; for (unsigned i : pair.second) { outs() << " " << i << " "; @@ -662,7 +648,8 @@ void MHP::printInterleaving() * Collect SCEV pass information for pointers at fork/join sites * Because ScalarEvolution is a function pass, previous knowledge of a function * may be overwritten when analyzing a new function. We use a - * internal wrapper class PTASCEV to record all the necessary information for determining symmetric fork/join inside loops + * internal wrapper class PTASCEV to record all the necessary information for determining symmetric fork/join inside + * loops */ void ForkJoinAnalysis::collectSCEVInfo() { @@ -730,9 +717,9 @@ void ForkJoinAnalysis::analyzeForkJoinPair() CallStrCxt forkSiteCxt = tct->getCxtOfCxtThread(ct); const ICFGNode* exitInst = getExitInstOfParentRoutineFun(rootTid); - for(const ICFGEdge* outEdge : forkInst->getOutEdges()) + for (const ICFGEdge* outEdge : forkInst->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == forkInst->getFun()) + if (outEdge->getDstNode()->getFun() == forkInst->getFun()) { CxtStmt newCts(forkSiteCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, TDAlive); @@ -771,8 +758,7 @@ void ForkJoinAnalysis::analyzeForkJoinPair() if (curInst == exitInst) { - if (getMarkedFlag(cts) != TDAlive) - addToFullJoin(tct->getParentThread(rootTid), rootTid); + if (getMarkedFlag(cts) != TDAlive) addToFullJoin(tct->getParentThread(rootTid), rootTid); else addToPartial(tct->getParentThread(rootTid), rootTid); } @@ -792,15 +778,14 @@ void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid) if (getTCG()->hasThreadForkEdge(cbn)) { for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(cbn), - ecgIt = getTCG()->getForkEdgeEnd(cbn); - cgIt != ecgIt; ++cgIt) + ecgIt = getTCG()->getForkEdgeEnd(cbn); + cgIt != ecgIt; ++cgIt) { const SVFFunction* callee = (*cgIt)->getDstNode()->getFunction(); CallStrCxt newCxt = curCxt; pushCxt(newCxt, cbn, callee); CxtThread ct(newCxt, call); - if (getMarkedFlag(cts) != TDAlive) - addToHBPair(rootTid, tct->getTCTNode(ct)->getId()); + if (getMarkedFlag(cts) != TDAlive) addToHBPair(rootTid, tct->getTCTNode(ct)->getId()); else addToHPPair(rootTid, tct->getTCTNode(ct)->getId()); } @@ -826,7 +811,7 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid) if (hasJoinLoop(joinSite)) { LoopBBs& joinLoop = getJoinLoop(joinSite); - std::vector exitbbs; + std::vector exitbbs; joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs); while (!exitbbs.empty()) { @@ -883,12 +868,11 @@ void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid) if (getTCG()->hasCallGraphEdge(cbn)) { for (CallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(cbn), - ecgIt = getTCG()->getCallEdgeEnd(cbn); - cgIt != ecgIt; ++cgIt) + ecgIt = getTCG()->getCallEdgeEnd(cbn); + cgIt != ecgIt; ++cgIt) { const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); - if (isExtCall(svfcallee)) - continue; + if (isExtCall(svfcallee)) continue; CallStrCxt newCxt = curCxt; pushCxt(newCxt, cbn, svfcallee); const SVFInstruction* svfEntryInst = svfcallee->getEntryBlock()->front(); @@ -907,19 +891,17 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts) CallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->getFun()); for (CallGraphEdge* edge : curFunNode->getInEdges()) { - if (SVFUtil::isa(edge)) - continue; - for (CallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(), - ecit = edge->directCallsEnd(); - cit != ecit; ++cit) + if (SVFUtil::isa(edge)) continue; + for (CallGraphEdge::CallInstSet::const_iterator cit = edge->directCallsBegin(), ecit = edge->directCallsEnd(); + cit != ecit; ++cit) { CallStrCxt newCxt = curCxt; const ICFGNode* curNode = tct->getICFGNode((*cit)->getCallSite()); if (matchCxt(newCxt, SVFUtil::cast(curNode), curFunNode->getFunction())) { - for(const ICFGEdge* outEdge : curNode->getOutEdges()) + for (const ICFGEdge* outEdge : curNode->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == curNode->getFun()) + if (outEdge->getDstNode()->getFun() == curNode->getFun()) { CxtStmt newCts(newCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, cts); @@ -928,17 +910,17 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts) } } for (CallGraphEdge::CallInstSet::const_iterator cit = edge->indirectCallsBegin(), - ecit = edge->indirectCallsEnd(); - cit != ecit; ++cit) + ecit = edge->indirectCallsEnd(); + cit != ecit; ++cit) { CallStrCxt newCxt = curCxt; const ICFGNode* curNode = tct->getICFGNode((*cit)->getCallSite()); if (matchCxt(newCxt, SVFUtil::cast(curNode), curFunNode->getFunction())) { - for(const ICFGEdge* outEdge : curNode->getOutEdges()) + for (const ICFGEdge* outEdge : curNode->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == curNode->getFun()) + if (outEdge->getDstNode()->getFun() == curNode->getFun()) { CxtStmt newCts(newCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, cts); @@ -956,9 +938,9 @@ void ForkJoinAnalysis::handleIntra(const CxtStmt& cts) const ICFGNode* curInst = cts.getStmt(); const CallStrCxt& curCxt = cts.getContext(); - for(const ICFGEdge* outEdge : curInst->getOutEdges()) + for (const ICFGEdge* outEdge : curInst->getOutEdges()) { - if(outEdge->getDstNode()->getFun() == curInst->getFun()) + if (outEdge->getDstNode()->getFun() == curInst->getFun()) { CxtStmt newCts(curCxt, outEdge->getDstNode()); markCxtStmtFlag(newCts, cts); @@ -975,8 +957,7 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs) { CxtStmtToTIDMap::const_iterator it = dirAndIndJoinMap.find(cs); - if (it != dirAndIndJoinMap.end()) - return it->second; + if (it != dirAndIndJoinMap.end()) return it->second; const NodeBS& directJoinTids = getDirectlyJoinedTid(cs); NodeBS allJoinTids = directJoinTids; @@ -991,7 +972,8 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs) { NodeID tid = worklist.pop(); TCTNode* node = tct->getTCTNode(tid); - for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); it != eit; ++it) + for (TCT::ThreadCreateEdgeSet::const_iterator it = tct->getChildrenBegin(node), eit = tct->getChildrenEnd(node); + it != eit; ++it) { NodeID childTid = (*it)->getDstID(); if (isFullJoin(tid, childTid)) @@ -1014,7 +996,8 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs) // for (gep_type_iterator gi = gep_type_begin(*ptr1), ge = gep_type_end(*ptr1); // gi != ge; ++gi) // { -// if(SVFConstantInt* ci = SVFUtil::dyn_cast(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gi.getOperand()))) +// if(SVFConstantInt* ci = +// SVFUtil::dyn_cast(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gi.getOperand()))) // { // s32_t idx = ci->getSExtValue(); // ptr1vec.push_back(idx); @@ -1027,7 +1010,8 @@ NodeBS ForkJoinAnalysis::getDirAndIndJoinedTid(const CxtStmt& cs) // for (gep_type_iterator gi = gep_type_begin(*ptr2), ge = gep_type_end(*ptr2); // gi != ge; ++gi) // { -// if(SVFConstantInt* ci = SVFUtil::dyn_cast(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gi.getOperand()))) +// if(SVFConstantInt* ci = +// SVFUtil::dyn_cast(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gi.getOperand()))) // { // s32_t idx = ci->getSExtValue(); // ptr2vec.push_back(idx); @@ -1058,7 +1042,8 @@ bool ForkJoinAnalysis::isSameSCEV(const ICFGNode* forkSite, const ICFGNode* join // if(forkse.inloop && joinse.inloop) // return forkse.start==joinse.start && forkse.step == joinse.step && forkse.tripcount <= joinse.tripcount; // else if(SVFUtil::isa(forkse.ptr) && SVFUtil::isa(joinse.ptr)) - // return accessSameArrayIndex(SVFUtil::cast(forkse.ptr),SVFUtil::cast(joinse.ptr)); + // return + // accessSameArrayIndex(SVFUtil::cast(forkse.ptr),SVFUtil::cast(joinse.ptr)); // else if(SVFUtil::isa(joinse.ptr)) // return false; // else diff --git a/svf/lib/MTA/MTA.cpp b/svf/lib/MTA/MTA.cpp index dc0476614..f5ac430e4 100644 --- a/svf/lib/MTA/MTA.cpp +++ b/svf/lib/MTA/MTA.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * MTA.cpp * @@ -47,10 +46,9 @@ MTA::MTA() : tcg(nullptr), tct(nullptr), mhp(nullptr), lsa(nullptr) MTA::~MTA() { - if (tcg) - delete tcg; - //if (tct) - // delete tct; + if (tcg) delete tcg; + // if (tct) + // delete tct; delete mhp; delete lsa; } @@ -63,8 +61,7 @@ bool MTA::runOnModule(SVFIR* pag) mhp = computeMHP(pag->getModule()); lsa = computeLocksets(mhp->getTCT()); - if(Options::RaceCheck()) - detect(pag->getModule()); + if (Options::RaceCheck()) detect(pag->getModule()); return false; } @@ -144,7 +141,7 @@ void MTA::detect(SVFModule* module) { for (const SVFInstruction* svfInst : svfbb->getInstructionList()) { - for(const SVFStmt* stmt : pag->getSVFStmtList(pag->getICFG()->getICFGNode(svfInst))) + for (const SVFStmt* stmt : pag->getSVFStmtList(pag->getICFG()->getICFGNode(svfInst))) { if (const LoadStmt* l = SVFUtil::dyn_cast(stmt)) { @@ -165,12 +162,12 @@ void MTA::detect(SVFModule* module) for (Set::const_iterator sit = stores.begin(), esit = stores.end(); sit != esit; ++sit) { const StoreStmt* store = *sit; - if(load->getInst()==nullptr || store->getInst()==nullptr) - continue; - if(mhp->mayHappenInParallelInst(load->getICFGNode(),store->getICFGNode()) && pta->alias(load->getRHSVarID(),store->getLHSVarID())) - if(lsa->isProtectedByCommonLock(load->getICFGNode(),store->getICFGNode()) == false) - outs() << SVFUtil::bugMsg1("race pair(") << " store: " << store->toString() << ", load: " << load->toString() << SVFUtil::bugMsg1(")") << "\n"; + if (load->getInst() == nullptr || store->getInst() == nullptr) continue; + if (mhp->mayHappenInParallelInst(load->getICFGNode(), store->getICFGNode()) && + pta->alias(load->getRHSVarID(), store->getLHSVarID())) + if (lsa->isProtectedByCommonLock(load->getICFGNode(), store->getICFGNode()) == false) + outs() << SVFUtil::bugMsg1("race pair(") << " store: " << store->toString() + << ", load: " << load->toString() << SVFUtil::bugMsg1(")") << "\n"; } } } - diff --git a/svf/lib/MTA/MTAStat.cpp b/svf/lib/MTA/MTAStat.cpp index be4974075..0ae9a5214 100644 --- a/svf/lib/MTA/MTAStat.cpp +++ b/svf/lib/MTA/MTAStat.cpp @@ -36,7 +36,6 @@ using namespace SVF; - /*! * Statistics for thread call graph */ @@ -46,34 +45,37 @@ void MTAStat::performThreadCallGraphStat(ThreadCallGraph* tcg) u32_t numOfJoinEdge = 0; u32_t numOfIndForksite = 0; u32_t numOfIndForkEdge = 0; - for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it) + for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; + ++it) { bool indirectfork = false; - const SVFFunction* spawnee = SVFUtil::dyn_cast(tcg->getThreadAPI()->getForkedFun((*it)->getCallSite())); - if(spawnee==nullptr) + const SVFFunction* spawnee = + SVFUtil::dyn_cast(tcg->getThreadAPI()->getForkedFun((*it)->getCallSite())); + if (spawnee == nullptr) { numOfIndForksite++; indirectfork = true; } - for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(*it), ecgIt = - tcg->getForkEdgeEnd(*it); cgIt != ecgIt; ++cgIt) + for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = tcg->getForkEdgeBegin(*it), + ecgIt = tcg->getForkEdgeEnd(*it); + cgIt != ecgIt; ++cgIt) { numOfForkEdge++; - if(indirectfork) - numOfIndForkEdge++; + if (indirectfork) numOfIndForkEdge++; } } - for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; ++it) + for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; + ++it) { - for (ThreadCallGraph::JoinEdgeSet::const_iterator cgIt = tcg->getJoinEdgeBegin(*it), ecgIt = - tcg->getJoinEdgeEnd(*it); cgIt != ecgIt; ++cgIt) + for (ThreadCallGraph::JoinEdgeSet::const_iterator cgIt = tcg->getJoinEdgeBegin(*it), + ecgIt = tcg->getJoinEdgeEnd(*it); + cgIt != ecgIt; ++cgIt) { numOfJoinEdge++; } } - PTNumStatMap.clear(); PTNumStatMap["NumOfForkSite"] = tcg->getNumOfForksite(); PTNumStatMap["NumOfForkEdge"] = numOfForkEdge; @@ -87,7 +89,6 @@ void MTAStat::performThreadCallGraphStat(ThreadCallGraph* tcg) PTAStat::printStat(); } - void MTAStat::performTCTStat(TCT* tct) { @@ -112,51 +113,46 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa) { SVFIR* pag = SVFIR::getPAG(); - if(Options::AllPairMHP()) + if (Options::AllPairMHP()) { Set instSet1; Set instSet2; SVFModule* mod = mhp->getTCT()->getSVFModule(); for (const SVFFunction* fun : mod->getFunctionSet()) { - if(SVFUtil::isExtCall(fun)) - continue; - if(!mhp->isConnectedfromMain(fun)) - continue; - for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit) + if (SVFUtil::isExtCall(fun)) continue; + if (!mhp->isConnectedfromMain(fun)) continue; + for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = *bit; for (SVFBasicBlock::const_iterator ii = bb->begin(), eii = bb->end(); ii != eii; ++ii) { const SVFInstruction* inst = *ii; - for(const SVFStmt* stmt : pag->getSVFStmtList(pag->getICFG()->getICFGNode(inst))) + for (const SVFStmt* stmt : pag->getSVFStmtList(pag->getICFG()->getICFGNode(inst))) { - if(SVFUtil::isa(stmt)) + if (SVFUtil::isa(stmt)) { instSet1.insert(stmt->getICFGNode()); } - else if(SVFUtil::isa(stmt)) + else if (SVFUtil::isa(stmt)) { instSet1.insert(stmt->getICFGNode()); instSet2.insert(stmt->getICFGNode()); } } - } } } - - for(Set::const_iterator it1 = instSet1.begin(), eit1 = instSet1.end(); it1!=eit1; ++it1) + for (Set::const_iterator it1 = instSet1.begin(), eit1 = instSet1.end(); it1 != eit1; ++it1) { - for(Set::const_iterator it2 = instSet2.begin(), eit2 = instSet2.end(); it2!=eit2; ++it2) + for (Set::const_iterator it2 = instSet2.begin(), eit2 = instSet2.end(); it2 != eit2; ++it2) { - mhp->mayHappenInParallel(*it1,*it2); + mhp->mayHappenInParallel(*it1, *it2); } } } - generalNumMap.clear(); PTNumStatMap.clear(); timeStatMap.clear(); @@ -174,4 +170,3 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa) SVFUtil::outs() << "\n****MHP Stmt Pairs Statistics****\n"; PTAStat::printStat(); } - diff --git a/svf/lib/MTA/TCT.cpp b/svf/lib/MTA/TCT.cpp index a8528df45..45fdbd77d 100644 --- a/svf/lib/MTA/TCT.cpp +++ b/svf/lib/MTA/TCT.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * TCT.cpp * @@ -50,35 +49,33 @@ bool TCT::isInLoopInstruction(const ICFGNode* inst) FIFOWorkList worklist; worklist.push(inst); - while(!worklist.empty()) + while (!worklist.empty()) { const ICFGNode* inst = worklist.pop(); insts.insert(inst); CallGraphNode* cgnode = tcg->getCallGraphNode(inst->getFun()); - for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++) + for (CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit != neit; nit++) { - for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(), - ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(), + ecit = (*nit)->directCallsEnd(); + cit != ecit; ++cit) { - if(insts.insert(*cit).second) - worklist.push(*cit); + if (insts.insert(*cit).second) worklist.push(*cit); } - for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(), - ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(), + ecit = (*nit)->indirectCallsEnd(); + cit != ecit; ++cit) { - if(insts.insert(*cit).second) - worklist.push(*cit); + if (insts.insert(*cit).second) worklist.push(*cit); } } } - for(const ICFGNode* i : insts) + for (const ICFGNode* i : insts) { - if(i->getFun()->hasLoopInfo(i->getBB())) - return true; + if (i->getFun()->hasLoopInfo(i->getBB())) return true; } - return false; } @@ -94,36 +91,34 @@ bool TCT::isInRecursion(const ICFGNode* inst) const Set visits; worklist.push(f); - while(!worklist.empty()) + while (!worklist.empty()) { const SVFFunction* svffun = worklist.pop(); visits.insert(svffun); - if(tcgSCC->isInCycle(tcg->getCallGraphNode(svffun)->getId())) - return true; + if (tcgSCC->isInCycle(tcg->getCallGraphNode(svffun)->getId())) return true; const CallGraphNode* cgnode = tcg->getCallGraphNode(svffun); - for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++) + for (CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit != neit; nit++) { - for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(), - ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(), + ecit = (*nit)->directCallsEnd(); + cit != ecit; ++cit) { const SVFFunction* caller = (*cit)->getCallSite()->getFunction(); - if(visits.find(caller)==visits.end()) - worklist.push(caller); + if (visits.find(caller) == visits.end()) worklist.push(caller); } - for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(), - ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(), + ecit = (*nit)->indirectCallsEnd(); + cit != ecit; ++cit) { const SVFFunction* caller = (*cit)->getCallSite()->getFunction(); - if(visits.find(caller)==visits.end()) - worklist.push(caller); + if (visits.find(caller) == visits.end()) worklist.push(caller); } } } return false; - } /*! @@ -131,27 +126,29 @@ bool TCT::isInRecursion(const ICFGNode* inst) const */ void TCT::markRelProcs() { - for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it) + for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; + ++it) { const SVFFunction* svfun = (*it)->getParent()->getParent(); markRelProcs(svfun); - for(ThreadCallGraph::ForkEdgeSet::const_iterator nit = tcg->getForkEdgeBegin(*it), neit = tcg->getForkEdgeEnd(*it); nit!=neit; nit++) + for (ThreadCallGraph::ForkEdgeSet::const_iterator nit = tcg->getForkEdgeBegin(*it), + neit = tcg->getForkEdgeEnd(*it); + nit != neit; nit++) { const CallGraphNode* forkeeNode = (*nit)->getDstNode(); candidateFuncSet.insert(forkeeNode->getFunction()); } - } - for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; ++it) + for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; + ++it) { const SVFFunction* svfun = (*it)->getParent()->getParent(); markRelProcs(svfun); } - if(candidateFuncSet.empty()) - writeWrnMsg("We didn't recognize any fork site, this is single thread program?"); + if (candidateFuncSet.empty()) writeWrnMsg("We didn't recognize any fork site, this is single thread program?"); } /*! @@ -164,14 +161,14 @@ void TCT::markRelProcs(const SVFFunction* svffun) PTACGNodeSet visited; worklist.push(cgnode); visited.insert(cgnode); - while(!worklist.empty()) + while (!worklist.empty()) { const CallGraphNode* node = worklist.pop(); candidateFuncSet.insert(node->getFunction()); - for(CallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit!=neit; nit++) + for (CallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++) { const CallGraphNode* srcNode = (*nit)->getSrcNode(); - if(visited.find(srcNode)==visited.end()) + if (visited.find(srcNode) == visited.end()) { visited.insert(srcNode); worklist.push(srcNode); @@ -185,11 +182,10 @@ void TCT::markRelProcs(const SVFFunction* svffun) */ void TCT::collectEntryFunInCallGraph() { - for(SVFModule::const_iterator it = getSVFModule()->begin(), eit = getSVFModule()->end(); it!=eit; ++it) + for (SVFModule::const_iterator it = getSVFModule()->begin(), eit = getSVFModule()->end(); it != eit; ++it) { const SVFFunction* fun = (*it); - if (SVFUtil::isExtCall(fun)) - continue; + if (SVFUtil::isExtCall(fun)) continue; CallGraphNode* node = tcg->getCallGraphNode(fun); if (!node->hasIncomingEdge()) { @@ -204,39 +200,37 @@ void TCT::collectEntryFunInCallGraph() */ void TCT::collectMultiForkedThreads() { - if (this->nodeNum == 0 ) - return; + if (this->nodeNum == 0) return; FIFOWorkList worklist; worklist.push(getTCTNode(0)); - while(!worklist.empty()) + while (!worklist.empty()) { TCTNode* node = worklist.pop(); - const CxtThread &ct = node->getCxtThread(); + const CxtThread& ct = node->getCxtThread(); - if(ct.isIncycle() || ct.isInloop()) + if (ct.isIncycle() || ct.isInloop()) { node->setMultiforked(true); } else { - for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getInEdges().begin(), eit = node->getInEdges().end(); it != eit; - ++it) + for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getInEdges().begin(), + eit = node->getInEdges().end(); + it != eit; ++it) { - if ((*it)->getSrcNode()->isMultiforked()) - node->setMultiforked(true); + if ((*it)->getSrcNode()->isMultiforked()) node->setMultiforked(true); } } - for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getOutEdges().begin(), eit = node->getOutEdges().end(); it != eit; - ++it) + for (TCT::ThreadCreateEdgeSet::const_iterator it = node->getOutEdges().begin(), eit = node->getOutEdges().end(); + it != eit; ++it) { worklist.push((*it)->getDstNode()); } } } - /*! * Handle call relations */ @@ -247,37 +241,36 @@ void TCT::handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, Ca CallStrCxt cxt(ctp.getContext()); CallStrCxt oldCxt = cxt; const CallICFGNode* callNode = SVFUtil::cast(getICFGNode(cs.getInstruction())); - pushCxt(cxt,callNode,callee); + pushCxt(cxt, callNode, callee); - if(cgEdge->getEdgeKind() == CallGraphEdge::CallRetEdge) + if (cgEdge->getEdgeKind() == CallGraphEdge::CallRetEdge) { - CxtThreadProc newctp(ctp.getTid(),cxt,callee); - if(pushToCTPWorkList(newctp)) + CxtThreadProc newctp(ctp.getTid(), cxt, callee); + if (pushToCTPWorkList(newctp)) { - DBOUT(DMTA,outs() << "TCT Process CallRet old ctp --"; ctp.dump()); - DBOUT(DMTA,outs() << "TCT Process CallRet new ctp --"; newctp.dump()); + DBOUT(DMTA, outs() << "TCT Process CallRet old ctp --"; ctp.dump()); + DBOUT(DMTA, outs() << "TCT Process CallRet new ctp --"; newctp.dump()); } } - else if(cgEdge->getEdgeKind() == CallGraphEdge::TDForkEdge) + else if (cgEdge->getEdgeKind() == CallGraphEdge::TDForkEdge) { /// Create spawnee TCT node - TCTNode* spawneeNode = getOrCreateTCTNode(cxt,callNode, oldCxt, callee); - CxtThreadProc newctp(spawneeNode->getId(),cxt,callee); + TCTNode* spawneeNode = getOrCreateTCTNode(cxt, callNode, oldCxt, callee); + CxtThreadProc newctp(spawneeNode->getId(), cxt, callee); - if(pushToCTPWorkList(newctp)) + if (pushToCTPWorkList(newctp)) { /// Add TCT nodes and edge - if(addTCTEdge(this->getGNode(ctp.getTid()), spawneeNode)) + if (addTCTEdge(this->getGNode(ctp.getTid()), spawneeNode)) { - DBOUT(DMTA,outs() << "Add TCT Edge from thread " << ctp.getTid() << " "; + DBOUT(DMTA, outs() << "Add TCT Edge from thread " << ctp.getTid() << " "; this->getGNode(ctp.getTid())->getCxtThread().dump(); - outs() << " to thread " << spawneeNode->getId() << " "; - spawneeNode->getCxtThread().dump(); - outs() << "\n" ); + outs() << " to thread " << spawneeNode->getId() << " "; spawneeNode->getCxtThread().dump(); + outs() << "\n"); } - DBOUT(DMTA,outs() << "TCT Process Fork old ctp --"; ctp.dump()); - DBOUT(DMTA,outs() << "TCT Process Fork new ctp --"; newctp.dump()); + DBOUT(DMTA, outs() << "TCT Process Fork old ctp --"; ctp.dump()); + DBOUT(DMTA, outs() << "TCT Process Fork new ctp --"; newctp.dump()); } } } @@ -286,20 +279,19 @@ void TCT::handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, Ca * Return true if a join instruction must be executed inside a loop * joinbb should post dominate the successive basic block of a loop header */ -bool TCT::isJoinMustExecutedInLoop(const LoopBBs& lp,const ICFGNode* join) +bool TCT::isJoinMustExecutedInLoop(const LoopBBs& lp, const ICFGNode* join) { assert(!lp.empty() && "this is not a loop, empty basic block"); const SVFFunction* svffun = join->getFun(); const SVFBasicBlock* loopheadbb = svffun->getLoopHeader(lp); const SVFBasicBlock* joinbb = join->getBB(); - assert(loopheadbb->getParent()==joinbb->getParent() && "should inside same function"); + assert(loopheadbb->getParent() == joinbb->getParent() && "should inside same function"); for (const SVFBasicBlock* svf_scc_bb : loopheadbb->getSuccessors()) { - if(svffun->loopContainsBB(lp,svf_scc_bb)) + if (svffun->loopContainsBB(lp, svf_scc_bb)) { - if(svffun->dominate(joinbb,svf_scc_bb)==false) - return false; + if (svffun->dominate(joinbb, svf_scc_bb) == false) return false; } } @@ -312,23 +304,23 @@ bool TCT::isJoinMustExecutedInLoop(const LoopBBs& lp,const ICFGNode* join) */ void TCT::collectLoopInfoForJoin() { - for(ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it!=eit; ++it) + for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; + ++it) { const ICFGNode* join = *it; const SVFFunction* svffun = join->getFun(); const SVFBasicBlock* svfbb = join->getBB(); - if(svffun->hasLoopInfo(svfbb)) + if (svffun->hasLoopInfo(svfbb)) { const LoopBBs& lp = svffun->getLoopInfo(svfbb); - if(!lp.empty() && isJoinMustExecutedInLoop(lp,join)) + if (!lp.empty() && isJoinMustExecutedInLoop(lp, join)) { joinSiteToLoopMap[join] = lp; } } - if(isInRecursion(join)) - inRecurJoinSites.insert(join); + if (isInRecursion(join)) inRecurJoinSites.insert(join); } } @@ -337,10 +329,9 @@ void TCT::collectLoopInfoForJoin() */ bool TCT::isLoopHeaderOfJoinLoop(const SVFBasicBlock* bb) { - for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it) + for (InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it != eit; ++it) { - if(bb->getParent()->getLoopHeader(it->second) == bb) - return true; + if (bb->getParent()->getLoopHeader(it->second) == bb) return true; } return false; @@ -351,16 +342,15 @@ bool TCT::isLoopHeaderOfJoinLoop(const SVFBasicBlock* bb) */ bool TCT::isLoopExitOfJoinLoop(const SVFBasicBlock* bb) { - for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it) + for (InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it != eit; ++it) { std::vector exitbbs; - it->first->getFun()->getExitBlocksOfLoop(it->first->getBB(),exitbbs); - while(!exitbbs.empty()) + it->first->getFun()->getExitBlocksOfLoop(it->first->getBB(), exitbbs); + while (!exitbbs.empty()) { const SVFBasicBlock* eb = exitbbs.back(); exitbbs.pop_back(); - if(eb == bb) - return true; + if (eb == bb) return true; } } @@ -391,38 +381,43 @@ void TCT::build() // start routine is empty collectEntryFunInCallGraph(); - for (FunSet::iterator it=entryFuncSet.begin(), eit=entryFuncSet.end(); it!=eit; ++it) + for (FunSet::iterator it = entryFuncSet.begin(), eit = entryFuncSet.end(); it != eit; ++it) { - if (!isCandidateFun(*it)) - continue; + if (!isCandidateFun(*it)) continue; CallStrCxt cxt; TCTNode* mainTCTNode = getOrCreateTCTNode(cxt, nullptr, cxt, *it); CxtThreadProc t(mainTCTNode->getId(), cxt, *it); pushToCTPWorkList(t); } - while(!ctpList.empty()) + while (!ctpList.empty()) { CxtThreadProc ctp = popFromCTPWorkList(); CallGraphNode* cgNode = tcg->getCallGraphNode(ctp.getProc()); - if(isCandidateFun(cgNode->getFunction()) == false) - continue; + if (isCandidateFun(cgNode->getFunction()) == false) continue; - for(CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit!=neit; nit++) + for (CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit != neit; + nit++) { const CallGraphEdge* cgEdge = (*nit); - for(CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(), - ecit = cgEdge->directCallsEnd(); cit!=ecit; ++cit) + for (CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(), + ecit = cgEdge->directCallsEnd(); + cit != ecit; ++cit) { - DBOUT(DMTA,outs() << "\nTCT handling direct call:" << **cit << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n"); - handleCallRelation(ctp,cgEdge,getSVFCallSite((*cit)->getCallSite())); + DBOUT(DMTA, outs() << "\nTCT handling direct call:" << **cit << "\t" + << cgEdge->getSrcNode()->getFunction()->getName() << "-->" + << cgEdge->getDstNode()->getFunction()->getName() << "\n"); + handleCallRelation(ctp, cgEdge, getSVFCallSite((*cit)->getCallSite())); } - for(CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(), - eind = cgEdge->indirectCallsEnd(); ind!=eind; ++ind) + for (CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(), + eind = cgEdge->indirectCallsEnd(); + ind != eind; ++ind) { - DBOUT(DMTA,outs() << "\nTCT handling indirect call:" << **ind << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n"); - handleCallRelation(ctp,cgEdge,getSVFCallSite((*ind)->getCallSite())); + DBOUT(DMTA, outs() << "\nTCT handling indirect call:" << **ind << "\t" + << cgEdge->getSrcNode()->getFunction()->getName() << "-->" + << cgEdge->getDstNode()->getFunction()->getName() << "\n"); + handleCallRelation(ctp, cgEdge, getSVFCallSite((*ind)->getCallSite())); } } } @@ -434,7 +429,6 @@ void TCT::build() print(); dump("tct"); } - } /*! @@ -447,17 +441,15 @@ void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* CallSiteID csId = tcg->getCallSiteID(call, callee); /// handle calling context for candidate functions only - if(isCandidateFun(caller) == false) - return; + if (isCandidateFun(caller) == false) return; - if(inSameCallGraphSCC(tcg->getCallGraphNode(caller),tcg->getCallGraphNode(callee))==false) + if (inSameCallGraphSCC(tcg->getCallGraphNode(caller), tcg->getCallGraphNode(callee)) == false) { - pushCxt(cxt,csId); - DBOUT(DMTA,dumpCxt(cxt)); + pushCxt(cxt, csId); + DBOUT(DMTA, dumpCxt(cxt)); } } - /*! * Match calling context */ @@ -468,26 +460,22 @@ bool TCT::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* CallSiteID csId = tcg->getCallSiteID(call, callee); /// handle calling context for candidate functions only - if(isCandidateFun(caller) == false) - return true; + if (isCandidateFun(caller) == false) return true; /// partial match - if(cxt.empty()) - return true; + if (cxt.empty()) return true; - if(inSameCallGraphSCC(tcg->getCallGraphNode(caller),tcg->getCallGraphNode(callee))==false) + if (inSameCallGraphSCC(tcg->getCallGraphNode(caller), tcg->getCallGraphNode(callee)) == false) { - if(cxt.back() == csId) - cxt.pop_back(); + if (cxt.back() == csId) cxt.pop_back(); else return false; - DBOUT(DMTA,dumpCxt(cxt)); + DBOUT(DMTA, dumpCxt(cxt)); } return true; } - /*! * Dump calling context information */ @@ -496,11 +484,12 @@ void TCT::dumpCxt(CallStrCxt& cxt) std::string str; std::stringstream rawstr(str); rawstr << "[:"; - for(CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it!=eit; ++it) + for (CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it != eit; ++it) { - rawstr << " ' "<< *it << " ' "; + rawstr << " ' " << *it << " ' "; rawstr << tcg->getCallSite(*it)->getCallSite()->toString(); - rawstr << " call " << tcg->getCallSite(*it)->getCaller()->getName() << "-->" << tcg->getCalleeOfCallSite(*it)->getName() << ", \n"; + rawstr << " call " << tcg->getCallSite(*it)->getCaller()->getName() << "-->" + << tcg->getCalleeOfCallSite(*it)->getName() << ", \n"; } rawstr << " ]"; outs() << "max cxt = " << cxt.size() << rawstr.str() << "\n"; @@ -511,8 +500,7 @@ void TCT::dumpCxt(CallStrCxt& cxt) */ void TCT::dump(const std::string& filename) { - if (Options::TCTDotGraph()) - GraphPrinter::WriteGraphToFile(outs(), filename, this); + if (Options::TCTDotGraph()) GraphPrinter::WriteGraphToFile(outs(), filename, this); } /*! @@ -520,7 +508,7 @@ void TCT::dump(const std::string& filename) */ void TCT::print() const { - for(TCT::const_iterator it = this->begin(), eit = this->end(); it!=eit; ++it) + for (TCT::const_iterator it = this->begin(), eit = this->end(); it != eit; ++it) { outs() << "TID " << it->first << "\t"; it->second->getCxtThread().dump(); @@ -552,8 +540,7 @@ TCTEdge* TCT::getGraphEdge(TCTNode* src, TCTNode* dst, TCTEdge::CEDGEK kind) for (TCTEdge::ThreadCreateEdgeSet::const_iterator iter = src->OutEdgeBegin(); iter != src->OutEdgeEnd(); ++iter) { TCTEdge* edge = (*iter); - if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId()) - return edge; + if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId()) return edge; } return nullptr; } @@ -563,29 +550,25 @@ namespace SVF /*! * Write value flow graph into dot file for debugging */ -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits +template <> struct DOTGraphTraits : public DefaultDOTGraphTraits { typedef TCTNode NodeType; typedef NodeType::iterator ChildIteratorType; - DOTGraphTraits(bool isSimple = false) : - DefaultDOTGraphTraits(isSimple) - { - } + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} /// Return name of the graph - static std::string getGraphName(TCT *graph) + static std::string getGraphName(TCT* graph) { return "Thread Create Tree"; } /// Return function name; - static std::string getNodeLabel(TCTNode *node, TCT *graph) + static std::string getNodeLabel(TCTNode* node, TCT* graph) { return std::to_string(node->getId()); } - static std::string getNodeAttributes(TCTNode *node, TCT *tct) + static std::string getNodeAttributes(TCTNode* node, TCT* tct) { std::string attr; if (node->isInloop()) @@ -599,8 +582,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return attr; } - template - static std::string getEdgeAttributes(TCTNode *node, EdgeIter EI, TCT *csThreadTree) + template static std::string getEdgeAttributes(TCTNode* node, EdgeIter EI, TCT* csThreadTree) { TCTEdge* edge = csThreadTree->getGraphEdge(node, *EI, TCTEdge::ThreadCreateEdge); @@ -610,5 +592,4 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits return "color=black"; } }; -} // End namespace llvm - +} // namespace SVF diff --git a/svf/lib/MemoryModel/AccessPath.cpp b/svf/lib/MemoryModel/AccessPath.cpp index be763bbfd..19ad646d3 100644 --- a/svf/lib/MemoryModel/AccessPath.cpp +++ b/svf/lib/MemoryModel/AccessPath.cpp @@ -48,10 +48,9 @@ bool AccessPath::addOffsetVarAndGepTypePair(const SVFVar* var, const SVFType* ge /// Return true if all offset values are constants bool AccessPath::isConstantOffset() const { - for(auto it : idxOperandPairs) + for (auto it : idxOperandPairs) { - if(SVFUtil::isa(it.first->getValue()) == false) - return false; + if (SVFUtil::isa(it.first->getValue()) == false) return false; } return true; } @@ -89,7 +88,6 @@ u32_t AccessPath::getElementNum(const SVFType* type) const } } - /// Return byte offset from the beginning of the structure to the field where it is located for struct type /// // e.g. idxOperandVar: i32 2 idxOperandType: %struct.Student = type { i32, [i8 x 12], i32 } @@ -99,9 +97,9 @@ u32_t AccessPath::getStructFieldOffset(const SVFVar* idxOperandVar, const SVFStr { const SVFValue* idxValue = idxOperandVar->getValue(); u32_t structByteOffset = 0; - if (const SVFConstantInt *op = SVFUtil::dyn_cast(idxValue)) + if (const SVFConstantInt* op = SVFUtil::dyn_cast(idxValue)) { - for (u32_t structField = 0; structField < (u32_t) op->getSExtValue(); ++structField) + for (u32_t structField = 0; structField < (u32_t)op->getSExtValue(); ++structField) { u32_t flattenIdx = idxOperandType->getTypeInfo()->getFlattenedFieldIdxVec()[structField]; structByteOffset += idxOperandType->getTypeInfo()->getOriginalElemType(flattenIdx)->getByteSize(); @@ -121,13 +119,14 @@ u32_t AccessPath::getStructFieldOffset(const SVFVar* idxOperandVar, const SVFStr /// "type" is the location where we want to compute offset /// Given a vector and elem byte size: [(value1,type1), (value2,type2), (value3,type3)], bytesize /// totalConstByteOffset = ByteOffset(value1,type1) * ByteOffset(value2,type2) + ByteOffset(value3,type3) -/// For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., getElementNum(t1) X off1 +/// For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., +/// getElementNum(t1) X off1 APOffset AccessPath::computeConstantByteOffset() const { assert(isConstantOffset() && "not a constant offset"); APOffset totalConstOffset = 0; - for(int i = idxOperandPairs.size() - 1; i >= 0; i--) + for (int i = idxOperandPairs.size() - 1; i >= 0; i--) { /// For example, there is struct DEST{int a, char b[10], int c[5]} /// (1) %c = getelementptr inbounds %struct.DEST, %struct.DEST* %arr, i32 0, i32 2 @@ -178,7 +177,7 @@ APOffset AccessPath::computeConstantByteOffset() const totalConstOffset += op->getSExtValue() * type2->getByteSize(); } } - totalConstOffset = Options::MaxFieldLimit() > totalConstOffset? totalConstOffset: Options::MaxFieldLimit(); + totalConstOffset = Options::MaxFieldLimit() > totalConstOffset ? totalConstOffset : Options::MaxFieldLimit(); return totalConstOffset; } @@ -188,7 +187,8 @@ APOffset AccessPath::computeConstantByteOffset() const /// "type" is the location where we want to compute offset /// Given a vector: [(value1,type1), (value2,type2), (value3,type3)] /// totalConstOffset = flattenOffset(value1,type1) * flattenOffset(value2,type2) + flattenOffset(value3,type3) -/// For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., getElementNum(t1) X off1 +/// For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., +/// getElementNum(t1) X off1 /// For example, // struct inner{ int rollNumber; float percentage;}; @@ -216,31 +216,30 @@ APOffset AccessPath::computeConstantOffset() const assert(isConstantOffset() && "not a constant offset"); APOffset totalConstOffset = 0; - //After the model-const and model-array options are turned on, - // the gepstmt offset generated by the array on the global - // node will be saved in getConstantStructFldIdx - if (idxOperandPairs.size() == 0) - return getConstantStructFldIdx(); - for(int i = idxOperandPairs.size() - 1; i >= 0; i--) + // After the model-const and model-array options are turned on, + // the gepstmt offset generated by the array on the global + // node will be saved in getConstantStructFldIdx + if (idxOperandPairs.size() == 0) return getConstantStructFldIdx(); + for (int i = idxOperandPairs.size() - 1; i >= 0; i--) { const SVFValue* value = idxOperandPairs[i].first->getValue(); const SVFType* type = idxOperandPairs[i].second; const SVFConstantInt* op = SVFUtil::dyn_cast(value); assert(op && "not a constant offset?"); - if(type==nullptr) + if (type == nullptr) { totalConstOffset += op->getSExtValue(); continue; } - if(SVFUtil::isa(type)) - totalConstOffset += op->getSExtValue() * getElementNum(gepPointeeType); + if (SVFUtil::isa(type)) totalConstOffset += op->getSExtValue() * getElementNum(gepPointeeType); else { APOffset offset = op->getSExtValue(); if (offset >= 0) { - const std::vector& so = SymbolTableInfo::SymbolInfo()->getTypeInfo(type)->getFlattenedElemIdxVec(); + const std::vector& so = + SymbolTableInfo::SymbolInfo()->getTypeInfo(type)->getFlattenedElemIdxVec(); // if offset is larger than the size of getFlattenedElemIdxVec (overflow) // set offset the last index of getFlattenedElemIdxVec to avoid assertion if (offset >= (APOffset)so.size()) @@ -250,12 +249,9 @@ APOffset AccessPath::computeConstantOffset() const } else { - } - u32_t flattenOffset = - SymbolTableInfo::SymbolInfo()->getFlattenedElemIdx(type, - offset); + u32_t flattenOffset = SymbolTableInfo::SymbolInfo()->getFlattenedElemIdx(type, offset); totalConstOffset += flattenOffset; } } @@ -277,22 +273,19 @@ AccessPath AccessPath::operator+(const AccessPath& rhs) const assert(gepPointeeType == rhs.gepSrcPointeeType() && "source element type not match"); AccessPath ap(rhs); ap.fldIdx += getConstantStructFldIdx(); - for (auto &p : ap.getIdxOperandPairVec()) - ap.addOffsetVarAndGepTypePair(p.first, p.second); + for (auto& p : ap.getIdxOperandPairVec()) ap.addOffsetVarAndGepTypePair(p.first, p.second); return ap; } -bool AccessPath::operator< (const AccessPath& rhs) const +bool AccessPath::operator<(const AccessPath& rhs) const { - if (fldIdx != rhs.fldIdx) - return (fldIdx < rhs.fldIdx); + if (fldIdx != rhs.fldIdx) return (fldIdx < rhs.fldIdx); else { const IdxOperandPairs& pairVec = getIdxOperandPairVec(); const IdxOperandPairs& rhsPairVec = rhs.getIdxOperandPairVec(); - if (pairVec.size() != rhsPairVec.size()) - return (pairVec.size() < rhsPairVec.size()); + if (pairVec.size() != rhsPairVec.size()) return (pairVec.size() < rhsPairVec.size()); else { IdxOperandPairs::const_iterator it = pairVec.begin(); @@ -313,8 +306,7 @@ SVF::AccessPath::LSRelation AccessPath::checkRelation(const AccessPath& LHS, con NodeBS rhsLocations = RHS.computeAllLocations(); if (lhsLocations.intersects(rhsLocations)) { - if (lhsLocations == rhsLocations) - return Same; + if (lhsLocations == rhsLocations) return Same; else if (lhsLocations.contains(rhsLocations)) return Superset; else if (rhsLocations.contains(lhsLocations)) diff --git a/svf/lib/MemoryModel/PointerAnalysis.cpp b/svf/lib/MemoryModel/PointerAnalysis.cpp index ac818f345..db106dea5 100644 --- a/svf/lib/MemoryModel/PointerAnalysis.cpp +++ b/svf/lib/MemoryModel/PointerAnalysis.cpp @@ -46,27 +46,27 @@ using namespace SVF; using namespace SVFUtil; - SVFIR* PointerAnalysis::pag = nullptr; -const std::string PointerAnalysis::aliasTestMayAlias = "MAYALIAS"; -const std::string PointerAnalysis::aliasTestMayAliasMangled = "_Z8MAYALIASPvS_"; -const std::string PointerAnalysis::aliasTestNoAlias = "NOALIAS"; -const std::string PointerAnalysis::aliasTestNoAliasMangled = "_Z7NOALIASPvS_"; -const std::string PointerAnalysis::aliasTestPartialAlias = "PARTIALALIAS"; +const std::string PointerAnalysis::aliasTestMayAlias = "MAYALIAS"; +const std::string PointerAnalysis::aliasTestMayAliasMangled = "_Z8MAYALIASPvS_"; +const std::string PointerAnalysis::aliasTestNoAlias = "NOALIAS"; +const std::string PointerAnalysis::aliasTestNoAliasMangled = "_Z7NOALIASPvS_"; +const std::string PointerAnalysis::aliasTestPartialAlias = "PARTIALALIAS"; const std::string PointerAnalysis::aliasTestPartialAliasMangled = "_Z12PARTIALALIASPvS_"; -const std::string PointerAnalysis::aliasTestMustAlias = "MUSTALIAS"; -const std::string PointerAnalysis::aliasTestMustAliasMangled = "_Z9MUSTALIASPvS_"; -const std::string PointerAnalysis::aliasTestFailMayAlias = "EXPECTEDFAIL_MAYALIAS"; +const std::string PointerAnalysis::aliasTestMustAlias = "MUSTALIAS"; +const std::string PointerAnalysis::aliasTestMustAliasMangled = "_Z9MUSTALIASPvS_"; +const std::string PointerAnalysis::aliasTestFailMayAlias = "EXPECTEDFAIL_MAYALIAS"; const std::string PointerAnalysis::aliasTestFailMayAliasMangled = "_Z21EXPECTEDFAIL_MAYALIASPvS_"; -const std::string PointerAnalysis::aliasTestFailNoAlias = "EXPECTEDFAIL_NOALIAS"; -const std::string PointerAnalysis::aliasTestFailNoAliasMangled = "_Z20EXPECTEDFAIL_NOALIASPvS_"; +const std::string PointerAnalysis::aliasTestFailNoAlias = "EXPECTEDFAIL_NOALIAS"; +const std::string PointerAnalysis::aliasTestFailNoAliasMangled = "_Z20EXPECTEDFAIL_NOALIASPvS_"; /*! * Constructor */ -PointerAnalysis::PointerAnalysis(SVFIR* p, PTATY ty, bool alias_check) : - svfMod(nullptr),ptaTy(ty),stat(nullptr),callgraph(nullptr),callGraphSCC(nullptr),icfg(nullptr),chgraph(nullptr) +PointerAnalysis::PointerAnalysis(SVFIR* p, PTATY ty, bool alias_check) + : svfMod(nullptr), ptaTy(ty), stat(nullptr), callgraph(nullptr), callGraphSCC(nullptr), icfg(nullptr), + chgraph(nullptr) { pag = p; OnTheFlyIterBudgetForStat = Options::StatBudget(); @@ -82,10 +82,9 @@ PointerAnalysis::~PointerAnalysis() { destroy(); // do not delete the SVFIR for now - //delete pag; + // delete pag; } - void PointerAnalysis::destroy() { delete callgraph; @@ -109,7 +108,7 @@ void PointerAnalysis::initialize() chgraph = pag->getCHG(); /// initialise pta call graph for every pointer analysis instance - if(Options::EnableThreadCallGraph()) + if (Options::EnableThreadCallGraph()) { ThreadCallGraph* cg = new ThreadCallGraph(); ThreadCallGraphBuilder bd(cg, pag->getICFG()); @@ -118,17 +117,15 @@ void PointerAnalysis::initialize() else { CallGraph* cg = new CallGraph(); - CallGraphBuilder bd(cg,pag->getICFG()); + CallGraphBuilder bd(cg, pag->getICFG()); callgraph = bd.buildCallGraph(pag->getModule()); } callGraphSCCDetection(); // dump callgraph - if (Options::CallGraphDotGraph()) - getCallGraph()->dump("callgraph_initial"); + if (Options::CallGraphDotGraph()) getCallGraph()->dump("callgraph_initial"); } - /*! * Return TRUE if this node is a local variable of recursive function. */ @@ -136,9 +133,9 @@ bool PointerAnalysis::isLocalVarInRecursiveFun(NodeID id) const { const MemObj* obj = pag->getObject(id); assert(obj && "object not found!!"); - if(obj->isStack()) + if (obj->isStack()) { - if(const SVFFunction* svffun = pag->getGNode(id)->getFunction()) + if (const SVFFunction* svffun = pag->getGNode(id)->getFunction()) { return callGraphSCC->isInCycle(getCallGraph()->getCallGraphNode(svffun)->getId()); } @@ -153,7 +150,7 @@ void PointerAnalysis::resetObjFieldSensitive() { for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter) { - if(ObjVar* node = SVFUtil::dyn_cast(nIter->second)) + if (ObjVar* node = SVFUtil::dyn_cast(nIter->second)) const_cast(node->getMemObj())->setFieldSensitive(); } } @@ -165,7 +162,7 @@ void PointerAnalysis::resetObjFieldSensitive() void PointerAnalysis::dumpStat() { - if(print_stat && stat) + if (print_stat && stat) { stat->performStat(); } @@ -185,29 +182,23 @@ void PointerAnalysis::finalize() if (Options::PTSPrint()) { dumpTopLevelPtsTo(); - //dumpAllPts(); - //dumpCPts(); + // dumpAllPts(); + // dumpCPts(); } - if (Options::TypePrint()) - dumpAllTypes(); + if (Options::TypePrint()) dumpAllTypes(); - if(Options::PTSAllPrint()) - dumpAllPts(); + if (Options::PTSAllPrint()) dumpAllPts(); - if (Options::FuncPointerPrint()) - printIndCSTargets(); + if (Options::FuncPointerPrint()) printIndCSTargets(); getCallGraph()->verifyCallGraph(); - if (Options::CallGraphDotGraph()) - getCallGraph()->dump("callgraph_final"); + if (Options::CallGraphDotGraph()) getCallGraph()->dump("callgraph_final"); - if(!pag->isBuiltFromFile() && alias_validation) - validateTests(); + if (!pag->isBuiltFromFile() && alias_validation) validateTests(); - if (!Options::UsePreCompFieldSensitive()) - resetObjFieldSensitive(); + if (!Options::UsePreCompFieldSensitive()) resetObjFieldSensitive(); } /*! @@ -230,15 +221,13 @@ void PointerAnalysis::validateTests() validateExpectedFailureTests(aliasTestFailNoAliasMangled); } - void PointerAnalysis::dumpAllTypes() { - for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); - nIter != this->getAllValidPtrs().end(); ++nIter) + for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); nIter != this->getAllValidPtrs().end(); + ++nIter) { const PAGNode* node = getPAG()->getGNode(*nIter); - if (SVFUtil::isa(node)) - continue; + if (SVFUtil::isa(node)) continue; outs() << "##<" << node->getValue()->getName() << "> "; outs() << "Source Loc: " << node->getValue()->getSourceLoc(); @@ -257,7 +246,7 @@ void PointerAnalysis::dumpPts(NodeID ptr, const PointsTo& pts) const PAGNode* node = pag->getGNode(ptr); /// print the points-to set of node which has the maximum pts size. - if (SVFUtil::isa (node)) + if (SVFUtil::isa(node)) { outs() << "## id:" << node->getId(); } @@ -278,9 +267,7 @@ void PointerAnalysis::dumpPts(NodeID ptr, const PointsTo& pts) else { outs() << "\t\tPointsTo: { "; - for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; - ++it) - outs() << *it << " "; + for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) outs() << *it << " "; outs() << "}\n\n"; } @@ -289,13 +276,11 @@ void PointerAnalysis::dumpPts(NodeID ptr, const PointsTo& pts) for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) { const PAGNode* node = pag->getGNode(*it); - if(SVFUtil::isa(node) == false) - continue; + if (SVFUtil::isa(node) == false) continue; NodeID ptd = node->getId(); outs() << "!!Target NodeID " << ptd << "\t ["; const PAGNode* pagNode = pag->getGNode(ptd); - if (SVFUtil::isa(node)) - outs() << "DummyVal\n"; + if (SVFUtil::isa(node)) outs() << "DummyVal\n"; else if (SVFUtil::isa(node)) outs() << "Dummy Obj id: " << node->getId() << "]\n"; else @@ -305,8 +290,7 @@ void PointerAnalysis::dumpPts(NodeID ptr, const PointsTo& pts) if (node->hasValue()) { outs() << "<" << pagNode->getValue()->getName() << "> "; - outs() << "Source Loc: " - << pagNode->getValue()->getSourceLoc() << "] \n"; + outs() << "Source Loc: " << pagNode->getValue()->getSourceLoc() << "] \n"; } } } @@ -375,8 +359,6 @@ void PointerAnalysis::printIndCSTargets() } } - - /*! * Resolve indirect calls */ @@ -385,29 +367,27 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta assert(pag->isIndirectCallSites(cs) && "not an indirect callsite?"); /// discover indirect pointer target - for (PointsTo::iterator ii = target.begin(), ie = target.end(); - ii != ie; ii++) + for (PointsTo::iterator ii = target.begin(), ie = target.end(); ii != ie; ii++) { - if(getNumOfResolvedIndCallEdge() >= Options::IndirectCallLimit()) + if (getNumOfResolvedIndCallEdge() >= Options::IndirectCallLimit()) { wrnMsg("Resolved Indirect Call Edges are Out-Of-Budget, please increase the limit"); return; } - if(ObjVar* objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) + if (ObjVar* objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) { const MemObj* obj = pag->getObject(objPN); - if(obj->isFunction()) + if (obj->isFunction()) { const SVFFunction* calleefun = SVFUtil::cast(obj->getValue()); const SVFFunction* callee = calleefun->getDefFunForMultipleModule(); - if(SVFUtil::matchArgs(cs->getCallSite(), callee) == false) - continue; + if (SVFUtil::matchArgs(cs->getCallSite(), callee) == false) continue; - if(0 == getIndCallMap()[cs].count(callee)) + if (0 == getIndCallMap()[cs].count(callee)) { newEdges[cs].insert(callee); getIndCallMap()[cs].insert(callee); @@ -415,8 +395,8 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta callgraph->addIndirectCallGraphEdge(cs, cs->getCaller(), callee); // FIXME: do we need to update llvm call graph here? // The indirect call is maintained by ourself, We may update llvm's when we need to - //CallGraphNode* callgraphNode = callgraph->getOrInsertFunction(cs.getCaller()); - //callgraphNode->addCalledFunction(cs,callgraph->getOrInsertFunction(callee)); + // CallGraphNode* callgraphNode = callgraph->getOrInsertFunction(cs.getCaller()); + // callgraphNode->addCalledFunction(cs,callgraph->getOrInsertFunction(callee)); } } } @@ -426,7 +406,7 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta /* * Get virtual functions "vfns" based on CHA */ -void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns) +void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet& vfns) { if (chgraph->csHasVFnsBasedonCHA(SVFUtil::getSVFCallSite(cs->getCallSite()))) vfns = chgraph->getCSVFsBasedonCHA(SVFUtil::getSVFCallSite(cs->getCallSite())); @@ -435,22 +415,21 @@ void PointerAnalysis::getVFnsFromCHA(const CallICFGNode* cs, VFunSet &vfns) /* * Get virtual functions "vfns" from PoninsTo set "target" for callsite "cs" */ -void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &target, VFunSet &vfns) +void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo& target, VFunSet& vfns) { if (chgraph->csHasVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs->getCallSite()))) { Set vtbls; - const VTableSet &chaVtbls = chgraph->getCSVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs->getCallSite())); + const VTableSet& chaVtbls = chgraph->getCSVtblsBasedonCHA(SVFUtil::getSVFCallSite(cs->getCallSite())); for (PointsTo::iterator it = target.begin(), eit = target.end(); it != eit; ++it) { - const PAGNode *ptdnode = pag->getGNode(*it); + const PAGNode* ptdnode = pag->getGNode(*it); if (ptdnode->hasValue()) { - if (const SVFGlobalValue *vtbl = SVFUtil::dyn_cast(ptdnode->getValue())) + if (const SVFGlobalValue* vtbl = SVFUtil::dyn_cast(ptdnode->getValue())) { - if (chaVtbls.find(vtbl) != chaVtbls.end()) - vtbls.insert(vtbl); + if (chaVtbls.find(vtbl) != chaVtbls.end()) vtbls.insert(vtbl); } } } @@ -461,23 +440,21 @@ void PointerAnalysis::getVFnsFromPts(const CallICFGNode* cs, const PointsTo &tar /* * Connect callsite "cs" to virtual functions in "vfns" */ -void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &vfns, CallEdgeMap& newEdges) +void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet& vfns, CallEdgeMap& newEdges) { //// connect all valid functions - for (VFunSet::const_iterator fit = vfns.begin(), - feit = vfns.end(); fit != feit; ++fit) + for (VFunSet::const_iterator fit = vfns.begin(), feit = vfns.end(); fit != feit; ++fit) { const SVFFunction* callee = *fit; callee = callee->getDefFunForMultipleModule(); - if (getIndCallMap()[cs].count(callee) > 0) - continue; - if(SVFUtil::getSVFCallSite(cs->getCallSite()).arg_size() == callee->arg_size() || - (SVFUtil::getSVFCallSite(cs->getCallSite()).isVarArg() && callee->isVarArg())) + if (getIndCallMap()[cs].count(callee) > 0) continue; + if (SVFUtil::getSVFCallSite(cs->getCallSite()).arg_size() == callee->arg_size() || + (SVFUtil::getSVFCallSite(cs->getCallSite()).isVarArg() && callee->isVarArg())) { newEdges[cs].insert(callee); getIndCallMap()[cs].insert(callee); const CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(cs->getCallSite()); - callgraph->addIndirectCallGraphEdge(callBlockNode, cs->getCaller(),callee); + callgraph->addIndirectCallGraphEdge(callBlockNode, cs->getCaller(), callee); } } } @@ -488,8 +465,7 @@ void PointerAnalysis::resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& assert(SVFUtil::getSVFCallSite(cs->getCallSite()).isVirtualCall() && "not cpp virtual call"); VFunSet vfns; - if (Options::ConnectVCallOnCHA()) - getVFnsFromCHA(cs, vfns); + if (Options::ConnectVCallOnCHA()) getVFnsFromCHA(cs, vfns); else getVFnsFromPts(cs, target, vfns); connectVCallToVFns(cs, vfns, newEdges); @@ -504,18 +480,16 @@ void PointerAnalysis::validateSuccessTests(std::string fun) // check for must alias cases, whether our alias analysis produce the correct results if (const SVFFunction* checkFun = svfMod->getSVFFunction(fun)) { - if(!checkFun->isUncalledFunction()) - outs() << "[" << this->PTAName() << "] Checking " << fun << "\n"; + if (!checkFun->isUncalledFunction()) outs() << "[" << this->PTAName() << "] Checking " << fun << "\n"; - for(const CallICFGNode* callNode : pag->getCallSiteSet()) + for (const CallICFGNode* callNode : pag->getCallSiteSet()) { const SVFInstruction* svfInst = callNode->getCallSite(); if (SVFUtil::getCallee(svfInst) == checkFun) { CallSite cs(svfInst); - assert(cs.getNumArgOperands() == 2 - && "arguments should be two pointers!!"); + assert(cs.getNumArgOperands() == 2 && "arguments should be two pointers!!"); const SVFValue* V1 = cs.getArgOperand(0); const SVFValue* V2 = cs.getArgOperand(1); AliasResult aliasRes = alias(V1, V2); @@ -523,25 +497,21 @@ void PointerAnalysis::validateSuccessTests(std::string fun) bool checkSuccessful = false; if (fun == aliasTestMayAlias || fun == aliasTestMayAliasMangled) { - if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::MustAlias) - checkSuccessful = true; + if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::MustAlias) checkSuccessful = true; } else if (fun == aliasTestNoAlias || fun == aliasTestNoAliasMangled) { - if (aliasRes == AliasResult::NoAlias) - checkSuccessful = true; + if (aliasRes == AliasResult::NoAlias) checkSuccessful = true; } else if (fun == aliasTestMustAlias || fun == aliasTestMustAliasMangled) { // change to must alias when our analysis support it - if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::MustAlias) - checkSuccessful = true; + if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::MustAlias) checkSuccessful = true; } else if (fun == aliasTestPartialAlias || fun == aliasTestPartialAliasMangled) { // change to partial alias when our analysis support it - if (aliasRes == AliasResult::MayAlias) - checkSuccessful = true; + if (aliasRes == AliasResult::MayAlias) checkSuccessful = true; } else assert(false && "not supported alias check!!"); @@ -554,8 +524,7 @@ void PointerAnalysis::validateSuccessTests(std::string fun) << svfInst->getSourceLoc() << ")\n"; else { - SVFUtil::errs() << errMsg("\t FAILURE :") << fun - << " check at (" << svfInst->getSourceLoc() << ")\n"; assert(false && "test case failed!"); } @@ -572,17 +541,15 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun) if (const SVFFunction* checkFun = svfMod->getSVFFunction(fun)) { - if(!checkFun->isUncalledFunction()) - outs() << "[" << this->PTAName() << "] Checking " << fun << "\n"; + if (!checkFun->isUncalledFunction()) outs() << "[" << this->PTAName() << "] Checking " << fun << "\n"; - for(const CallICFGNode* callNode : pag->getCallSiteSet()) + for (const CallICFGNode* callNode : pag->getCallSiteSet()) { const SVFInstruction* svfInst = callNode->getCallSite(); if (SVFUtil::getCallee(svfInst) == checkFun) { CallSite call = getSVFCallSite(svfInst); - assert(call.arg_size() == 2 - && "arguments should be two pointers!!"); + assert(call.arg_size() == 2 && "arguments should be two pointers!!"); const SVFValue* V1 = call.getArgOperand(0); const SVFValue* V2 = call.getArgOperand(1); AliasResult aliasRes = alias(V1, V2); @@ -591,13 +558,13 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun) if (fun == aliasTestFailMayAlias || fun == aliasTestFailMayAliasMangled) { // change to must alias when our analysis support it - if (aliasRes == AliasResult::NoAlias) - expectedFailure = true; + if (aliasRes == AliasResult::NoAlias) expectedFailure = true; } else if (fun == aliasTestFailNoAlias || fun == aliasTestFailNoAliasMangled) { // change to partial alias when our analysis support it - if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::PartialAlias || aliasRes == AliasResult::MustAlias) + if (aliasRes == AliasResult::MayAlias || aliasRes == AliasResult::PartialAlias || + aliasRes == AliasResult::MustAlias) expectedFailure = true; } else @@ -607,12 +574,12 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun) NodeID id2 = pag->getValueNode(V2); if (expectedFailure) - outs() << sucMsg("\t EXPECTED-FAILURE :") << fun << " check at (" - << call.getInstruction()->getSourceLoc() << ")\n"; + outs() << sucMsg("\t EXPECTED-FAILURE :") << fun << " check at (" << call.getInstruction()->getSourceLoc() << ")\n"; else { - SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << fun << " check at (" - << call.getInstruction()->getSourceLoc() << ")\n"; + SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << fun << " check at (" << call.getInstruction()->getSourceLoc() << ")\n"; assert(false && "test case failed!"); } } diff --git a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp index de0ccd365..f58399750 100644 --- a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +++ b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * PointerAnalysisImpl.cpp * @@ -28,7 +27,6 @@ * Author: yulei */ - #include "MemoryModel/PointerAnalysisImpl.h" #include "Util/Options.h" #include @@ -41,49 +39,60 @@ using namespace std; /*! * Constructor */ -BVDataPTAImpl::BVDataPTAImpl(SVFIR* p, PointerAnalysis::PTATY type, bool alias_check) : - PointerAnalysis(p, type, alias_check), ptCache() +BVDataPTAImpl::BVDataPTAImpl(SVFIR* p, PointerAnalysis::PTATY type, bool alias_check) + : PointerAnalysis(p, type, alias_check), ptCache() { - if (type == Andersen_BASE || type == Andersen_WPA || type == AndersenWaveDiff_WPA - || type == TypeCPP_WPA || type == FlowS_DDA - || type == AndersenSCD_WPA || type == AndersenSFR_WPA || type == CFLFICI_WPA || type == CFLFSCS_WPA) + if (type == Andersen_BASE || type == Andersen_WPA || type == AndersenWaveDiff_WPA || type == TypeCPP_WPA || + type == FlowS_DDA || type == AndersenSCD_WPA || type == AndersenSFR_WPA || type == CFLFICI_WPA || + type == CFLFSCS_WPA) { // Only maintain reverse points-to when the analysis is field-sensitive, as objects turning // field-insensitive is all it is used for. bool maintainRevPts = Options::MaxFieldLimit() != 0; if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique(maintainRevPts); - else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique(getPtCache(), maintainRevPts); - else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); + else if (Options::ptDataBacking() == PTBackingType::Persistent) + ptD = std::make_unique(getPtCache(), maintainRevPts); + else + assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); } else if (type == Steensgaard_WPA) { // Steensgaard is only field-insensitive (for now?), so no reverse points-to. if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique(false); - else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique(getPtCache(), false); - else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); + else if (Options::ptDataBacking() == PTBackingType::Persistent) + ptD = std::make_unique(getPtCache(), false); + else + assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); } else if (type == FSSPARSE_WPA) { if (Options::INCDFPTData()) { if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique(false); - else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique(getPtCache(), false); - else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); + else if (Options::ptDataBacking() == PTBackingType::Persistent) + ptD = std::make_unique(getPtCache(), false); + else + assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); } else { if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique(false); - else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique(getPtCache(), false); - else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); + else if (Options::ptDataBacking() == PTBackingType::Persistent) + ptD = std::make_unique(getPtCache(), false); + else + assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); } } else if (type == VFS_WPA) { if (Options::ptDataBacking() == PTBackingType::Mutable) ptD = std::make_unique(false); - else if (Options::ptDataBacking() == PTBackingType::Persistent) ptD = std::make_unique(getPtCache(), false); - else assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); + else if (Options::ptDataBacking() == PTBackingType::Persistent) + ptD = std::make_unique(getPtCache(), false); + else + assert(false && "BVDataPTAImpl::BVDataPTAImpl: unexpected points-to backing type!"); } - else assert(false && "no points-to data available"); + else + assert(false && "no points-to data available"); ptaImplTy = BVDataImpl; } @@ -96,21 +105,19 @@ void BVDataPTAImpl::finalize() if (Options::ptDataBacking() == PTBackingType::Persistent && print_stat) { std::string moduleName(pag->getModule()->getModuleIdentifier()); - std::vector names = SVFUtil::split(moduleName,'/'); - if (names.size() > 1) - moduleName = names[names.size() - 1]; + std::vector names = SVFUtil::split(moduleName, '/'); + if (names.size() > 1) moduleName = names[names.size() - 1]; std::string subtitle; - if(ptaTy >= Andersen_BASE && ptaTy <= Steensgaard_WPA) - subtitle = "Andersen's analysis bitvector"; - else if(ptaTy >=FSDATAFLOW_WPA && ptaTy <=FSCS_WPA) + if (ptaTy >= Andersen_BASE && ptaTy <= Steensgaard_WPA) subtitle = "Andersen's analysis bitvector"; + else if (ptaTy >= FSDATAFLOW_WPA && ptaTy <= FSCS_WPA) subtitle = "flow-sensitive analysis bitvector"; - else if(ptaTy >=CFLFICI_WPA && ptaTy <=CFLFSCS_WPA) + else if (ptaTy >= CFLFICI_WPA && ptaTy <= CFLFSCS_WPA) subtitle = "CFL analysis bitvector"; - else if(ptaTy == TypeCPP_WPA) + else if (ptaTy == TypeCPP_WPA) subtitle = "Type analysis bitvector"; - else if(ptaTy >=FieldS_DDA && ptaTy <=Cxt_DDA) + else if (ptaTy >= FieldS_DDA && ptaTy <= Cxt_DDA) subtitle = "DDA bitvector"; else subtitle = "bitvector"; @@ -122,7 +129,6 @@ void BVDataPTAImpl::finalize() SVFUtil::outs() << "#######################################################" << std::endl; SVFUtil::outs().flush(); } - } /*! @@ -130,8 +136,9 @@ void BVDataPTAImpl::finalize() */ void BVDataPTAImpl::expandFIObjs(const PointsTo& pts, PointsTo& expandedPts) { - expandedPts = pts;; - for(PointsTo::iterator pit = pts.begin(), epit = pts.end(); pit!=epit; ++pit) + expandedPts = pts; + ; + for (PointsTo::iterator pit = pts.begin(), epit = pts.end(); pit != epit; ++pit) { if (pag->getBaseObjVar(*pit) == *pit || isFieldInsensitive(*pit)) { @@ -189,8 +196,6 @@ void BVDataPTAImpl::writeObjVarToFile(const string& filename) outs() << "\n"; return; } - - } void BVDataPTAImpl::writePtsResultToFile(std::fstream& f) @@ -199,7 +204,7 @@ void BVDataPTAImpl::writePtsResultToFile(std::fstream& f) for (auto it = pag->begin(), ie = pag->end(); it != ie; ++it) { NodeID var = it->first; - const PointsTo &pts = getPts(var); + const PointsTo& pts = getPts(var); stringstream ss; f << var << " -> { "; @@ -209,31 +214,29 @@ void BVDataPTAImpl::writePtsResultToFile(std::fstream& f) } else { - for (NodeID n: pts) + for (NodeID n : pts) { f << n << " "; } } f << "}\n"; } - } void BVDataPTAImpl::writeGepObjVarMapToFile(std::fstream& f) { - //write gepObjVarMap to file(in form of: baseID offset gepObjNodeId) - SVFIR::NodeOffsetMap &gepObjVarMap = pag->getGepObjNodeMap(); - for(SVFIR::NodeOffsetMap::const_iterator it = gepObjVarMap.begin(), eit = gepObjVarMap.end(); it != eit; it++) + // write gepObjVarMap to file(in form of: baseID offset gepObjNodeId) + SVFIR::NodeOffsetMap& gepObjVarMap = pag->getGepObjNodeMap(); + for (SVFIR::NodeOffsetMap::const_iterator it = gepObjVarMap.begin(), eit = gepObjVarMap.end(); it != eit; it++) { - const SVFIR::NodeOffset offsetPair = it -> first; - //write the base id to file + const SVFIR::NodeOffset offsetPair = it->first; + // write the base id to file f << offsetPair.first << " "; - //write the offset to file + // write the offset to file f << offsetPair.second << " "; - //write the gepObjNodeId to file + // write the gepObjNodeId to file f << it->second << "\n"; } - } /*! @@ -288,7 +291,7 @@ void BVDataPTAImpl::readPtsResultFromFile(std::ifstream& F) { string line; // Read analysis results from file - PTDataTy *ptD = getPTDataTy(); + PTDataTy* ptD = getPTDataTy(); // Read points-to sets string delimiter1 = " -> { "; @@ -301,10 +304,10 @@ void BVDataPTAImpl::readPtsResultFromFile(std::ifstream& F) // Parse a single line in the form of "var -> { obj1 obj2 obj3 }" getline(F, line); if (line.at(0) == '[' || line == "---VERSIONED---") continue; - if (line == "------") break; + if (line == "------") break; size_t pos = line.find(delimiter1); - if (pos == string::npos) break; - if (line.back() != '}') break; + if (pos == string::npos) break; + if (line.back() != '}') break; // var NodeID var = atoi(line.substr(0, pos).c_str()); @@ -334,32 +337,30 @@ void BVDataPTAImpl::readPtsResultFromFile(std::ifstream& F) } // map the variable ID to its pointer set - for (auto t: nodePtsMap) - ptD->unionPts(t.first, strPtsMap[t.second]); + for (auto t : nodePtsMap) ptD->unionPts(t.first, strPtsMap[t.second]); } void BVDataPTAImpl::readGepObjVarMapFromFile(std::ifstream& F) { string line; - //read GepObjVarMap from file + // read GepObjVarMap from file SVFIR::NodeOffsetMap gepObjVarMap = pag->getGepObjNodeMap(); while (F.good()) { getline(F, line); - if (line == "------") break; + if (line == "------") break; // Parse a single line in the form of "ID baseNodeID offset" istringstream ss(line); NodeID base; size_t offset; NodeID id; - ss >> base >> offset >>id; + ss >> base >> offset >> id; SVFIR::NodeOffsetMap::const_iterator iter = gepObjVarMap.find(std::make_pair(base, offset)); if (iter == gepObjVarMap.end()) { SVFVar* node = pag->getGNode(base); const MemObj* obj = nullptr; - if (GepObjVar* gepObjVar = SVFUtil::dyn_cast(node)) - obj = gepObjVar->getMemObj(); + if (GepObjVar* gepObjVar = SVFUtil::dyn_cast(node)) obj = gepObjVar->getMemObj(); else if (FIObjVar* baseNode = SVFUtil::dyn_cast(node)) obj = baseNode->getMemObj(); else if (DummyObjVar* baseNode = SVFUtil::dyn_cast(node)) @@ -369,8 +370,6 @@ void BVDataPTAImpl::readGepObjVarMapFromFile(std::ifstream& F) pag->addGepObjNode(obj, offset, id); NodeIDAllocator::get()->increaseNumOfObjAndNodes(); } - - } } @@ -381,18 +380,15 @@ void BVDataPTAImpl::readAndSetObjFieldSensitivity(std::ifstream& F, const std::s while (F.good()) { getline(F, line); - if (line.empty() || line == delimiterStr) - break; + if (line.empty() || line == delimiterStr) break; // Parse a single line in the form of "baseNodeID insensitive" istringstream ss(line); NodeID base; bool insensitive; ss >> base >> insensitive; - if (insensitive) - setObjFieldInsensitive(base); + if (insensitive) setObjFieldInsensitive(base); } - } /*! @@ -412,13 +408,13 @@ bool BVDataPTAImpl::readFromFile(const string& filename) return false; } - readAndSetObjFieldSensitivity(F,"------"); + readAndSetObjFieldSensitivity(F, "------"); readPtsResultFromFile(F); readGepObjVarMapFromFile(F); - readAndSetObjFieldSensitivity(F,""); + readAndSetObjFieldSensitivity(F, ""); // Update callgraph updateCallGraph(pag->getIndirectCallsites()); @@ -429,14 +425,13 @@ bool BVDataPTAImpl::readFromFile(const string& filename) return true; } - /*! * Dump points-to of each pag node */ void BVDataPTAImpl::dumpTopLevelPtsTo() { - for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); - nIter != this->getAllValidPtrs().end(); ++nIter) + for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); nIter != this->getAllValidPtrs().end(); + ++nIter) { const PAGNode* node = getPAG()->getGNode(*nIter); if (getPAG()->isValidTopLevelPtr(node)) @@ -451,9 +446,7 @@ void BVDataPTAImpl::dumpTopLevelPtsTo() else { outs() << "\t\tPointsTo: { "; - for (PointsTo::iterator it = pts.begin(), eit = pts.end(); - it != eit; ++it) - outs() << *it << " "; + for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) outs() << *it << " "; outs() << "}\n\n"; } } @@ -462,14 +455,13 @@ void BVDataPTAImpl::dumpTopLevelPtsTo() outs().flush(); } - /*! * Dump all points-to including top-level (ValVar) and address-taken (ObjVar) variables */ void BVDataPTAImpl::dumpAllPts() { OrderedNodeSet pagNodes; - for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; it++) + for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; it++) { pagNodes.insert(it->first); } @@ -483,7 +475,6 @@ void BVDataPTAImpl::dumpAllPts() outs() << "----------------------------------------------\n"; } - /*! * On the fly call graph construction * callsites is candidate indirect callsites need to be analyzed based on points-to results @@ -491,7 +482,7 @@ void BVDataPTAImpl::dumpAllPts() */ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, CallEdgeMap& newEdges) { - for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter) + for (CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter != eiter; ++iter) { const CallICFGNode* cs = iter->first; @@ -503,7 +494,7 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, resolveCPPIndCalls(cs, getPts(vtblId), newEdges); } else - resolveIndCalls(iter->first,getPts(iter->second),newEdges); + resolveIndCalls(iter->first, getPts(iter->second), newEdges); } } @@ -512,12 +503,12 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, */ void BVDataPTAImpl::normalizePointsTo() { - SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap(); - SVFIR::NodeOffsetMap &GepObjVarMap = pag->getGepObjNodeMap(); + SVFIR::MemObjToFieldsMap& memToFieldsMap = pag->getMemToFieldsMap(); + SVFIR::NodeOffsetMap& GepObjVarMap = pag->getGepObjNodeMap(); // collect each gep node whose base node has been set as field-insensitive NodeBS dropNodes; - for (auto t: memToFieldsMap) + for (auto t : memToFieldsMap) { NodeID base = t.first; const MemObj* memObj = pag->getObject(base); @@ -541,11 +532,10 @@ void BVDataPTAImpl::normalizePointsTo() { NodeID n = nIter->first; - const PointsTo &tmpPts = getPts(n); + const PointsTo& tmpPts = getPts(n); for (NodeID obj : tmpPts) { - if (!dropNodes.test(obj)) - continue; + if (!dropNodes.test(obj)) continue; NodeID baseObj = pag->getBaseObjVar(obj); clearPts(n, obj); addPts(n, baseObj); @@ -554,10 +544,10 @@ void BVDataPTAImpl::normalizePointsTo() // clear GepObjVarMap and memToFieldsMap for redundant gepnodes // and remove those nodes from pag - for (NodeID n: dropNodes) + for (NodeID n : dropNodes) { NodeID base = pag->getBaseObjVar(n); - GepObjVar *gepNode = SVFUtil::dyn_cast(pag->getGNode(n)); + GepObjVar* gepNode = SVFUtil::dyn_cast(pag->getGNode(n)); const APOffset apOffset = gepNode->getConstantFieldIdx(); GepObjVarMap.erase(std::make_pair(base, apOffset)); memToFieldsMap[base].reset(n); @@ -569,10 +559,9 @@ void BVDataPTAImpl::normalizePointsTo() /*! * Return alias results based on our points-to/alias analysis */ -AliasResult BVDataPTAImpl::alias(const SVFValue* V1, - const SVFValue* V2) +AliasResult BVDataPTAImpl::alias(const SVFValue* V1, const SVFValue* V2) { - return alias(pag->getValueNode(V1),pag->getValueNode(V2)); + return alias(pag->getValueNode(V1), pag->getValueNode(V2)); } /*! @@ -580,7 +569,7 @@ AliasResult BVDataPTAImpl::alias(const SVFValue* V1, */ AliasResult BVDataPTAImpl::alias(NodeID node1, NodeID node2) { - return alias(getPts(node1),getPts(node2)); + return alias(getPts(node1), getPts(node2)); } /*! @@ -590,12 +579,11 @@ AliasResult BVDataPTAImpl::alias(const PointsTo& p1, const PointsTo& p2) { PointsTo pts1; - expandFIObjs(p1,pts1); + expandFIObjs(p1, pts1); PointsTo pts2; - expandFIObjs(p2,pts2); + expandFIObjs(p2, pts2); - if (containBlackHoleNode(pts1) || containBlackHoleNode(pts2) || pts1.intersects(pts2)) - return AliasResult::MayAlias; + if (containBlackHoleNode(pts1) || containBlackHoleNode(pts2) || pts1.intersects(pts2)) return AliasResult::MayAlias; else return AliasResult::NoAlias; } diff --git a/svf/lib/MemoryModel/PointsTo.cpp b/svf/lib/MemoryModel/PointsTo.cpp index 6170c5d3d..1df6350a3 100644 --- a/svf/lib/MemoryModel/PointsTo.cpp +++ b/svf/lib/MemoryModel/PointsTo.cpp @@ -23,74 +23,87 @@ PointsTo::MappingPtr PointsTo::currentBestNodeMapping = nullptr; PointsTo::MappingPtr PointsTo::currentBestReverseNodeMapping = nullptr; PointsTo::PointsTo() - : type(Options::PtType()), nodeMapping(currentBestNodeMapping), - reverseNodeMapping(currentBestReverseNodeMapping) + : type(Options::PtType()), nodeMapping(currentBestNodeMapping), reverseNodeMapping(currentBestReverseNodeMapping) { if (type == SBV) new (&sbv) SparseBitVector<>(); - else if (type == CBV) new (&cbv) CoreBitVector(); - else if (type == BV) new (&bv) BitVector(); - else assert(false && "PointsTo::PointsTo: unknown type"); + else if (type == CBV) + new (&cbv) CoreBitVector(); + else if (type == BV) + new (&bv) BitVector(); + else + assert(false && "PointsTo::PointsTo: unknown type"); } -PointsTo::PointsTo(const PointsTo &pt) - : type(pt.type), nodeMapping(pt.nodeMapping), - reverseNodeMapping(pt.reverseNodeMapping) +PointsTo::PointsTo(const PointsTo& pt) + : type(pt.type), nodeMapping(pt.nodeMapping), reverseNodeMapping(pt.reverseNodeMapping) { if (type == SBV) new (&sbv) SparseBitVector<>(pt.sbv); - else if (type == CBV) new (&cbv) CoreBitVector(pt.cbv); - else if (type == BV) new (&bv) BitVector(pt.bv); - else assert(false && "PointsTo::PointsTo&: unknown type"); + else if (type == CBV) + new (&cbv) CoreBitVector(pt.cbv); + else if (type == BV) + new (&bv) BitVector(pt.bv); + else + assert(false && "PointsTo::PointsTo&: unknown type"); } -PointsTo::PointsTo(PointsTo &&pt) -noexcept : type(pt.type), nodeMapping(std::move(pt.nodeMapping)), - reverseNodeMapping(std::move(pt.reverseNodeMapping)) +PointsTo::PointsTo(PointsTo&& pt) noexcept + : type(pt.type), nodeMapping(std::move(pt.nodeMapping)), reverseNodeMapping(std::move(pt.reverseNodeMapping)) { if (type == SBV) new (&sbv) SparseBitVector<>(std::move(pt.sbv)); - else if (type == CBV) new (&cbv) CoreBitVector(std::move(pt.cbv)); - else if (type == BV) new (&bv) BitVector(std::move(pt.bv)); - else assert(false && "PointsTo::PointsTo&&: unknown type"); + else if (type == CBV) + new (&cbv) CoreBitVector(std::move(pt.cbv)); + else if (type == BV) + new (&bv) BitVector(std::move(pt.bv)); + else + assert(false && "PointsTo::PointsTo&&: unknown type"); } PointsTo::~PointsTo() { if (type == SBV) sbv.~SparseBitVector<>(); - else if (type == CBV) cbv.~CoreBitVector(); - else if (type == BV) bv.~BitVector(); - else assert(false && "PointsTo::~PointsTo: unknown type"); + else if (type == CBV) + cbv.~CoreBitVector(); + else if (type == BV) + bv.~BitVector(); + else + assert(false && "PointsTo::~PointsTo: unknown type"); nodeMapping = nullptr; reverseNodeMapping = nullptr; } -PointsTo &PointsTo::operator=(const PointsTo &rhs) +PointsTo& PointsTo::operator=(const PointsTo& rhs) { - if (this == &rhs) - return *this; + if (this == &rhs) return *this; this->type = rhs.type; this->nodeMapping = rhs.nodeMapping; this->reverseNodeMapping = rhs.reverseNodeMapping; // Placement new because if type has changed, we have // not constructed the new type yet. if (type == SBV) new (&sbv) SparseBitVector<>(rhs.sbv); - else if (type == CBV) new (&cbv) CoreBitVector(rhs.cbv); - else if (type == BV) new (&bv) BitVector(rhs.bv); - else assert(false && "PointsTo::PointsTo=&: unknown type"); + else if (type == CBV) + new (&cbv) CoreBitVector(rhs.cbv); + else if (type == BV) + new (&bv) BitVector(rhs.bv); + else + assert(false && "PointsTo::PointsTo=&: unknown type"); return *this; } -PointsTo &PointsTo::operator=(PointsTo &&rhs) -noexcept +PointsTo& PointsTo::operator=(PointsTo&& rhs) noexcept { this->type = rhs.type; this->nodeMapping = rhs.nodeMapping; this->reverseNodeMapping = rhs.reverseNodeMapping; // See comment in copy assignment. if (type == SBV) new (&sbv) SparseBitVector<>(std::move(rhs.sbv)); - else if (type == CBV) new (&cbv) CoreBitVector(std::move(rhs.cbv)); - else if (type == BV) new (&bv) BitVector(std::move(rhs.bv)); - else assert(false && "PointsTo::PointsTo=&&: unknown type"); + else if (type == CBV) + new (&cbv) CoreBitVector(std::move(rhs.cbv)); + else if (type == BV) + new (&bv) BitVector(std::move(rhs.bv)); + else + assert(false && "PointsTo::PointsTo=&&: unknown type"); return *this; } @@ -98,8 +111,10 @@ noexcept bool PointsTo::empty() const { if (type == CBV) return cbv.empty(); - else if (type == SBV) return sbv.empty(); - else if (type == BV) return bv.empty(); + else if (type == SBV) + return sbv.empty(); + else if (type == BV) + return bv.empty(); else { assert(false && "PointsTo::empty: unknown type"); @@ -111,8 +126,10 @@ bool PointsTo::empty() const u32_t PointsTo::count(void) const { if (type == CBV) return cbv.count(); - else if (type == SBV) return sbv.count(); - else if (type == BV) return bv.count(); + else if (type == SBV) + return sbv.count(); + else if (type == BV) + return bv.count(); else { assert(false && "PointsTo::count: unknown type"); @@ -123,17 +140,22 @@ u32_t PointsTo::count(void) const void PointsTo::clear() { if (type == CBV) cbv.clear(); - else if (type == SBV) sbv.clear(); - else if (type == BV) bv.clear(); - else assert(false && "PointsTo::clear: unknown type"); + else if (type == SBV) + sbv.clear(); + else if (type == BV) + bv.clear(); + else + assert(false && "PointsTo::clear: unknown type"); } bool PointsTo::test(u32_t n) const { n = getInternalNode(n); if (type == CBV) return cbv.test(n); - else if (type == SBV) return sbv.test(n); - else if (type == BV) return bv.test(n); + else if (type == SBV) + return sbv.test(n); + else if (type == BV) + return bv.test(n); else { assert(false && "PointsTo::test: unknown type"); @@ -145,8 +167,10 @@ bool PointsTo::test_and_set(u32_t n) { n = getInternalNode(n); if (type == CBV) return cbv.test_and_set(n); - else if (type == SBV) return sbv.test_and_set(n); - else if (type == BV) return bv.test_and_set(n); + else if (type == SBV) + return sbv.test_and_set(n); + else if (type == BV) + return bv.test_and_set(n); else { assert(false && "PointsTo::test_and_set: unknown type"); @@ -158,27 +182,35 @@ void PointsTo::set(u32_t n) { n = getInternalNode(n); if (type == CBV) cbv.set(n); - else if (type == SBV) sbv.set(n); - else if (type == BV) bv.set(n); - else assert(false && "PointsTo::set: unknown type"); + else if (type == SBV) + sbv.set(n); + else if (type == BV) + bv.set(n); + else + assert(false && "PointsTo::set: unknown type"); } void PointsTo::reset(u32_t n) { n = getInternalNode(n); if (type == CBV) cbv.reset(n); - else if (type == SBV) sbv.reset(n); - else if (type == BV) bv.reset(n); - else assert(false && "PointsTo::reset: unknown type"); + else if (type == SBV) + sbv.reset(n); + else if (type == BV) + bv.reset(n); + else + assert(false && "PointsTo::reset: unknown type"); } -bool PointsTo::contains(const PointsTo &rhs) const +bool PointsTo::contains(const PointsTo& rhs) const { assert(metaSame(rhs) && "PointsTo::contains: mappings of operands do not match!"); if (type == CBV) return cbv.contains(rhs.cbv); - else if (type == SBV) return sbv.contains(rhs.sbv); - else if (type == BV) return bv.contains(rhs.bv); + else if (type == SBV) + return sbv.contains(rhs.sbv); + else if (type == BV) + return bv.contains(rhs.bv); else { assert(false && "PointsTo::contains: unknown type"); @@ -186,13 +218,15 @@ bool PointsTo::contains(const PointsTo &rhs) const } } -bool PointsTo::intersects(const PointsTo &rhs) const +bool PointsTo::intersects(const PointsTo& rhs) const { assert(metaSame(rhs) && "PointsTo::intersects: mappings of operands do not match!"); if (type == CBV) return cbv.intersects(rhs.cbv); - else if (type == SBV) return sbv.intersects(rhs.sbv); - else if (type == BV) return bv.intersects(rhs.bv); + else if (type == SBV) + return sbv.intersects(rhs.sbv); + else if (type == BV) + return bv.intersects(rhs.bv); else { assert(false && "PointsTo::intersects: unknown type"); @@ -206,13 +240,15 @@ int PointsTo::find_first() return *begin(); } -bool PointsTo::operator==(const PointsTo &rhs) const +bool PointsTo::operator==(const PointsTo& rhs) const { assert(metaSame(rhs) && "PointsTo::==: mappings of operands do not match!"); if (type == CBV) return cbv == rhs.cbv; - else if (type == SBV) return sbv == rhs.sbv; - else if (type == BV) return bv == rhs.bv; + else if (type == SBV) + return sbv == rhs.sbv; + else if (type == BV) + return bv == rhs.bv; else { assert(false && "PointsTo::==: unknown type"); @@ -220,7 +256,7 @@ bool PointsTo::operator==(const PointsTo &rhs) const } } -bool PointsTo::operator!=(const PointsTo &rhs) const +bool PointsTo::operator!=(const PointsTo& rhs) const { // TODO: we're asserting and checking twice... should be okay... assert(metaSame(rhs) && "PointsTo::!=: mappings of operands do not match!"); @@ -228,13 +264,15 @@ bool PointsTo::operator!=(const PointsTo &rhs) const return !(*this == rhs); } -bool PointsTo::operator|=(const PointsTo &rhs) +bool PointsTo::operator|=(const PointsTo& rhs) { assert(metaSame(rhs) && "PointsTo::|=: mappings of operands do not match!"); if (type == CBV) return cbv |= rhs.cbv; - else if (type == SBV) return sbv |= rhs.sbv; - else if (type == BV) return bv |= rhs.bv; + else if (type == SBV) + return sbv |= rhs.sbv; + else if (type == BV) + return bv |= rhs.bv; else { assert(false && "PointsTo::|=: unknown type"); @@ -242,26 +280,29 @@ bool PointsTo::operator|=(const PointsTo &rhs) } } -bool PointsTo::operator|=(const NodeBS &rhs) +bool PointsTo::operator|=(const NodeBS& rhs) { // TODO: bool changed = false; for (NodeID n : rhs) { if (changed) set(n); - else changed = test_and_set(n); + else + changed = test_and_set(n); } return changed; } -bool PointsTo::operator&=(const PointsTo &rhs) +bool PointsTo::operator&=(const PointsTo& rhs) { assert(metaSame(rhs) && "PointsTo::&=: mappings of operands do not match!"); if (type == CBV) return cbv &= rhs.cbv; - else if (type == SBV) return sbv &= rhs.sbv; - else if (type == BV) return bv &= rhs.bv; + else if (type == SBV) + return sbv &= rhs.sbv; + else if (type == BV) + return bv &= rhs.bv; else { assert(false && "PointsTo::&=: unknown type"); @@ -269,13 +310,15 @@ bool PointsTo::operator&=(const PointsTo &rhs) } } -bool PointsTo::operator-=(const PointsTo &rhs) +bool PointsTo::operator-=(const PointsTo& rhs) { assert(metaSame(rhs) && "PointsTo::-=: mappings of operands do not match!"); if (type == CBV) return cbv.intersectWithComplement(rhs.cbv); - else if (type == SBV) return sbv.intersectWithComplement(rhs.sbv); - else if (type == BV) return bv.intersectWithComplement(rhs.bv); + else if (type == SBV) + return sbv.intersectWithComplement(rhs.sbv); + else if (type == BV) + return bv.intersectWithComplement(rhs.bv); else { assert(false && "PointsTo::-=: unknown type"); @@ -283,26 +326,30 @@ bool PointsTo::operator-=(const PointsTo &rhs) } } -bool PointsTo::intersectWithComplement(const PointsTo &rhs) +bool PointsTo::intersectWithComplement(const PointsTo& rhs) { assert(metaSame(rhs) && "PointsTo::intersectWithComplement: mappings of operands do not match!"); if (type == CBV) return cbv.intersectWithComplement(rhs.cbv); - else if (type == SBV) return sbv.intersectWithComplement(rhs.sbv); - else if (type == BV) return bv.intersectWithComplement(rhs.bv); + else if (type == SBV) + return sbv.intersectWithComplement(rhs.sbv); + else if (type == BV) + return bv.intersectWithComplement(rhs.bv); assert(false && "PointsTo::intersectWithComplement(PT): unknown type"); abort(); } -void PointsTo::intersectWithComplement(const PointsTo &lhs, const PointsTo &rhs) +void PointsTo::intersectWithComplement(const PointsTo& lhs, const PointsTo& rhs) { assert(metaSame(rhs) && "PointsTo::intersectWithComplement: mappings of operands do not match!"); assert(metaSame(lhs) && "PointsTo::intersectWithComplement: mappings of operands do not match!"); if (type == CBV) cbv.intersectWithComplement(lhs.cbv, rhs.cbv); - else if (type == SBV) sbv.intersectWithComplement(lhs.sbv, rhs.sbv); - else if (type == BV) bv.intersectWithComplement(lhs.bv, rhs.bv); + else if (type == SBV) + sbv.intersectWithComplement(lhs.sbv, rhs.sbv); + else if (type == BV) + bv.intersectWithComplement(lhs.bv, rhs.bv); else { assert(false && "PointsTo::intersectWithComplement(PT, PT): unknown type"); @@ -325,7 +372,8 @@ size_t PointsTo::hash() const std::hash> h; return h(sbv); } - else if (type == BV) return bv.hash(); + else if (type == BV) + return bv.hash(); else { @@ -353,7 +401,7 @@ NodeID PointsTo::getExternalNode(NodeID n) const return reverseNodeMapping->at(n); } -bool PointsTo::metaSame(const PointsTo &pt) const +bool PointsTo::metaSame(const PointsTo& pt) const { return nodeMapping == pt.nodeMapping && reverseNodeMapping == pt.reverseNodeMapping; } @@ -369,7 +417,7 @@ PointsTo::MappingPtr PointsTo::getCurrentBestReverseNodeMapping() } void PointsTo::setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, - MappingPtr newCurrentBestReverseNodeMapping) + MappingPtr newCurrentBestReverseNodeMapping) { currentBestNodeMapping = std::move(newCurrentBestNodeMapping); currentBestReverseNodeMapping = std::move(newCurrentBestReverseNodeMapping); @@ -386,8 +434,7 @@ void PointsTo::checkAndRemap() } } -PointsTo::PointsToIterator::PointsToIterator(const PointsTo *pt, bool end) - : pt(pt) +PointsTo::PointsToIterator::PointsToIterator(const PointsTo* pt, bool end) : pt(pt) { if (pt->type == Type::CBV) { @@ -408,8 +455,7 @@ PointsTo::PointsToIterator::PointsToIterator(const PointsTo *pt, bool end) } } -PointsTo::PointsToIterator::PointsToIterator(const PointsToIterator &pt) - : pt(pt.pt) +PointsTo::PointsToIterator::PointsToIterator(const PointsToIterator& pt) : pt(pt.pt) { if (this->pt->type == PointsTo::Type::SBV) { @@ -430,8 +476,7 @@ PointsTo::PointsToIterator::PointsToIterator(const PointsToIterator &pt) } } -PointsTo::PointsToIterator::PointsToIterator(PointsToIterator &&pt) -noexcept : pt(pt.pt) +PointsTo::PointsToIterator::PointsToIterator(PointsToIterator&& pt) noexcept : pt(pt.pt) { if (this->pt->type == PointsTo::Type::SBV) { @@ -452,7 +497,7 @@ noexcept : pt(pt.pt) } } -PointsTo::PointsToIterator &PointsTo::PointsToIterator::operator=(const PointsToIterator &rhs) +PointsTo::PointsToIterator& PointsTo::PointsToIterator::operator=(const PointsToIterator& rhs) { this->pt = rhs.pt; @@ -468,12 +513,13 @@ PointsTo::PointsToIterator &PointsTo::PointsToIterator::operator=(const PointsTo { new (&bvIt) BitVector::iterator(rhs.bvIt); } - else assert(false && "PointsToIterator::PointsToIterator&: unknown type"); + else + assert(false && "PointsToIterator::PointsToIterator&: unknown type"); return *this; } -PointsTo::PointsToIterator &PointsTo::PointsToIterator::operator=(PointsToIterator &&rhs) noexcept +PointsTo::PointsToIterator& PointsTo::PointsToIterator::operator=(PointsToIterator&& rhs) noexcept { this->pt = rhs.pt; @@ -489,18 +535,22 @@ PointsTo::PointsToIterator &PointsTo::PointsToIterator::operator=(PointsToIterat { new (&bvIt) BitVector::iterator(std::move(rhs.bvIt)); } - else assert(false && "PointsToIterator::PointsToIterator&&: unknown type"); + else + assert(false && "PointsToIterator::PointsToIterator&&: unknown type"); return *this; } -const PointsTo::PointsToIterator &PointsTo::PointsToIterator::operator++() +const PointsTo::PointsToIterator& PointsTo::PointsToIterator::operator++() { assert(!atEnd() && "PointsToIterator::++(pre): incrementing past end!"); if (pt->type == Type::CBV) ++cbvIt; - else if (pt->type == Type::SBV) ++sbvIt; - else if (pt->type == Type::BV) ++bvIt; - else assert(false && "PointsToIterator::++(void): unknown type"); + else if (pt->type == Type::SBV) + ++sbvIt; + else if (pt->type == Type::BV) + ++bvIt; + else + assert(false && "PointsToIterator::++(void): unknown type"); return *this; } @@ -517,8 +567,10 @@ NodeID PointsTo::PointsToIterator::operator*() const { assert(!atEnd() && "PointsToIterator: dereferencing end!"); if (pt->type == Type::CBV) return pt->getExternalNode(*cbvIt); - else if (pt->type == Type::SBV) return pt->getExternalNode(*sbvIt); - else if (pt->type == Type::BV) return pt->getExternalNode(*bvIt); + else if (pt->type == Type::SBV) + return pt->getExternalNode(*sbvIt); + else if (pt->type == Type::BV) + return pt->getExternalNode(*bvIt); else { assert(false && "PointsToIterator::*: unknown type"); @@ -526,15 +578,16 @@ NodeID PointsTo::PointsToIterator::operator*() const } } -bool PointsTo::PointsToIterator::operator==(const PointsToIterator &rhs) const +bool PointsTo::PointsToIterator::operator==(const PointsToIterator& rhs) const { - assert(pt == rhs.pt - && "PointsToIterator::==: comparing iterators from different PointsTos!"); + assert(pt == rhs.pt && "PointsToIterator::==: comparing iterators from different PointsTos!"); // Handles end implicitly. if (pt->type == Type::CBV) return cbvIt == rhs.cbvIt; - else if (pt->type == Type::SBV) return sbvIt == rhs.sbvIt; - else if (pt->type == Type::BV) return bvIt == rhs.bvIt; + else if (pt->type == Type::SBV) + return sbvIt == rhs.sbvIt; + else if (pt->type == Type::BV) + return bvIt == rhs.bvIt; else { assert(false && "PointsToIterator::==: unknown type"); @@ -542,10 +595,9 @@ bool PointsTo::PointsToIterator::operator==(const PointsToIterator &rhs) const } } -bool PointsTo::PointsToIterator::operator!=(const PointsToIterator &rhs) const +bool PointsTo::PointsToIterator::operator!=(const PointsToIterator& rhs) const { - assert(pt == rhs.pt - && "PointsToIterator::!=: comparing iterators from different PointsTos!"); + assert(pt == rhs.pt && "PointsToIterator::!=: comparing iterators from different PointsTos!"); return !(*this == rhs); } @@ -553,8 +605,10 @@ bool PointsTo::PointsToIterator::atEnd() const { assert(pt != nullptr && "PointsToIterator::atEnd: iterator iterating over nothing!"); if (pt->type == Type::CBV) return cbvIt == pt->cbv.end(); - else if (pt->type == Type::SBV) return sbvIt == pt->sbv.end(); - else if (pt->type == Type::BV) return bvIt == pt->bv.end(); + else if (pt->type == Type::SBV) + return sbvIt == pt->sbv.end(); + else if (pt->type == Type::BV) + return bvIt == pt->bv.end(); else { assert(false && "PointsToIterator::atEnd: unknown type"); @@ -562,7 +616,7 @@ bool PointsTo::PointsToIterator::atEnd() const } } -PointsTo operator|(const PointsTo &lhs, const PointsTo &rhs) +PointsTo operator|(const PointsTo& lhs, const PointsTo& rhs) { // TODO: optimise. PointsTo result = lhs; @@ -570,7 +624,7 @@ PointsTo operator|(const PointsTo &lhs, const PointsTo &rhs) return result; } -PointsTo operator&(const PointsTo &lhs, const PointsTo &rhs) +PointsTo operator&(const PointsTo& lhs, const PointsTo& rhs) { // TODO: optimise. PointsTo result = lhs; @@ -578,7 +632,7 @@ PointsTo operator&(const PointsTo &lhs, const PointsTo &rhs) return result; } -PointsTo operator-(const PointsTo &lhs, const PointsTo &rhs) +PointsTo operator-(const PointsTo& lhs, const PointsTo& rhs) { // TODO: optimise. PointsTo result = lhs; @@ -586,4 +640,4 @@ PointsTo operator-(const PointsTo &lhs, const PointsTo &rhs) return result; } -}; // namespace SVF +}; // namespace SVF diff --git a/svf/lib/SABER/DoubleFreeChecker.cpp b/svf/lib/SABER/DoubleFreeChecker.cpp index e16dddf18..e36afba15 100644 --- a/svf/lib/SABER/DoubleFreeChecker.cpp +++ b/svf/lib/SABER/DoubleFreeChecker.cpp @@ -37,49 +37,42 @@ using namespace SVFUtil; void DoubleFreeChecker::reportBug(ProgSlice* slice) { - if(slice->isSatisfiableForPairs() == false) + if (slice->isSatisfiableForPairs() == false) { GenericBug::EventStack eventStack; slice->evalFinalCond2Event(eventStack); - eventStack.push_back( - SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())); + eventStack.push_back(SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())); report.addSaberBug(GenericBug::DOUBLEFREE, eventStack); } - if(Options::ValidateTests()) - testsValidation(slice); + if (Options::ValidateTests()) testsValidation(slice); } - - -void DoubleFreeChecker::testsValidation(ProgSlice *slice) +void DoubleFreeChecker::testsValidation(ProgSlice* slice) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); const SVFFunction* fun = getCallee(cs->getCallSite()); - if(fun==nullptr) - return; - validateSuccessTests(slice,fun); - validateExpectedFailureTests(slice,fun); + if (fun == nullptr) return; + validateSuccessTests(slice, fun); + validateExpectedFailureTests(slice, fun); } -void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const SVFFunction *fun) +void DoubleFreeChecker::validateSuccessTests(ProgSlice* slice, const SVFFunction* fun) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); bool success = false; - if(fun->getName() == "SAFEMALLOC") + if (fun->getName() == "SAFEMALLOC") { - if(slice->isSatisfiableForPairs() == true) - success = true; + if (slice->isSatisfiableForPairs() == true) success = true; } - else if(fun->getName() == "DOUBLEFREEMALLOC") + else if (fun->getName() == "DOUBLEFREEMALLOC") { - if(slice->isSatisfiableForPairs() == false) - success = true; + if (slice->isSatisfiableForPairs() == false) success = true; } - else if(fun->getName() == "DOUBLEFREEMALLOCFN" || fun->getName() == "SAFEMALLOCFP") + else if (fun->getName() == "DOUBLEFREEMALLOCFN" || fun->getName() == "SAFEMALLOCFP") { return; } @@ -101,31 +94,29 @@ void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const SVFFunction else { SVFUtil::errs() << errMsg("\t FAILURE :") << funName << " check getId() - << ", cs id:" <getCallSite()->toString() << "> at (" + << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at (" << cs->getCallSite()->getSourceLoc() << ")\n"; SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n"; assert(false && "test case failed!"); } } -void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice *slice, const SVFFunction *fun) +void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice* slice, const SVFFunction* fun) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); bool expectedFailure = false; /// output safe but should be double free - if(fun->getName() == "DOUBLEFREEMALLOCFN") + if (fun->getName() == "DOUBLEFREEMALLOCFN") { - if(slice->isSatisfiableForPairs() == true) - expectedFailure = true; + if (slice->isSatisfiableForPairs() == true) expectedFailure = true; } /// output double free but should be safe - else if(fun->getName() == "SAFEMALLOCFP") + else if (fun->getName() == "SAFEMALLOCFP") { - if(slice->isSatisfiableForPairs() == false) - expectedFailure = true; + if (slice->isSatisfiableForPairs() == false) expectedFailure = true; } - else if(fun->getName() == "SAFEMALLOC" || fun->getName() == "DOUBLEFREEMALLOC") + else if (fun->getName() == "SAFEMALLOC" || fun->getName() == "DOUBLEFREEMALLOC") { return; } @@ -146,8 +137,7 @@ void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice *slice, const SVF } else { - SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName - << " check getId() + SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName << " check getId() << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at (" << cs->getCallSite()->getSourceLoc() << ")\n"; SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n"; diff --git a/svf/lib/SABER/FileChecker.cpp b/svf/lib/SABER/FileChecker.cpp index e5d03d48a..bd7c9f314 100644 --- a/svf/lib/SABER/FileChecker.cpp +++ b/svf/lib/SABER/FileChecker.cpp @@ -32,25 +32,21 @@ using namespace SVF; using namespace SVFUtil; - void FileChecker::reportBug(ProgSlice* slice) { - if(isAllPathReachable() == false && isSomePathReachable() == false) + if (isAllPathReachable() == false && isSomePathReachable() == false) { // full leakage - GenericBug::EventStack eventStack = - { - SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite()) - }; + GenericBug::EventStack eventStack = { + SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())}; report.addSaberBug(GenericBug::FILENEVERCLOSE, eventStack); } else if (isAllPathReachable() == false && isSomePathReachable() == true) { GenericBug::EventStack eventStack; slice->evalFinalCond2Event(eventStack); - eventStack.push_back( - SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())); + eventStack.push_back(SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())); report.addSaberBug(GenericBug::FILEPARTIALCLOSE, eventStack); } } diff --git a/svf/lib/SABER/LeakChecker.cpp b/svf/lib/SABER/LeakChecker.cpp index 495397423..a1b47aac0 100644 --- a/svf/lib/SABER/LeakChecker.cpp +++ b/svf/lib/SABER/LeakChecker.cpp @@ -33,7 +33,6 @@ using namespace SVF; using namespace SVFUtil; - /*! * Initialize sources */ @@ -42,19 +41,19 @@ void LeakChecker::initSrcs() SVFIR* pag = getPAG(); ICFG* icfg = pag->getICFG(); - for(SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), - eit = pag->getCallSiteRets().end(); it!=eit; ++it) + for (SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), eit = pag->getCallSiteRets().end(); it != eit; + ++it) { const RetICFGNode* cs = it->first; /// if this callsite return reside in a dead function then we do not care about its leaks - /// for example instruction `int* p = malloc(size)` is in a dead function, then program won't allocate this memory - /// for example a customized malloc `int p = malloc()` returns an integer value, then program treat it as a system malloc - if(cs->getCallSite()->ptrInUncalledFunction() || !cs->getCallSite()->getType()->isPointerTy()) - continue; + /// for example instruction `int* p = malloc(size)` is in a dead function, then program won't allocate this + /// memory for example a customized malloc `int p = malloc()` returns an integer value, then program treat it as + /// a system malloc + if (cs->getCallSite()->ptrInUncalledFunction() || !cs->getCallSite()->getType()->isPointerTy()) continue; CallGraph::FunctionSet callees; - getCallgraph()->getCallees(cs->getCallICFGNode(),callees); - for(CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++) + getCallgraph()->getCallees(cs->getCallICFGNode(), callees); + for (CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit != ecit; cit++) { const SVFFunction* fun = *cit; if (isSourceLikeFun(fun)) @@ -68,8 +67,7 @@ void LeakChecker::initSrcs() const RetICFGNode* retBlockNode = icfg->getRetICFGNode(cs->getCallSite()); const PAGNode* pagNode = pag->getCallSiteRet(retBlockNode); const SVFGNode* node = getSVFG()->getDefSVFGNode(pagNode); - if (visited.test(node->getId()) == 0) - visited.set(node->getId()); + if (visited.test(node->getId()) == 0) visited.set(node->getId()); else continue; @@ -77,8 +75,7 @@ void LeakChecker::initSrcs() // if this node is in an allocation wrapper, find all its call nodes if (isInAWrapper(node, csSet)) { - for (CallSiteSet::iterator it = csSet.begin(), eit = - csSet.end(); it != eit; ++it) + for (CallSiteSet::iterator it = csSet.begin(), eit = csSet.end(); it != eit; ++it) { worklist.push(*it); } @@ -87,7 +84,8 @@ void LeakChecker::initSrcs() else { // exclude sources in dead functions or sources in functions that have summary - if (!cs->getCallSite()->ptrInUncalledFunction() && !isExtCall(cs->getCallSite()->getParent()->getParent())) + if (!cs->getCallSite()->ptrInUncalledFunction() && + !isExtCall(cs->getCallSite()->getParent()->getParent())) { addToSources(node); addSrcToCSID(node, cs); @@ -97,7 +95,6 @@ void LeakChecker::initSrcs() } } } - } /*! @@ -108,36 +105,35 @@ void LeakChecker::initSnks() SVFIR* pag = getPAG(); - for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), - eit = pag->getCallSiteArgsMap().end(); it!=eit; ++it) + for (SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); + it != eit; ++it) { CallGraph::FunctionSet callees; - getCallgraph()->getCallees(it->first,callees); - for(CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++) + getCallgraph()->getCallees(it->first, callees); + for (CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit != ecit; cit++) { const SVFFunction* fun = *cit; if (isSinkLikeFun(fun)) { - SVFIR::SVFVarList &arglist = it->second; - assert(!arglist.empty() && "no actual parameter at deallocation site?"); + SVFIR::SVFVarList& arglist = it->second; + assert(!arglist.empty() && "no actual parameter at deallocation site?"); /// we only choose pointer parameters among all the actual parameters - for (SVFIR::SVFVarList::const_iterator ait = arglist.begin(), - aeit = arglist.end(); ait != aeit; ++ait) + for (SVFIR::SVFVarList::const_iterator ait = arglist.begin(), aeit = arglist.end(); ait != aeit; ++ait) { - const PAGNode *pagNode = *ait; + const PAGNode* pagNode = *ait; if (pagNode->isPointer()) { - const SVFGNode *snk = getSVFG()->getActualParmVFGNode(pagNode, it->first); + const SVFGNode* snk = getSVFG()->getActualParmVFGNode(pagNode, it->first); addToSinks(snk); - // For any multi-level pointer e.g., XFree(void** pagNode) that passed into a ExtAPI::EFT_FREE_MULTILEVEL function (e.g., XFree), - // we will add the DstNode of a load edge, i.e., dummy = *pagNode + // For any multi-level pointer e.g., XFree(void** pagNode) that passed into a + // ExtAPI::EFT_FREE_MULTILEVEL function (e.g., XFree), we will add the DstNode of a load edge, + // i.e., dummy = *pagNode SVFStmt::SVFStmtSetTy& loads = const_cast(pagNode)->getOutgoingEdges(SVFStmt::Load); - for(const SVFStmt* ld : loads) + for (const SVFStmt* ld : loads) { - if(SVFUtil::isa(ld->getDstNode())) - addToSinks(getSVFG()->getStmtVFGNode(ld)); + if (SVFUtil::isa(ld->getDstNode())) addToSinks(getSVFG()->getStmtVFGNode(ld)); } } } @@ -149,13 +145,11 @@ void LeakChecker::initSnks() void LeakChecker::reportBug(ProgSlice* slice) { - if(isAllPathReachable() == false && isSomePathReachable() == false) + if (isAllPathReachable() == false && isSomePathReachable() == false) { // full leakage - GenericBug::EventStack eventStack = - { - SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite()) - }; + GenericBug::EventStack eventStack = { + SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())}; report.addSaberBug(GenericBug::NEVERFREE, eventStack); } else if (isAllPathReachable() == false && isSomePathReachable() == true) @@ -163,16 +157,13 @@ void LeakChecker::reportBug(ProgSlice* slice) // partial leakage GenericBug::EventStack eventStack; slice->evalFinalCond2Event(eventStack); - eventStack.push_back( - SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())); + eventStack.push_back(SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())->getCallSite())); report.addSaberBug(GenericBug::PARTIALLEAK, eventStack); } - if(Options::ValidateTests()) - testsValidation(slice); + if (Options::ValidateTests()) testsValidation(slice); } - /*! * Validate test cases for regression test purpose */ @@ -181,14 +172,12 @@ void LeakChecker::testsValidation(const ProgSlice* slice) const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); const SVFFunction* fun = getCallee(cs->getCallSite()); - if(fun==nullptr) - return; + if (fun == nullptr) return; - validateSuccessTests(source,fun); - validateExpectedFailureTests(source,fun); + validateSuccessTests(source, fun); + validateExpectedFailureTests(source, fun); } - void LeakChecker::validateSuccessTests(const SVFGNode* source, const SVFFunction* fun) { @@ -196,28 +185,23 @@ void LeakChecker::validateSuccessTests(const SVFGNode* source, const SVFFunction bool success = false; - if(fun->getName() == "SAFEMALLOC") + if (fun->getName() == "SAFEMALLOC") { - if(isAllPathReachable() == true && isSomePathReachable() == true) - success = true; + if (isAllPathReachable() == true && isSomePathReachable() == true) success = true; } - else if(fun->getName() == "NFRMALLOC") + else if (fun->getName() == "NFRMALLOC") { - if(isAllPathReachable() == false && isSomePathReachable() == false) - success = true; + if (isAllPathReachable() == false && isSomePathReachable() == false) success = true; } - else if(fun->getName() == "PLKMALLOC") + else if (fun->getName() == "PLKMALLOC") { - if(isAllPathReachable() == false && isSomePathReachable() == true) - success = true; + if (isAllPathReachable() == false && isSomePathReachable() == true) success = true; } - else if(fun->getName() == "CLKMALLOC") + else if (fun->getName() == "CLKMALLOC") { - if(isAllPathReachable() == false && isSomePathReachable() == false) - success = true; + if (isAllPathReachable() == false && isSomePathReachable() == false) success = true; } - else if(fun->getName() == "NFRLEAKFP" || fun->getName() == "PLKLEAKFP" - || fun->getName() == "LEAKFN") + else if (fun->getName() == "NFRLEAKFP" || fun->getName() == "PLKLEAKFP" || fun->getName() == "LEAKFN") { return; } @@ -251,23 +235,20 @@ void LeakChecker::validateExpectedFailureTests(const SVFGNode* source, const SVF bool expectedFailure = false; - if(fun->getName() == "NFRLEAKFP") + if (fun->getName() == "NFRLEAKFP") { - if(isAllPathReachable() == false && isSomePathReachable() == false) - expectedFailure = true; + if (isAllPathReachable() == false && isSomePathReachable() == false) expectedFailure = true; } - else if(fun->getName() == "PLKLEAKFP") + else if (fun->getName() == "PLKLEAKFP") { - if(isAllPathReachable() == false && isSomePathReachable() == true) - expectedFailure = true; + if (isAllPathReachable() == false && isSomePathReachable() == true) expectedFailure = true; } - else if(fun->getName() == "LEAKFN") + else if (fun->getName() == "LEAKFN") { - if(isAllPathReachable() == true && isSomePathReachable() == true) - expectedFailure = true; + if (isAllPathReachable() == true && isSomePathReachable() == true) expectedFailure = true; } - else if(fun->getName() == "SAFEMALLOC" || fun->getName() == "NFRMALLOC" - || fun->getName() == "PLKMALLOC" || fun->getName() == "CLKLEAKFN") + else if (fun->getName() == "SAFEMALLOC" || fun->getName() == "NFRMALLOC" || fun->getName() == "PLKMALLOC" || + fun->getName() == "CLKLEAKFN") { return; } @@ -287,8 +268,7 @@ void LeakChecker::validateExpectedFailureTests(const SVFGNode* source, const SVF } else { - SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName - << " check getId() + SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName << " check getId() << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at (" << cs->getCallSite()->getSourceLoc() << ")\n"; assert(false && "test case failed!"); diff --git a/svf/lib/SABER/ProgSlice.cpp b/svf/lib/SABER/ProgSlice.cpp index 7ecf3a159..7c43e29fe 100644 --- a/svf/lib/SABER/ProgSlice.cpp +++ b/svf/lib/SABER/ProgSlice.cpp @@ -46,20 +46,20 @@ bool ProgSlice::AllPathReachableSolve() VFWorkList worklist; worklist.push(source); /// mark source node conditions to be true - setVFCond(source,getTrueCond()); + setVFCond(source, getTrueCond()); - while(!worklist.empty()) + while (!worklist.empty()) { const SVFGNode* node = worklist.pop(); setCurSVFGNode(node); Condition invalidCond = computeInvalidCondFromRemovedSUVFEdge(node); Condition cond = getVFCond(node); - for(SVFGNode::const_iterator it = node->OutEdgeBegin(), eit = node->OutEdgeEnd(); it!=eit; ++it) + for (SVFGNode::const_iterator it = node->OutEdgeBegin(), eit = node->OutEdgeEnd(); it != eit; ++it) { const SVFGEdge* edge = (*it); const SVFGNode* succ = edge->getDstNode(); - if(inBackwardSlice(succ)) + if (inBackwardSlice(succ)) { Condition vfCond; const SVFBasicBlock* nodeBB = getSVFGNodeBB(node); @@ -67,24 +67,23 @@ bool ProgSlice::AllPathReachableSolve() /// clean up the control flow conditions for next round guard computation clearCFCond(); - if(edge->isCallVFGEdge()) + if (edge->isCallVFGEdge()) { - vfCond = ComputeInterCallVFGGuard(nodeBB,succBB, getCallSite(edge)->getParent()); + vfCond = ComputeInterCallVFGGuard(nodeBB, succBB, getCallSite(edge)->getParent()); } - else if(edge->isRetVFGEdge()) + else if (edge->isRetVFGEdge()) { - vfCond = ComputeInterRetVFGGuard(nodeBB,succBB, getRetSite(edge)->getParent()); + vfCond = ComputeInterRetVFGGuard(nodeBB, succBB, getRetSite(edge)->getParent()); } else - vfCond = ComputeIntraVFGGuard(nodeBB,succBB); + vfCond = ComputeIntraVFGGuard(nodeBB, succBB); vfCond = condAnd(vfCond, condNeg(invalidCond)); Condition succPathCond = condAnd(cond, vfCond); - if(setVFCond(succ, condOr(getVFCond(succ), succPathCond) )) - worklist.push(succ); + if (setVFCond(succ, condOr(getVFCond(succ), succPathCond))) worklist.push(succ); } - DBOUT(DSaber, outs() << " node (" << node->getId() << - ") --> " << "succ (" << succ->getId() << ") condition: " << getVFCond(succ) << "\n"); + DBOUT(DSaber, outs() << " node (" << node->getId() << ") --> " + << "succ (" << succ->getId() << ") condition: " << getVFCond(succ) << "\n"); } } @@ -95,24 +94,24 @@ bool ProgSlice::AllPathReachableSolve() * Compute invalid branch condition stemming from removed strong update value-flow edges * * Fix issue: https://github.com/SVF-tools/SVF/issues/1306 - * Line 11->13 is removed due to a strong update at Line 13, which means Line 11 is unreachable to Line 13 on the value flow graph. - * However on the control flow graph they are still considered as reachable, - * making the vf guard on Line 11 -> Line 15 a true condition (should consider the infeasible branch Line 11 -> Line 13) - * Therefore, we collect this infeasible branch condition (condition on Line 11 -> Line 13, `a == b`) as an invalid condition (invalidCond), - * and add the negation of invalidCond when computing value flow guard starting from the source of the SU. - * In this example, we add `a != b` on Line 11 -> Line 15. + * Line 11->13 is removed due to a strong update at Line 13, which means Line 11 is unreachable to Line 13 on the value + * flow graph. However on the control flow graph they are still considered as reachable, making the vf guard on Line 11 + * -> Line 15 a true condition (should consider the infeasible branch Line 11 -> Line 13) Therefore, we collect this + * infeasible branch condition (condition on Line 11 -> Line 13, `a == b`) as an invalid condition (invalidCond), and + * add the negation of invalidCond when computing value flow guard starting from the source of the SU. In this example, + * we add `a != b` on Line 11 -> Line 15. * * @param cur current SVFG node * @return invalid branch condition */ -ProgSlice::Condition ProgSlice::computeInvalidCondFromRemovedSUVFEdge(const SVFGNode * cur) +ProgSlice::Condition ProgSlice::computeInvalidCondFromRemovedSUVFEdge(const SVFGNode* cur) { Set validOutBBs; // the BBs of valid successors - for(SVFGNode::const_iterator it = cur->OutEdgeBegin(), eit = cur->OutEdgeEnd(); it!=eit; ++it) + for (SVFGNode::const_iterator it = cur->OutEdgeBegin(), eit = cur->OutEdgeEnd(); it != eit; ++it) { const SVFGEdge* edge = (*it); const SVFGNode* succ = edge->getDstNode(); - if(inBackwardSlice(succ)) + if (inBackwardSlice(succ)) { validOutBBs.insert(getSVFGNodeBB(succ)); } @@ -121,13 +120,13 @@ ProgSlice::Condition ProgSlice::computeInvalidCondFromRemovedSUVFEdge(const SVFG auto suVFEdgesIt = getRemovedSUVFEdges().find(cur); if (suVFEdgesIt != getRemovedSUVFEdges().end()) { - for (const auto &succ: suVFEdgesIt->second) + for (const auto& succ : suVFEdgesIt->second) { if (!validOutBBs.count(getSVFGNodeBB(succ))) { // removed vfg node does not reside in the BBs of valid successors - const SVFBasicBlock *nodeBB = getSVFGNodeBB(cur); - const SVFBasicBlock *succBB = getSVFGNodeBB(succ); + const SVFBasicBlock* nodeBB = getSVFGNodeBB(cur); + const SVFBasicBlock* succBB = getSVFGNodeBB(succ); clearCFCond(); invalidCond = condOr(invalidCond, ComputeIntraVFGGuard(nodeBB, succBB)); } @@ -143,9 +142,9 @@ bool ProgSlice::isSatisfiableForAll() { Condition guard = getFalseCond(); - for(SVFGNodeSetIter it = sinksBegin(), eit = sinksEnd(); it!=eit; ++it) + for (SVFGNodeSetIter it = sinksBegin(), eit = sinksEnd(); it != eit; ++it) { - guard = condOr(guard,getVFCond(*it)); + guard = condOr(guard, getVFCond(*it)); } setFinalCond(guard); @@ -158,14 +157,13 @@ bool ProgSlice::isSatisfiableForAll() bool ProgSlice::isSatisfiableForPairs() { - for(SVFGNodeSetIter it = sinksBegin(), eit = sinksEnd(); it!=eit; ++it) + for (SVFGNodeSetIter it = sinksBegin(), eit = sinksEnd(); it != eit; ++it) { - for(SVFGNodeSetIter sit = it, esit = sinksEnd(); sit!=esit; ++sit) + for (SVFGNodeSetIter sit = it, esit = sinksEnd(); sit != esit; ++sit) { - if(*it == *sit) - continue; - Condition guard = condAnd(getVFCond(*sit),getVFCond(*it)); - if(!isEquivalentBranchCond(guard, getFalseCond())) + if (*it == *sit) continue; + Condition guard = condAnd(getVFCond(*sit), getVFCond(*it)); + if (!isEquivalentBranchCond(guard, getFalseCond())) { setFinalCond(guard); return false; @@ -179,7 +177,7 @@ bool ProgSlice::isSatisfiableForPairs() const CallICFGNode* ProgSlice::getCallSite(const SVFGEdge* edge) const { assert(edge->isCallVFGEdge() && "not a call svfg edge?"); - if(const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) + if (const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) return getSVFG()->getCallSite(callEdge->getCallSiteId()); else return getSVFG()->getCallSite(SVFUtil::cast(edge)->getCallSiteId()); @@ -187,24 +185,22 @@ const CallICFGNode* ProgSlice::getCallSite(const SVFGEdge* edge) const const CallICFGNode* ProgSlice::getRetSite(const SVFGEdge* edge) const { assert(edge->isRetVFGEdge() && "not a return svfg edge?"); - if(const RetDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) + if (const RetDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) return getSVFG()->getCallSite(callEdge->getCallSiteId()); else return getSVFG()->getCallSite(SVFUtil::cast(edge)->getCallSiteId()); } -void ProgSlice::evalFinalCond2Event(GenericBug::EventStack &eventStack) const +void ProgSlice::evalFinalCond2Event(GenericBug::EventStack& eventStack) const { NodeBS elems = pathAllocator->exactCondElem(finalCond); - for(NodeBS::iterator it = elems.begin(), eit = elems.end(); it!=eit; ++it) + for (NodeBS::iterator it = elems.begin(), eit = elems.end(); it != eit; ++it) { const SVFInstruction* tinst = pathAllocator->getCondInst(*it); - if(pathAllocator->isNegCond(*it)) - eventStack.push_back(SVFBugEvent( - SVFBugEvent::Branch|((((u32_t)false) << 4) & BRANCHFLAGMASK), tinst)); + if (pathAllocator->isNegCond(*it)) + eventStack.push_back(SVFBugEvent(SVFBugEvent::Branch | ((((u32_t) false) << 4) & BRANCHFLAGMASK), tinst)); else - eventStack.push_back(SVFBugEvent( - SVFBugEvent::Branch|((((u32_t)true) << 4) & BRANCHFLAGMASK), tinst)); + eventStack.push_back(SVFBugEvent(SVFBugEvent::Branch | ((((u32_t) true) << 4) & BRANCHFLAGMASK), tinst)); } } @@ -224,18 +220,16 @@ std::string ProgSlice::evalFinalCond() const Set locations; NodeBS elems = pathAllocator->exactCondElem(finalCond); - for(NodeBS::iterator it = elems.begin(), eit = elems.end(); it!=eit; ++it) + for (NodeBS::iterator it = elems.begin(), eit = elems.end(); it != eit; ++it) { const SVFInstruction* tinst = pathAllocator->getCondInst(*it); - if(pathAllocator->isNegCond(*it)) - locations.insert(tinst->getSourceLoc()+"|False"); + if (pathAllocator->isNegCond(*it)) locations.insert(tinst->getSourceLoc() + "|False"); else - locations.insert(tinst->getSourceLoc()+"|True"); + locations.insert(tinst->getSourceLoc() + "|True"); } /// print leak path after eliminating duplicated element - for(Set::iterator iter = locations.begin(), eiter = locations.end(); - iter!=eiter; ++iter) + for (Set::iterator iter = locations.begin(), eiter = locations.end(); iter != eiter; ++iter) { rawstr << "\t\t --> (" << *iter << ") \n"; } @@ -243,6 +237,4 @@ std::string ProgSlice::evalFinalCond() const return rawstr.str(); } -void ProgSlice::destroy() -{ -} +void ProgSlice::destroy() {} diff --git a/svf/lib/SABER/SaberCheckerAPI.cpp b/svf/lib/SABER/SaberCheckerAPI.cpp index 9baab29dc..a19fdb15c 100644 --- a/svf/lib/SABER/SaberCheckerAPI.cpp +++ b/svf/lib/SABER/SaberCheckerAPI.cpp @@ -40,137 +40,129 @@ namespace /// string and type pair struct ei_pair { - const char *n; + const char* n; SaberCheckerAPI::CHECKER_TYPE t; }; } // End anonymous namespace -//Each (name, type) pair will be inserted into the map. -//All entries of the same type must occur together (for error detection). -static const ei_pair ei_pairs[]= -{ - {"alloc", SaberCheckerAPI::CK_ALLOC}, - {"alloc_check", SaberCheckerAPI::CK_ALLOC}, - {"alloc_clear", SaberCheckerAPI::CK_ALLOC}, - {"calloc", SaberCheckerAPI::CK_ALLOC}, - {"jpeg_alloc_huff_table", SaberCheckerAPI::CK_ALLOC}, - {"jpeg_alloc_quant_table", SaberCheckerAPI::CK_ALLOC}, - {"lalloc", SaberCheckerAPI::CK_ALLOC}, - {"lalloc_clear", SaberCheckerAPI::CK_ALLOC}, - {"malloc", SaberCheckerAPI::CK_ALLOC}, - {"nhalloc", SaberCheckerAPI::CK_ALLOC}, - {"oballoc", SaberCheckerAPI::CK_ALLOC}, - {"permalloc", SaberCheckerAPI::CK_ALLOC}, - {"png_create_info_struct", SaberCheckerAPI::CK_ALLOC}, - {"png_create_write_struct", SaberCheckerAPI::CK_ALLOC}, - {"safe_calloc", SaberCheckerAPI::CK_ALLOC}, - {"safe_malloc", SaberCheckerAPI::CK_ALLOC}, - {"safecalloc", SaberCheckerAPI::CK_ALLOC}, - {"safemalloc", SaberCheckerAPI::CK_ALLOC}, - {"safexcalloc", SaberCheckerAPI::CK_ALLOC}, - {"safexmalloc", SaberCheckerAPI::CK_ALLOC}, - {"savealloc", SaberCheckerAPI::CK_ALLOC}, - {"xalloc", SaberCheckerAPI::CK_ALLOC}, - {"xcalloc", SaberCheckerAPI::CK_ALLOC}, - {"xmalloc", SaberCheckerAPI::CK_ALLOC}, - {"SSL_CTX_new", SaberCheckerAPI::CK_ALLOC}, - {"SSL_new", SaberCheckerAPI::CK_ALLOC}, - {"VOS_MemAlloc", SaberCheckerAPI::CK_ALLOC}, - - {"VOS_MemFree", SaberCheckerAPI::CK_FREE}, - {"cfree", SaberCheckerAPI::CK_FREE}, - {"free", SaberCheckerAPI::CK_FREE}, - {"free_all_mem", SaberCheckerAPI::CK_FREE}, - {"freeaddrinfo", SaberCheckerAPI::CK_FREE}, - {"gcry_mpi_release", SaberCheckerAPI::CK_FREE}, - {"gcry_sexp_release", SaberCheckerAPI::CK_FREE}, - {"globfree", SaberCheckerAPI::CK_FREE}, - {"nhfree", SaberCheckerAPI::CK_FREE}, - {"obstack_free", SaberCheckerAPI::CK_FREE}, - {"safe_cfree", SaberCheckerAPI::CK_FREE}, - {"safe_free", SaberCheckerAPI::CK_FREE}, - {"safefree", SaberCheckerAPI::CK_FREE}, - {"safexfree", SaberCheckerAPI::CK_FREE}, - {"sm_free", SaberCheckerAPI::CK_FREE}, - {"vim_free", SaberCheckerAPI::CK_FREE}, - {"xfree", SaberCheckerAPI::CK_FREE}, - {"SSL_CTX_free", SaberCheckerAPI::CK_FREE}, - {"SSL_free", SaberCheckerAPI::CK_FREE}, - {"XFree", SaberCheckerAPI::CK_FREE}, - - {"fopen", SaberCheckerAPI::CK_FOPEN}, - {"\01_fopen", SaberCheckerAPI::CK_FOPEN}, - {"\01fopen64", SaberCheckerAPI::CK_FOPEN}, - {"\01readdir64", SaberCheckerAPI::CK_FOPEN}, - {"\01tmpfile64", SaberCheckerAPI::CK_FOPEN}, - {"fopen64", SaberCheckerAPI::CK_FOPEN}, - {"XOpenDisplay", SaberCheckerAPI::CK_FOPEN}, - {"XtOpenDisplay", SaberCheckerAPI::CK_FOPEN}, - {"fopencookie", SaberCheckerAPI::CK_FOPEN}, - {"popen", SaberCheckerAPI::CK_FOPEN}, - {"readdir", SaberCheckerAPI::CK_FOPEN}, - {"readdir64", SaberCheckerAPI::CK_FOPEN}, - {"gzdopen", SaberCheckerAPI::CK_FOPEN}, - {"iconv_open", SaberCheckerAPI::CK_FOPEN}, - {"tmpfile", SaberCheckerAPI::CK_FOPEN}, - {"tmpfile64", SaberCheckerAPI::CK_FOPEN}, - {"BIO_new_socket", SaberCheckerAPI::CK_FOPEN}, - {"gcry_md_open", SaberCheckerAPI::CK_FOPEN}, - {"gcry_cipher_open", SaberCheckerAPI::CK_FOPEN}, - - - {"fclose", SaberCheckerAPI::CK_FCLOSE}, - {"XCloseDisplay", SaberCheckerAPI::CK_FCLOSE}, - {"XtCloseDisplay", SaberCheckerAPI::CK_FCLOSE}, - {"__res_nclose", SaberCheckerAPI::CK_FCLOSE}, - {"pclose", SaberCheckerAPI::CK_FCLOSE}, - {"closedir", SaberCheckerAPI::CK_FCLOSE}, - {"dlclose", SaberCheckerAPI::CK_FCLOSE}, - {"gzclose", SaberCheckerAPI::CK_FCLOSE}, - {"iconv_close", SaberCheckerAPI::CK_FCLOSE}, - {"gcry_md_close", SaberCheckerAPI::CK_FCLOSE}, - {"gcry_cipher_close", SaberCheckerAPI::CK_FCLOSE}, - - //This must be the last entry. - {0, SaberCheckerAPI::CK_DUMMY} +// Each (name, type) pair will be inserted into the map. +// All entries of the same type must occur together (for error detection). +static const ei_pair ei_pairs[] = {{"alloc", SaberCheckerAPI::CK_ALLOC}, + {"alloc_check", SaberCheckerAPI::CK_ALLOC}, + {"alloc_clear", SaberCheckerAPI::CK_ALLOC}, + {"calloc", SaberCheckerAPI::CK_ALLOC}, + {"jpeg_alloc_huff_table", SaberCheckerAPI::CK_ALLOC}, + {"jpeg_alloc_quant_table", SaberCheckerAPI::CK_ALLOC}, + {"lalloc", SaberCheckerAPI::CK_ALLOC}, + {"lalloc_clear", SaberCheckerAPI::CK_ALLOC}, + {"malloc", SaberCheckerAPI::CK_ALLOC}, + {"nhalloc", SaberCheckerAPI::CK_ALLOC}, + {"oballoc", SaberCheckerAPI::CK_ALLOC}, + {"permalloc", SaberCheckerAPI::CK_ALLOC}, + {"png_create_info_struct", SaberCheckerAPI::CK_ALLOC}, + {"png_create_write_struct", SaberCheckerAPI::CK_ALLOC}, + {"safe_calloc", SaberCheckerAPI::CK_ALLOC}, + {"safe_malloc", SaberCheckerAPI::CK_ALLOC}, + {"safecalloc", SaberCheckerAPI::CK_ALLOC}, + {"safemalloc", SaberCheckerAPI::CK_ALLOC}, + {"safexcalloc", SaberCheckerAPI::CK_ALLOC}, + {"safexmalloc", SaberCheckerAPI::CK_ALLOC}, + {"savealloc", SaberCheckerAPI::CK_ALLOC}, + {"xalloc", SaberCheckerAPI::CK_ALLOC}, + {"xcalloc", SaberCheckerAPI::CK_ALLOC}, + {"xmalloc", SaberCheckerAPI::CK_ALLOC}, + {"SSL_CTX_new", SaberCheckerAPI::CK_ALLOC}, + {"SSL_new", SaberCheckerAPI::CK_ALLOC}, + {"VOS_MemAlloc", SaberCheckerAPI::CK_ALLOC}, + + {"VOS_MemFree", SaberCheckerAPI::CK_FREE}, + {"cfree", SaberCheckerAPI::CK_FREE}, + {"free", SaberCheckerAPI::CK_FREE}, + {"free_all_mem", SaberCheckerAPI::CK_FREE}, + {"freeaddrinfo", SaberCheckerAPI::CK_FREE}, + {"gcry_mpi_release", SaberCheckerAPI::CK_FREE}, + {"gcry_sexp_release", SaberCheckerAPI::CK_FREE}, + {"globfree", SaberCheckerAPI::CK_FREE}, + {"nhfree", SaberCheckerAPI::CK_FREE}, + {"obstack_free", SaberCheckerAPI::CK_FREE}, + {"safe_cfree", SaberCheckerAPI::CK_FREE}, + {"safe_free", SaberCheckerAPI::CK_FREE}, + {"safefree", SaberCheckerAPI::CK_FREE}, + {"safexfree", SaberCheckerAPI::CK_FREE}, + {"sm_free", SaberCheckerAPI::CK_FREE}, + {"vim_free", SaberCheckerAPI::CK_FREE}, + {"xfree", SaberCheckerAPI::CK_FREE}, + {"SSL_CTX_free", SaberCheckerAPI::CK_FREE}, + {"SSL_free", SaberCheckerAPI::CK_FREE}, + {"XFree", SaberCheckerAPI::CK_FREE}, + + {"fopen", SaberCheckerAPI::CK_FOPEN}, + {"\01_fopen", SaberCheckerAPI::CK_FOPEN}, + {"\01fopen64", SaberCheckerAPI::CK_FOPEN}, + {"\01readdir64", SaberCheckerAPI::CK_FOPEN}, + {"\01tmpfile64", SaberCheckerAPI::CK_FOPEN}, + {"fopen64", SaberCheckerAPI::CK_FOPEN}, + {"XOpenDisplay", SaberCheckerAPI::CK_FOPEN}, + {"XtOpenDisplay", SaberCheckerAPI::CK_FOPEN}, + {"fopencookie", SaberCheckerAPI::CK_FOPEN}, + {"popen", SaberCheckerAPI::CK_FOPEN}, + {"readdir", SaberCheckerAPI::CK_FOPEN}, + {"readdir64", SaberCheckerAPI::CK_FOPEN}, + {"gzdopen", SaberCheckerAPI::CK_FOPEN}, + {"iconv_open", SaberCheckerAPI::CK_FOPEN}, + {"tmpfile", SaberCheckerAPI::CK_FOPEN}, + {"tmpfile64", SaberCheckerAPI::CK_FOPEN}, + {"BIO_new_socket", SaberCheckerAPI::CK_FOPEN}, + {"gcry_md_open", SaberCheckerAPI::CK_FOPEN}, + {"gcry_cipher_open", SaberCheckerAPI::CK_FOPEN}, + + {"fclose", SaberCheckerAPI::CK_FCLOSE}, + {"XCloseDisplay", SaberCheckerAPI::CK_FCLOSE}, + {"XtCloseDisplay", SaberCheckerAPI::CK_FCLOSE}, + {"__res_nclose", SaberCheckerAPI::CK_FCLOSE}, + {"pclose", SaberCheckerAPI::CK_FCLOSE}, + {"closedir", SaberCheckerAPI::CK_FCLOSE}, + {"dlclose", SaberCheckerAPI::CK_FCLOSE}, + {"gzclose", SaberCheckerAPI::CK_FCLOSE}, + {"iconv_close", SaberCheckerAPI::CK_FCLOSE}, + {"gcry_md_close", SaberCheckerAPI::CK_FCLOSE}, + {"gcry_cipher_close", SaberCheckerAPI::CK_FCLOSE}, + + // This must be the last entry. + {0, SaberCheckerAPI::CK_DUMMY} }; - /*! * initialize the map */ void SaberCheckerAPI::init() { set t_seen; - CHECKER_TYPE prev_t= CK_DUMMY; + CHECKER_TYPE prev_t = CK_DUMMY; t_seen.insert(CK_DUMMY); - for(const ei_pair *p= ei_pairs; p->n; ++p) + for (const ei_pair* p = ei_pairs; p->n; ++p) { - if(p->t != prev_t) + if (p->t != prev_t) { - //This will detect if you move an entry to another block - // but forget to change the type. - if(t_seen.count(p->t)) + // This will detect if you move an entry to another block + // but forget to change the type. + if (t_seen.count(p->t)) { fputs(p->n, stderr); putc('\n', stderr); assert(!"ei_pairs not grouped by type"); } t_seen.insert(p->t); - prev_t= p->t; + prev_t = p->t; } - if(tdAPIMap.count(p->n)) + if (tdAPIMap.count(p->n)) { fputs(p->n, stderr); putc('\n', stderr); assert(!"duplicate name in ei_pairs"); } - tdAPIMap[p->n]= p->t; + tdAPIMap[p->n] = p->t; } } - - - - diff --git a/svf/lib/SABER/SaberCondAllocator.cpp b/svf/lib/SABER/SaberCondAllocator.cpp index 8313b8d9e..b65bc082e 100644 --- a/svf/lib/SABER/SaberCondAllocator.cpp +++ b/svf/lib/SABER/SaberCondAllocator.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * PathAllocator.cpp * @@ -46,26 +45,21 @@ u32_t ContextCond::maximumPathLen = 0; u32_t ContextCond::maximumPath = 0; u32_t SaberCondAllocator::totalCondNum = 0; - -SaberCondAllocator::SaberCondAllocator() -{ - -} +SaberCondAllocator::SaberCondAllocator() {} /*! * Allocate path condition for each branch */ -void SaberCondAllocator::allocate(const SVFModule *M) +void SaberCondAllocator::allocate(const SVFModule* M) { DBOUT(DGENERAL, outs() << pasMsg("path condition allocation starts\n")); - for (const auto &func: *M) + for (const auto& func : *M) { if (!SVFUtil::isExtCall(func)) { // Allocate conditions for a program. - for (SVFFunction::const_iterator bit = func->begin(), ebit = func->end(); - bit != ebit; ++bit) + for (SVFFunction::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = *bit; collectBBCallingProgExit(*bb); @@ -74,8 +68,7 @@ void SaberCondAllocator::allocate(const SVFModule *M) } } - if (Options::PrintPathCond()) - printPathCond(); + if (Options::PrintPathCond()) printPathCond(); DBOUT(DGENERAL, outs() << pasMsg("path condition allocation ends\n")); } @@ -83,7 +76,7 @@ void SaberCondAllocator::allocate(const SVFModule *M) /*! * Allocate conditions for a basic block and propagate its condition to its successors. */ -void SaberCondAllocator::allocateForBB(const SVFBasicBlock &bb) +void SaberCondAllocator::allocateForBB(const SVFBasicBlock& bb) { u32_t succ_number = bb.getNumSuccessors(); @@ -92,9 +85,9 @@ void SaberCondAllocator::allocateForBB(const SVFBasicBlock &bb) if (succ_number > 1) { - //allocate log2(num_succ) decision variables + // allocate log2(num_succ) decision variables double num = log(succ_number) / log(2); - u32_t bit_num = (u32_t) ceil(num); + u32_t bit_num = (u32_t)ceil(num); u32_t succ_index = 0; std::vector condVec; for (u32_t i = 0; i < bit_num; i++) @@ -108,14 +101,14 @@ void SaberCondAllocator::allocateForBB(const SVFBasicBlock &bb) { Condition path_cond = getTrueCond(); - ///TODO: handle BranchInst and SwitchInst individually here!! + /// TODO: handle BranchInst and SwitchInst individually here!! // for each successor decide its bit representation // decide whether each bit of succ_index is 1 or 0, if (three successor) succ_index is 000 then use C1^C2^C3 // if 001 use C1^C2^negC3 for (u32_t j = 0; j < bit_num; j++) { - //test each bit of this successor's index (binary representation) + // test each bit of this successor's index (binary representation) u32_t tool = 0x01 << j; if (tool & succ_index) { @@ -130,18 +123,17 @@ void SaberCondAllocator::allocateForBB(const SVFBasicBlock &bb) succ_index++; } - } } /*! * Get a branch condition */ -SaberCondAllocator::Condition SaberCondAllocator::getBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ) const +SaberCondAllocator::Condition SaberCondAllocator::getBranchCond(const SVFBasicBlock* bb, + const SVFBasicBlock* succ) const { u32_t pos = bb->getBBSuccessorPos(succ); - if(bb->getNumSuccessors() == 1) - return getTrueCond(); + if (bb->getNumSuccessors() == 1) return getTrueCond(); else { BBCondMap::const_iterator it = bbConds.find(bb); @@ -154,8 +146,7 @@ SaberCondAllocator::Condition SaberCondAllocator::getBranchCond(const SVFBasicBl SaberCondAllocator::Condition SaberCondAllocator::getEvalBrCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ) { - if (getCurEvalSVFGNode() && getCurEvalSVFGNode()->getValue()) - return evaluateBranchCond(bb, succ); + if (getCurEvalSVFGNode() && getCurEvalSVFGNode()->getValue()) return evaluateBranchCond(bb, succ); else return getBranchCond(bb, succ); } @@ -163,7 +154,7 @@ SaberCondAllocator::Condition SaberCondAllocator::getEvalBrCond(const SVFBasicBl /*! * Set a branch condition */ -void SaberCondAllocator::setBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ, const Condition &cond) +void SaberCondAllocator::setBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ, const Condition& cond) { /// we only care about basic blocks have more than one successor assert(bb->getNumSuccessors() > 1 && "not more than one successor??"); @@ -172,7 +163,7 @@ void SaberCondAllocator::setBranchCond(const SVFBasicBlock* bb, const SVFBasicBl /// FIXME: llvm getNumSuccessors allows duplicated block in the successors, it makes this assertion fail /// In this case we may waste a condition allocation, because the overwrite of the previous cond - //assert(condPosMap.find(pos) == condPosMap.end() && "this branch has already been set "); + // assert(condPosMap.find(pos) == condPosMap.end() && "this branch has already been set "); condPosMap[pos] = cond; } @@ -180,8 +171,8 @@ void SaberCondAllocator::setBranchCond(const SVFBasicBlock* bb, const SVFBasicBl /*! * Evaluate null like expression for source-sink related bug detection in SABER */ -SaberCondAllocator::Condition -SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const SVFBasicBlock* succ) +SaberCondAllocator::Condition SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt* branchStmt, + const SVFBasicBlock* succ) { const SVFBasicBlock* succ1 = branchStmt->getSuccessor(0)->getBB(); @@ -189,8 +180,7 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const if (isTestNullExpr(branchStmt->getCondition()->getValue())) { // succ is then branch - if (succ1 == succ) - return getFalseCond(); + if (succ1 == succ) return getFalseCond(); // succ is else branch else return getTrueCond(); @@ -198,8 +188,7 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const if (isTestNotNullExpr(branchStmt->getCondition()->getValue())) { // succ is then branch - if (succ1 == succ) - return getTrueCond(); + if (succ1 == succ) return getTrueCond(); // succ is else branch else return getFalseCond(); @@ -210,7 +199,8 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const /*! * Evaluate condition for program exit (e.g., exit(0)) */ -SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchStmt *branchStmt, const SVFBasicBlock* succ) +SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchStmt* branchStmt, + const SVFBasicBlock* succ) { const SVFBasicBlock* succ1 = branchStmt->getSuccessor(0)->getBB(); const SVFBasicBlock* succ2 = branchStmt->getSuccessor(1)->getBB(); @@ -222,8 +212,7 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchS if (branch1 && !branch2) { // succ is then branch - if (succ1 == succ) - return getFalseCond(); + if (succ1 == succ) return getFalseCond(); // succ is else branch else return getTrueCond(); @@ -232,8 +221,7 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchS else if (!branch1 && branch2) { // succ is else branch - if (succ2 == succ) - return getFalseCond(); + if (succ2 == succ) return getFalseCond(); // succ is then branch else return getTrueCond(); @@ -246,7 +234,6 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchS /// no branch call program exit else return Condition::nullExpr(); - } /*! @@ -254,33 +241,31 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchS * bb is loop header and succ is the only exit basic block outside the loop (excluding exit bbs which call program exit) * for all other case, we conservatively evaluate false for now */ -SaberCondAllocator::Condition SaberCondAllocator::evaluateLoopExitBranch(const SVFBasicBlock* bb, const SVFBasicBlock* dst) +SaberCondAllocator::Condition SaberCondAllocator::evaluateLoopExitBranch(const SVFBasicBlock* bb, + const SVFBasicBlock* dst) { const SVFFunction* svffun = bb->getParent(); assert(svffun == dst->getParent() && "two basic blocks should be in the same function"); if (svffun->isLoopHeader(bb)) { - Set filteredbbs; + Set filteredbbs; std::vector exitbbs; - svffun->getExitBlocksOfLoop(bb,exitbbs); + svffun->getExitBlocksOfLoop(bb, exitbbs); /// exclude exit bb which calls program exit - for(const SVFBasicBlock* eb : exitbbs) + for (const SVFBasicBlock* eb : exitbbs) { - if(!isBBCallsProgExit(eb)) - filteredbbs.insert(eb); + if (!isBBCallsProgExit(eb)) filteredbbs.insert(eb); } /// if the dst dominate all other loop exit bbs, then dst can certainly be reached bool allPDT = true; - for (const auto &filteredbb: filteredbbs) + for (const auto& filteredbb : filteredbbs) { - if (!postDominate(dst, filteredbb)) - allPDT = false; + if (!postDominate(dst, filteredbb)) allPDT = false; } - if (allPDT) - return getTrueCond(); + if (allPDT) return getTrueCond(); } return Condition::nullExpr(); } @@ -292,17 +277,17 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateLoopExitBranch(const S */ SaberCondAllocator::Condition SaberCondAllocator::evaluateBranchCond(const SVFBasicBlock* bb, const SVFBasicBlock* succ) { - if(bb->getNumSuccessors() == 1) + if (bb->getNumSuccessors() == 1) { return getTrueCond(); } const SVFInstruction* svfInst = bb->getTerminator(); - if (ICFGNode *icfgNode = getICFG()->getICFGNode(svfInst)) + if (ICFGNode* icfgNode = getICFG()->getICFGNode(svfInst)) { - for (const auto &svfStmt: icfgNode->getSVFStmts()) + for (const auto& svfStmt : icfgNode->getSVFStmts()) { - if (const BranchStmt *branchStmt = SVFUtil::dyn_cast(svfStmt)) + if (const BranchStmt* branchStmt = SVFUtil::dyn_cast(svfStmt)) { if (branchStmt->getNumSuccessors() == 2) { @@ -312,16 +297,13 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateBranchCond(const SVFBa (void)is_succ; // Suppress warning of unused variable under release build assert(is_succ && "not a successor??"); Condition evalLoopExit = evaluateLoopExitBranch(bb, succ); - if (!eq(evalLoopExit, Condition::nullExpr())) - return evalLoopExit; + if (!eq(evalLoopExit, Condition::nullExpr())) return evalLoopExit; Condition evalProgExit = evaluateProgExit(branchStmt, succ); - if (!eq(evalProgExit, Condition::nullExpr())) - return evalProgExit; + if (!eq(evalProgExit, Condition::nullExpr())) return evalProgExit; Condition evalTestNullLike = evaluateTestNullLikeExpr(branchStmt, succ); - if (!eq(evalTestNullLike, Condition::nullExpr())) - return evalTestNullLike; + if (!eq(evalTestNullLike, Condition::nullExpr())) return evalTestNullLike; break; } } @@ -331,23 +313,23 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateBranchCond(const SVFBa return getBranchCond(bb, succ); } -bool SaberCondAllocator::isEQCmp(const CmpStmt *cmp) const +bool SaberCondAllocator::isEQCmp(const CmpStmt* cmp) const { return (cmp->getPredicate() == CmpStmt::ICMP_EQ); } -bool SaberCondAllocator::isNECmp(const CmpStmt *cmp) const +bool SaberCondAllocator::isNECmp(const CmpStmt* cmp) const { return (cmp->getPredicate() == CmpStmt::ICMP_NE); } bool SaberCondAllocator::isTestNullExpr(const SVFValue* test) const { - if(const SVFInstruction* svfInst = SVFUtil::dyn_cast(test)) + if (const SVFInstruction* svfInst = SVFUtil::dyn_cast(test)) { - for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(getICFG()->getICFGNode(svfInst))) + for (const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(getICFG()->getICFGNode(svfInst))) { - if(const CmpStmt* cmp = SVFUtil::dyn_cast(stmt)) + if (const CmpStmt* cmp = SVFUtil::dyn_cast(stmt)) { return isTestContainsNullAndTheValue(cmp) && isEQCmp(cmp); } @@ -358,11 +340,11 @@ bool SaberCondAllocator::isTestNullExpr(const SVFValue* test) const bool SaberCondAllocator::isTestNotNullExpr(const SVFValue* test) const { - if(const SVFInstruction* svfInst = SVFUtil::dyn_cast(test)) + if (const SVFInstruction* svfInst = SVFUtil::dyn_cast(test)) { - for(const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(getICFG()->getICFGNode(svfInst))) + for (const SVFStmt* stmt : PAG::getPAG()->getSVFStmtList(getICFG()->getICFGNode(svfInst))) { - if(const CmpStmt* cmp = SVFUtil::dyn_cast(stmt)) + if (const CmpStmt* cmp = SVFUtil::dyn_cast(stmt)) { return isTestContainsNullAndTheValue(cmp) && isNECmp(cmp); } @@ -391,16 +373,16 @@ bool SaberCondAllocator::isTestNotNullExpr(const SVFValue* test) const * There is an direct edge 1->2 with value %3 * */ -bool SaberCondAllocator::isTestContainsNullAndTheValue(const CmpStmt *cmp) const +bool SaberCondAllocator::isTestContainsNullAndTheValue(const CmpStmt* cmp) const { const SVFValue* op0 = cmp->getOpVar(0)->getValue(); const SVFValue* op1 = cmp->getOpVar(1)->getValue(); if (SVFUtil::isa(op1)) { - Set inDirVal; + Set inDirVal; inDirVal.insert(getCurEvalSVFGNode()->getValue()); - for (const auto &it: getCurEvalSVFGNode()->getOutEdges()) + for (const auto& it : getCurEvalSVFGNode()->getOutEdges()) { inDirVal.insert(it->getDstNode()->getValue()); } @@ -408,9 +390,9 @@ bool SaberCondAllocator::isTestContainsNullAndTheValue(const CmpStmt *cmp) const } else if (SVFUtil::isa(op0)) { - Set inDirVal; + Set inDirVal; inDirVal.insert(getCurEvalSVFGNode()->getValue()); - for (const auto &it: getCurEvalSVFGNode()->getOutEdges()) + for (const auto& it : getCurEvalSVFGNode()->getOutEdges()) { inDirVal.insert(it->getDstNode()->getValue()); } @@ -422,7 +404,7 @@ bool SaberCondAllocator::isTestContainsNullAndTheValue(const CmpStmt *cmp) const /*! * Whether this basic block contains program exit function call */ -void SaberCondAllocator::collectBBCallingProgExit(const SVFBasicBlock &bb) +void SaberCondAllocator::collectBBCallingProgExit(const SVFBasicBlock& bb) { for (SVFBasicBlock::const_iterator it = bb.begin(), eit = bb.end(); it != eit; it++) @@ -446,10 +428,9 @@ bool SaberCondAllocator::isBBCallsProgExit(const SVFBasicBlock* bb) FunToExitBBsMap::const_iterator it = funToExitBBsMap.find(svfun); if (it != funToExitBBsMap.end()) { - for (const auto &bit: it->second) + for (const auto& bit : it->second) { - if (postDominate(bit, bb)) - return true; + if (postDominate(bit, bb)) return true; } } return false; @@ -461,13 +442,14 @@ bool SaberCondAllocator::isBBCallsProgExit(const SVFBasicBlock* bb) * Assume B0 (phi node) is the successor of both B1 and B2. * If B1 dominates B2, and B0 not dominate B2 then condition from B1-->B0 = neg(B1-->B2)^(B1-->B0) */ -SaberCondAllocator::Condition -SaberCondAllocator::getPHIComplementCond(const SVFBasicBlock* BB1, const SVFBasicBlock* BB2, const SVFBasicBlock* BB0) +SaberCondAllocator::Condition SaberCondAllocator::getPHIComplementCond(const SVFBasicBlock* BB1, + const SVFBasicBlock* BB2, + const SVFBasicBlock* BB0) { assert(BB1 && BB2 && "expect nullptr BB here!"); /// avoid both BB0 and BB1 dominate BB2 (e.g., while loop), then BB2 is not necessarily a complement BB - if (dominate(BB1, BB2) && ! dominate(BB0, BB2)) + if (dominate(BB1, BB2) && !dominate(BB0, BB2)) { Condition cond = ComputeIntraVFGGuard(BB1, BB2); return condNeg(cond); @@ -481,9 +463,9 @@ SaberCondAllocator::getPHIComplementCond(const SVFBasicBlock* BB1, const SVFBasi * src --c1--> callBB --true--> funEntryBB --c2--> dst * the InterCallVFGGuard is c1 ^ c2 */ -SaberCondAllocator::Condition -SaberCondAllocator::ComputeInterCallVFGGuard(const SVFBasicBlock* srcBB, const SVFBasicBlock* dstBB, - const SVFBasicBlock* callBB) +SaberCondAllocator::Condition SaberCondAllocator::ComputeInterCallVFGGuard(const SVFBasicBlock* srcBB, + const SVFBasicBlock* dstBB, + const SVFBasicBlock* callBB) { const SVFBasicBlock* funEntryBB = dstBB->getParent()->getEntryBlock(); @@ -498,8 +480,9 @@ SaberCondAllocator::ComputeInterCallVFGGuard(const SVFBasicBlock* srcBB, const S * src --c1--> funExitBB --true--> retBB --c2--> dst * the InterRetVFGGuard is c1 ^ c2 */ -SaberCondAllocator::Condition -SaberCondAllocator::ComputeInterRetVFGGuard(const SVFBasicBlock* srcBB, const SVFBasicBlock* dstBB, const SVFBasicBlock* retBB) +SaberCondAllocator::Condition SaberCondAllocator::ComputeInterRetVFGGuard(const SVFBasicBlock* srcBB, + const SVFBasicBlock* dstBB, + const SVFBasicBlock* retBB) { const SVFFunction* parent = srcBB->getParent(); const SVFBasicBlock* funExitBB = parent->getExitBB(); @@ -513,13 +496,13 @@ SaberCondAllocator::ComputeInterRetVFGGuard(const SVFBasicBlock* srcBB, const SV /*! * Compute intra-procedural guards between two SVFGNodes (inside same function) */ -SaberCondAllocator::Condition SaberCondAllocator::ComputeIntraVFGGuard(const SVFBasicBlock* srcBB, const SVFBasicBlock* dstBB) +SaberCondAllocator::Condition SaberCondAllocator::ComputeIntraVFGGuard(const SVFBasicBlock* srcBB, + const SVFBasicBlock* dstBB) { assert(srcBB->getParent() == dstBB->getParent() && "two basic blocks are not in the same function??"); - if (postDominate(dstBB, srcBB)) - return getTrueCond(); + if (postDominate(dstBB, srcBB)) return getTrueCond(); CFWorkList worklist; worklist.push(srcBB); @@ -533,8 +516,7 @@ SaberCondAllocator::Condition SaberCondAllocator::ComputeIntraVFGGuard(const SVF /// if the dstBB is the eligible loop exit of the current basic block /// we can early terminate the computation Condition loopExitCond = evaluateLoopExitBranch(bb, dstBB); - if (!eq(loopExitCond, Condition::nullExpr())) - return condAnd(cond, loopExitCond); + if (!eq(loopExitCond, Condition::nullExpr())) return condAnd(cond, loopExitCond); for (const SVFBasicBlock* succ : bb->getSuccessors()) { @@ -543,27 +525,23 @@ SaberCondAllocator::Condition SaberCondAllocator::ComputeIntraVFGGuard(const SVF /// note that we assume loop exit always post dominate loop bodys /// which means loops are approximated only once. Condition brCond; - if (postDominate(succ, bb)) - brCond = getTrueCond(); + if (postDominate(succ, bb)) brCond = getTrueCond(); else brCond = getEvalBrCond(bb, succ); - DBOUT(DSaber, outs() << " bb (" << bb->getName() << - ") --> " << "succ_bb (" << succ->getName() << ") condition: " << brCond << "\n"); + DBOUT(DSaber, outs() << " bb (" << bb->getName() << ") --> " + << "succ_bb (" << succ->getName() << ") condition: " << brCond << "\n"); Condition succPathCond = condAnd(cond, brCond); - if (setCFCond(succ, condOr(getCFCond(succ), succPathCond))) - worklist.push(succ); + if (setCFCond(succ, condOr(getCFCond(succ), succPathCond))) worklist.push(succ); } } - DBOUT(DSaber, outs() << " src_bb (" << srcBB->getName() << - ") --> " << "dst_bb (" << dstBB->getName() << ") condition: " << getCFCond(dstBB) - << "\n"); + DBOUT(DSaber, outs() << " src_bb (" << srcBB->getName() << ") --> " + << "dst_bb (" << dstBB->getName() << ") condition: " << getCFCond(dstBB) << "\n"); return getCFCond(dstBB); } - /*! * Print path conditions */ @@ -572,13 +550,13 @@ void SaberCondAllocator::printPathCond() outs() << "print path condition\n"; - for (const auto &bbCond: bbConds) + for (const auto& bbCond : bbConds) { const SVFBasicBlock* bb = bbCond.first; - for (const auto &cit: bbCond.second) + for (const auto& cit : bbCond.second) { u32_t i = 0; - for (const SVFBasicBlock* succ: bb->getSuccessors()) + for (const SVFBasicBlock* succ : bb->getSuccessors()) { if (i == cit.first) { @@ -607,8 +585,7 @@ SaberCondAllocator::Condition SaberCondAllocator::newCond(const SVFInstruction* } /// Whether lhs and rhs are equivalent branch conditions -bool SaberCondAllocator::isEquivalentBranchCond(const Condition &lhs, - const Condition &rhs) const +bool SaberCondAllocator::isEquivalentBranchCond(const Condition& lhs, const Condition& rhs) const { Condition::getSolver().push(); Condition::getSolver().add(lhs.getExpr() != rhs.getExpr()); /// check equal using z3 solver @@ -618,19 +595,18 @@ bool SaberCondAllocator::isEquivalentBranchCond(const Condition &lhs, } /// whether condition is satisfiable -bool SaberCondAllocator::isSatisfiable(const Condition &condition) +bool SaberCondAllocator::isSatisfiable(const Condition& condition) { Condition::getSolver().add(condition.getExpr()); z3::check_result result = Condition::getSolver().check(); Condition::getSolver().pop(); - if (result == z3::sat || result == z3::unknown) - return true; + if (result == z3::sat || result == z3::unknown) return true; else return false; } /// extract subexpression from a Z3 expression -void SaberCondAllocator::extractSubConds(const Condition &condition, NodeBS &support) const +void SaberCondAllocator::extractSubConds(const Condition& condition, NodeBS& support) const { if (condition.getExpr().num_args() == 1 && isNegCond(condition.id())) { @@ -638,12 +614,10 @@ void SaberCondAllocator::extractSubConds(const Condition &condition, NodeBS &sup return; } if (condition.getExpr().num_args() == 0) - if (!condition.getExpr().is_true() && !condition.getExpr().is_false()) - support.set(condition.getExpr().id()); + if (!condition.getExpr().is_true() && !condition.getExpr().is_false()) support.set(condition.getExpr().id()); for (u32_t i = 0; i < condition.getExpr().num_args(); ++i) { Condition expr = condition.getExpr().arg(i); extractSubConds(expr, support); } - } diff --git a/svf/lib/SABER/SaberSVFGBuilder.cpp b/svf/lib/SABER/SaberSVFGBuilder.cpp index 4278b6cc9..de7b509e6 100644 --- a/svf/lib/SABER/SaberSVFGBuilder.cpp +++ b/svf/lib/SABER/SaberSVFGBuilder.cpp @@ -34,7 +34,6 @@ #include "Util/Options.h" #include "SABER/SaberCondAllocator.h" - using namespace SVF; using namespace SVFUtil; @@ -59,11 +58,9 @@ void SaberSVFGBuilder::buildSVFG() AddExtActualParmSVFGNodes(pta->getCallGraph()); - if(pta->printStat()) - svfg->performStat(); + if (pta->printStat()) svfg->performStat(); } - /*! * Recursively collect global memory objects */ @@ -71,39 +68,35 @@ void SaberSVFGBuilder::collectGlobals(BVDataPTAImpl* pta) { SVFIR* pag = svfg->getPAG(); NodeVector worklist; - for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; it++) + for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; it++) { PAGNode* pagNode = it->second; - if (SVFUtil::isa(pagNode)) - continue; + if (SVFUtil::isa(pagNode)) continue; - if(GepObjVar* gepobj = SVFUtil::dyn_cast(pagNode)) + if (GepObjVar* gepobj = SVFUtil::dyn_cast(pagNode)) { - if(SVFUtil::isa(pag->getGNode(gepobj->getBaseNode()))) - continue; + if (SVFUtil::isa(pag->getGNode(gepobj->getBaseNode()))) continue; } - if(const SVFValue* val = pagNode->getValue()) + if (const SVFValue* val = pagNode->getValue()) { - if(SVFUtil::isa(val)) - worklist.push_back(it->first); + if (SVFUtil::isa(val)) worklist.push_back(it->first); } } NodeToPTSSMap cachedPtsMap; - while(!worklist.empty()) + while (!worklist.empty()) { NodeID id = worklist.back(); worklist.pop_back(); globs.set(id); const PointsTo& pts = pta->getPts(id); - for(PointsTo::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it) + for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) { - globs |= CollectPtsChain(pta,*it,cachedPtsMap); + globs |= CollectPtsChain(pta, *it, cachedPtsMap); } } } - /* * https://github.com/SVF-tools/SVF/issues/991 * @@ -125,7 +118,7 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT NodeID baseId = pag->getBaseObjVar(id); NodeToPTSSMap::iterator it = cachedPtsMap.find(baseId); - if(it!=cachedPtsMap.end()) + if (it != cachedPtsMap.end()) { return it->second; } @@ -135,10 +128,10 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT // base object if (!Options::CollectExtRetGlobals()) { - if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue()) + if (pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue()) { const SVFCallInst* inst = SVFUtil::dyn_cast(pag->getGNode(baseId)->getValue()); - if(inst && SVFUtil::isExtCall(inst)) + if (inst && SVFUtil::isExtCall(inst)) { return pts; } @@ -148,16 +141,15 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT pts |= pag->getFieldsAfterCollapse(baseId); WorkList worklist; - for(PointsTo::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it) - worklist.push(*it); + for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) worklist.push(*it); - while(!worklist.empty()) + while (!worklist.empty()) { NodeID nodeId = worklist.pop(); const PointsTo& tmp = pta->getPts(nodeId); - for(PointsTo::iterator it = tmp.begin(), eit = tmp.end(); it!=eit; ++it) + for (PointsTo::iterator it = tmp.begin(), eit = tmp.end(); it != eit; ++it) { - pts |= CollectPtsChain(pta,*it,cachedPtsMap); + pts |= CollectPtsChain(pta, *it, cachedPtsMap); } } return pts; @@ -167,7 +159,7 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT /*! * Decide whether the node and its points-to contains a global objects */ -bool SaberSVFGBuilder::accessGlobal(BVDataPTAImpl* pta,const PAGNode* pagNode) +bool SaberSVFGBuilder::accessGlobal(BVDataPTAImpl* pta, const PAGNode* pagNode) { NodeID id = pagNode->getId(); @@ -180,40 +172,41 @@ bool SaberSVFGBuilder::accessGlobal(BVDataPTAImpl* pta,const PAGNode* pagNode) void SaberSVFGBuilder::rmDerefDirSVFGEdges(BVDataPTAImpl* pta) { - for(SVFG::iterator it = svfg->begin(), eit = svfg->end(); it!=eit; ++it) + for (SVFG::iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it) { const SVFGNode* node = it->second; - if(const StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (const StmtSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { /// for store, connect the RHS/LHS pointer to its def - if(SVFUtil::isa(stmtNode)) + if (SVFUtil::isa(stmtNode)) { const SVFGNode* def = svfg->getDefSVFGNode(stmtNode->getPAGDstNode()); - if(SVFGEdge* edge = svfg->getIntraVFGEdge(def,stmtNode,SVFGEdge::IntraDirectVF)) + if (SVFGEdge* edge = svfg->getIntraVFGEdge(def, stmtNode, SVFGEdge::IntraDirectVF)) svfg->removeSVFGEdge(edge); else - assert((svfg->getKind()==VFG::FULLSVFG_OPT || svfg->getKind()==VFG::PTRONLYSVFG_OPT) && "Edge not found!"); + assert((svfg->getKind() == VFG::FULLSVFG_OPT || svfg->getKind() == VFG::PTRONLYSVFG_OPT) && + "Edge not found!"); - if(accessGlobal(pta,stmtNode->getPAGDstNode())) + if (accessGlobal(pta, stmtNode->getPAGDstNode())) { globSVFGNodes.insert(stmtNode); } } - else if(SVFUtil::isa(stmtNode)) + else if (SVFUtil::isa(stmtNode)) { const SVFGNode* def = svfg->getDefSVFGNode(stmtNode->getPAGSrcNode()); - if(SVFGEdge* edge = svfg->getIntraVFGEdge(def,stmtNode,SVFGEdge::IntraDirectVF)) + if (SVFGEdge* edge = svfg->getIntraVFGEdge(def, stmtNode, SVFGEdge::IntraDirectVF)) svfg->removeSVFGEdge(edge); else - assert((svfg->getKind()==VFG::FULLSVFG_OPT || svfg->getKind()==VFG::PTRONLYSVFG_OPT) && "Edge not found!"); + assert((svfg->getKind() == VFG::FULLSVFG_OPT || svfg->getKind() == VFG::PTRONLYSVFG_OPT) && + "Edge not found!"); - if(accessGlobal(pta,stmtNode->getPAGSrcNode())) + if (accessGlobal(pta, stmtNode->getPAGSrcNode())) { globSVFGNodes.insert(stmtNode); } } - } } } @@ -234,9 +227,9 @@ bool SaberSVFGBuilder::isStrongUpdate(const SVFGNode* node, NodeID& singleton, B singleton = *it; // Strong update can be made if this points-to target is not heap, array or field-insensitive. - if (!pta->isHeapMemObj(singleton) && !pta->isArrayMemObj(singleton) - && SVFIR::getPAG()->getBaseObj(singleton)->isFieldInsensitive() == false - && !pta->isLocalVarInRecursiveFun(singleton)) + if (!pta->isHeapMemObj(singleton) && !pta->isArrayMemObj(singleton) && + SVFIR::getPAG()->getBaseObj(singleton)->isFieldInsensitive() == false && + !pta->isLocalVarInRecursiveFun(singleton)) { isSU = true; } @@ -258,26 +251,27 @@ bool SaberSVFGBuilder::isStrongUpdate(const SVFGNode* node, NodeID& singleton, B void SaberSVFGBuilder::rmIncomingEdgeForSUStore(BVDataPTAImpl* pta) { - for(SVFG::iterator it = svfg->begin(), eit = svfg->end(); it!=eit; ++it) + for (SVFG::iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it) { const SVFGNode* node = it->second; - if(const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) + if (const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast(node)) { - if(SVFUtil::isa(stmtNode->getPAGEdge())) + if (SVFUtil::isa(stmtNode->getPAGEdge())) { NodeID singleton; - if(isStrongUpdate(node, singleton, pta)) + if (isStrongUpdate(node, singleton, pta)) { Set toRemove; - for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; ++it2) + for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; + ++it2) { if ((*it2)->isIndirectVFGEdge()) { toRemove.insert(*it2); } } - for (SVFGEdge* edge: toRemove) + for (SVFGEdge* edge : toRemove) { if (isa(edge->getSrcNode())) saberCondAllocator->getRemovedSUVFEdges()[edge->getSrcNode()].insert(edge->getDstNode()); @@ -289,32 +283,30 @@ void SaberSVFGBuilder::rmIncomingEdgeForSUStore(BVDataPTAImpl* pta) } } - /// Add actual parameter SVFGNode for 1st argument of a deallocation like external function void SaberSVFGBuilder::AddExtActualParmSVFGNodes(CallGraph* callgraph) { SVFIR* pag = SVFIR::getPAG(); - for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), - eit = pag->getCallSiteArgsMap().end(); it!=eit; ++it) + for (SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); + it != eit; ++it) { CallGraph::FunctionSet callees; callgraph->getCallees(it->first, callees); - for (CallGraph::FunctionSet::const_iterator cit = callees.begin(), - ecit = callees.end(); cit != ecit; cit++) + for (CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit != ecit; cit++) { const SVFFunction* fun = *cit; - if (SaberCheckerAPI::getCheckerAPI()->isMemDealloc(fun) - || SaberCheckerAPI::getCheckerAPI()->isFClose(fun)) + if (SaberCheckerAPI::getCheckerAPI()->isMemDealloc(fun) || SaberCheckerAPI::getCheckerAPI()->isFClose(fun)) { SVFIR::SVFVarList& arglist = it->second; - for(SVFIR::SVFVarList::const_iterator ait = arglist.begin(), aeit = arglist.end(); ait!=aeit; ++ait) + for (SVFIR::SVFVarList::const_iterator ait = arglist.begin(), aeit = arglist.end(); ait != aeit; ++ait) { - const PAGNode *pagNode = *ait; + const PAGNode* pagNode = *ait; if (pagNode->isPointer()) { addActualParmVFGNode(pagNode, it->first); - svfg->addIntraDirectVFEdge(svfg->getDefSVFGNode(pagNode)->getId(), svfg->getActualParmVFGNode(pagNode, it->first)->getId()); + svfg->addIntraDirectVFEdge(svfg->getDefSVFGNode(pagNode)->getId(), + svfg->getActualParmVFGNode(pagNode, it->first)->getId()); } } } diff --git a/svf/lib/SABER/SrcSnkDDA.cpp b/svf/lib/SABER/SrcSnkDDA.cpp index 707390abc..54a50a3e3 100644 --- a/svf/lib/SABER/SrcSnkDDA.cpp +++ b/svf/lib/SABER/SrcSnkDDA.cpp @@ -27,7 +27,6 @@ * Author: Yulei Sui */ - #include "Util/Options.h" #include "SABER/SrcSnkDDA.h" #include "Graphs/SVFGStat.h" @@ -44,13 +43,12 @@ void SrcSnkDDA::initialize(SVFModule* module) AndersenWaveDiff* ander = AndersenWaveDiff::createAndersenWaveDiff(pag); memSSA.setSaberCondAllocator(getSaberCondAllocator()); - if(Options::SABERFULLSVFG()) - svfg = memSSA.buildFullSVFG(ander); + if (Options::SABERFULLSVFG()) svfg = memSSA.buildFullSVFG(ander); else - svfg = memSSA.buildPTROnlySVFG(ander); + svfg = memSSA.buildPTROnlySVFG(ander); setGraph(memSSA.getSVFG()); callgraph = ander->getCallGraph(); - //AndersenWaveDiff::releaseAndersenWaveDiff(); + // AndersenWaveDiff::releaseAndersenWaveDiff(); /// allocate control-flow graph branch conditions getSaberCondAllocator()->allocate(getPAG()->getModule()); @@ -65,14 +63,13 @@ void SrcSnkDDA::analyze(SVFModule* module) ContextCond::setMaxCxtLen(Options::CxtLimit()); - for (SVFGNodeSetIter iter = sourcesBegin(), eiter = sourcesEnd(); - iter != eiter; ++iter) + for (SVFGNodeSetIter iter = sourcesBegin(), eiter = sourcesEnd(); iter != eiter; ++iter) { setCurSlice(*iter); DBOUT(DGENERAL, outs() << "Analysing slice:" << (*iter)->getId() << ")\n"); ContextCond cxt; - DPIm item((*iter)->getId(),cxt); + DPIm item((*iter)->getId(), cxt); forwardTraverse(item); /// do not consider there is bug when reaching a global SVFGNode @@ -83,23 +80,23 @@ void SrcSnkDDA::analyze(SVFModule* module) } else { - DBOUT(DSaber, outs() << "Forward process for slice:" << (*iter)->getId() << " (size = " << getCurSlice()->getForwardSliceSize() << ")\n"); + DBOUT(DSaber, outs() << "Forward process for slice:" << (*iter)->getId() + << " (size = " << getCurSlice()->getForwardSliceSize() << ")\n"); - for (SVFGNodeSetIter sit = getCurSlice()->sinksBegin(), esit = - getCurSlice()->sinksEnd(); sit != esit; ++sit) + for (SVFGNodeSetIter sit = getCurSlice()->sinksBegin(), esit = getCurSlice()->sinksEnd(); sit != esit; + ++sit) { ContextCond cxt; - DPIm item((*sit)->getId(),cxt); + DPIm item((*sit)->getId(), cxt); backwardTraverse(item); } - DBOUT(DSaber, outs() << "Backward process for slice:" << (*iter)->getId() << " (size = " << getCurSlice()->getBackwardSliceSize() << ")\n"); + DBOUT(DSaber, outs() << "Backward process for slice:" << (*iter)->getId() + << " (size = " << getCurSlice()->getBackwardSliceSize() << ")\n"); - if(Options::DumpSlice()) - annotateSlice(_curSlice); + if (Options::DumpSlice()) annotateSlice(_curSlice); - if(_curSlice->AllPathReachableSolve()) - _curSlice->setAllReachable(); + if (_curSlice->AllPathReachableSolve()) _curSlice->setAllReachable(); DBOUT(DSaber, outs() << "Guard computation for slice:" << (*iter)->getId() << ")\n"); } @@ -107,10 +104,8 @@ void SrcSnkDDA::analyze(SVFModule* module) reportBug(getCurSlice()); } finalize(); - } - /*! * determine whether a SVFGNode n is in a allocation wrapper function, * if so, return all SVFGNodes which receive the value of node n @@ -126,50 +121,46 @@ bool SrcSnkDDA::isInAWrapper(const SVFGNode* src, CallSiteSet& csIdSet) u32_t step = 0; while (!worklist.empty()) { - const SVFGNode* node = worklist.pop(); + const SVFGNode* node = worklist.pop(); - if(visited.test(node->getId())==0) - visited.set(node->getId()); + if (visited.test(node->getId()) == 0) visited.set(node->getId()); else continue; // reaching maximum steps when traversing on SVFG to identify a memory allocation wrapper - if (step++ > Options::MaxStepInWrapper()) - return false; + if (step++ > Options::MaxStepInWrapper()) return false; - for (SVFGNode::const_iterator it = node->OutEdgeBegin(), eit = - node->OutEdgeEnd(); it != eit; ++it) + for (SVFGNode::const_iterator it = node->OutEdgeBegin(), eit = node->OutEdgeEnd(); it != eit; ++it) { const SVFGEdge* edge = (*it); - //assert(edge->isDirectVFGEdge() && "the edge should always be direct VF"); - // if this is a call edge - if(edge->isCallDirectVFGEdge()) + // assert(edge->isDirectVFGEdge() && "the edge should always be direct VF"); + // if this is a call edge + if (edge->isCallDirectVFGEdge()) { return false; } // if this is a return edge - else if(edge->isRetDirectVFGEdge()) + else if (edge->isRetDirectVFGEdge()) { reachFunExit = true; csIdSet.insert(getSVFG()->getCallSite(SVFUtil::cast(edge)->getCallSiteId())); } // (1) an intra direct edge, we will keep tracking - // (2) an intra indirect edge, we only track if the succ SVFGNode is a load, which means we only track one level store-load pair . - // (3) do not track for all other interprocedural edges. + // (2) an intra indirect edge, we only track if the succ SVFGNode is a load, which means we only track one + // level store-load pair . (3) do not track for all other interprocedural edges. else { const SVFGNode* succ = edge->getDstNode(); - if(SVFUtil::isa(edge)) + if (SVFUtil::isa(edge)) { - if (SVFUtil::isa(succ)) + if (SVFUtil::isa(succ)) { worklist.push(succ); } } - else if(SVFUtil::isa(edge)) + else if (SVFUtil::isa(edge)) { - if(SVFUtil::isa(succ)) + if (SVFUtil::isa(succ)) { worklist.push(succ); } @@ -179,40 +170,38 @@ bool SrcSnkDDA::isInAWrapper(const SVFGNode* src, CallSiteSet& csIdSet) } } } - if(reachFunExit) - return true; + if (reachFunExit) return true; else return false; } - /*! * Propagate information forward by matching context */ void SrcSnkDDA::FWProcessOutgoingEdge(const DPIm& item, SVFGEdge* edge) { - DBOUT(DSaber,outs() << "\n##processing source: " << getCurSlice()->getSource()->getId() <<" forward propagate from (" << edge->getSrcID()); + DBOUT(DSaber, outs() << "\n##processing source: " << getCurSlice()->getSource()->getId() + << " forward propagate from (" << edge->getSrcID()); // for indirect SVFGEdge, the propagation should follow the def-use chains // points-to on the edge indicate whether the object of source node can be propagated const SVFGNode* dstNode = edge->getDstNode(); - DPIm newItem(dstNode->getId(),item.getContexts()); + DPIm newItem(dstNode->getId(), item.getContexts()); /// handle globals here - if(isGlobalSVFGNode(dstNode) || getCurSlice()->isReachGlobal()) + if (isGlobalSVFGNode(dstNode) || getCurSlice()->isReachGlobal()) { getCurSlice()->setReachGlobal(); return; } - /// perform context sensitive reachability // push context for calling if (edge->isCallVFGEdge()) { CallSiteID csId = 0; - if(const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) + if (const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) csId = callEdge->getCallSiteId(); else csId = SVFUtil::cast(edge)->getCallSiteId(); @@ -224,8 +213,7 @@ void SrcSnkDDA::FWProcessOutgoingEdge(const DPIm& item, SVFGEdge* edge) else if (edge->isRetVFGEdge()) { CallSiteID csId = 0; - if(const RetDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) - csId = callEdge->getCallSiteId(); + if (const RetDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) csId = callEdge->getCallSiteId(); else csId = SVFUtil::cast(edge)->getCallSiteId(); @@ -238,17 +226,17 @@ void SrcSnkDDA::FWProcessOutgoingEdge(const DPIm& item, SVFGEdge* edge) } /// whether this dstNode has been visited or not - if(forwardVisited(dstNode,newItem)) + if (forwardVisited(dstNode, newItem)) { - DBOUT(DSaber,outs() << " node "<< dstNode->getId() <<" has been visited\n"); + DBOUT(DSaber, outs() << " node " << dstNode->getId() << " has been visited\n"); return; } else addForwardVisited(dstNode, newItem); - if(pushIntoWorklist(newItem)) - DBOUT(DSaber,outs() << " --> " << edge->getDstID() << ", cxt size: " << newItem.getContexts().cxtSize() <<")\n"); - + if (pushIntoWorklist(newItem)) + DBOUT(DSaber, + outs() << " --> " << edge->getDstID() << ", cxt size: " << newItem.getContexts().cxtSize() << ")\n"); } /*! @@ -256,10 +244,9 @@ void SrcSnkDDA::FWProcessOutgoingEdge(const DPIm& item, SVFGEdge* edge) */ void SrcSnkDDA::BWProcessIncomingEdge(const DPIm&, SVFGEdge* edge) { - DBOUT(DSaber,outs() << "backward propagate from (" << edge->getDstID() << " --> " << edge->getSrcID() << ")\n"); + DBOUT(DSaber, outs() << "backward propagate from (" << edge->getDstID() << " --> " << edge->getSrcID() << ")\n"); const SVFGNode* srcNode = edge->getSrcNode(); - if(backwardVisited(srcNode)) - return; + if (backwardVisited(srcNode)) return; else addBackwardVisited(srcNode); @@ -271,32 +258,31 @@ void SrcSnkDDA::BWProcessIncomingEdge(const DPIm&, SVFGEdge* edge) /// Set current slice void SrcSnkDDA::setCurSlice(const SVFGNode* src) { - if(_curSlice!=nullptr) + if (_curSlice != nullptr) { delete _curSlice; _curSlice = nullptr; clearVisitedMap(); } - _curSlice = new ProgSlice(src,getSaberCondAllocator(), getSVFG()); + _curSlice = new ProgSlice(src, getSaberCondAllocator(), getSVFG()); } void SrcSnkDDA::annotateSlice(ProgSlice* slice) { getSVFG()->getStat()->addToSources(slice->getSource()); - for(SVFGNodeSetIter it = slice->sinksBegin(), eit = slice->sinksEnd(); it!=eit; ++it ) + for (SVFGNodeSetIter it = slice->sinksBegin(), eit = slice->sinksEnd(); it != eit; ++it) getSVFG()->getStat()->addToSinks(*it); - for(SVFGNodeSetIter it = slice->forwardSliceBegin(), eit = slice->forwardSliceEnd(); it!=eit; ++it ) + for (SVFGNodeSetIter it = slice->forwardSliceBegin(), eit = slice->forwardSliceEnd(); it != eit; ++it) getSVFG()->getStat()->addToForwardSlice(*it); - for(SVFGNodeSetIter it = slice->backwardSliceBegin(), eit = slice->backwardSliceEnd(); it!=eit; ++it ) + for (SVFGNodeSetIter it = slice->backwardSliceBegin(), eit = slice->backwardSliceEnd(); it != eit; ++it) getSVFG()->getStat()->addToBackwardSlice(*it); } void SrcSnkDDA::dumpSlices() { - if(Options::DumpSlice()) - const_cast(getSVFG())->dump("Slice",true); + if (Options::DumpSlice()) const_cast(getSVFG())->dump("Slice", true); } void SrcSnkDDA::printZ3Stat() diff --git a/svf/lib/SVFIR/PAGBuilderFromFile.cpp b/svf/lib/SVFIR/PAGBuilderFromFile.cpp index 6cfda819c..4bd4fb9aa 100644 --- a/svf/lib/SVFIR/PAGBuilderFromFile.cpp +++ b/svf/lib/SVFIR/PAGBuilderFromFile.cpp @@ -28,9 +28,9 @@ */ #include "SVFIR/PAGBuilderFromFile.h" -#include // for PAGBuilderFromFile -#include // for PAGBuilderFromFile -#include // for PAGBuilderFromFile +#include // for PAGBuilderFromFile +#include // for PAGBuilderFromFile +#include // for PAGBuilderFromFile using namespace std; using namespace SVF; @@ -78,8 +78,7 @@ SVFIR* PAGBuilderFromFile::build() token_count++; } - if (token_count == 0) - continue; + if (token_count == 0) continue; else if (token_count == 2) { @@ -89,8 +88,7 @@ SVFIR* PAGBuilderFromFile::build() ss >> nodeId; ss >> nodetype; outs() << "reading node :" << nodeId << "\n"; - if (nodetype == "v") - pag->addDummyValNode(nodeId); + if (nodetype == "v") pag->addDummyValNode(nodeId); else if (nodetype == "o") { const MemObj* mem = pag->addDummyMemObj(nodeId, nullptr); @@ -112,16 +110,15 @@ SVFIR* PAGBuilderFromFile::build() ss >> edge; ss >> nodeDst; ss >> offsetOrCSId; - outs() << "reading edge :" << nodeSrc << " " << edge << " " - << nodeDst << " offsetOrCSId=" << offsetOrCSId << " \n"; + outs() << "reading edge :" << nodeSrc << " " << edge << " " << nodeDst + << " offsetOrCSId=" << offsetOrCSId << " \n"; addEdge(nodeSrc, nodeDst, offsetOrCSId, edge); } else { if (!line.empty()) { - outs() << "format not supported, token count = " - << token_count << "\n"; + outs() << "format not supported, token count = " << token_count << "\n"; assert(false && "format not supported"); } } @@ -134,8 +131,7 @@ SVFIR* PAGBuilderFromFile::build() /// new gep node's id from lower bound, nodeNum may not reflect the total nodes. u32_t lower_bound = gepNodeNumIndex; - for(u32_t i = 0; i < lower_bound; i++) - pag->incNodeNum(); + for (u32_t i = 0; i < lower_bound; i++) pag->incNodeNum(); pag->setNodeNumAfterPAGBuild(pag->getTotalNodeNum()); @@ -145,18 +141,16 @@ SVFIR* PAGBuilderFromFile::build() /*! * Add SVFIR edge according to a file format */ -void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, - APOffset offsetOrCSId, std::string edge) +void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, APOffset offsetOrCSId, std::string edge) { - //check whether these two nodes available + // check whether these two nodes available PAGNode* srcNode = pag->getGNode(srcID); PAGNode* dstNode = pag->getGNode(dstID); /// sanity check for SVFIR from txt assert(SVFUtil::isa(dstNode) && "dst not an value node?"); - if(edge=="addr") - assert(SVFUtil::isa(srcNode) && "src not an value node?"); + if (edge == "addr") assert(SVFUtil::isa(srcNode) && "src not an value node?"); else assert(!SVFUtil::isa(srcNode) && "src not an object node?"); @@ -234,7 +228,7 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, else if (edge == "call") pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, nullptr, nullptr)); else if (edge == "ret") - pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, nullptr,nullptr)); + pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, nullptr, nullptr)); else if (edge == "cmp") pag->addCmpStmt(srcID, dstID, dstID, dstID); else if (edge == "binary-op") @@ -248,9 +242,8 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, else if (edge == "branch") { assert(false && "fix successors here!"); - //pag->addBranchStmt(srcID, dstID, nullptr); + // pag->addBranchStmt(srcID, dstID, nullptr); } else assert(false && "format not support, can not create such edge"); } - diff --git a/svf/lib/SVFIR/SVFFileSystem.cpp b/svf/lib/SVFIR/SVFFileSystem.cpp index 4e8675be5..d5565665d 100644 --- a/svf/lib/SVFIR/SVFFileSystem.cpp +++ b/svf/lib/SVFIR/SVFFileSystem.cpp @@ -8,8 +8,7 @@ #include #include -static const Option humanReadableOption( - "human-readable", "Whether to output human-readable JSON", true); +static const Option humanReadableOption("human-readable", "Whether to output human-readable JSON", true); namespace SVF { @@ -42,11 +41,9 @@ SVFType* createSVFType(SVFType::GNodeK kind, bool isSingleValTy) } } -static SVFValue* createSVFValue(SVFValue::GNodeK kind, const SVFType* type, - std::string&& name) +static SVFValue* createSVFValue(SVFValue::GNodeK kind, const SVFType* type, std::string&& name) { - auto creator = [=]() -> SVFValue* - { + auto creator = [=]() -> SVFValue* { switch (kind) { default: @@ -90,8 +87,7 @@ static SVFValue* createSVFValue(SVFValue::GNodeK kind, const SVFType* type, return val; } -template -static inline void readSmallNumber(const cJSON* obj, SmallNumberType& val) +template static inline void readSmallNumber(const cJSON* obj, SmallNumberType& val) { val = static_cast(jsonGetNumber(obj)); } @@ -99,8 +95,7 @@ static inline void readSmallNumber(const cJSON* obj, SmallNumberType& val) template static inline void readBigNumber(const cJSON* obj, BigNumberType& val, CStrToVal conv) { - ABORT_IFNOT(jsonIsString(obj), - "Expect (number) string JSON for " << JSON_KEY(obj)); + ABORT_IFNOT(jsonIsString(obj), "Expect (number) string JSON for " << JSON_KEY(obj)); val = conv(obj->valuestring); } @@ -156,8 +151,8 @@ cJSON* SVFIRWriter::virtToJson(const SVFType* type) default: assert(false && "Impossible SVFType kind"); -#define CASE(Kind) \ - case SVFType::Kind: \ +#define CASE(Kind) \ + case SVFType::Kind: \ return contentToJson(static_cast(type)) CASE(SVFTy); @@ -180,8 +175,8 @@ cJSON* SVFIRWriter::virtToJson(const SVFValue* value) default: assert(false && "Impossible SVFValue kind"); -#define CASE(ValueKind, type) \ - case SVFValue::ValueKind: \ +#define CASE(ValueKind, type) \ + case SVFValue::ValueKind: \ return contentToJson(static_cast(value)) CASE(SVFVal, SVFValue); @@ -211,8 +206,8 @@ cJSON* SVFIRWriter::virtToJson(const SVFVar* var) default: assert(false && "Unknown SVFVar kind"); -#define CASE(VarKind, VarType) \ - case SVFVar::VarKind: \ +#define CASE(VarKind, VarType) \ + case SVFVar::VarKind: \ return contentToJson(static_cast(var)) CASE(ValNode, ValVar); @@ -235,8 +230,8 @@ cJSON* SVFIRWriter::virtToJson(const SVFStmt* stmt) default: assert(false && "Unknown SVFStmt kind"); -#define CASE(EdgeKind, EdgeType) \ - case SVFStmt::EdgeKind: \ +#define CASE(EdgeKind, EdgeType) \ + case SVFStmt::EdgeKind: \ return contentToJson(static_cast(stmt)) CASE(Addr, AddrStmt); @@ -265,8 +260,8 @@ cJSON* SVFIRWriter::virtToJson(const ICFGNode* node) default: assert(false && "Unknown ICFGNode kind"); -#define CASE(NodeKind, NodeType) \ - case ICFGNode::NodeKind: \ +#define CASE(NodeKind, NodeType) \ + case ICFGNode::NodeKind: \ return contentToJson(static_cast(node)) CASE(IntraBlock, IntraICFGNode); @@ -811,25 +806,21 @@ bool jsonAddStringToObject(cJSON* obj, const char* name, const std::string& s) bool jsonIsBool(const cJSON* item) { - return humanReadableOption() - ? cJSON_IsBool(item) - : cJSON_IsNumber(item) && - (item->valuedouble == 0 || item->valuedouble == 1); + return humanReadableOption() ? cJSON_IsBool(item) + : cJSON_IsNumber(item) && (item->valuedouble == 0 || item->valuedouble == 1); } bool jsonIsBool(const cJSON* item, bool& flag) { if (humanReadableOption()) { - if (!cJSON_IsBool(item)) - return false; + if (!cJSON_IsBool(item)) return false; flag = cJSON_IsTrue(item); return true; } else { - if (!cJSON_IsNumber(item)) - return false; + if (!cJSON_IsNumber(item)) return false; flag = item->valuedouble == 1; return true; } @@ -871,7 +862,7 @@ bool jsonKeyEquals(const cJSON* item, const char* key) return item && !(humanReadableOption() && std::strcmp(item->string, key)); } -std::pair jsonUnpackPair(const cJSON* item) +std::pair jsonUnpackPair(const cJSON* item) { ABORT_IFNOT(jsonIsArray(item), "Expected array as pair"); cJSON* child1 = item->child; @@ -945,8 +936,7 @@ bool jsonAddPairToMap(cJSON* mapObj, cJSON* key, cJSON* value) bool jsonAddItemToObject(cJSON* obj, const char* name, cJSON* item) { - return humanReadableOption() ? cJSON_AddItemToObject(obj, name, item) - : cJSON_AddItemToArray(obj, item); + return humanReadableOption() ? cJSON_AddItemToObject(obj, name, item) : cJSON_AddItemToArray(obj, item); } bool jsonAddItemToArray(cJSON* array, cJSON* item) @@ -984,15 +974,13 @@ SVFModuleWriter::SVFModuleWriter(const SVFModule* svfModule) stInfoPool.saveID(stInfo); } - svfValuePool.reserve(svfModule->getFunctionSet().size() + - svfModule->getConstantSet().size() + + svfValuePool.reserve(svfModule->getFunctionSet().size() + svfModule->getConstantSet().size() + svfModule->getOtherValueSet().size()); } SVFIRWriter::SVFIRWriter(const SVFIR* svfir) : svfIR(svfir), svfModuleWriter(svfir->svfModule), icfgWriter(svfir->icfg), - chgWriter(SVFUtil::dyn_cast(svfir->chgraph)), - irGraphWriter(svfir) + chgWriter(SVFUtil::dyn_cast(svfir->chgraph)), irGraphWriter(svfir) { } @@ -1012,8 +1000,7 @@ void SVFIRWriter::writeJsonToPath(const SVFIR* svfir, const std::string& path) } else { - SVFUtil::errs() << "Failed to open file '" << path - << "' to write SVFIR's JSON\n"; + SVFUtil::errs() << "Failed to open file '" << path << "' to write SVFIR's JSON\n"; } } @@ -1030,8 +1017,7 @@ const char* SVFIRWriter::numToStr(size_t n) SVFIRWriter::autoCStr SVFIRWriter::generateJsonString() { autoJSON object = generateJson(); - char* str = humanReadableOption() ? cJSON_Print(object.get()) - : cJSON_PrintUnformatted(object.get()); + char* str = humanReadableOption() ? cJSON_Print(object.get()) : cJSON_PrintUnformatted(object.get()); return {str, cJSON_free}; } @@ -1399,19 +1385,19 @@ SVFIR* SVFIRReader::read(const cJSON* root) const cJSON* SVFIRReader::createObjs(const cJSON* root) { -#define READ_CREATE_NODE_FWD(GType) \ - [](const cJSON*& nodeJson) { \ - JSON_DEF_READ_FWD(nodeJson, NodeID, id); \ - JSON_DEF_READ_FWD(nodeJson, GNodeK, nodeKind); \ - return std::make_pair(id, create##GType##Node(id, nodeKind)); \ +#define READ_CREATE_NODE_FWD(GType) \ + [](const cJSON*& nodeJson) { \ + JSON_DEF_READ_FWD(nodeJson, NodeID, id); \ + JSON_DEF_READ_FWD(nodeJson, GNodeK, nodeKind); \ + return std::make_pair(id, create##GType##Node(id, nodeKind)); \ } -#define READ_CREATE_EDGE_FWD(GType) \ - [](const cJSON*& edgeJson) { \ - JSON_DEF_READ_FWD(edgeJson, GEdgeFlag, edgeFlag); \ - auto kind = applyEdgeMask(edgeFlag); \ - auto edge = create##GType##Edge(kind); \ - setEdgeFlag(edge, edgeFlag); \ - return edge; \ +#define READ_CREATE_EDGE_FWD(GType) \ + [](const cJSON*& edgeJson) { \ + JSON_DEF_READ_FWD(edgeJson, GEdgeFlag, edgeFlag); \ + auto kind = applyEdgeMask(edgeFlag); \ + auto edge = create##GType##Edge(kind); \ + setEdgeFlag(edge, edgeFlag); \ + return edge; \ } ABORT_IFNOT(jsonIsObject(root), "Root should be an object"); @@ -1421,103 +1407,62 @@ const cJSON* SVFIRReader::createObjs(const cJSON* root) svfModuleReader.createObjs( svfModule, // SVFType Creator - [](const cJSON*& svfTypeFldJson) - { - JSON_DEF_READ_FWD(svfTypeFldJson, SVFType::GNodeK, kind); - JSON_DEF_READ_FWD(svfTypeFldJson, bool, isSingleValTy); - return createSVFType(kind, isSingleValTy); - }, - // SVFType Filler - [this](const cJSON*& svfVarFldJson, SVFType* type) - { - virtFill(svfVarFldJson, type); - }, - // SVFValue Creator - [this](const cJSON*& svfValueFldJson) - { - JSON_DEF_READ_FWD(svfValueFldJson, SVFValue::GNodeK, kind); - JSON_DEF_READ_FWD(svfValueFldJson, const SVFType*, type, {}); - JSON_DEF_READ_FWD(svfValueFldJson, std::string, name); - return createSVFValue(kind, type, std::move(name)); - }, - // SVFValue Filler - [this](const cJSON*& svfVarFldJson, SVFValue* value) - { - virtFill(svfVarFldJson, value); - }, - // StInfo Creator (no filler needed) - [this](const cJSON*& stInfoFldJson) - { - JSON_DEF_READ_FWD(stInfoFldJson, u32_t, stride); - auto si = new StInfo(stride); - fill(stInfoFldJson, si); - ABORT_IFNOT(!stInfoFldJson, "StInfo has extra field"); - return si; - }); + [](const cJSON*& svfTypeFldJson) { + JSON_DEF_READ_FWD(svfTypeFldJson, SVFType::GNodeK, kind); + JSON_DEF_READ_FWD(svfTypeFldJson, bool, isSingleValTy); + return createSVFType(kind, isSingleValTy); + }, + // SVFType Filler + [this](const cJSON*& svfVarFldJson, SVFType* type) { virtFill(svfVarFldJson, type); }, + // SVFValue Creator + [this](const cJSON*& svfValueFldJson) { + JSON_DEF_READ_FWD(svfValueFldJson, SVFValue::GNodeK, kind); + JSON_DEF_READ_FWD(svfValueFldJson, const SVFType*, type, {}); + JSON_DEF_READ_FWD(svfValueFldJson, std::string, name); + return createSVFValue(kind, type, std::move(name)); + }, + // SVFValue Filler + [this](const cJSON*& svfVarFldJson, SVFValue* value) { virtFill(svfVarFldJson, value); }, + // StInfo Creator (no filler needed) + [this](const cJSON*& stInfoFldJson) { + JSON_DEF_READ_FWD(stInfoFldJson, u32_t, stride); + auto si = new StInfo(stride); + fill(stInfoFldJson, si); + ABORT_IFNOT(!stInfoFldJson, "StInfo has extra field"); + return si; + }); const cJSON* const symInfo = svfModule->next; CHECK_JSON_KEY(symInfo); - symTableReader.createObjs( - symInfo, - // MemObj Creator (no filler needed) - [this](const cJSON*& memObjFldJson) - { - JSON_DEF_READ_FWD(memObjFldJson, SymID, symId); - JSON_DEF_READ_FWD(memObjFldJson, ObjTypeInfo*, typeInfo, {}); - JSON_DEF_READ_FWD(memObjFldJson, const SVFValue*, refVal, {}); - return std::make_pair(symId, new MemObj(symId, typeInfo, refVal)); - }); + symTableReader.createObjs(symInfo, + // MemObj Creator (no filler needed) + [this](const cJSON*& memObjFldJson) { + JSON_DEF_READ_FWD(memObjFldJson, SymID, symId); + JSON_DEF_READ_FWD(memObjFldJson, ObjTypeInfo*, typeInfo, {}); + JSON_DEF_READ_FWD(memObjFldJson, const SVFValue*, refVal, {}); + return std::make_pair(symId, new MemObj(symId, typeInfo, refVal)); + }); const cJSON* const icfg = symInfo->next; CHECK_JSON_KEY(icfg); - icfgReader.createObjs(icfg, READ_CREATE_NODE_FWD(ICFG), - READ_CREATE_EDGE_FWD(ICFG), - [](auto) - { - return new SVFLoop({}, 0); - }); + icfgReader.createObjs(icfg, READ_CREATE_NODE_FWD(ICFG), READ_CREATE_EDGE_FWD(ICFG), + [](auto) { return new SVFLoop({}, 0); }); const cJSON* const chgraph = icfg->next; CHECK_JSON_KEY(chgraph); - chGraphReader.createObjs(chgraph, READ_CREATE_NODE_FWD(CH), - READ_CREATE_EDGE_FWD(CH)); + chGraphReader.createObjs(chgraph, READ_CREATE_NODE_FWD(CH), READ_CREATE_EDGE_FWD(CH)); const cJSON* const irGraph = chgraph->next; CHECK_JSON_KEY(irGraph); - irGraphReader.createObjs(irGraph, READ_CREATE_NODE_FWD(PAG), - READ_CREATE_EDGE_FWD(PAG)); + irGraphReader.createObjs(irGraph, READ_CREATE_NODE_FWD(PAG), READ_CREATE_EDGE_FWD(PAG)); - icfgReader.fillObjs( - [this](const cJSON*& j, ICFGNode* node) - { - virtFill(j, node); - }, - [this](const cJSON*& j, ICFGEdge* edge) - { - virtFill(j, edge); - }, - [this](const cJSON*& j, SVFLoop* loop) - { - fill(j, loop); - }); - chGraphReader.fillObjs( - [this](const cJSON*& j, CHNode* node) - { - virtFill(j, node); - }, - [this](const cJSON*& j, CHEdge* edge) - { - virtFill(j, edge); - }); - irGraphReader.fillObjs( - [this](const cJSON*& j, SVFVar* var) - { - virtFill(j, var); - }, - [this](const cJSON*& j, SVFStmt* stmt) - { - virtFill(j, stmt); - }); + icfgReader.fillObjs([this](const cJSON*& j, ICFGNode* node) { virtFill(j, node); }, + [this](const cJSON*& j, ICFGEdge* edge) { virtFill(j, edge); }, + [this](const cJSON*& j, SVFLoop* loop) { fill(j, loop); }); + chGraphReader.fillObjs([this](const cJSON*& j, CHNode* node) { virtFill(j, node); }, + [this](const cJSON*& j, CHEdge* edge) { virtFill(j, edge); }); + irGraphReader.fillObjs([this](const cJSON*& j, SVFVar* var) { virtFill(j, var); }, + [this](const cJSON*& j, SVFStmt* stmt) { virtFill(j, stmt); }); return irGraph->next; @@ -1552,29 +1497,17 @@ void SVFIRReader::readJson(const cJSON* obj, float& val) void SVFIRReader::readJson(const cJSON* obj, unsigned long& val) { - readBigNumber(obj, val, - [](const char* s) - { - return std::strtoul(s, nullptr, 10); - }); + readBigNumber(obj, val, [](const char* s) { return std::strtoul(s, nullptr, 10); }); } void SVFIRReader::readJson(const cJSON* obj, long long& val) { - readBigNumber(obj, val, - [](const char* s) - { - return std::strtoll(s, nullptr, 10); - }); + readBigNumber(obj, val, [](const char* s) { return std::strtoll(s, nullptr, 10); }); } void SVFIRReader::readJson(const cJSON* obj, unsigned long long& val) { - readBigNumber(obj, val, - [](const char* s) - { - return std::strtoull(s, nullptr, 10); - }); + readBigNumber(obj, val, [](const char* s) { return std::strtoull(s, nullptr, 10); }); } void SVFIRReader::readJson(const cJSON* obj, std::string& str) @@ -1589,8 +1522,8 @@ ICFGNode* SVFIRReader::createICFGNode(NodeID id, GNodeK kind) { default: ABORT_MSG(kind << " is an impossible ICFGNodeKind in create()"); -#define CASE(kind, constructor) \ - case ICFGNode::kind: \ +#define CASE(kind, constructor) \ + case ICFGNode::kind: \ return new constructor(id); CASE(IntraBlock, IntraICFGNode); CASE(FunEntryBlock, FunEntryICFGNode); @@ -1638,8 +1571,8 @@ SVFVar* SVFIRReader::createPAGNode(NodeID id, GNodeK kind) { default: ABORT_MSG(kind << " is an impossible SVFVarKind in create()"); -#define CASE(kind, constructor) \ - case SVFVar::kind: \ +#define CASE(kind, constructor) \ + case SVFVar::kind: \ return new constructor(id); CASE(ValNode, ValVar); CASE(RetNode, RetPN); @@ -1660,8 +1593,8 @@ SVFStmt* SVFIRReader::createPAGEdge(GEdgeKind kind) { default: ABORT_MSG(kind << " is an impossible SVFStmtKind in create()"); -#define CASE(kind, constructor) \ - case SVFStmt::kind: \ +#define CASE(kind, constructor) \ + case SVFStmt::kind: \ return new constructor; CASE(Addr, AddrStmt); CASE(Copy, CopyStmt); @@ -1819,8 +1752,7 @@ void SVFIRReader::readJson(const cJSON* obj, SVFValue*& value) void SVFIRReader::readJson(const cJSON* obj, SVFVar*& var) { assert(!var && "SVFVar already read?"); - if (jsonIsNullId(obj)) - var = nullptr; + if (jsonIsNullId(obj)) var = nullptr; else var = irGraphReader.getNodePtr(jsonGetNumber(obj)); } @@ -1916,8 +1848,7 @@ void SVFIRReader::readJson(const cJSON* obj, SVFLoopAndDomInfo*& ldInfo) JSON_READ_FIELD_FWD(field, ldInfo, bb2PdomLevel); JSON_READ_FIELD_FWD(field, ldInfo, bb2PIdom); - ABORT_IFNOT(!field, - "Extra field in SVFLoopAndDomInfo: " << JSON_KEY(field)); + ABORT_IFNOT(!field, "Extra field in SVFLoopAndDomInfo: " << JSON_KEY(field)); } void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFVar* var) @@ -1927,8 +1858,8 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFVar* var) default: assert(false && "Unknown SVFVar kind"); -#define CASE(VarKind, VarType) \ - case SVFVar::VarKind: \ +#define CASE(VarKind, VarType) \ + case SVFVar::VarKind: \ return fill(fieldJson, static_cast(var)) CASE(ValNode, ValVar); @@ -2012,8 +1943,8 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFStmt* stmt) default: ABORT_MSG("Unknown SVFStmt kind " << kind); -#define CASE(EdgeKind, EdgeType) \ - case SVFStmt::EdgeKind: \ +#define CASE(EdgeKind, EdgeType) \ + case SVFStmt::EdgeKind: \ return fill(fieldJson, static_cast(stmt)) CASE(Addr, AddrStmt); @@ -2173,8 +2104,8 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, ICFGNode* node) default: ABORT_MSG("Unknown ICFGNode kind " << node->getNodeKind()); -#define CASE(NodeKind, NodeType) \ - case ICFGNode::NodeKind: \ +#define CASE(NodeKind, NodeType) \ + case ICFGNode::NodeKind: \ return fill(fieldJson, static_cast(node)) CASE(IntraBlock, IntraICFGNode); @@ -2310,8 +2241,7 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, CHEdge* edge) fill(fieldJson, static_cast(edge)); // edgeType is a enum JSON_DEF_READ_FWD(fieldJson, unsigned, edgeType); - if (edgeType == CHEdge::INHERITANCE) - edge->edgeType = CHEdge::INHERITANCE; + if (edgeType == CHEdge::INHERITANCE) edge->edgeType = CHEdge::INHERITANCE; else if (edgeType == CHEdge::INSTANTCE) edge->edgeType = CHEdge::INSTANTCE; else @@ -2327,8 +2257,8 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFValue* value) default: ABORT_MSG("Impossible SVFValue kind " << kind); -#define CASE(ValueKind, Type) \ - case SVFValue::ValueKind: \ +#define CASE(ValueKind, Type) \ + case SVFValue::ValueKind: \ return fill(fieldJson, static_cast(value)) CASE(SVFVal, SVFValue); @@ -2479,8 +2409,8 @@ void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFType* type) default: assert(false && "Impossible SVFType kind"); -#define CASE(Kind) \ - case SVFType::Kind: \ +#define CASE(Kind) \ + case SVFType::Kind: \ return fill(fieldJson, SVFUtil::dyn_cast(type)) CASE(SVFTy); @@ -2552,8 +2482,7 @@ SVFIR* SVFIRReader::read(const std::string& path) perror(info.c_str()); abort(); } - auto addr = - (char*)mmap(nullptr, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + auto addr = (char*)mmap(nullptr, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { std::string info = "mmap(content of \"" + path + "\")"; @@ -2563,11 +2492,9 @@ SVFIR* SVFIRReader::read(const std::string& path) auto root = cJSON_ParseWithLength(addr, buf.st_size); - if (munmap(addr, buf.st_size) == -1) - perror("munmap()"); + if (munmap(addr, buf.st_size) == -1) perror("munmap()"); - if (close(fd) < 0) - perror("close()"); + if (close(fd) < 0) perror("close()"); SVFIRReader reader; SVFIR* ir = reader.read(root); diff --git a/svf/lib/SVFIR/SVFIR.cpp b/svf/lib/SVFIR/SVFIR.cpp index b9e289620..bd9739ebd 100644 --- a/svf/lib/SVFIR/SVFIR.cpp +++ b/svf/lib/SVFIR/SVFIR.cpp @@ -33,12 +33,9 @@ using namespace SVF; using namespace SVFUtil; - std::unique_ptr SVFIR::pag; -SVFIR::SVFIR(bool buildFromFile) : IRGraph(buildFromFile), svfModule(nullptr), icfg(nullptr), chgraph(nullptr) -{ -} +SVFIR::SVFIR(bool buildFromFile) : IRGraph(buildFromFile), svfModule(nullptr), icfg(nullptr), chgraph(nullptr) {} /*! * Add Address edge @@ -47,13 +44,12 @@ AddrStmt* SVFIR::addAddrStmt(NodeID src, NodeID dst) { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Addr)) - return nullptr; + if (hasNonlabeledEdge(srcNode, dstNode, SVFStmt::Addr)) return nullptr; else { AddrStmt* addrPE = new AddrStmt(srcNode, dstNode); addToStmt2TypeMap(addrPE); - addEdge(srcNode,dstNode, addrPE); + addEdge(srcNode, dstNode, addrPE); return addrPE; } } @@ -65,13 +61,12 @@ CopyStmt* SVFIR::addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type) { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Copy)) - return nullptr; + if (hasNonlabeledEdge(srcNode, dstNode, SVFStmt::Copy)) return nullptr; else { CopyStmt* copyPE = new CopyStmt(srcNode, dstNode, type); addToStmt2TypeMap(copyPE); - addEdge(srcNode,dstNode, copyPE); + addEdge(srcNode, dstNode, copyPE); return copyPE; } } @@ -84,7 +79,7 @@ PhiStmt* SVFIR::addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred) SVFVar* opNode = getGNode(opnd); SVFVar* resNode = getGNode(res); PHINodeMap::iterator it = phiNodeMap.find(resNode); - if(it == phiNodeMap.end()) + if (it == phiNodeMap.end()) { PhiStmt* phi = new PhiStmt(resNode, {opNode}, {pred}); addToStmt2TypeMap(phi); @@ -94,7 +89,7 @@ PhiStmt* SVFIR::addPhiStmt(NodeID res, NodeID opnd, const ICFGNode* pred) } else { - it->second->addOpVar(opNode,pred); + it->second->addOpVar(opNode, pred); /// return null if we already added this PhiStmt return nullptr; } @@ -109,8 +104,7 @@ SelectStmt* SVFIR::addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond SVFVar* op2Node = getGNode(op2); SVFVar* dstNode = getGNode(res); SVFVar* condNode = getGNode(cond); - if(hasLabeledEdge(op1Node, dstNode, SVFStmt::Select, op2Node)) - return nullptr; + if (hasLabeledEdge(op1Node, dstNode, SVFStmt::Select, op2Node)) return nullptr; else { std::vector opnds = {op1Node, op2Node}; @@ -129,8 +123,7 @@ CmpStmt* SVFIR::addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predicate) SVFVar* op1Node = getGNode(op1); SVFVar* op2Node = getGNode(op2); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(op1Node, dstNode, SVFStmt::Cmp, op2Node)) - return nullptr; + if (hasLabeledEdge(op1Node, dstNode, SVFStmt::Cmp, op2Node)) return nullptr; else { std::vector opnds = {op1Node, op2Node}; @@ -141,7 +134,6 @@ CmpStmt* SVFIR::addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predicate) } } - /*! * Add Compare edge */ @@ -150,14 +142,13 @@ BinaryOPStmt* SVFIR::addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, u32_t o SVFVar* op1Node = getGNode(op1); SVFVar* op2Node = getGNode(op2); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(op1Node, dstNode, SVFStmt::BinaryOp, op2Node)) - return nullptr; + if (hasLabeledEdge(op1Node, dstNode, SVFStmt::BinaryOp, op2Node)) return nullptr; else { std::vector opnds = {op1Node, op2Node}; BinaryOPStmt* binaryOP = new BinaryOPStmt(dstNode, opnds, opcode); addToStmt2TypeMap(binaryOP); - addEdge(op1Node,dstNode, binaryOP); + addEdge(op1Node, dstNode, binaryOP); return binaryOP; } } @@ -169,31 +160,29 @@ UnaryOPStmt* SVFIR::addUnaryOPStmt(NodeID src, NodeID dst, u32_t opcode) { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::UnaryOp)) - return nullptr; + if (hasNonlabeledEdge(srcNode, dstNode, SVFStmt::UnaryOp)) return nullptr; else { UnaryOPStmt* unaryOP = new UnaryOPStmt(srcNode, dstNode, opcode); addToStmt2TypeMap(unaryOP); - addEdge(srcNode,dstNode, unaryOP); + addEdge(srcNode, dstNode, unaryOP); return unaryOP; } } /* -* Add BranchStmt -*/ -BranchStmt* SVFIR::addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec& succs) + * Add BranchStmt + */ +BranchStmt* SVFIR::addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec& succs) { SVFVar* brNode = getGNode(br); SVFVar* condNode = getGNode(cond); - if(hasNonlabeledEdge(condNode,brNode, SVFStmt::Branch)) - return nullptr; + if (hasNonlabeledEdge(condNode, brNode, SVFStmt::Branch)) return nullptr; else { BranchStmt* branch = new BranchStmt(brNode, condNode, succs); addToStmt2TypeMap(branch); - addEdge(condNode,brNode, branch); + addEdge(condNode, brNode, branch); return branch; } } @@ -205,13 +194,12 @@ LoadStmt* SVFIR::addLoadStmt(NodeID src, NodeID dst) { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasNonlabeledEdge(srcNode,dstNode, SVFStmt::Load)) - return nullptr; + if (hasNonlabeledEdge(srcNode, dstNode, SVFStmt::Load)) return nullptr; else { LoadStmt* loadPE = new LoadStmt(srcNode, dstNode); addToStmt2TypeMap(loadPE); - addEdge(srcNode,dstNode, loadPE); + addEdge(srcNode, dstNode, loadPE); return loadPE; } } @@ -224,13 +212,12 @@ StoreStmt* SVFIR::addStoreStmt(NodeID src, NodeID dst, const IntraICFGNode* curV { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Store, curVal)) - return nullptr; + if (hasLabeledEdge(srcNode, dstNode, SVFStmt::Store, curVal)) return nullptr; else { StoreStmt* storePE = new StoreStmt(srcNode, dstNode, curVal); addToStmt2TypeMap(storePE); - addEdge(srcNode,dstNode, storePE); + addEdge(srcNode, dstNode, storePE); return storePE; } } @@ -242,13 +229,12 @@ CallPE* SVFIR::addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs, const F { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Call, cs)) - return nullptr; + if (hasLabeledEdge(srcNode, dstNode, SVFStmt::Call, cs)) return nullptr; else { - CallPE* callPE = new CallPE(srcNode, dstNode, cs,entry); + CallPE* callPE = new CallPE(srcNode, dstNode, cs, entry); addToStmt2TypeMap(callPE); - addEdge(srcNode,dstNode, callPE); + addEdge(srcNode, dstNode, callPE); return callPE; } } @@ -260,13 +246,12 @@ RetPE* SVFIR::addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs, const Fun { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(srcNode,dstNode, SVFStmt::Ret, cs)) - return nullptr; + if (hasLabeledEdge(srcNode, dstNode, SVFStmt::Ret, cs)) return nullptr; else { RetPE* retPE = new RetPE(srcNode, dstNode, cs, exit); addToStmt2TypeMap(retPE); - addEdge(srcNode,dstNode, retPE); + addEdge(srcNode, dstNode, retPE); return retPE; } } @@ -276,8 +261,7 @@ RetPE* SVFIR::addRetPE(NodeID src, NodeID dst, const CallICFGNode* cs, const Fun */ SVFStmt* SVFIR::addBlackHoleAddrStmt(NodeID node) { - if(Options::HandBlackHole()) - return pag->addAddrStmt(pag->getBlackHoleNode(), node); + if (Options::HandBlackHole()) return pag->addAddrStmt(pag->getBlackHoleNode(), node); else return pag->addCopyStmt(pag->getNullPtr(), node, CopyStmt::COPYVAL); } @@ -289,13 +273,12 @@ TDForkPE* SVFIR::addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode* cs, { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(srcNode,dstNode, SVFStmt::ThreadFork, cs)) - return nullptr; + if (hasLabeledEdge(srcNode, dstNode, SVFStmt::ThreadFork, cs)) return nullptr; else { TDForkPE* forkPE = new TDForkPE(srcNode, dstNode, cs, entry); addToStmt2TypeMap(forkPE); - addEdge(srcNode,dstNode, forkPE); + addEdge(srcNode, dstNode, forkPE); return forkPE; } } @@ -307,18 +290,16 @@ TDJoinPE* SVFIR::addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode* cs, { SVFVar* srcNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasLabeledEdge(srcNode,dstNode, SVFStmt::ThreadJoin, cs)) - return nullptr; + if (hasLabeledEdge(srcNode, dstNode, SVFStmt::ThreadJoin, cs)) return nullptr; else { TDJoinPE* joinPE = new TDJoinPE(srcNode, dstNode, cs, exit); addToStmt2TypeMap(joinPE); - addEdge(srcNode,dstNode, joinPE); + addEdge(srcNode, dstNode, joinPE); return joinPE; } } - /*! * Add Offset(Gep) edge * Find the base node id of src and connect base node to dst node @@ -347,8 +328,7 @@ GepStmt* SVFIR::addNormalGepStmt(NodeID src, NodeID dst, const AccessPath& ap) { SVFVar* baseNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep)) - return nullptr; + if (hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep)) return nullptr; else { GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap); @@ -366,8 +346,7 @@ GepStmt* SVFIR::addVariantGepStmt(NodeID src, NodeID dst, const AccessPath& ap) { SVFVar* baseNode = getGNode(src); SVFVar* dstNode = getGNode(dst); - if(hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep)) - return nullptr; + if (hasNonlabeledEdge(baseNode, dstNode, SVFStmt::Gep)) return nullptr; else { GepStmt* gepPE = new GepStmt(baseNode, dstNode, ap, true); @@ -377,20 +356,19 @@ GepStmt* SVFIR::addVariantGepStmt(NodeID src, NodeID dst, const AccessPath& ap) } } - - /*! * Add a temp field value node, this method can only invoked by getGepValVar - * due to constraint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when creating GepValVar. + * due to constraint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when creating + * GepValVar. */ -NodeID SVFIR::addGepValNode(const SVFValue* curInst,const SVFValue* gepVal, const AccessPath& ap, NodeID i, const SVFType* type) +NodeID SVFIR::addGepValNode(const SVFValue* curInst, const SVFValue* gepVal, const AccessPath& ap, NodeID i, + const SVFType* type) { NodeID base = getValueNode(gepVal); - //assert(findPAGNode(i) == false && "this node should not be created before"); - assert(0==GepValObjMap[curInst].count(std::make_pair(base, ap)) - && "this node should not be created before"); + // assert(findPAGNode(i) == false && "this node should not be created before"); + assert(0 == GepValObjMap[curInst].count(std::make_pair(base, ap)) && "this node should not be created before"); GepValObjMap[curInst][std::make_pair(base, ap)] = i; - GepValVar *node = new GepValVar(gepVal, i, ap, type); + GepValVar* node = new GepValVar(gepVal, i, ap, type); return addValNode(gepVal, node, i); } @@ -424,8 +402,7 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset) NodeID base = obj->getId(); /// if this obj is field-insensitive, just return the field-insensitive node. - if (obj->isFieldInsensitive()) - return getFIObjVar(obj); + if (obj->isFieldInsensitive()) return getFIObjVar(obj); APOffset newLS = pag->getSymbolInfo()->getModulusOffset(obj, apOffset); @@ -436,11 +413,10 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset) if (iter == GepObjVarMap.end()) { NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, apOffset, Options::MaxFieldLimit()); - return addGepObjNode(obj, newLS,gepId); + return addGepObjNode(obj, newLS, gepId); } else return iter->second; - } /*! @@ -448,13 +424,12 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset) */ NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId) { - //assert(findPAGNode(i) == false && "this node should not be created before"); + // assert(findPAGNode(i) == false && "this node should not be created before"); NodeID base = obj->getId(); - assert(0==GepObjVarMap.count(std::make_pair(base, apOffset)) - && "this node should not be created before"); + assert(0 == GepObjVarMap.count(std::make_pair(base, apOffset)) && "this node should not be created before"); GepObjVarMap[std::make_pair(base, apOffset)] = gepId; - GepObjVar *node = new GepObjVar(obj, gepId, apOffset); + GepObjVar* node = new GepObjVar(obj, gepId, apOffset); memToFieldsMap[base].set(gepId); return addObjNode(obj->getValue(), node, gepId); } @@ -464,10 +439,10 @@ NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset, const N */ NodeID SVFIR::addFIObjNode(const MemObj* obj) { - //assert(findPAGNode(i) == false && "this node should not be created before"); + // assert(findPAGNode(i) == false && "this node should not be created before"); NodeID base = obj->getId(); memToFieldsMap[base].set(obj->getId()); - FIObjVar *node = new FIObjVar(obj->getValue(), obj->getId(), obj); + FIObjVar* node = new FIObjVar(obj->getValue(), obj->getId(), obj); return addObjNode(obj->getValue(), node, obj->getId()); } @@ -501,7 +476,7 @@ NodeBS SVFIR::getFieldsAfterCollapse(NodeID id) const SVFVar* node = pag->getGNode(id); assert(SVFUtil::isa(node) && "need an object node"); const MemObj* mem = SVFUtil::cast(node)->getMemObj(); - if(mem->isFieldInsensitive()) + if (mem->isFieldInsensitive()) { NodeBS bs; bs.set(getFIObjVar(mem)); @@ -517,22 +492,19 @@ NodeBS SVFIR::getFieldsAfterCollapse(NodeID id) NodeID SVFIR::getGepValVar(const SVFValue* curInst, NodeID base, const AccessPath& ap) const { GepValueVarMap::const_iterator iter = GepValObjMap.find(curInst); - if(iter==GepValObjMap.end()) + if (iter == GepValObjMap.end()) { return UINT_MAX; } else { - NodeAccessPathMap::const_iterator lit = - iter->second.find(std::make_pair(base, ap)); - if (lit == iter->second.end()) - return UINT_MAX; + NodeAccessPathMap::const_iterator lit = iter->second.find(std::make_pair(base, ap)); + if (lit == iter->second.end()) return UINT_MAX; else return lit->second; } } - /*! * Clean up memory */ @@ -554,83 +526,64 @@ void SVFIR::print() outs() << "-------------------SVFIR------------------------------------\n"; SVFStmt::SVFStmtSetTy& addrs = pag->getSVFStmtSet(SVFStmt::Addr); - for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter = - addrs.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter = addrs.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Addr --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& copys = pag->getSVFStmtSet(SVFStmt::Copy); - for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter = - copys.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter = copys.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Copy --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Copy --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& calls = pag->getSVFStmtSet(SVFStmt::Call); - for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter = - calls.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = calls.begin(), eiter = calls.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Call --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Call --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& rets = pag->getSVFStmtSet(SVFStmt::Ret); - for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter = - rets.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = rets.begin(), eiter = rets.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Ret --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Ret --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& tdfks = pag->getSVFStmtSet(SVFStmt::ThreadFork); - for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter = - tdfks.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = tdfks.begin(), eiter = tdfks.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- ThreadFork --> " - << (*iter)->getDstID() << "\n"; + outs() << (*iter)->getSrcID() << " -- ThreadFork --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& tdjns = pag->getSVFStmtSet(SVFStmt::ThreadJoin); - for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter = - tdjns.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = tdjns.begin(), eiter = tdjns.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- ThreadJoin --> " - << (*iter)->getDstID() << "\n"; + outs() << (*iter)->getSrcID() << " -- ThreadJoin --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& ngeps = pag->getSVFStmtSet(SVFStmt::Gep); - for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter = - ngeps.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter = ngeps.end(); iter != eiter; ++iter) { GepStmt* gep = SVFUtil::cast(*iter); - if(gep->isVariantFieldGep()) - outs() << (*iter)->getSrcID() << " -- VariantGep --> " - << (*iter)->getDstID() << "\n"; + if (gep->isVariantFieldGep()) + outs() << (*iter)->getSrcID() << " -- VariantGep --> " << (*iter)->getDstID() << "\n"; else - outs() << gep->getRHSVarID() << " -- Gep (" << gep->getConstantStructFldIdx() - << ") --> " << gep->getLHSVarID() << "\n"; + outs() << gep->getRHSVarID() << " -- Gep (" << gep->getConstantStructFldIdx() << ") --> " + << gep->getLHSVarID() << "\n"; } SVFStmt::SVFStmtSetTy& loads = pag->getSVFStmtSet(SVFStmt::Load); - for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = - loads.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter = loads.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Load --> " << (*iter)->getDstID() << "\n"; } SVFStmt::SVFStmtSetTy& stores = pag->getSVFStmtSet(SVFStmt::Store); - for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = - stores.end(); iter != eiter; ++iter) + for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter = stores.end(); iter != eiter; ++iter) { - outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID() - << "\n"; + outs() << (*iter)->getSrcID() << " -- Store --> " << (*iter)->getDstID() << "\n"; } outs() << "----------------------------------------------------------\n"; - } /// Initialize candidate pointers @@ -641,8 +594,7 @@ void SVFIR::initialiseCandidatePointers() { NodeID nodeId = nIter->first; // do not compute points-to for isolated node - if (isValidPointer(nodeId) == false) - continue; + if (isValidPointer(nodeId) == false) continue; candidatePointers.insert(nodeId); } } @@ -656,15 +608,13 @@ bool SVFIR::isValidPointer(NodeID nodeId) const if (node->hasValue() && node->isPointer()) { - if(const SVFArgument* arg = SVFUtil::dyn_cast(node->getValue())) + if (const SVFArgument* arg = SVFUtil::dyn_cast(node->getValue())) { - if (!(arg->getParent()->isDeclaration())) - return true; + if (!(arg->getParent()->isDeclaration())) return true; } } - if ((node->getInEdges().empty() && node->getOutEdges().empty())) - return false; + if ((node->getInEdges().empty() && node->getOutEdges().empty())) return false; return node->isPointer(); } @@ -687,6 +637,3 @@ void SVFIR::handleBlackHole(bool b) { Options::HandBlackHole.setValue(b); } - - - diff --git a/svf/lib/SVFIR/SVFModule.cpp b/svf/lib/SVFIR/SVFModule.cpp index 9c4da6128..d42c53dbe 100644 --- a/svf/lib/SVFIR/SVFModule.cpp +++ b/svf/lib/SVFIR/SVFModule.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - #include "SVFIR/SVFModule.h" #include "SVFIR/SymbolTableInfo.h" #include "Util/SVFUtil.h" @@ -34,12 +33,9 @@ SVFModule* SVFModule::svfModule = nullptr; SVFModule::~SVFModule() { - for (const SVFFunction* f : FunctionSet) - delete f; - for (const SVFConstant* c : ConstantSet) - delete c; - for (const SVFValue* o : OtherValueSet) - delete o; + for (const SVFFunction* f : FunctionSet) delete f; + for (const SVFConstant* c : ConstantSet) delete c; + for (const SVFValue* o : OtherValueSet) delete o; NodeIDAllocator::unset(); ThreadAPI::destroy(); ExtAPI::destory(); diff --git a/svf/lib/SVFIR/SVFStatements.cpp b/svf/lib/SVFIR/SVFStatements.cpp index 5335bc27a..19f8d75a4 100644 --- a/svf/lib/SVFIR/SVFStatements.cpp +++ b/svf/lib/SVFIR/SVFStatements.cpp @@ -34,21 +34,19 @@ using namespace SVF; using namespace SVFUtil; - u64_t SVFStmt::callEdgeLabelCounter = 0; u64_t SVFStmt::storeEdgeLabelCounter = 0; u64_t SVFStmt::multiOpndLabelCounter = 0; SVFStmt::Inst2LabelMap SVFStmt::inst2LabelMap; SVFStmt::Var2LabelMap SVFStmt::var2LabelMap; - /*! * SVFStmt constructor */ -SVFStmt::SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real) : - GenericPAGEdgeTy(s,d,k),value(nullptr),basicBlock(nullptr),icfgNode(nullptr),edgeId(UINT_MAX) +SVFStmt::SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real) + : GenericPAGEdgeTy(s, d, k), value(nullptr), basicBlock(nullptr), icfgNode(nullptr), edgeId(UINT_MAX) { - if(real) + if (real) { edgeId = SVFIR::getPAG()->getTotalEdgeNum(); SVFIR::getPAG()->incEdgeNum(); @@ -102,8 +100,8 @@ const std::string PhiStmt::toString() const std::string str; std::stringstream rawstr(str); rawstr << "PhiStmt: [Var" << getResID() << " <-- ("; - for(u32_t i = 0; i < getOpVarNum(); i++) - rawstr << "[Var" << getOpVar(i)->getId() << ", ICFGNode" << getOpICFGNode(i)->getId() << "],"; + for (u32_t i = 0; i < getOpVarNum(); i++) + rawstr << "[Var" << getOpVar(i)->getId() << ", ICFGNode" << getOpICFGNode(i)->getId() << "],"; rawstr << ")]\t"; if (Options::ShowSVFIRValue()) { @@ -117,9 +115,8 @@ const std::string SelectStmt::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "SelectStmt: (Condition Var" << getCondition()->getId() << ") [Var" << getResID() << " <-- (Var"; - for(const SVFVar* op : getOpndVars()) - rawstr << op->getId() << ","; + rawstr << "SelectStmt: (Condition Var" << getCondition()->getId() << ") [Var" << getResID() << " <-- (Var"; + for (const SVFVar* op : getOpndVars()) rawstr << op->getId() << ","; rawstr << ")]\t"; if (Options::ShowSVFIRValue()) { @@ -133,7 +130,8 @@ const std::string CmpStmt::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "CmpStmt: [Var" << getResID() << " <-- (Var" << getOpVarID(0) << " predicate" << getPredicate() << " Var" << getOpVarID(1) << ")]\t"; + rawstr << "CmpStmt: [Var" << getResID() << " <-- (Var" << getOpVarID(0) << " predicate" << getPredicate() << " Var" + << getOpVarID(1) << ")]\t"; if (Options::ShowSVFIRValue()) { rawstr << "\n"; @@ -146,7 +144,8 @@ const std::string BinaryOPStmt::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "BinaryOPStmt: [Var" << getResID() << " <-- (Var" << getOpVarID(0) << " opcode" << getOpcode() << " Var" << getOpVarID(1) << ")]\t"; + rawstr << "BinaryOPStmt: [Var" << getResID() << " <-- (Var" << getOpVarID(0) << " opcode" << getOpcode() << " Var" + << getOpVarID(1) << ")]\t"; if (Options::ShowSVFIRValue()) { rawstr << "\n"; @@ -159,7 +158,8 @@ const std::string UnaryOPStmt::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "UnaryOPStmt: [Var" << getResID() << " <-- " << " opcode" << getOpcode() << " Var" << getOpVarID() << "]\t"; + rawstr << "UnaryOPStmt: [Var" << getResID() << " <-- " + << " opcode" << getOpcode() << " Var" << getOpVarID() << "]\t"; if (Options::ShowSVFIRValue()) { rawstr << "\n"; @@ -172,12 +172,13 @@ const std::string BranchStmt::toString() const { std::string str; std::stringstream rawstr(str); - if(isConditional()) - rawstr << "BranchStmt: [Condition Var" << getCondition()->getId() << "]\n"; + if (isConditional()) rawstr << "BranchStmt: [Condition Var" << getCondition()->getId() << "]\n"; else - rawstr << "BranchStmt: [" << " Unconditional branch" << "]\n"; + rawstr << "BranchStmt: [" + << " Unconditional branch" + << "]\n"; - for(u32_t i = 0; i < getNumSuccessors(); i++) + for (u32_t i = 0; i < getNumSuccessors(); i++) rawstr << "Successor " << i << " ICFGNode" << getSuccessor(i)->getId() << " "; if (Options::ShowSVFIRValue()) @@ -188,7 +189,6 @@ const std::string BranchStmt::toString() const return rawstr.str(); } - const std::string LoadStmt::toString() const { std::string str; @@ -280,7 +280,6 @@ const std::string TDJoinPE::toString() const return rawstr.str(); } - NodeID MultiOpndStmt::getOpVarID(u32_t pos) const { return getOpVar(pos)->getId(); @@ -307,7 +306,6 @@ bool PhiStmt::isFunctionRetPhi() const return SVFUtil::isa(getRes()); } - /// The branch is unconditional if cond is a null value bool BranchStmt::isUnconditional() const { @@ -316,12 +314,13 @@ bool BranchStmt::isUnconditional() const /// The branch is conditional if cond is not a null value bool BranchStmt::isConditional() const { - return cond->getId() != SymbolTableInfo::SymbolInfo()->nullPtrSymID();; + return cond->getId() != SymbolTableInfo::SymbolInfo()->nullPtrSymID(); + ; } /// Return the condition const SVFVar* BranchStmt::getCondition() const { - //assert(isConditional() && "this is a unconditional branch"); + // assert(isConditional() && "this is a unconditional branch"); return cond; } @@ -330,44 +329,32 @@ StoreStmt::StoreStmt(SVFVar* s, SVFVar* d, const IntraICFGNode* st) { } -CallPE::CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, - const FunEntryICFGNode* e, GEdgeKind k) +CallPE::CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunEntryICFGNode* e, GEdgeKind k) : AssignStmt(s, d, makeEdgeFlagWithCallInst(k, i)), call(i), entry(e) { } -RetPE::RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, - const FunExitICFGNode* e, GEdgeKind k) +RetPE::RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e, GEdgeKind k) : AssignStmt(s, d, makeEdgeFlagWithCallInst(k, i)), call(i), exit(e) { } -MultiOpndStmt::MultiOpndStmt(SVFVar* r, const OPVars& opnds, GEdgeFlag k) - : SVFStmt(opnds.at(0), r, k), opVars(opnds) -{ -} +MultiOpndStmt::MultiOpndStmt(SVFVar* r, const OPVars& opnds, GEdgeFlag k) : SVFStmt(opnds.at(0), r, k), opVars(opnds) {} CmpStmt::CmpStmt(SVFVar* s, const OPVars& opnds, u32_t pre) - : MultiOpndStmt(s, opnds, - makeEdgeFlagWithAddionalOpnd(SVFStmt::Cmp, opnds.at(1))), - predicate(pre) + : MultiOpndStmt(s, opnds, makeEdgeFlagWithAddionalOpnd(SVFStmt::Cmp, opnds.at(1))), predicate(pre) { assert(opnds.size() == 2 && "CmpStmt can only have two operands!"); } SelectStmt::SelectStmt(SVFVar* s, const OPVars& opnds, const SVFVar* cond) - : MultiOpndStmt(s, opnds, - makeEdgeFlagWithAddionalOpnd(SVFStmt::Select, opnds.at(1))), - condition(cond) + : MultiOpndStmt(s, opnds, makeEdgeFlagWithAddionalOpnd(SVFStmt::Select, opnds.at(1))), condition(cond) { assert(opnds.size() == 2 && "SelectStmt can only have two operands!"); } BinaryOPStmt::BinaryOPStmt(SVFVar* s, const OPVars& opnds, u32_t oc) - : MultiOpndStmt( - s, opnds, - makeEdgeFlagWithAddionalOpnd(SVFStmt::BinaryOp, opnds.at(1))), - opcode(oc) + : MultiOpndStmt(s, opnds, makeEdgeFlagWithAddionalOpnd(SVFStmt::BinaryOp, opnds.at(1))), opcode(oc) { assert(opnds.size() == 2 && "BinaryOPStmt can only have two operands!"); } diff --git a/svf/lib/SVFIR/SVFType.cpp b/svf/lib/SVFIR/SVFType.cpp index f262b4764..c9fc4408d 100644 --- a/svf/lib/SVFIR/SVFType.cpp +++ b/svf/lib/SVFIR/SVFType.cpp @@ -7,8 +7,7 @@ namespace SVF SVFType* SVFType::svfI8Ty = nullptr; SVFType* SVFType::svfPtrTy = nullptr; -__attribute__((weak)) -std::string SVFType::toString() const +__attribute__((weak)) std::string SVFType::toString() const { std::ostringstream os; print(os); @@ -28,8 +27,7 @@ void SVFPointerType::print(std::ostream& os) const void SVFIntegerType::print(std::ostream& os) const { - if (signAndWidth < 0) - os << 'i' << -signAndWidth; + if (signAndWidth < 0) os << 'i' << -signAndWidth; else os << 'u' << signAndWidth; } diff --git a/svf/lib/SVFIR/SVFValue.cpp b/svf/lib/SVFIR/SVFValue.cpp index a0a9082b0..002bf68c6 100644 --- a/svf/lib/SVFIR/SVFValue.cpp +++ b/svf/lib/SVFIR/SVFValue.cpp @@ -4,8 +4,7 @@ using namespace SVF; using namespace SVFUtil; -__attribute__((weak)) -std::string SVFValue::toString() const +__attribute__((weak)) std::string SVFValue::toString() const { assert("SVFValue::toString should be implemented or supported by fronted" && false); abort(); @@ -26,8 +25,7 @@ void StInfo::addFldWithType(u32_t fldIdx, const SVFType* type, u32_t elemIdx) const SVFType* StInfo::getOriginalElemType(u32_t fldIdx) const { Map::const_iterator it = fldIdx2TypeMap.find(fldIdx); - if(it!=fldIdx2TypeMap.end()) - return it->second; + if (it != fldIdx2TypeMap.end()) return it->second; return nullptr; } @@ -49,8 +47,7 @@ void SVFLoopAndDomInfo::getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exi { for (const SVFBasicBlock* succ : block->getSuccessors()) { - if ((std::find(blocks.begin(), blocks.end(), succ)==blocks.end())) - exitbbs.push_back(succ); + if ((std::find(blocks.begin(), blocks.end(), succ) == blocks.end())) exitbbs.push_back(succ); } } } @@ -59,8 +56,7 @@ void SVFLoopAndDomInfo::getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exi bool SVFLoopAndDomInfo::dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - if (bbKey == bbValue) - return true; + if (bbKey == bbValue) return true; // An unreachable node is dominated by anything. if (isUnreachable(bbValue)) @@ -74,11 +70,11 @@ bool SVFLoopAndDomInfo::dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock return false; } - const Map& dtBBsMap = getDomTreeMap(); - Map::const_iterator mapIter = dtBBsMap.find(bbKey); + const Map& dtBBsMap = getDomTreeMap(); + Map::const_iterator mapIter = dtBBsMap.find(bbKey); if (mapIter != dtBBsMap.end()) { - const BBSet & dtBBs = mapIter->second; + const BBSet& dtBBs = mapIter->second; if (dtBBs.find(bbValue) != dtBBs.end()) { return true; @@ -90,8 +86,7 @@ bool SVFLoopAndDomInfo::dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock bool SVFLoopAndDomInfo::postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - if (bbKey == bbValue) - return true; + if (bbKey == bbValue) return true; // An unreachable node is dominated by anything. if (isUnreachable(bbValue)) @@ -105,11 +100,11 @@ bool SVFLoopAndDomInfo::postDominate(const SVFBasicBlock* bbKey, const SVFBasicB return false; } - const Map& dtBBsMap = getPostDomTreeMap(); - Map::const_iterator mapIter = dtBBsMap.find(bbKey); + const Map& dtBBsMap = getPostDomTreeMap(); + Map::const_iterator mapIter = dtBBsMap.find(bbKey); if (mapIter != dtBBsMap.end()) { - const BBSet & dtBBs = mapIter->second; + const BBSet& dtBBs = mapIter->second; if (dtBBs.find(bbValue) != dtBBs.end()) { return true; @@ -118,18 +113,18 @@ bool SVFLoopAndDomInfo::postDominate(const SVFBasicBlock* bbKey, const SVFBasicB return false; } -const SVFBasicBlock* SVFLoopAndDomInfo::findNearestCommonPDominator(const SVFBasicBlock* A, const SVFBasicBlock* B) const +const SVFBasicBlock* SVFLoopAndDomInfo::findNearestCommonPDominator(const SVFBasicBlock* A, + const SVFBasicBlock* B) const { assert(A && B && "Pointers are not valid"); - assert(A->getParent() == B->getParent() && - "Two blocks are not in same function"); + assert(A->getParent() == B->getParent() && "Two blocks are not in same function"); // Use level information to go up the tree until the levels match. Then // continue going up til we arrive at the same node. while (A != B) { // no common PDominator - if(A == NULL) return NULL; + if (A == NULL) return NULL; const auto lvA = getBBPDomLevel().find(A); const auto lvB = getBBPDomLevel().find(B); assert(lvA != getBBPDomLevel().end() && lvB != getBBPDomLevel().end()); @@ -155,21 +150,17 @@ bool SVFLoopAndDomInfo::isLoopHeader(const SVFBasicBlock* bb) const return false; } -SVFFunction::SVFFunction(const SVFType* ty, const SVFFunctionType* ft, - bool declare, bool intrinsic, bool adt, bool varg, - SVFLoopAndDomInfo* ld) - : SVFValue(ty, SVFValue::SVFFunc), isDecl(declare), intrinsic(intrinsic), - addrTaken(adt), isUncalled(false), isNotRet(false), varArg(varg), - funcType(ft), loopAndDom(ld), realDefFun(nullptr), exitBlock(nullptr) +SVFFunction::SVFFunction(const SVFType* ty, const SVFFunctionType* ft, bool declare, bool intrinsic, bool adt, + bool varg, SVFLoopAndDomInfo* ld) + : SVFValue(ty, SVFValue::SVFFunc), isDecl(declare), intrinsic(intrinsic), addrTaken(adt), isUncalled(false), + isNotRet(false), varArg(varg), funcType(ft), loopAndDom(ld), realDefFun(nullptr), exitBlock(nullptr) { } SVFFunction::~SVFFunction() { - for(const SVFBasicBlock* bb : allBBs) - delete bb; - for(const SVFArgument* arg : allArgs) - delete arg; + for (const SVFBasicBlock* bb : allBBs) delete bb; + for (const SVFArgument* arg : allArgs) delete arg; delete loopAndDom; } @@ -180,7 +171,7 @@ u32_t SVFFunction::arg_size() const const SVFArgument* SVFFunction::getArg(u32_t idx) const { - assert (idx < allArgs.size() && "getArg() out of range!"); + assert(idx < allArgs.size() && "getArg() out of range!"); return allArgs[idx]; } @@ -189,7 +180,7 @@ bool SVFFunction::isVarArg() const return varArg; } -const SVFBasicBlock *SVFFunction::getExitBB() const +const SVFBasicBlock* SVFFunction::getExitBB() const { assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); assert((!hasReturn() || exitBlock->back()->isRetInst()) && "last inst must be return inst"); @@ -197,21 +188,17 @@ const SVFBasicBlock *SVFFunction::getExitBB() const return exitBlock; } -void SVFFunction::setExitBlock(SVFBasicBlock *bb) +void SVFFunction::setExitBlock(SVFBasicBlock* bb) { assert(!exitBlock && "have already set exit Basicblock!"); exitBlock = bb; } -SVFBasicBlock::SVFBasicBlock(const SVFType* ty, const SVFFunction* f) - : SVFValue(ty, SVFValue::SVFBB), fun(f) -{ -} +SVFBasicBlock::SVFBasicBlock(const SVFType* ty, const SVFFunction* f) : SVFValue(ty, SVFValue::SVFBB), fun(f) {} SVFBasicBlock::~SVFBasicBlock() { - for(const SVFInstruction* inst : allInsts) - delete inst; + for (const SVFInstruction* inst : allInsts) delete inst; } /*! @@ -220,10 +207,9 @@ SVFBasicBlock::~SVFBasicBlock() u32_t SVFBasicBlock::getBBSuccessorPos(const SVFBasicBlock* Succ) { u32_t i = 0; - for (const SVFBasicBlock* SuccBB: succBBs) + for (const SVFBasicBlock* SuccBB : succBBs) { - if (SuccBB == Succ) - return i; + if (SuccBB == Succ) return i; i++; } assert(false && "Didn't find successor edge?"); @@ -233,10 +219,9 @@ u32_t SVFBasicBlock::getBBSuccessorPos(const SVFBasicBlock* Succ) u32_t SVFBasicBlock::getBBSuccessorPos(const SVFBasicBlock* Succ) const { u32_t i = 0; - for (const SVFBasicBlock* SuccBB: succBBs) + for (const SVFBasicBlock* SuccBB : succBBs) { - if (SuccBB == Succ) - return i; + if (SuccBB == Succ) return i; i++; } assert(false && "Didn't find successor edge?"); @@ -245,8 +230,7 @@ u32_t SVFBasicBlock::getBBSuccessorPos(const SVFBasicBlock* Succ) const const SVFInstruction* SVFBasicBlock::getTerminator() const { - if (allInsts.empty() || !allInsts.back()->isTerminator()) - return nullptr; + if (allInsts.empty() || !allInsts.back()->isTerminator()) return nullptr; return allInsts.back(); } @@ -258,8 +242,7 @@ u32_t SVFBasicBlock::getBBPredecessorPos(const SVFBasicBlock* succbb) u32_t pos = 0; for (const SVFBasicBlock* PredBB : succbb->getPredecessors()) { - if(PredBB == this) - return pos; + if (PredBB == this) return pos; ++pos; } assert(false && "Didn't find predecessor edge?"); @@ -270,16 +253,14 @@ u32_t SVFBasicBlock::getBBPredecessorPos(const SVFBasicBlock* succbb) const u32_t pos = 0; for (const SVFBasicBlock* PredBB : succbb->getPredecessors()) { - if(PredBB == this) - return pos; + if (PredBB == this) return pos; ++pos; } assert(false && "Didn't find predecessor edge?"); return pos; } -SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, - bool tm, bool isRet, SVFValKind k) +SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b, bool tm, bool isRet, SVFValKind k) : SVFValue(ty, k), bb(b), terminator(tm), ret(isRet) { } diff --git a/svf/lib/SVFIR/SVFVariables.cpp b/svf/lib/SVFIR/SVFVariables.cpp index e936e1dea..0667b0634 100644 --- a/svf/lib/SVFIR/SVFVariables.cpp +++ b/svf/lib/SVFIR/SVFVariables.cpp @@ -34,43 +34,36 @@ using namespace SVF; using namespace SVFUtil; - /*! * SVFVar constructor */ -SVFVar::SVFVar(const SVFValue* val, NodeID i, PNODEK k) : - GenericPAGNodeTy(i,k), value(val) +SVFVar::SVFVar(const SVFValue* val, NodeID i, PNODEK k) : GenericPAGNodeTy(i, k), value(val) { - assert( ValNode <= k && k <= DummyObjNode && "new SVFIR node kind?"); + assert(ValNode <= k && k <= DummyObjNode && "new SVFIR node kind?"); switch (k) { case ValNode: - case GepValNode: - { + case GepValNode: { assert(val != nullptr && "value is nullptr for ValVar or GepValNode"); isPtr = val->getType()->isPointerTy(); break; } - case RetNode: - { + case RetNode: { assert(val != nullptr && "value is nullptr for RetNode"); isPtr = SVFUtil::cast(val)->getReturnType()->isPointerTy(); break; } case VarargNode: - case DummyValNode: - { + case DummyValNode: { isPtr = true; break; } case ObjNode: case GepObjNode: case FIObjNode: - case DummyObjNode: - { + case DummyObjNode: { isPtr = true; - if(val) - isPtr = val->getType()->isPointerTy(); + if (val) isPtr = val->getType()->isPointerTy(); break; } } @@ -78,8 +71,7 @@ SVFVar::SVFVar(const SVFValue* val, NodeID i, PNODEK k) : bool SVFVar::isIsolatedNode() const { - if (getInEdges().empty() && getOutEdges().empty()) - return true; + if (getInEdges().empty() && getOutEdges().empty()) return true; else if (isConstDataOrAggDataButNotNullPtr()) return true; else if (value && SVFUtil::isa(value)) @@ -88,7 +80,6 @@ bool SVFVar::isIsolatedNode() const return false; } - const std::string SVFVar::toString() const { std::string str; @@ -171,7 +162,8 @@ const std::string RetPN::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "RetPN ID: " << getId() << " unique return node for function " << SVFUtil::cast(value)->getName(); + rawstr << "RetPN ID: " << getId() << " unique return node for function " + << SVFUtil::cast(value)->getName(); return rawstr.str(); } @@ -179,7 +171,8 @@ const std::string VarArgPN::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "VarArgPN ID: " << getId() << " Var arg node for function " << SVFUtil::cast(value)->getName(); + rawstr << "VarArgPN ID: " << getId() << " Var arg node for function " + << SVFUtil::cast(value)->getName(); return rawstr.str(); } @@ -204,8 +197,8 @@ const std::string DummyObjVar::toString() const bool SVFVar::isConstDataOrAggDataButNotNullPtr() const { if (hasValue()) - return value->isConstDataOrAggData() && (!SVFUtil::isa(value)) && (!SVFUtil::isa(value)); + return value->isConstDataOrAggData() && (!SVFUtil::isa(value)) && + (!SVFUtil::isa(value)); else return false; } - diff --git a/svf/lib/SVFIR/SymbolTableInfo.cpp b/svf/lib/SVFIR/SymbolTableInfo.cpp index e0d201653..20deac1bf 100644 --- a/svf/lib/SVFIR/SymbolTableInfo.cpp +++ b/svf/lib/SVFIR/SymbolTableInfo.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * SymbolTableInfo.cpp * @@ -40,13 +39,11 @@ using namespace SVFUtil; SymbolTableInfo* SymbolTableInfo::symInfo = nullptr; - ObjTypeInfo::ObjTypeInfo(const SVFType* t, u32_t max) : type(t), flags(0), maxOffsetLimit(max), elemNum(max) { assert(t && "no type information for this object?"); } - void ObjTypeInfo::resetTypeForHeapStaticObj(const SVFType* t) { assert((isStaticObj() || isHeap()) && "can only reset the inferred type for heap and static objects!"); @@ -67,7 +64,7 @@ const StInfo* SymbolTableInfo::getTypeInfo(const SVFType* T) const ObjTypeInfo* SymbolTableInfo::createObjTypeInfo(const SVFType* type) { ObjTypeInfo* typeInfo = new ObjTypeInfo(type, Options::MaxFieldLimit()); - if(type && type->isPointerTy()) + if (type && type->isPointerTy()) { typeInfo->setFlag(ObjTypeInfo::HEAP_OBJ); } @@ -98,7 +95,7 @@ APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& ap /// struct to represent this obj. APOffset offset = apOffset; - if(offset < 0) + if (offset < 0) { writeWrnMsg("try to create a gep node with negative offset."); offset = abs(offset); @@ -110,8 +107,7 @@ APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& ap * @Options::MaxFieldLimit(): preset upper bound of field number; * @maxOffset: the max field number of the base object; */ - if (maxOffset == 0) - offset = 0; + if (maxOffset == 0) offset = 0; else if (Options::MaxFieldLimit() < maxOffset) /*! * E.g., offset == 260, maxOffset == 270, Options::MaxFieldLimit() == 256 ==> offset = 4 @@ -134,26 +130,21 @@ APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& ap return offset; } - - /*! * Destroy the memory for this symbol table after use */ void SymbolTableInfo::destroy() { - for (auto &pair: objMap) + for (auto& pair : objMap) { - if (MemObj* memObj = pair.second) - delete memObj; + if (MemObj* memObj = pair.second) delete memObj; } - for (const SVFType* type : svfTypes) - delete type; + for (const SVFType* type : svfTypes) delete type; svfTypes.clear(); - for (const StInfo* st : stInfos) - delete st; + for (const StInfo* st : stInfos) delete st; stInfos.clear(); mod = nullptr; @@ -161,7 +152,7 @@ void SymbolTableInfo::destroy() const MemObj* SymbolTableInfo::createDummyObj(SymID symId, const SVFType* type) { - assert(objMap.find(symId)==objMap.end() && "this dummy obj has been created before"); + assert(objMap.find(symId) == objMap.end() && "this dummy obj has been created before"); MemObj* memObj = new MemObj(symId, createObjTypeInfo(type)); objMap[symId] = memObj; return memObj; @@ -170,8 +161,7 @@ const MemObj* SymbolTableInfo::createDummyObj(SymID symId, const SVFType* type) /// Number of flattened elements of an array or struct u32_t SymbolTableInfo::getNumOfFlattenElements(const SVFType* T) { - if(Options::ModelArrays()) - return getTypeInfo(T)->getNumOfFlattenElements(); + if (Options::ModelArrays()) return getTypeInfo(T)->getNumOfFlattenElements(); else return getTypeInfo(T)->getNumOfFlattenFields(); } @@ -179,24 +169,27 @@ u32_t SymbolTableInfo::getNumOfFlattenElements(const SVFType* T) /// Flattened offset information of a struct or an array including its array fields u32_t SymbolTableInfo::getFlattenedElemIdx(const SVFType* T, u32_t origId) { - if(Options::ModelArrays()) + if (Options::ModelArrays()) { const std::vector& so = getTypeInfo(T)->getFlattenedElemIdxVec(); - assert ((unsigned)origId < so.size() && !so.empty() && "element index out of bounds, can't get flattened index!"); + assert((unsigned)origId < so.size() && !so.empty() && + "element index out of bounds, can't get flattened index!"); return so[origId]; } else { - if(SVFUtil::isa(T)) + if (SVFUtil::isa(T)) { const std::vector& so = getTypeInfo(T)->getFlattenedFieldIdxVec(); - assert ((unsigned)origId < so.size() && !so.empty() && "Struct index out of bounds, can't get flattened index!"); + assert((unsigned)origId < so.size() && !so.empty() && + "Struct index out of bounds, can't get flattened index!"); return so[origId]; } else { /// When Options::ModelArrays is disabled, any element index Array is modeled as the base - assert(SVFUtil::isa(T) && "Only accept struct or array type if Options::ModelArrays is disabled!"); + assert(SVFUtil::isa(T) && + "Only accept struct or array type if Options::ModelArrays is disabled!"); return 0; } } @@ -210,22 +203,23 @@ const SVFType* SymbolTableInfo::getOriginalElemType(const SVFType* baseType, u32 /// Return the type of a flattened element given a flattened index const SVFType* SymbolTableInfo::getFlatternedElemType(const SVFType* baseType, u32_t flatten_idx) { - if(Options::ModelArrays()) + if (Options::ModelArrays()) { const std::vector& so = getTypeInfo(baseType)->getFlattenElementTypes(); - assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!"); + assert(flatten_idx < so.size() && !so.empty() && + "element index out of bounds or struct opaque type, can't get element type!"); return so[flatten_idx]; } else { const std::vector& so = getTypeInfo(baseType)->getFlattenFieldTypes(); - assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!"); + assert(flatten_idx < so.size() && !so.empty() && + "element index out of bounds or struct opaque type, can't get element type!"); return so[flatten_idx]; } } - -const std::vector& SymbolTableInfo::getFlattenFieldTypes(const SVFStructType *T) +const std::vector& SymbolTableInfo::getFlattenFieldTypes(const SVFStructType* T) { return getTypeInfo(T)->getFlattenFieldTypes(); } @@ -243,30 +237,28 @@ void SymbolTableInfo::printFlattenFields(const SVFType* type) << "\t [element size = " << getNumOfFlattenElements(at) << "]\n" << "\n"; } - else if (const SVFStructType *st = SVFUtil::dyn_cast(type)) + else if (const SVFStructType* st = SVFUtil::dyn_cast(type)) { - outs() <<" {Type: " << *st << "}\n"; + outs() << " {Type: " << *st << "}\n"; const std::vector& finfo = getTypeInfo(st)->getFlattenFieldTypes(); int field_idx = 0; - for(const SVFType* type : finfo) + for (const SVFType* type : finfo) { - outs() << " \tField_idx = " << ++field_idx - << ", field type: " << *type << "\n"; + outs() << " \tField_idx = " << ++field_idx << ", field type: " << *type << "\n"; } outs() << "\n"; } - else if (const SVFPointerType* pt= SVFUtil::dyn_cast(type)) + else if (const SVFPointerType* pt = SVFUtil::dyn_cast(type)) { outs() << *pt << "\n"; } - else if (const SVFFunctionType* fu = - SVFUtil::dyn_cast(type)) + else if (const SVFFunctionType* fu = SVFUtil::dyn_cast(type)) { outs() << " {Type: " << *fu << "}\n\n"; } else if (const SVFOtherType* ot = SVFUtil::dyn_cast(type)) { - outs() << " {Type: "<< *ot << "(SVFOtherType)}\n\n"; + outs() << " {Type: " << *ot << "(SVFOtherType)}\n\n"; } else { @@ -283,40 +275,31 @@ std::string SymbolTableInfo::toString(SYMTYPE symtype) { switch (symtype) { - case SYMTYPE::BlackHole: - { + case SYMTYPE::BlackHole: { return "BlackHole"; } - case SYMTYPE::ConstantObj: - { + case SYMTYPE::ConstantObj: { return "ConstantObj"; } - case SYMTYPE::BlkPtr: - { + case SYMTYPE::BlkPtr: { return "BlkPtr"; } - case SYMTYPE::NullPtr: - { + case SYMTYPE::NullPtr: { return "NullPtr"; } - case SYMTYPE::ValSymbol: - { + case SYMTYPE::ValSymbol: { return "ValSym"; } - case SYMTYPE::ObjSymbol: - { + case SYMTYPE::ObjSymbol: { return "ObjSym"; } - case SYMTYPE::RetSymbol: - { + case SYMTYPE::RetSymbol: { return "RetSym"; } - case SYMTYPE::VarargSymbol: - { + case SYMTYPE::VarargSymbol: { return "VarargSym"; } - default: - { + default: { return "Invalid SYMTYPE"; } } @@ -325,32 +308,28 @@ std::string SymbolTableInfo::toString(SYMTYPE symtype) void SymbolTableInfo::dump() { OrderedMap idmap; - for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end(); - ++iter) + for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end(); ++iter) { const SymID i = iter->second; - SVFValue* val = (SVFValue*) iter->first; + SVFValue* val = (SVFValue*)iter->first; idmap[i] = val; } - for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end(); - ++iter) + for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end(); ++iter) { const SymID i = iter->second; - SVFValue* val = (SVFValue*) iter->first; + SVFValue* val = (SVFValue*)iter->first; idmap[i] = val; } - for (FunToIDMapTy::iterator iter = returnSymMap.begin(); iter != returnSymMap.end(); - ++iter) + for (FunToIDMapTy::iterator iter = returnSymMap.begin(); iter != returnSymMap.end(); ++iter) { const SymID i = iter->second; - SVFValue* val = (SVFValue*) iter->first; + SVFValue* val = (SVFValue*)iter->first; idmap[i] = val; } - for (FunToIDMapTy::iterator iter = varargSymMap.begin(); iter != varargSymMap.end(); - ++iter) + for (FunToIDMapTy::iterator iter = varargSymMap.begin(); iter != varargSymMap.end(); ++iter) { const SymID i = iter->second; - SVFValue* val = (SVFValue*) iter->first; + SVFValue* val = (SVFValue*)iter->first; idmap[i] = val; } outs() << "{SymbolTableInfo \n"; @@ -369,14 +348,10 @@ void MemObj::setFieldSensitive() typeInfo->setMaxFieldOffsetLimit(typeInfo->getNumOfElements()); } - /*! * Constructor of a memory object */ -MemObj::MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val) : - typeInfo(ti), refVal(val), symId(id) -{ -} +MemObj::MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val) : typeInfo(ti), refVal(val), symId(id) {} /*! * Whether it is a black hole object @@ -404,7 +379,6 @@ bool MemObj::isConstantByteSize() const return typeInfo->isConstantByteSize(); } - /// Set the number of elements of this object void MemObj::setNumOfElements(u32_t num) { @@ -508,7 +482,6 @@ bool MemObj::isConstDataOrAggData() const return typeInfo->isConstDataOrAggData(); } - const std::string MemObj::toString() const { std::string str; @@ -522,22 +495,20 @@ const std::string MemObj::toString() const SymID SymbolTableInfo::getValSym(const SVFValue* val) { - if(val->isNullPtr()) - return nullPtrSymID(); + if (val->isNullPtr()) return nullPtrSymID(); else if (val->isblackHole()) return blkPtrSymID(); else { - ValueToIDMapTy::const_iterator iter = valSymMap.find(val); - assert(iter!=valSymMap.end() &&"value sym not found"); + ValueToIDMapTy::const_iterator iter = valSymMap.find(val); + assert(iter != valSymMap.end() && "value sym not found"); return iter->second; } } bool SymbolTableInfo::hasValSym(const SVFValue* val) { - if (val->isNullPtr() || val->isblackHole()) - return true; + if (val->isNullPtr() || val->isblackHole()) return true; else return (valSymMap.find(val) != valSymMap.end()); } diff --git a/svf/lib/Util/BitVector.cpp b/svf/lib/Util/BitVector.cpp index c71698aac..93a94e0aa 100644 --- a/svf/lib/Util/BitVector.cpp +++ b/svf/lib/Util/BitVector.cpp @@ -14,33 +14,29 @@ namespace SVF { -BitVector::BitVector(void) - : BitVector(0) { } +BitVector::BitVector(void) : BitVector(0) {} -BitVector::BitVector(size_t n) - : CoreBitVector(n) +BitVector::BitVector(size_t n) : CoreBitVector(n) { // This ensures that leading zeroes are never stripped. set(0); reset(0); } -BitVector::BitVector(const BitVector &bv) - : CoreBitVector(bv) { } +BitVector::BitVector(const BitVector& bv) : CoreBitVector(bv) {} -BitVector::BitVector(BitVector &&bv) - : CoreBitVector(bv) { } +BitVector::BitVector(BitVector&& bv) : CoreBitVector(bv) {} -BitVector &BitVector::operator=(const BitVector &rhs) +BitVector& BitVector::operator=(const BitVector& rhs) { CoreBitVector::operator=(rhs); return *this; } -BitVector &BitVector::operator=(BitVector &&rhs) +BitVector& BitVector::operator=(BitVector&& rhs) { CoreBitVector::operator=(rhs); return *this; } -} // namespace SVF +} // namespace SVF diff --git a/svf/lib/Util/CDGBuilder.cpp b/svf/lib/Util/CDGBuilder.cpp index df0b13d90..628141c0f 100644 --- a/svf/lib/Util/CDGBuilder.cpp +++ b/svf/lib/Util/CDGBuilder.cpp @@ -31,11 +31,9 @@ using namespace SVF; using namespace SVFUtil; -void CDGBuilder::dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur, - const SVFBasicBlock *tgt, - std::vector &path, - std::vector &tgtNodes, - SVFLoopAndDomInfo *ld) +void CDGBuilder::dfsNodesBetweenPdomNodes(const SVFBasicBlock* cur, const SVFBasicBlock* tgt, + std::vector& path, + std::vector& tgtNodes, SVFLoopAndDomInfo* ld) { path.push_back(cur); if (cur == tgt) @@ -45,7 +43,7 @@ void CDGBuilder::dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur, else { auto it = ld->getPostDomTreeMap().find(cur); - for (const auto &nxt: it->second) + for (const auto& nxt : it->second) { dfsNodesBetweenPdomNodes(nxt, tgt, path, tgtNodes, ld); } @@ -60,13 +58,12 @@ void CDGBuilder::dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur, * @param LCA * @param tgtNodes */ -void -CDGBuilder::extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBasicBlock *LCA, - std::vector &tgtNodes) +void CDGBuilder::extractNodesBetweenPdomNodes(const SVFBasicBlock* succ, const SVFBasicBlock* LCA, + std::vector& tgtNodes) { if (succ == LCA) return; - std::vector path; - SVFLoopAndDomInfo *ld = const_cast(LCA->getFunction())->getLoopAndDomInfo(); + std::vector path; + SVFLoopAndDomInfo* ld = const_cast(LCA->getFunction())->getLoopAndDomInfo(); dfsNodesBetweenPdomNodes(LCA, succ, path, tgtNodes, ld); } @@ -75,31 +72,28 @@ CDGBuilder::extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBas */ void CDGBuilder::build() { - if (_controlDG->getTotalNodeNum() > 0) - return; - PAG *pag = PAG::getPAG(); + if (_controlDG->getTotalNodeNum() > 0) return; + PAG* pag = PAG::getPAG(); buildControlDependence(pag->getModule()); buildICFGNodeControlMap(); } - -s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasicBlock *Succ) +s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock* BB, const SVFBasicBlock* Succ) { - ICFG *icfg = PAG::getPAG()->getICFG(); - const ICFGNode *pred = icfg->getICFGNode(BB->getTerminator()); - const ICFGEdge *edge = nullptr; - for (const auto &inst: Succ->getInstructionList()) + ICFG* icfg = PAG::getPAG()->getICFG(); + const ICFGNode* pred = icfg->getICFGNode(BB->getTerminator()); + const ICFGEdge* edge = nullptr; + for (const auto& inst : Succ->getInstructionList()) { - if (const ICFGEdge *e = icfg->getICFGEdge(pred, icfg->getICFGNode(inst), ICFGEdge::ICFGEdgeK::IntraCF)) + if (const ICFGEdge* e = icfg->getICFGEdge(pred, icfg->getICFGNode(inst), ICFGEdge::ICFGEdgeK::IntraCF)) { edge = e; break; } } - if (const IntraCFGEdge *intraEdge = SVFUtil::dyn_cast(edge)) + if (const IntraCFGEdge* intraEdge = SVFUtil::dyn_cast(edge)) { - if(intraEdge->getCondition()) - return intraEdge->getSuccessorCondValue(); + if (intraEdge->getCondition()) return intraEdge->getSuccessorCondValue(); else return 0; } @@ -120,27 +114,26 @@ s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasic * including LCA if LCA is pred, excluding LCA if LCA is not pred * @param svfgModule */ -void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) +void CDGBuilder::buildControlDependence(const SVFModule* svfgModule) { - for (const auto &svfFun: *svfgModule) + for (const auto& svfFun : *svfgModule) { if (SVFUtil::isExtCall(svfFun)) continue; // extract basic block edges to be processed - Map> BBS; + Map> BBS; extractBBS(svfFun, BBS); - for (const auto &item: BBS) + for (const auto& item : BBS) { - const SVFBasicBlock *pred = item.first; + const SVFBasicBlock* pred = item.first; // for each bb pair - for (const SVFBasicBlock *succ: item.second) + for (const SVFBasicBlock* succ : item.second) { - const SVFBasicBlock *SVFLCA = const_cast(svfFun)-> - getLoopAndDomInfo()->findNearestCommonPDominator(pred, succ); - std::vector tgtNodes; + const SVFBasicBlock* SVFLCA = + const_cast(svfFun)->getLoopAndDomInfo()->findNearestCommonPDominator(pred, succ); + std::vector tgtNodes; // no common ancestor, may be exit() - if (SVFLCA == NULL) - tgtNodes.push_back(succ); + if (SVFLCA == NULL) tgtNodes.push_back(succ); else { if (SVFLCA == pred) tgtNodes.push_back(SVFLCA); @@ -149,7 +142,7 @@ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) } s64_t pos = getBBSuccessorBranchID(pred, succ); - for (const SVFBasicBlock *bb: tgtNodes) + for (const SVFBasicBlock* bb : tgtNodes) { updateMap(pred, bb, pos); } @@ -158,22 +151,20 @@ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) } } - /*! * (2) extract basic block edges on the CFG (pred->succ) to be processed * succ does not post-dominates pred (!postDT->dominates(succ, pred)) * @param func * @param res */ -void CDGBuilder::extractBBS(const SVF::SVFFunction *func, - Map> &res) +void CDGBuilder::extractBBS(const SVF::SVFFunction* func, + Map>& res) { - for (const auto &bb: *func) + for (const auto& bb : *func) { - for (const auto &succ: bb->getSuccessors()) + for (const auto& succ : bb->getSuccessors()) { - if (func->postDominate(succ, bb)) - continue; + if (func->postDominate(succ, bb)) continue; res[bb].push_back(succ); } } @@ -184,29 +175,28 @@ void CDGBuilder::extractBBS(const SVF::SVFFunction *func, */ void CDGBuilder::buildICFGNodeControlMap() { - ICFG *icfg = PAG::getPAG()->getICFG(); - for (const auto &it: _svfcontrolMap) + ICFG* icfg = PAG::getPAG()->getICFG(); + for (const auto& it : _svfcontrolMap) { - for (const auto &it2: it.second) + for (const auto& it2 : it.second) { - const SVFBasicBlock *controllingBB = it2.first; + const SVFBasicBlock* controllingBB = it2.first; // const ICFGNode *controlNode = _bbToNode[it.first].first; // if(!controlNode) continue; - const SVFInstruction *terminator = it.first->getInstructionList().back(); + const SVFInstruction* terminator = it.first->getInstructionList().back(); if (!terminator) continue; - const ICFGNode *controlNode = icfg->getICFGNode(terminator); + const ICFGNode* controlNode = icfg->getICFGNode(terminator); if (!controlNode) continue; // controlNode control at pos - for (const auto &inst: *controllingBB) + for (const auto& inst : *controllingBB) { - const ICFGNode *controllee = icfg->getICFGNode(inst); + const ICFGNode* controllee = icfg->getICFGNode(inst); _nodeControlMap[controlNode][controllee].insert(it2.second.begin(), it2.second.end()); _nodeDependentOnMap[controllee][controlNode].insert(it2.second.begin(), it2.second.end()); - for (s32_t pos: it2.second) + for (s32_t pos : it2.second) { _controlDG->addCDGEdgeFromSrcDst(controlNode, controllee, - SVFUtil::dyn_cast(controlNode)->getInst(), - pos); + SVFUtil::dyn_cast(controlNode)->getInst(), pos); } } } diff --git a/svf/lib/Util/CallGraphBuilder.cpp b/svf/lib/Util/CallGraphBuilder.cpp index 3655381dd..bd92552e4 100644 --- a/svf/lib/Util/CallGraphBuilder.cpp +++ b/svf/lib/Util/CallGraphBuilder.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - /* * CallGraphBuilder.cpp * @@ -52,10 +51,10 @@ CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule) { if (SVFUtil::isNonInstricCallSite(inst)) { - if(const SVFFunction* callee = getCallee(inst)) + if (const SVFFunction* callee = getCallee(inst)) { const CallICFGNode* callBlockNode = icfg->getCallICFGNode(inst); - callgraph->addDirectCallGraphEdge(callBlockNode,*F,callee); + callgraph->addDirectCallGraphEdge(callBlockNode, *F, callee); } } } @@ -92,7 +91,7 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule) // indirect call to the start routine function else { - cg->addThreadForkEdgeSetMap(cs,nullptr); + cg->addThreadForkEdgeSetMap(cs, nullptr); } } } @@ -116,7 +115,3 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule) return cg; } - - - - diff --git a/svf/lib/Util/CoreBitVector.cpp b/svf/lib/Util/CoreBitVector.cpp index d32fe2ba5..a426759a2 100644 --- a/svf/lib/Util/CoreBitVector.cpp +++ b/svf/lib/Util/CoreBitVector.cpp @@ -11,7 +11,7 @@ #include -#include "Util/SparseBitVector.h" // For LLVM's countPopulation. +#include "Util/SparseBitVector.h" // For LLVM's countPopulation. #include "Util/CoreBitVector.h" #include "SVFIR/SVFType.h" #include "Util/SVFUtil.h" @@ -21,26 +21,22 @@ namespace SVF const size_t CoreBitVector::WordSize = sizeof(Word) * CHAR_BIT; -CoreBitVector::CoreBitVector(void) - : CoreBitVector(0) { } +CoreBitVector::CoreBitVector(void) : CoreBitVector(0) {} -CoreBitVector::CoreBitVector(size_t n) - : offset(0), words(n, 0) { } +CoreBitVector::CoreBitVector(size_t n) : offset(0), words(n, 0) {} -CoreBitVector::CoreBitVector(const CoreBitVector &cbv) - : offset(cbv.offset), words(cbv.words) { } +CoreBitVector::CoreBitVector(const CoreBitVector& cbv) : offset(cbv.offset), words(cbv.words) {} -CoreBitVector::CoreBitVector(CoreBitVector &&cbv) - : offset(cbv.offset), words(std::move(cbv.words)) { } +CoreBitVector::CoreBitVector(CoreBitVector&& cbv) : offset(cbv.offset), words(std::move(cbv.words)) {} -CoreBitVector &CoreBitVector::operator=(const CoreBitVector &rhs) +CoreBitVector& CoreBitVector::operator=(const CoreBitVector& rhs) { this->offset = rhs.offset; this->words = rhs.words; return *this; } -CoreBitVector &CoreBitVector::operator=(CoreBitVector &&rhs) +CoreBitVector& CoreBitVector::operator=(CoreBitVector&& rhs) { this->offset = rhs.offset; this->words = std::move(rhs.words); @@ -50,15 +46,14 @@ CoreBitVector &CoreBitVector::operator=(CoreBitVector &&rhs) bool CoreBitVector::empty(void) const { for (const Word& w : words) - if (w) - return false; + if (w) return false; return true; } u32_t CoreBitVector::count(void) const { u32_t n = 0; - for (const Word &w : words) n += countPopulation(w); + for (const Word& w : words) n += countPopulation(w); return n; } @@ -72,7 +67,7 @@ void CoreBitVector::clear(void) bool CoreBitVector::test(u32_t bit) const { if (bit < offset || bit >= offset + words.size() * WordSize) return false; - const Word &containingWord = words[(bit - offset) / WordSize]; + const Word& containingWord = words[(bit - offset) / WordSize]; const Word mask = (Word)0b1 << (bit % WordSize); return mask & containingWord; } @@ -89,7 +84,7 @@ void CoreBitVector::set(u32_t bit) { extendTo(bit); - Word &containingWord = words[(bit - offset) / WordSize]; + Word& containingWord = words[(bit - offset) / WordSize]; Word mask = (Word)0b1 << (bit % WordSize); containingWord |= mask; } @@ -97,40 +92,42 @@ void CoreBitVector::set(u32_t bit) void CoreBitVector::reset(u32_t bit) { if (bit < offset || bit >= offset + words.size() * WordSize) return; - Word &containingWord = words[(bit - offset) / WordSize]; + Word& containingWord = words[(bit - offset) / WordSize]; Word mask = ~((Word)0b1 << (bit % WordSize)); containingWord &= mask; } -bool CoreBitVector::contains(const CoreBitVector &rhs) const +bool CoreBitVector::contains(const CoreBitVector& rhs) const { CoreBitVector tmp(*this); tmp &= rhs; return tmp == rhs; } -bool CoreBitVector::intersects(const CoreBitVector &rhs) const +bool CoreBitVector::intersects(const CoreBitVector& rhs) const { // TODO: want some common iteration method. if (empty() && rhs.empty()) return false; - const CoreBitVector &earlierOffsetCBV = offset <= rhs.offset ? *this : rhs; - const CoreBitVector &laterOffsetCBV = offset <= rhs.offset ? rhs : *this; + const CoreBitVector& earlierOffsetCBV = offset <= rhs.offset ? *this : rhs; + const CoreBitVector& laterOffsetCBV = offset <= rhs.offset ? rhs : *this; size_t earlierOffset = (offset < rhs.offset ? offset : rhs.offset) / WordSize; size_t laterOffset = (offset > rhs.offset ? offset : rhs.offset) / WordSize; laterOffset -= earlierOffset; - const Word *eWords = &earlierOffsetCBV.words[0]; + const Word* eWords = &earlierOffsetCBV.words[0]; const size_t eSize = earlierOffsetCBV.words.size(); - const Word *lWords = &laterOffsetCBV.words[0]; + const Word* lWords = &laterOffsetCBV.words[0]; const size_t lSize = laterOffsetCBV.words.size(); size_t e = 0; - for ( ; e != laterOffset && e != eSize; ++e) { } + for (; e != laterOffset && e != eSize; ++e) + { + } size_t l = 0; - for ( ; e != eSize && l != lSize; ++e, ++l) + for (; e != eSize && l != lSize; ++e, ++l) { if (eWords[e] & lWords[l]) return true; } @@ -138,7 +135,7 @@ bool CoreBitVector::intersects(const CoreBitVector &rhs) const return false; } -bool CoreBitVector::operator==(const CoreBitVector &rhs) const +bool CoreBitVector::operator==(const CoreBitVector& rhs) const { if (this == &rhs) return true; @@ -152,8 +149,8 @@ bool CoreBitVector::operator==(const CoreBitVector &rhs) const { // If the first bit is not the same in the word or words are different, // then we have a mismatch. - if (lhsSetIndex * WordSize + offset != rhsSetIndex * WordSize + rhs.offset - || words[lhsSetIndex] != rhs.words[rhsSetIndex]) + if (lhsSetIndex * WordSize + offset != rhsSetIndex * WordSize + rhs.offset || + words[lhsSetIndex] != rhs.words[rhsSetIndex]) { return false; } @@ -166,12 +163,12 @@ bool CoreBitVector::operator==(const CoreBitVector &rhs) const return lhsSetIndex >= words.size() && rhsSetIndex >= rhs.words.size(); } -bool CoreBitVector::operator!=(const CoreBitVector &rhs) const +bool CoreBitVector::operator!=(const CoreBitVector& rhs) const { return !(*this == rhs); } -bool CoreBitVector::operator|=(const CoreBitVector &rhs) +bool CoreBitVector::operator|=(const CoreBitVector& rhs) { if (words.size() == 0) { @@ -192,15 +189,15 @@ bool CoreBitVector::operator|=(const CoreBitVector &rhs) size_t rhsIndex = 0; // Only need to test against rhs's size since we extended this to hold rhs. - Word *thisWords = &words[thisIndex]; - const Word *rhsWords = &rhs.words[rhsIndex]; + Word* thisWords = &words[thisIndex]; + const Word* rhsWords = &rhs.words[rhsIndex]; const size_t length = rhs.words.size(); Word changed = 0; // Can start counting from 0 because we took the addresses of both // word vectors at the correct index. // #pragma omp simd - for (size_t i = 0 ; i < length; ++i) + for (size_t i = 0; i < length; ++i) { const Word oldWord = thisWords[i]; // Is there anything in rhs not in *this? @@ -211,7 +208,7 @@ bool CoreBitVector::operator|=(const CoreBitVector &rhs) return changed; } -bool CoreBitVector::operator&=(const CoreBitVector &rhs) +bool CoreBitVector::operator&=(const CoreBitVector& rhs) { // The first bit this and rhs have in common is the greater of // their offsets if the CBV with the smaller offset can hold @@ -243,7 +240,7 @@ bool CoreBitVector::operator&=(const CoreBitVector &rhs) } Word oldWord; - for ( ; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex) + for (; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex) { if (!changed) oldWord = words[thisIndex]; words[thisIndex] &= rhs.words[rhsIndex]; @@ -251,7 +248,7 @@ bool CoreBitVector::operator&=(const CoreBitVector &rhs) } // Clear the remaining bits with no rhs analogue. - for ( ; thisIndex < words.size(); ++thisIndex) + for (; thisIndex < words.size(); ++thisIndex) { if (!changed && words[thisIndex] != 0) changed = true; words[thisIndex] = 0; @@ -260,7 +257,7 @@ bool CoreBitVector::operator&=(const CoreBitVector &rhs) return changed; } -bool CoreBitVector::operator-=(const CoreBitVector &rhs) +bool CoreBitVector::operator-=(const CoreBitVector& rhs) { // Similar to |= in that we only iterate over rhs within this, but we // don't need to extend anything since nothing from rhs is being added. @@ -273,7 +270,7 @@ bool CoreBitVector::operator-=(const CoreBitVector &rhs) size_t thisIndex = indexForBit(greaterOffset); size_t rhsIndex = rhs.indexForBit(greaterOffset); Word oldWord; - for ( ; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex) + for (; thisIndex < words.size() && rhsIndex < rhs.words.size(); ++thisIndex, ++rhsIndex) { if (!changed) oldWord = words[thisIndex]; words[thisIndex] &= ~rhs.words[rhsIndex]; @@ -283,12 +280,12 @@ bool CoreBitVector::operator-=(const CoreBitVector &rhs) return changed; } -bool CoreBitVector::intersectWithComplement(const CoreBitVector &rhs) +bool CoreBitVector::intersectWithComplement(const CoreBitVector& rhs) { return *this -= rhs; } -void CoreBitVector::intersectWithComplement(const CoreBitVector &lhs, const CoreBitVector &rhs) +void CoreBitVector::intersectWithComplement(const CoreBitVector& lhs, const CoreBitVector& rhs) { // TODO: inefficient! *this = lhs; @@ -299,7 +296,7 @@ size_t CoreBitVector::hash(void) const { // From https://stackoverflow.com/a/27216842 size_t h = words.size(); - for (const Word &w : words) + for (const Word& w : words) { h ^= w + 0x9e3779b9 + (h << 6) + (h >> 2); } @@ -351,8 +348,10 @@ void CoreBitVector::extendTo(u32_t bit) offset = (bit / WordSize) * WordSize; words.push_back(0); } - else if (bit < offset) extendBackward(bit); - else if (bit >= offset + words.size() * WordSize) extendForward(bit); + else if (bit < offset) + extendBackward(bit); + else if (bit >= offset + words.size() * WordSize) + extendForward(bit); } size_t CoreBitVector::indexForBit(u32_t bit) const @@ -376,7 +375,7 @@ u32_t CoreBitVector::finalBit(void) const size_t CoreBitVector::nextSetIndex(const size_t start) const { size_t index = start; - for ( ; index < words.size(); ++index) + for (; index < words.size(); ++index) { if (words[index]) break; } @@ -384,8 +383,7 @@ size_t CoreBitVector::nextSetIndex(const size_t start) const return index; } -CoreBitVector::CoreBitVectorIterator::CoreBitVectorIterator(const CoreBitVector *cbv, bool end) - : cbv(cbv), bit(0) +CoreBitVector::CoreBitVectorIterator::CoreBitVectorIterator(const CoreBitVector* cbv, bool end) : cbv(cbv), bit(0) { wordIt = end ? cbv->words.end() : cbv->words.begin(); // If user didn't request an end iterator, or words is non-empty, @@ -394,7 +392,7 @@ CoreBitVector::CoreBitVectorIterator::CoreBitVectorIterator(const CoreBitVector if (wordIt != cbv->words.end() && !(cbv->words[0] & (Word)0b1)) ++(*this); } -const CoreBitVector::CoreBitVectorIterator &CoreBitVector::CoreBitVectorIterator::operator++(void) +const CoreBitVector::CoreBitVectorIterator& CoreBitVector::CoreBitVectorIterator::operator++(void) { assert(!atEnd() && "CoreBitVectorIterator::++(pre): incrementing past end!"); @@ -435,7 +433,7 @@ u32_t CoreBitVector::CoreBitVectorIterator::operator*(void) const return cbv->offset + wordsIndex * WordSize + bit; } -bool CoreBitVector::CoreBitVectorIterator::operator==(const CoreBitVectorIterator &rhs) const +bool CoreBitVector::CoreBitVectorIterator::operator==(const CoreBitVectorIterator& rhs) const { assert(cbv == rhs.cbv && "CoreBitVectorIterator::==: comparing iterators from different CBVs"); // When we're at the end we don't care about bit. @@ -443,7 +441,7 @@ bool CoreBitVector::CoreBitVectorIterator::operator==(const CoreBitVectorIterato return wordIt == rhs.wordIt && bit == rhs.bit; } -bool CoreBitVector::CoreBitVectorIterator::operator!=(const CoreBitVectorIterator &rhs) const +bool CoreBitVector::CoreBitVectorIterator::operator!=(const CoreBitVectorIterator& rhs) const { assert(cbv == rhs.cbv && "CoreBitVectorIterator::!=: comparing iterators from different CBVs"); return !(*this == rhs); @@ -454,4 +452,4 @@ bool CoreBitVector::CoreBitVectorIterator::atEnd(void) const return wordIt == cbv->words.end(); } -}; // namespace SVF +}; // namespace SVF diff --git a/svf/lib/Util/ExtAPI.cpp b/svf/lib/Util/ExtAPI.cpp index 57f4470b4..b409c27fc 100644 --- a/svf/lib/Util/ExtAPI.cpp +++ b/svf/lib/Util/ExtAPI.cpp @@ -84,8 +84,7 @@ static std::string GetStdoutFromCommand(const std::string& command) while (!feof(pipe)) { // use buffer to read and add to result - if (fgets(buffer, 128, pipe) != NULL) - result += buffer; + if (fgets(buffer, 128, pipe) != NULL) result += buffer; } pclose(pipe); // remove "\n" @@ -100,8 +99,7 @@ static std::string getFilePath(const std::string& path) if (path.compare("SVF_DIR") == 0) { char const* svfdir = getenv("SVF_DIR"); - if (svfdir) - bcFilePath = svfdir; + if (svfdir) bcFilePath = svfdir; } else if (path.compare("npm root") == 0) { @@ -109,8 +107,7 @@ static std::string getFilePath(const std::string& path) bcFilePath.append("/SVF"); } - if (!bcFilePath.empty() && bcFilePath.back() != '/') - bcFilePath.push_back('/'); + if (!bcFilePath.empty() && bcFilePath.back() != '/') bcFilePath.push_back('/'); bcFilePath.append(SVF_BUILD_TYPE "-build").append("/lib/extapi.bc"); return bcFilePath; } @@ -127,30 +124,25 @@ std::string ExtAPI::getExtBcPath() // 6. Search for `extapi.bc` from root directory for npm installation (iff SVF installed through npm) // 1. Set `path/to/extapi.bc` through `setExtBcPath()` - if (!extBcPath.empty()) - return extBcPath; + if (!extBcPath.empty()) return extBcPath; // 2. Set `path/to/extapi.bc` through the command line argument `-extapi=path/to/extapi.bc` - if (setExtBcPath(Options::ExtAPIPath())) - return extBcPath; + if (setExtBcPath(Options::ExtAPIPath())) return extBcPath; // 3. Get location generated by CMakeLists.txt from `config.h` header file (if SVF was installed) - if (setExtBcPath(SVF_EXTAPI_BC)) // Full path is available (for custom file names) + if (setExtBcPath(SVF_EXTAPI_BC)) // Full path is available (for custom file names) return extBcPath; - if (setExtBcPath(SVF_EXTAPI_DIR "/extapi.bc")) // Based on directory & default filename + if (setExtBcPath(SVF_EXTAPI_DIR "/extapi.bc")) // Based on directory & default filename return extBcPath; // 4. Get location in build tree based from `config.h` header file (if SVF was only built) - if (setExtBcPath(SVF_BUILD_DIR "/lib/extapi.bc")) - return extBcPath; + if (setExtBcPath(SVF_BUILD_DIR "/lib/extapi.bc")) return extBcPath; // 5. Get location based on environment variable $ENV{SVF_DIR} - if (setExtBcPath(getFilePath("SVF_DIR"))) - return extBcPath; + if (setExtBcPath(getFilePath("SVF_DIR"))) return extBcPath; // 6. Search for `extapi.bc` from root directory for npm installation (iff SVF installed through npm) - if (setExtBcPath(getFilePath("npm root"))) - return extBcPath; + if (setExtBcPath(getFilePath("npm root"))) return extBcPath; SVFUtil::errs() << "ERROR: Failed to find \"extapi.bc\" LLVM bitcode file in " << extBcPath << std::endl << "To override the default locations for \"extapi.bc\", you can:" << std::endl @@ -165,8 +157,7 @@ std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::stri { assert(fun && "Null SVFFunction* pointer"); for (const std::string& annotation : fun->getAnnotations()) - if (annotation.find(funcAnnotation) != std::string::npos) - return annotation; + if (annotation.find(funcAnnotation) != std::string::npos) return annotation; return ""; } @@ -174,19 +165,17 @@ bool ExtAPI::hasExtFuncAnnotation(const SVFFunction* fun, const std::string& fun { assert(fun && "Null SVFFunction* pointer"); for (const std::string& annotation : fun->getAnnotations()) - if (annotation.find(funcAnnotation) != std::string::npos) - return true; + if (annotation.find(funcAnnotation) != std::string::npos) return true; return false; } -bool ExtAPI::is_memcpy(const SVFFunction *F) +bool ExtAPI::is_memcpy(const SVFFunction* F) { - return F && - (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY") - || hasExtFuncAnnotation(F, "STRCAT")); + return F && (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY") || + hasExtFuncAnnotation(F, "STRCAT")); } -bool ExtAPI::is_memset(const SVFFunction *F) +bool ExtAPI::is_memset(const SVFFunction* F) { return F && hasExtFuncAnnotation(F, "MEMSET"); } @@ -211,8 +200,7 @@ s32_t ExtAPI::get_alloc_arg_pos(const SVFFunction* F) std::string number; for (char c : allocArg) { - if (isdigit(c)) - number.push_back(c); + if (isdigit(c)) number.push_back(c); } assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_ARG + number)?"); return std::stoi(number); @@ -224,14 +212,12 @@ bool ExtAPI::is_realloc(const SVFFunction* F) return F && hasExtFuncAnnotation(F, "REALLOC_RET"); } - // Should (F) be considered "external" (either not defined in the program // or a user-defined version of a known alloc or no-op)? bool ExtAPI::is_ext(const SVFFunction* F) { assert(F && "Null SVFFunction* pointer"); - if (F->isDeclaration() || F->isIntrinsic()) - return true; + if (F->isDeclaration() || F->isIntrinsic()) return true; else if (hasExtFuncAnnotation(F, "OVERWRITE") && F->getAnnotations().size() == 1) return false; else diff --git a/svf/lib/Util/NodeIDAllocator.cpp b/svf/lib/Util/NodeIDAllocator.cpp index 32fc94959..ecc633d5d 100644 --- a/svf/lib/Util/NodeIDAllocator.cpp +++ b/svf/lib/Util/NodeIDAllocator.cpp @@ -21,9 +21,9 @@ const NodeID NodeIDAllocator::constantObjectId = 1; const NodeID NodeIDAllocator::blackHolePointerId = 2; const NodeID NodeIDAllocator::nullPointerId = 3; -NodeIDAllocator *NodeIDAllocator::allocator = nullptr; +NodeIDAllocator* NodeIDAllocator::allocator = nullptr; -NodeIDAllocator *NodeIDAllocator::get(void) +NodeIDAllocator* NodeIDAllocator::get(void) { if (allocator == nullptr) { @@ -45,7 +45,8 @@ void NodeIDAllocator::unset(void) // Initialise counts to 4 because that's how many special nodes we have. NodeIDAllocator::NodeIDAllocator(void) : numObjects(4), numValues(4), numSymbols(4), numNodes(4), strategy(Options::NodeAllocStrat()) -{ } +{ +} NodeID NodeIDAllocator::allocateObjectId(void) { @@ -89,7 +90,7 @@ NodeID NodeIDAllocator::allocateGepObjectId(NodeID base, u32_t offset, u32_t max if (strategy == Strategy::DENSE) { // Nothing different to the other case. - id = numObjects; + id = numObjects; } else if (strategy == Strategy::REVERSE_DENSE) { @@ -107,10 +108,7 @@ NodeID NodeIDAllocator::allocateGepObjectId(NodeID base, u32_t offset, u32_t max // The offset is 10, not 11, because we add 1 to the offset to ensure that the // high bits are never 0. For example, we do not want the gep id to be 50 when // the base is 50 and the offset is 0. - NodeID gepMultiplier = pow(10, ceil(log10( - numSymbols > maxFieldLimit ? - numSymbols : maxFieldLimit - ))); + NodeID gepMultiplier = pow(10, ceil(log10(numSymbols > maxFieldLimit ? numSymbols : maxFieldLimit))); id = (offset + 1) * gepMultiplier + base; assert(id > numSymbols && "NodeIDAllocator::allocateGepObjectId: GEP allocation clashing with other nodes"); } @@ -184,10 +182,13 @@ const std::string NodeIDAllocator::Clusterer::LargestRegion = "LargestRegion"; const std::string NodeIDAllocator::Clusterer::BestCandidate = "BestCandidate"; const std::string NodeIDAllocator::Clusterer::NumNonTrivialRegionObjects = "NumNonTrivObj"; -std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, const std::vector> keys, std::vector>> &candidates, std::string evalSubtitle) +std::vector NodeIDAllocator::Clusterer::cluster( + BVDataPTAImpl* pta, const std::vector> keys, + std::vector>>& candidates, std::string evalSubtitle) { assert(pta != nullptr && "Clusterer::cluster: given null BVDataPTAImpl"); - assert(Options::NodeAllocStrat() == Strategy::DENSE && "Clusterer::cluster: only dense allocation clustering currently supported"); + assert(Options::NodeAllocStrat() == Strategy::DENSE && + "Clusterer::cluster: only dense allocation clustering currently supported"); Map overallStats; double fastClusterTime = 0.0; @@ -206,18 +207,19 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons // Objects each object shares at least a points-to set with. Map> coPointeeGraph; - for (const std::pair &keyOcc : keys) + for (const std::pair& keyOcc : keys) { - const PointsTo &pts = pta->getPts(keyOcc.first); + const PointsTo& pts = pta->getPts(keyOcc.first); const size_t oldSize = pointsToSets.size(); - pointsToSets[pts] += keyOcc.second;; + pointsToSets[pts] += keyOcc.second; + ; // Edges in this graph have no weight or uniqueness, so we only need to // do this for each points-to set once. if (oldSize != pointsToSets.size()) { NodeID firstO = !pts.empty() ? *(pts.begin()) : 0; - Set &firstOsNeighbours = coPointeeGraph[firstO]; + Set& firstOsNeighbours = coPointeeGraph[firstO]; for (const NodeID o : pts) { if (o != firstO) @@ -286,10 +288,10 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons // Points-to sets which are relevant to a region, i.e., those whose elements // belong to that region. Pair is for occurrences. - std::vector>> regionsPointsTos(numRegions); - for (const Map::value_type &ptocc : pointsToSets) + std::vector>> regionsPointsTos(numRegions); + for (const Map::value_type& ptocc : pointsToSets) { - const PointsTo &pt = ptocc.first; + const PointsTo& pt = ptocc.first; const unsigned occ = ptocc.second; if (pt.empty()) continue; // Guaranteed that begin() != end() because of the continue above. All objects in pt @@ -332,8 +334,7 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons // many words and multiply to get the number of bits; if we're aligning. if (Options::RegionAlign()) { - allocCounter = - ((allocCounter + NATIVE_INT_SIZE - 1) / NATIVE_INT_SIZE) * NATIVE_INT_SIZE; + allocCounter = ((allocCounter + NATIVE_INT_SIZE - 1) / NATIVE_INT_SIZE) * NATIVE_INT_SIZE; } if (regionNumObjects > largestRegion) largestRegion = regionNumObjects; @@ -349,12 +350,12 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons ++numGtIntRegions; nonTrivialRegionObjects += regionNumObjects; - double *distMatrix = getDistanceMatrix(regionsPointsTos[region], regionNumObjects, + double* distMatrix = getDistanceMatrix(regionsPointsTos[region], regionNumObjects, regionReverseMappings[region], distanceMatrixTime); clkStart = PTAStat::getClk(true); - int *dendrogram = new int[2 * (regionNumObjects - 1)]; - double *height = new double[regionNumObjects - 1]; + int* dendrogram = new int[2 * (regionNumObjects - 1)]; + double* height = new double[regionNumObjects - 1]; hclust_fast(regionNumObjects, distMatrix, method, dendrogram, height); delete[] distMatrix; delete[] height; @@ -363,8 +364,8 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons clkStart = PTAStat::getClk(true); Set visited; - traverseDendrogram(nodeMap, dendrogram, regionNumObjects, allocCounter, - visited, regionNumObjects - 1, regionMappings[region]); + traverseDendrogram(nodeMap, dendrogram, regionNumObjects, allocCounter, visited, regionNumObjects - 1, + regionMappings[region]); delete[] dendrogram; clkEnd = PTAStat::getClk(true); dendrogramTraversalTime += (clkEnd - clkStart) / TIMEINTERVAL; @@ -379,14 +380,15 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons } // Work out which of the mappings we generated looks best. - std::pair> bestMapping = determineBestMapping(candidates, pointsToSets, - evalSubtitle, evalTime); + std::pair> bestMapping = + determineBestMapping(candidates, pointsToSets, evalSubtitle, evalTime); overallStats[DistanceMatrixTime] = std::to_string(distanceMatrixTime); overallStats[DendrogramTraversalTime] = std::to_string(dendrogramTraversalTime); overallStats[FastClusterTime] = std::to_string(fastClusterTime); overallStats[EvalTime] = std::to_string(evalTime); - overallStats[TotalTime] = std::to_string(distanceMatrixTime + dendrogramTraversalTime + fastClusterTime + regioningTime + evalTime); + overallStats[TotalTime] = + std::to_string(distanceMatrixTime + dendrogramTraversalTime + fastClusterTime + regioningTime + evalTime); overallStats[BestCandidate] = SVFUtil::hclustMethodToString(bestMapping.first); printStats(evalSubtitle + ": overall", overallStats); @@ -394,7 +396,7 @@ std::vector NodeIDAllocator::Clusterer::cluster(BVDataPTAImpl *pta, cons return bestMapping.second; } -std::vector NodeIDAllocator::Clusterer::getReverseNodeMapping(const std::vector &nodeMapping) +std::vector NodeIDAllocator::Clusterer::getReverseNodeMapping(const std::vector& nodeMapping) { // nodeMapping.size() may not be big enough because we leave some gaps, but it's a start. std::vector reverseNodeMapping(nodeMapping.size(), UINT_MAX); @@ -411,10 +413,10 @@ std::vector NodeIDAllocator::Clusterer::getReverseNodeMapping(const std: size_t NodeIDAllocator::Clusterer::condensedIndex(size_t n, size_t i, size_t j) { // From https://stackoverflow.com/a/14839010 - return n*(n-1)/2 - (n-i)*(n-i-1)/2 + j - i - 1; + return n * (n - 1) / 2 - (n - i) * (n - i - 1) / 2 + j - i - 1; } -unsigned NodeIDAllocator::Clusterer::requiredBits(const PointsTo &pts) +unsigned NodeIDAllocator::Clusterer::requiredBits(const PointsTo& pts) { return requiredBits(pts.count()); } @@ -427,13 +429,13 @@ unsigned NodeIDAllocator::Clusterer::requiredBits(const size_t n) return ((n - 1) / NATIVE_INT_SIZE + 1) * NATIVE_INT_SIZE; } -double *NodeIDAllocator::Clusterer::getDistanceMatrix(const std::vector> pointsToSets, - const size_t numObjects, const Map &nodeMap, - double &distanceMatrixTime) +double* NodeIDAllocator::Clusterer::getDistanceMatrix( + const std::vector> pointsToSets, const size_t numObjects, + const Map& nodeMap, double& distanceMatrixTime) { const double clkStart = PTAStat::getClk(true); size_t condensedSize = (numObjects * (numObjects - 1)) / 2; - double *distMatrix = new double[condensedSize]; + double* distMatrix = new double[condensedSize]; for (size_t i = 0; i < condensedSize; ++i) distMatrix[i] = numObjects * numObjects; // TODO: maybe use machine epsilon? @@ -441,9 +443,9 @@ double *NodeIDAllocator::Clusterer::getDistanceMatrix(const std::vector &ptsOcc : pointsToSets) + for (const std::pair& ptsOcc : pointsToSets) { - const PointsTo *pts = ptsOcc.first; + const PointsTo* pts = ptsOcc.first; assert(pts != nullptr); const unsigned occ = ptsOcc.second; @@ -463,7 +465,7 @@ double *NodeIDAllocator::Clusterer::getDistanceMatrix(const std::vector::const_iterator moj = nodeMap.find(oj); assert(moj != nodeMap.end()); - double &existingDistance = distMatrix[condensedIndex(numObjects, moi->second, moj->second)]; + double& existingDistance = distMatrix[condensedIndex(numObjects, moi->second, moj->second)]; // Subtract extra occurrenceEpsilon to make upcoming logic simpler. // When existingDistance is never whole, it is always between two distances. @@ -489,7 +491,6 @@ double *NodeIDAllocator::Clusterer::getDistanceMatrix(const std::vector &nodeMap, const int *dendrogram, const size_t numObjects, unsigned &allocCounter, Set &visited, const int index, const std::vector ®ionNodeMap) +void NodeIDAllocator::Clusterer::traverseDendrogram(std::vector& nodeMap, const int* dendrogram, + const size_t numObjects, unsigned& allocCounter, Set& visited, + const int index, const std::vector& regionNodeMap) { if (visited.find(index) != visited.end()) return; visited.insert(index); @@ -529,12 +532,13 @@ void NodeIDAllocator::Clusterer::traverseDendrogram(std::vector &nodeMap } } -std::vector NodeIDAllocator::Clusterer::regionObjects(const Map> &graph, size_t numObjects, size_t &numLabels) +std::vector NodeIDAllocator::Clusterer::regionObjects(const Map>& graph, size_t numObjects, + size_t& numLabels) { unsigned label = UINT_MAX; std::vector labels(numObjects, UINT_MAX); Set labelled; - for (const Map>::value_type &oos : graph) + for (const Map>::value_type& oos : graph) { const NodeID o = oos.first; if (labels[o] != UINT_MAX) continue; @@ -569,7 +573,9 @@ std::vector NodeIDAllocator::Clusterer::regionObjects(const Map &nodeMap, const Map pointsToSets, Map &stats, bool accountForOcc) +void NodeIDAllocator::Clusterer::evaluate(const std::vector& nodeMap, + const Map pointsToSets, + Map& stats, bool accountForOcc) { u64_t totalTheoretical = 0; u64_t totalOriginalSbv = 0; @@ -577,9 +583,9 @@ void NodeIDAllocator::Clusterer::evaluate(const std::vector &nodeMap, co u64_t totalNewSbv = 0; u64_t totalNewBv = 0; - for (const Map::value_type &ptsOcc : pointsToSets) + for (const Map::value_type& ptsOcc : pointsToSets) { - const PointsTo &pts = ptsOcc.first; + const PointsTo& pts = ptsOcc.first; const unsigned occ = ptsOcc.second; if (pts.count() == 0) continue; @@ -648,8 +654,8 @@ void NodeIDAllocator::Clusterer::evaluate(const std::vector &nodeMap, co // Work out which of the mappings we generated looks best. std::pair> NodeIDAllocator::Clusterer::determineBestMapping( - const std::vector>> &candidates, - Map pointsToSets, const std::string &evalSubtitle, double &evalTime) + const std::vector>>& candidates, + Map pointsToSets, const std::string& evalSubtitle, double& evalTime) { // In case we're not comparing anything, set to first "candidate". std::pair> bestMapping = candidates[0]; @@ -657,7 +663,7 @@ std::pair> NodeIDAllocator::Clusterer:: size_t bestWords = std::numeric_limits::max(); if (evalSubtitle != "" || Options::ClusterMethod() == HCLUST_METHOD_SVF_BEST) { - for (const std::pair> &candidate : candidates) + for (const std::pair>& candidate : candidates) { Map candidateStats; hclust_fast_methods candidateMethod = candidate.first; @@ -673,8 +679,10 @@ std::pair> NodeIDAllocator::Clusterer:: size_t candidateWords = 0; if (Options::PtType() == PointsTo::SBV) candidateWords = std::stoull(candidateStats[NewSbvNumWords]); - else if (Options::PtType() == PointsTo::CBV) candidateWords = std::stoull(candidateStats[NewBvNumWords]); - else assert(false && "Clusterer::cluster: unsupported BV type for clustering."); + else if (Options::PtType() == PointsTo::CBV) + candidateWords = std::stoull(candidateStats[NewBvNumWords]); + else + assert(false && "Clusterer::cluster: unsupported BV type for clustering."); if (candidateWords < bestWords) { @@ -687,17 +695,14 @@ std::pair> NodeIDAllocator::Clusterer:: return bestMapping; } -void NodeIDAllocator::Clusterer::printStats(std::string subtitle, Map &stats) +void NodeIDAllocator::Clusterer::printStats(std::string subtitle, Map& stats) { // When not in order, it is too hard to compare original/new SBV/BV words, so this array forces an order. - static const std::string statKeys[] = - { - NumObjects, TheoreticalNumWords, OriginalSbvNumWords, OriginalBvNumWords, - NewSbvNumWords, NewBvNumWords, NumRegions, NumGtIntRegions, - NumNonTrivialRegionObjects, LargestRegion, RegioningTime, - DistanceMatrixTime, FastClusterTime, DendrogramTraversalTime, - EvalTime, TotalTime, BestCandidate - }; + static const std::string statKeys[] = { + NumObjects, TheoreticalNumWords, OriginalSbvNumWords, OriginalBvNumWords, NewSbvNumWords, + NewBvNumWords, NumRegions, NumGtIntRegions, NumNonTrivialRegionObjects, LargestRegion, + RegioningTime, DistanceMatrixTime, FastClusterTime, DendrogramTraversalTime, EvalTime, + TotalTime, BestCandidate}; const unsigned fieldWidth = 20; SVFUtil::outs().flags(std::ios::left); @@ -714,4 +719,4 @@ void NodeIDAllocator::Clusterer::printStats(std::string subtitle, Map Options::ClockType( - "clock-type", - "how time should be measured", - PTAStat::ClockType::CPU, -{ - {PTAStat::ClockType::Wall, "wall", "use wall time"}, - {PTAStat::ClockType::CPU, "cpu", "use CPU time"}, -} -); +const OptionMap Options::ClockType("clock-type", "how time should be measured", + PTAStat::ClockType::CPU, + { + {PTAStat::ClockType::Wall, "wall", "use wall time"}, + {PTAStat::ClockType::CPU, "cpu", "use CPU time"}, + }); -const Option Options::MarkedClocksOnly( - "marked-clocks-only", - "Only measure times where explicitly marked", - true -); +const Option Options::MarkedClocksOnly("marked-clocks-only", "Only measure times where explicitly marked", true); const OptionMap Options::NodeAllocStrat( - "node-alloc-strat", - "Method of allocating (LLVM) values and memory objects as node IDs", + "node-alloc-strat", "Method of allocating (LLVM) values and memory objects as node IDs", NodeIDAllocator::Strategy::SEQ, -{ - {NodeIDAllocator::Strategy::DENSE, "dense", "allocate objects together [0-n] and values together [m-MAX], separately"}, - {NodeIDAllocator::Strategy::REVERSE_DENSE, "reverse-dense", "like dense but flipped, objects are [m-MAX], values are [0-n]"}, - {NodeIDAllocator::Strategy::SEQ, "seq", "allocate values and objects sequentially, intermixed (default)"}, - {NodeIDAllocator::Strategy::DBUG, "debug", "allocate value and objects sequentially, intermixed, except GEP objects as offsets"}, -} -); - -const Option Options::MaxFieldLimit( - "field-limit", - "Maximum number of fields for field sensitive analysis", - 512 -); + { + {NodeIDAllocator::Strategy::DENSE, "dense", + "allocate objects together [0-n] and values together [m-MAX], separately"}, + {NodeIDAllocator::Strategy::REVERSE_DENSE, "reverse-dense", + "like dense but flipped, objects are [m-MAX], values are [0-n]"}, + {NodeIDAllocator::Strategy::SEQ, "seq", "allocate values and objects sequentially, intermixed (default)"}, + {NodeIDAllocator::Strategy::DBUG, "debug", + "allocate value and objects sequentially, intermixed, except GEP objects as offsets"}, + }); + +const Option Options::MaxFieldLimit("field-limit", "Maximum number of fields for field sensitive analysis", 512); const OptionMap Options::ptDataBacking( - "ptd", - "Overarching points-to data structure", - BVDataPTAImpl::PTBackingType::Persistent, -{ - {BVDataPTAImpl::PTBackingType::Mutable, "mutable", "points-to set per pointer"}, - {BVDataPTAImpl::PTBackingType::Persistent, "persistent", "points-to set ID per pointer, operations hash-consed"}, -} -); + "ptd", "Overarching points-to data structure", BVDataPTAImpl::PTBackingType::Persistent, + { + {BVDataPTAImpl::PTBackingType::Mutable, "mutable", "points-to set per pointer"}, + {BVDataPTAImpl::PTBackingType::Persistent, "persistent", + "points-to set ID per pointer, operations hash-consed"}, + }); -const Option Options::FsTimeLimit( - "fs-time-limit", - "time limit for main phase of flow-sensitive analyses", - 0 -); +const Option Options::FsTimeLimit("fs-time-limit", "time limit for main phase of flow-sensitive analyses", 0); const Option Options::VersioningThreads( - "versioning-threads", - "number of threads to use in the versioning phase of versioned flow-sensitive analysis", - 1 -); + "versioning-threads", "number of threads to use in the versioning phase of versioned flow-sensitive analysis", 1); -const Option Options::AnderTimeLimit( - "ander-time-limit", - "time limit for Andersen's analyses (ignored when -fs-time-limit set)", - 0 -); +const Option Options::AnderTimeLimit("ander-time-limit", + "time limit for Andersen's analyses (ignored when -fs-time-limit set)", 0); // ContextDDA.cpp -const Option Options::CxtBudget( - "cxt-bg", - "Maximum step budget of context-sensitive traversing", - 10000 -); +const Option Options::CxtBudget("cxt-bg", "Maximum step budget of context-sensitive traversing", 10000); // DDAPass.cpp -const Option Options::MaxPathLen( - "max-path", - "Maximum path limit for DDA", - 100000 -); - -const Option Options::MaxContextLen( - "max-cxt", - "Maximum context limit for DDA", - 3 -); +const Option Options::MaxPathLen("max-path", "Maximum path limit for DDA", 100000); + +const Option Options::MaxContextLen("max-cxt", "Maximum context limit for DDA", 3); const Option Options::MaxStepInWrapper( - "max-step", - "Maximum steps when traversing on SVFG to identify a memory allocation wrapper", - 10 -); - -const Option Options::UserInputQuery( - "query", - "Please specify queries by inputing their pointer ids", - "all" -); - -const Option Options::InsenRecur( - "in-recur", - "Mark context insensitive SVFG edges due to function recursions", - false -); - -const Option Options::InsenCycle( - "in-cycle", - "Mark context insensitive SVFG edges due to value-flow cycles", - false -); - -const Option Options::PrintCPts( - "cpts", - "Dump conditional points-to set ", - false -); - -const Option Options::PrintQueryPts( - "print-query-pts", - "Dump queries' conditional points-to set ", - false -); - -const Option Options::WPANum( - "wpa-num", - "collect WPA FS number only ", - false -); + "max-step", "Maximum steps when traversing on SVFG to identify a memory allocation wrapper", 10); + +const Option Options::UserInputQuery("query", "Please specify queries by inputing their pointer ids", + "all"); + +const Option Options::InsenRecur("in-recur", "Mark context insensitive SVFG edges due to function recursions", + false); + +const Option Options::InsenCycle("in-cycle", "Mark context insensitive SVFG edges due to value-flow cycles", + false); + +const Option Options::PrintCPts("cpts", "Dump conditional points-to set ", false); + +const Option Options::PrintQueryPts("print-query-pts", "Dump queries' conditional points-to set ", false); + +const Option Options::WPANum("wpa-num", "collect WPA FS number only ", false); /// register this into alias analysis group -//static RegisterAnalysisGroup AA_GROUP(DDAPA); +// static RegisterAnalysisGroup AA_GROUP(DDAPA); OptionMultiple Options::DDASelected( - "Select pointer analysis", -{ - {PointerAnalysis::FlowS_DDA, "dfs", "Demand-driven flow sensitive analysis"}, - {PointerAnalysis::Cxt_DDA, "cxt", "Demand-driven context- flow- sensitive analysis"}, -} -); + "Select pointer analysis", { + {PointerAnalysis::FlowS_DDA, "dfs", "Demand-driven flow sensitive analysis"}, + {PointerAnalysis::Cxt_DDA, "cxt", "Demand-driven context- flow- sensitive analysis"}, + }); // FlowDDA.cpp -const Option Options::FlowBudget( - "flow-bg", - "Maximum step budget of flow-sensitive traversing", - 10000 -); - +const Option Options::FlowBudget("flow-bg", "Maximum step budget of flow-sensitive traversing", 10000); // Offline constraint graph (OfflineConsG.cpp) -const Option Options::OCGDotGraph( - "dump-ocg", - "Dump dot graph of Offline Constraint Graph", - false -); - +const Option Options::OCGDotGraph("dump-ocg", "Dump dot graph of Offline Constraint Graph", false); // Program Assignment Graph for pointer analysis (SVFIR.cpp) -Option Options::HandBlackHole( - "blk", - "Handle blackhole edge", - false -); - -const Option Options::FirstFieldEqBase( - "ff-eq-base", - "Treat base objects as their first fields", - false -); +Option Options::HandBlackHole("blk", "Handle blackhole edge", false); +const Option Options::FirstFieldEqBase("ff-eq-base", "Treat base objects as their first fields", false); // SVFG optimizer (SVFGOPT.cpp) -const Option Options::ContextInsensitive( - "ci-svfg", - "Reduce SVFG into a context-insensitive one", - false -); +const Option Options::ContextInsensitive("ci-svfg", "Reduce SVFG into a context-insensitive one", false); -const Option Options::KeepAOFI( - "keep-aofi", - "Keep formal-in and actual-out parameters", - false -); - -const Option Options::SelfCycle( - "keep-self-cycle", - "How to handle self cycle edges: all, context, none", - "" -); +const Option Options::KeepAOFI("keep-aofi", "Keep formal-in and actual-out parameters", false); +const Option Options::SelfCycle("keep-self-cycle", "How to handle self cycle edges: all, context, none", + ""); // Sparse value-flow graph (VFG.cpp) -const Option Options::DumpVFG( - "dump-vfg", - "Dump dot graph of VFG", - false -); - +const Option Options::DumpVFG("dump-vfg", "Dump dot graph of VFG", false); // Base class of pointer analyses (PointerAnalysis.cpp) -const Option Options::TypePrint( - "print-type", - "Print type", - false -); - -const Option Options::FuncPointerPrint( - "print-fp", - "Print targets of indirect call site", - false -); - -const Option Options::PTSPrint( - "print-pts", - "Print points-to set of top-level pointers", - false -); - -const Option Options::PrintFieldWithBasePrefix( - "print-field", - "Print field object with base object id as the prefix", - false -); - -const Option Options::PTSAllPrint( - "print-all-pts", - "Print all points-to set of both top-level and address-taken variables", - false -); - -const Option Options::PStat( - "stat", - "Statistic for Pointer analysis", - true -); - -const Option Options::StatBudget( - "stat-limit", - "Iteration budget for On-the-fly statistics", - 20 -); - -const Option Options::PAGDotGraph( - "dump-pag", - "Dump dot graph of SVFIR", - false -); - -const Option Options::ShowSVFIRValue( - "show-ir-value", - "Show values of SVFIR (e.g., when generating dot graph)", - true -); - -const Option Options::DumpICFG( - "dump-icfg", - "Dump dot graph of ICFG", - false -); - -const Option Options::DumpJson( - "dump-json", - "Dump the SVFIR in JSON format", - "" -); - -const Option Options::ReadJson( - "read-json", - "Read the SVFIR in JSON format", - false -); - -const Option Options::CallGraphDotGraph( - "dump-callgraph", - "Dump dot graph of Call Graph", - false -); - -const Option Options::PAGPrint( - "print-pag", - "Print SVFIR to command line", - false -); - -const Option Options::IndirectCallLimit( - "ind-call-limit", - "Indirect solved call edge limit", - 50000 -); - -const Option Options::UsePreCompFieldSensitive( - "pre-field-sensitive", - "Use pre-computed field-sensitivity for later analysis", - true -); - -const Option Options::EnableAliasCheck( - "alias-check", - "Enable alias check functions", - true -); - -const Option Options::EnableTypeCheck( - "type-check", - "Enable type check functions", - true -); - -const Option Options::EnableThreadCallGraph( - "enable-tcg", - "Enable pointer analysis to use thread call graph", - true -); - -const Option Options::ConnectVCallOnCHA( - "v-call-cha", - "connect virtual calls using cha", - false -); +const Option Options::TypePrint("print-type", "Print type", false); + +const Option Options::FuncPointerPrint("print-fp", "Print targets of indirect call site", false); + +const Option Options::PTSPrint("print-pts", "Print points-to set of top-level pointers", false); + +const Option Options::PrintFieldWithBasePrefix("print-field", + "Print field object with base object id as the prefix", false); + +const Option Options::PTSAllPrint("print-all-pts", + "Print all points-to set of both top-level and address-taken variables", false); + +const Option Options::PStat("stat", "Statistic for Pointer analysis", true); + +const Option Options::StatBudget("stat-limit", "Iteration budget for On-the-fly statistics", 20); +const Option Options::PAGDotGraph("dump-pag", "Dump dot graph of SVFIR", false); + +const Option Options::ShowSVFIRValue("show-ir-value", "Show values of SVFIR (e.g., when generating dot graph)", + true); + +const Option Options::DumpICFG("dump-icfg", "Dump dot graph of ICFG", false); + +const Option Options::DumpJson("dump-json", "Dump the SVFIR in JSON format", ""); + +const Option Options::ReadJson("read-json", "Read the SVFIR in JSON format", false); + +const Option Options::CallGraphDotGraph("dump-callgraph", "Dump dot graph of Call Graph", false); + +const Option Options::PAGPrint("print-pag", "Print SVFIR to command line", false); + +const Option Options::IndirectCallLimit("ind-call-limit", "Indirect solved call edge limit", 50000); + +const Option Options::UsePreCompFieldSensitive("pre-field-sensitive", + "Use pre-computed field-sensitivity for later analysis", true); + +const Option Options::EnableAliasCheck("alias-check", "Enable alias check functions", true); + +const Option Options::EnableTypeCheck("type-check", "Enable type check functions", true); + +const Option Options::EnableThreadCallGraph("enable-tcg", "Enable pointer analysis to use thread call graph", + true); + +const Option Options::ConnectVCallOnCHA("v-call-cha", "connect virtual calls using cha", false); // PointerAnalysisImpl.cpp -const Option Options::INCDFPTData( - "inc-data", - "Enable incremental DFPTData for flow-sensitive analysis", - true -); - -const Option Options::ClusterAnder( - "cluster-ander", - "Stage Andersen's with Steensgard's and cluster based on that", - false -); - -const Option Options::ClusterFs( - "cluster-fs", - "Cluster for FS/VFS with auxiliary Andersen's", - false -); - -const Option Options::PlainMappingFs( - "plain-mapping-fs", - "Use an explicitly (not null) plain mapping for FS", - false -); +const Option Options::INCDFPTData("inc-data", "Enable incremental DFPTData for flow-sensitive analysis", true); + +const Option Options::ClusterAnder("cluster-ander", + "Stage Andersen's with Steensgard's and cluster based on that", false); + +const Option Options::ClusterFs("cluster-fs", "Cluster for FS/VFS with auxiliary Andersen's", false); + +const Option Options::PlainMappingFs("plain-mapping-fs", "Use an explicitly (not null) plain mapping for FS", + false); const OptionMap Options::PtType( - "pt-type", - "points-to set data structure to use in all analyses", - PointsTo::Type::SBV, -{ - {PointsTo::Type::SBV, "sbv", "sparse bit-vector"}, - {PointsTo::Type::CBV, "cbv", "core bit-vector (dynamic bit-vector without leading and trailing 0s)"}, - {PointsTo::Type::BV, "bv", "bit-vector (dynamic bit-vector without trailing 0s)"}, -} -); + "pt-type", "points-to set data structure to use in all analyses", PointsTo::Type::SBV, + { + {PointsTo::Type::SBV, "sbv", "sparse bit-vector"}, + {PointsTo::Type::CBV, "cbv", "core bit-vector (dynamic bit-vector without leading and trailing 0s)"}, + {PointsTo::Type::BV, "bv", "bit-vector (dynamic bit-vector without trailing 0s)"}, + }); const OptionMap Options::ClusterMethod( - "cluster-method", - "hierarchical clustering method for objects", - HCLUST_METHOD_SVF_BEST, -{ - {HCLUST_METHOD_SINGLE, "single", "single linkage; minimum spanning tree algorithm"}, - {HCLUST_METHOD_COMPLETE, "complete", "complete linkage; nearest-neighbour-chain algorithm"}, - {HCLUST_METHOD_AVERAGE, "average", "unweighted average linkage; nearest-neighbour-chain algorithm"}, - {HCLUST_METHOD_SVF_BEST, "best", "try all linkage criteria; choose best"}, -} -); + "cluster-method", "hierarchical clustering method for objects", HCLUST_METHOD_SVF_BEST, + { + {HCLUST_METHOD_SINGLE, "single", "single linkage; minimum spanning tree algorithm"}, + {HCLUST_METHOD_COMPLETE, "complete", "complete linkage; nearest-neighbour-chain algorithm"}, + {HCLUST_METHOD_AVERAGE, "average", "unweighted average linkage; nearest-neighbour-chain algorithm"}, + {HCLUST_METHOD_SVF_BEST, "best", "try all linkage criteria; choose best"}, + }); const Option Options::RegionedClustering( // Use cluster to "gather" the options closer together, even if it sounds a little worse. - "cluster-regioned", - "cluster regions separately", - true -); - -const Option Options::RegionAlign( - "cluster-region-aligned", - "align each region's identifiers to the native word size", - true -); - -const Option Options::PredictPtOcc( - "cluster-predict-occ", - "try to predict which points-to sets are more important in staged analysis", - false -); + "cluster-regioned", "cluster regions separately", true); -// Memory region (MemRegion.cpp) -const Option Options::IgnoreDeadFun( - "mssa-ignore-dead-fun", - "Don't construct memory SSA for deadfunction", - false -); +const Option Options::RegionAlign("cluster-region-aligned", + "align each region's identifiers to the native word size", true); +const Option Options::PredictPtOcc("cluster-predict-occ", + "try to predict which points-to sets are more important in staged analysis", + false); + +// Memory region (MemRegion.cpp) +const Option Options::IgnoreDeadFun("mssa-ignore-dead-fun", "Don't construct memory SSA for deadfunction", false); // Base class of pointer analyses (MemSSA.cpp) -const Option Options::DumpMSSA( - "dump-mssa", - "Dump memory SSA", - false -); - -const Option Options::MSSAFun( - "mssa-fun", - "Please specify which function needs to be dumped", - "" -); +const Option Options::DumpMSSA("dump-mssa", "Dump memory SSA", false); -const OptionMap Options::MemPar( - "mem-par", - "Memory region partition strategies (e.g., for SVFG construction)", - MemSSA::MemPartition::IntraDisjoint, -{ - {MemSSA::MemPartition::Distinct, "distinct", "memory region per each object"}, - {MemSSA::MemPartition::IntraDisjoint, "intra-disjoint", "memory regions partitioned based on each function"}, - {MemSSA::MemPartition::InterDisjoint, "inter-disjoint", "memory regions partitioned across functions"}, -} -); +const Option Options::MSSAFun("mssa-fun", "Please specify which function needs to be dumped", ""); +const OptionMap Options::MemPar( + "mem-par", "Memory region partition strategies (e.g., for SVFG construction)", MemSSA::MemPartition::IntraDisjoint, + { + {MemSSA::MemPartition::Distinct, "distinct", "memory region per each object"}, + {MemSSA::MemPartition::IntraDisjoint, "intra-disjoint", "memory regions partitioned based on each function"}, + {MemSSA::MemPartition::InterDisjoint, "inter-disjoint", "memory regions partitioned across functions"}, + }); // SVFG builder (SVFGBuilder.cpp) -const Option Options::SVFGWithIndirectCall( - "svfg-with-ind-call", - "Update Indirect Calls for SVFG using pre-analysis", - false -); - -Option Options::OPTSVFG( - "opt-svfg", - "Optimize SVFG to eliminate formal-in and actual-out", - false -); - -const Option Options::WriteSVFG( - "write-svfg", - "Write SVFG's analysis results to a file", - "" -); - -const Option Options::ReadSVFG( - "read-svfg", - "Read SVFG's analysis results from a file", - "" -); - - -const Option Options::IntraLock( - "intra-lock-td-edge", - "Use simple intra-procedural lock for adding SVFG edges", - true -); +const Option Options::SVFGWithIndirectCall("svfg-with-ind-call", + "Update Indirect Calls for SVFG using pre-analysis", false); +Option Options::OPTSVFG("opt-svfg", "Optimize SVFG to eliminate formal-in and actual-out", false); -// LockAnalysis.cpp -const Option Options::PrintLockSpan( - "print-lock", - "Print Thread Interleaving Results", - false -); +const Option Options::WriteSVFG("write-svfg", "Write SVFG's analysis results to a file", ""); +const Option Options::ReadSVFG("read-svfg", "Read SVFG's analysis results from a file", ""); -// MHP.cpp -const Option Options::PrintInterLev( - "print-interlev", - "Print Thread Interleaving Results", - false -); +const Option Options::IntraLock("intra-lock-td-edge", "Use simple intra-procedural lock for adding SVFG edges", + true); + +// LockAnalysis.cpp +const Option Options::PrintLockSpan("print-lock", "Print Thread Interleaving Results", false); -const Option Options::DoLockAnalysis( - "lock-analysis", - "Run Lock Analysis", - true -); +// MHP.cpp +const Option Options::PrintInterLev("print-interlev", "Print Thread Interleaving Results", false); +const Option Options::DoLockAnalysis("lock-analysis", "Run Lock Analysis", true); // MTAStat.cpp -const Option Options::AllPairMHP( - "all-pair-mhp", - "All pair MHP computation", - false -); - +const Option Options::AllPairMHP("all-pair-mhp", "All pair MHP computation", false); // TCT.cpp -const Option Options::TCTDotGraph( - "dump-tct", - "Dump dot graph of Call Graph", - false -); - +const Option Options::TCTDotGraph("dump-tct", "Dump dot graph of Call Graph", false); // LeakChecker.cpp -const Option Options::ValidateTests( - "valid-tests", - "Validate memory leak tests", - false -); - +const Option Options::ValidateTests("valid-tests", "Validate memory leak tests", false); // Source-sink analyzer (SrcSnkDDA.cpp) -const Option Options::DumpSlice( - "dump-slice", - "Dump dot graph of Saber Slices", - false -); - -const Option Options::CxtLimit( - "cxt-limit", - "Source-Sink Analysis Contexts Limit", - 3 -); +const Option Options::DumpSlice("dump-slice", "Dump dot graph of Saber Slices", false); +const Option Options::CxtLimit("cxt-limit", "Source-Sink Analysis Contexts Limit", 3); // CHG.cpp -const Option Options::DumpCHA( - "dump-cha", - "dump the class hierarchy graph", - false -); - +const Option Options::DumpCHA("dump-cha", "dump the class hierarchy graph", false); // DCHG.cpp -const Option Options::PrintDCHG( - "print-dchg", - "print the DCHG if debug information is available", - false -); - +const Option Options::PrintDCHG("print-dchg", "print the DCHG if debug information is available", false); // LLVMModule.cpp -const Option Options::Graphtxt( - "graph-txt", - "graph txt file to build SVFIR", - "" -); - -const Option Options::SVFMain( - "svf-main", - "add svf.main()", - false -); - -const Option Options::ModelConsts( - "model-consts", - "Modeling individual constant objects", - false -); - -const Option Options::ModelArrays( - "model-arrays", - "Modeling Gep offsets for array accesses", - false -); - -const Option Options::CyclicFldIdx( - "cyclic-field-index", - "Enable cyclic field index when generating field objects using modulus offset", - false -); - -const Option Options::SymTabPrint( - "print-symbol-table", - "Print Symbol Table to command line", - false -); +const Option Options::Graphtxt("graph-txt", "graph txt file to build SVFIR", ""); -// Conditions.cpp -const Option Options::MaxZ3Size( - "max-z3-size", - "Maximum size limit for Z3 expression", - 30 -); +const Option Options::SVFMain("svf-main", "add svf.main()", false); -// BoundedZ3Expr.cpp -const Option Options::MaxBVLen( - "max-bv-len", - "Maximum length limit for Z3 bitvector", - 64 -); +const Option Options::ModelConsts("model-consts", "Modeling individual constant objects", false); +const Option Options::ModelArrays("model-arrays", "Modeling Gep offsets for array accesses", false); +const Option Options::CyclicFldIdx("cyclic-field-index", + "Enable cyclic field index when generating field objects using modulus offset", + false); -// SaberCondAllocator.cpp -const Option Options::PrintPathCond( - "print-pc", - "Print out path condition", - false -); +const Option Options::SymTabPrint("print-symbol-table", "Print Symbol Table to command line", false); + +// Conditions.cpp +const Option Options::MaxZ3Size("max-z3-size", "Maximum size limit for Z3 expression", 30); +// BoundedZ3Expr.cpp +const Option Options::MaxBVLen("max-bv-len", "Maximum length limit for Z3 bitvector", 64); + +// SaberCondAllocator.cpp +const Option Options::PrintPathCond("print-pc", "Print out path condition", false); // SaberSVFGBuilder.cpp const Option Options::CollectExtRetGlobals( - "saber-collect-extret-globals", - "Don't include pointers returned by external function during collecting globals", - true -); - + "saber-collect-extret-globals", "Don't include pointers returned by external function during collecting globals", + true); // SVFUtil.cpp -const Option Options::DisableWarn( - "dwarn", - "Disable warning", - true -); - +const Option Options::DisableWarn("dwarn", "Disable warning", true); // Andersen.cpp -const Option Options::ConsCGDotGraph( - "dump-constraint-graph", - "Dump dot graph of Constraint Graph", - false -); - -const Option Options::BriefConsCGDotGraph( - "brief-constraint-graph", - "Dump dot graph of Constraint Graph", - true -); - -const Option Options::PrintCGGraph( - "print-constraint-graph", - "Print Constraint Graph to Terminal", - false -); - -const Option Options::WriteAnder( - "write-ander", - "-write-ander=ir_annotator (Annotated IR with Andersen's results) or write Andersen's analysis results to a user-specified text file", - "" -); - -const Option Options::ReadAnder( - "read-ander", - "-read-ander=ir_annotator (Read Andersen's analysis results from the annotated IR, e.g., *.pre.bc) or from a text file", - "" -); - -const Option Options::DiffPts( - "diff", - "Enable differential point-to set", - true -); - -Option Options::DetectPWC( - "merge-pwc", - "Enable PWC detection", - true -); - -//SVFIRBuilder.cpp +const Option Options::ConsCGDotGraph("dump-constraint-graph", "Dump dot graph of Constraint Graph", false); + +const Option Options::BriefConsCGDotGraph("brief-constraint-graph", "Dump dot graph of Constraint Graph", true); + +const Option Options::PrintCGGraph("print-constraint-graph", "Print Constraint Graph to Terminal", false); + +const Option Options::WriteAnder("write-ander", + "-write-ander=ir_annotator (Annotated IR with Andersen's results) or " + "write Andersen's analysis results to a user-specified text file", + ""); + +const Option Options::ReadAnder("read-ander", + "-read-ander=ir_annotator (Read Andersen's analysis results from the " + "annotated IR, e.g., *.pre.bc) or from a text file", + ""); + +const Option Options::DiffPts("diff", "Enable differential point-to set", true); + +Option Options::DetectPWC("merge-pwc", "Enable PWC detection", true); + +// SVFIRBuilder.cpp const Option Options::VtableInSVFIR( - "vt-in-ir", - "Handle vtable in ConstantArray/ConstantStruct in SVFIRBuilder (already handled in CHA?)", - false -); - -//WPAPass.cpp -const Option Options::ExtAPIPath( - "extapi", - "External API extapi.bc", - "" -); - -const Option Options::AnderSVFG( - "svfg", - "Generate SVFG after Andersen's Analysis", - false -); + "vt-in-ir", "Handle vtable in ConstantArray/ConstantStruct in SVFIRBuilder (already handled in CHA?)", false); + +// WPAPass.cpp +const Option Options::ExtAPIPath("extapi", "External API extapi.bc", ""); + +const Option Options::AnderSVFG("svfg", "Generate SVFG after Andersen's Analysis", false); const Option Options::SABERFULLSVFG( - "saber-full-svfg", - "When using SABER for bug detection pass, enable full svfg on top of the pointer-only one", - false -); + "saber-full-svfg", "When using SABER for bug detection pass, enable full svfg on top of the pointer-only one", + false); -const Option Options::PrintAliases( - "print-aliases", - "Print results for all pair aliases", - false -); +const Option Options::PrintAliases("print-aliases", "Print results for all pair aliases", false); OptionMultiple Options::PASelected( "Select pointer analysis", -{ - {PointerAnalysis::Andersen_WPA, "nander", "Standard inclusion-based analysis"}, - {PointerAnalysis::AndersenSCD_WPA, "sander", "Selective cycle detection inclusion-based analysis"}, - {PointerAnalysis::AndersenSFR_WPA, "sfrander", "Stride-based field representation inclusion-based analysis"}, - {PointerAnalysis::AndersenWaveDiff_WPA, "ander", "Diff wave propagation inclusion-based analysis"}, - {PointerAnalysis::Steensgaard_WPA, "steens", "Steensgaard's pointer analysis"}, - // Disabled till further work is done. - {PointerAnalysis::FSSPARSE_WPA, "fspta", "Sparse flow sensitive pointer analysis"}, - {PointerAnalysis::VFS_WPA, "vfspta", "Versioned sparse flow-sensitive points-to analysis"}, - {PointerAnalysis::TypeCPP_WPA, "type", "Type-based fast analysis for Callgraph, SVFIR and CHA"}, -} -); - + { + {PointerAnalysis::Andersen_WPA, "nander", "Standard inclusion-based analysis"}, + {PointerAnalysis::AndersenSCD_WPA, "sander", "Selective cycle detection inclusion-based analysis"}, + {PointerAnalysis::AndersenSFR_WPA, "sfrander", "Stride-based field representation inclusion-based analysis"}, + {PointerAnalysis::AndersenWaveDiff_WPA, "ander", "Diff wave propagation inclusion-based analysis"}, + {PointerAnalysis::Steensgaard_WPA, "steens", "Steensgaard's pointer analysis"}, + // Disabled till further work is done. + {PointerAnalysis::FSSPARSE_WPA, "fspta", "Sparse flow sensitive pointer analysis"}, + {PointerAnalysis::VFS_WPA, "vfspta", "Versioned sparse flow-sensitive points-to analysis"}, + {PointerAnalysis::TypeCPP_WPA, "type", "Type-based fast analysis for Callgraph, SVFIR and CHA"}, + }); OptionMultiple Options::AliasRule( - "Select alias check rule", -{ - {WPAPass::Conservative, "conservative", "return MayAlias if any pta says alias"}, - {WPAPass::Veto, "veto", "return NoAlias if any pta says no alias"}, -} -); - -const Option Options::ShowHiddenNode( - "show-hidden-nodes", - "Show hidden nodes on DOT Graphs (e.g., isolated node on a graph)", - false -); - -const Option Options::GrammarFilename( - "grammar", - "", - "" -); - -const Option Options::CFLGraph( - "cflgraph", - "", - "" -); - -const Option Options::PrintCFL( - "print-cfl", - "Print ir, grammar and cflgraph for debug.", - false -); - -const Option Options::FlexSymMap( - "flex-symmap", - "Extend exist sym map while read graph from dot if sym not in map.", - false -); + "Select alias check rule", { + {WPAPass::Conservative, "conservative", "return MayAlias if any pta says alias"}, + {WPAPass::Veto, "veto", "return NoAlias if any pta says no alias"}, + }); + +const Option Options::ShowHiddenNode("show-hidden-nodes", + "Show hidden nodes on DOT Graphs (e.g., isolated node on a graph)", false); + +const Option Options::GrammarFilename("grammar", "", ""); + +const Option Options::CFLGraph("cflgraph", "", ""); + +const Option Options::PrintCFL("print-cfl", "Print ir, grammar and cflgraph for debug.", false); + +const Option Options::FlexSymMap("flex-symmap", + "Extend exist sym map while read graph from dot if sym not in map.", false); const Option Options::PEGTransfer( - "peg-transfer", - "When explicit to true, cfl graph builder will transfer PAG load and store edges to copy and addr.", - false -); - -const Option Options::CFLSVFG( - "cflsvfg", - "When explicit to true, cfl graph builder will transfer SVFG to CFL Reachability.", - false -); - -const Option Options::POCRAlias( - "pocr-alias", - "When explicit to true, cfl data builder will transfer CFL graph to CFLData.", - false -); + "peg-transfer", "When explicit to true, cfl graph builder will transfer PAG load and store edges to copy and addr.", + false); + +const Option Options::CFLSVFG("cflsvfg", + "When explicit to true, cfl graph builder will transfer SVFG to CFL Reachability.", + false); + +const Option Options::POCRAlias("pocr-alias", + "When explicit to true, cfl data builder will transfer CFL graph to CFLData.", + false); const Option Options::POCRHybrid( "pocr-hybrid", - "When explicit to true, POCRHybridSolver transfer CFL graph to internal hybrid graph representation.", - false -); - -const Option Options::Customized( - "customized", - "When explicit to true, user can use any grammar file.", - false -); - -const Option Options::LoopAnalysis( - "loop-analysis", - "Analyze every func and get loop info and loop bounds.", - true -); - -const Option Options::LoopBound( - "loop-bound", - "Maximum number of loop", - 1 -); - -const Option Options::WidenDelay( - "widen-delay", "Loop Widen Delay", 3); -const Option Options::Timeout( - "timeout", "time out (seconds), set -1 (no timeout), default 14400s",14400); -const Option Options::OutputName( - "output","output db file","output.db"); -const Option Options::BufferOverflowCheck( - "overflow","Buffer Overflow Detection",false); -const Option Options::MemoryLeakCheck( - "leak", "Memory Leak Detection",false); -const Option Options::FileCheck( - "fileck", "File Open/Close Detection",false); -const Option Options::DFreeCheck( - "dfree", "Double Free Detection",false); -const Option Options::RaceCheck( - "race", "Data race Detection",false); -const Option Options::GepUnknownIdx( - "gep-unknown-idx","Skip Gep Unknown Index",false); -const Option Options::RunUncallFuncs( - "run-uncall-fun","Skip Gep Unknown Index",false); -const Option Options::ICFGMergeAdjacentNodes( - "icfg-merge-adjnodes","ICFG Simplification - Merge Adjacent Nodes in the Same Basic Block.",false); + "When explicit to true, POCRHybridSolver transfer CFL graph to internal hybrid graph representation.", false); + +const Option Options::Customized("customized", "When explicit to true, user can use any grammar file.", false); + +const Option Options::LoopAnalysis("loop-analysis", "Analyze every func and get loop info and loop bounds.", + true); +const Option Options::LoopBound("loop-bound", "Maximum number of loop", 1); + +const Option Options::WidenDelay("widen-delay", "Loop Widen Delay", 3); +const Option Options::Timeout("timeout", "time out (seconds), set -1 (no timeout), default 14400s", 14400); +const Option Options::OutputName("output", "output db file", "output.db"); +const Option Options::BufferOverflowCheck("overflow", "Buffer Overflow Detection", false); +const Option Options::MemoryLeakCheck("leak", "Memory Leak Detection", false); +const Option Options::FileCheck("fileck", "File Open/Close Detection", false); +const Option Options::DFreeCheck("dfree", "Double Free Detection", false); +const Option Options::RaceCheck("race", "Data race Detection", false); +const Option Options::GepUnknownIdx("gep-unknown-idx", "Skip Gep Unknown Index", false); +const Option Options::RunUncallFuncs("run-uncall-fun", "Skip Gep Unknown Index", false); +const Option Options::ICFGMergeAdjacentNodes( + "icfg-merge-adjnodes", "ICFG Simplification - Merge Adjacent Nodes in the Same Basic Block.", false); -const Option Options::AEPrecision( - "precision", - "symbolic abstraction precision for float", - 0 -); +const Option Options::AEPrecision("precision", "symbolic abstraction precision for float", 0); } // namespace SVF. diff --git a/svf/lib/Util/PTAStat.cpp b/svf/lib/Util/PTAStat.cpp index 705b6f2ee..92dd94914 100644 --- a/svf/lib/Util/PTAStat.cpp +++ b/svf/lib/Util/PTAStat.cpp @@ -36,12 +36,8 @@ using namespace SVF; using namespace std; -PTAStat::PTAStat(PointerAnalysis* p) : SVFStat(), - pta(p), - _vmrssUsageBefore(0), - _vmrssUsageAfter(0), - _vmsizeUsageBefore(0), - _vmsizeUsageAfter(0) +PTAStat::PTAStat(PointerAnalysis* p) + : SVFStat(), pta(p), _vmrssUsageBefore(0), _vmrssUsageAfter(0), _vmsizeUsageBefore(0), _vmsizeUsageAfter(0) { u32_t vmrss = 0; u32_t vmsize = 0; @@ -57,12 +53,12 @@ void PTAStat::performStat() callgraphStat(); SVFIR* pag = SVFIR::getPAG(); - for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; ++it) + for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; ++it) { PAGNode* node = it->second; - if(SVFUtil::isa(node)) + if (SVFUtil::isa(node)) { - if(pta->isLocalVarInRecursiveFun(node->getId())) + if (pta->isLocalVarInRecursiveFun(node->getId())) { localVarInRecursion.set(node->getId()); } @@ -98,24 +94,23 @@ void PTAStat::callgraphStat() for (; it != eit; ++it) { totalNode++; - if(callgraphSCC->isInCycle(it->first)) + if (callgraphSCC->isInCycle(it->first)) { sccRepNodeSet.insert(callgraphSCC->repNode(it->first)); nodeInCycle++; const NodeBS& subNodes = callgraphSCC->subNodes(it->first); - if(subNodes.count() > maxNodeInCycle) - maxNodeInCycle = subNodes.count(); + if (subNodes.count() > maxNodeInCycle) maxNodeInCycle = subNodes.count(); } CallGraphNode::const_iterator edgeIt = it->second->InEdgeBegin(); CallGraphNode::const_iterator edgeEit = it->second->InEdgeEnd(); for (; edgeIt != edgeEit; ++edgeIt) { - CallGraphEdge *edge = *edgeIt; - totalEdge+= edge->getDirectCalls().size() + edge->getIndirectCalls().size(); - if(callgraphSCC->repNode(edge->getSrcID()) == callgraphSCC->repNode(edge->getDstID())) + CallGraphEdge* edge = *edgeIt; + totalEdge += edge->getDirectCalls().size() + edge->getIndirectCalls().size(); + if (callgraphSCC->repNode(edge->getSrcID()) == callgraphSCC->repNode(edge->getDstID())) { - edgeInCycle+=edge->getDirectCalls().size() + edge->getIndirectCalls().size(); + edgeInCycle += edge->getDirectCalls().size() + edge->getIndirectCalls().size(); } } } @@ -129,13 +124,17 @@ void PTAStat::callgraphStat() PTNumStatMap["TotalEdge"] = totalEdge; PTNumStatMap["CalRetPairInCycle"] = edgeInCycle; - if(pta->getAnalysisTy() >= PointerAnalysis::PTATY::Andersen_BASE && pta->getAnalysisTy() <= PointerAnalysis::PTATY::Steensgaard_WPA) + if (pta->getAnalysisTy() >= PointerAnalysis::PTATY::Andersen_BASE && + pta->getAnalysisTy() <= PointerAnalysis::PTATY::Steensgaard_WPA) SVFStat::printStat("CallGraph Stats (Andersen analysis)"); - else if(pta->getAnalysisTy() >= PointerAnalysis::PTATY::FSDATAFLOW_WPA && pta->getAnalysisTy() <= PointerAnalysis::PTATY::FSCS_WPA) + else if (pta->getAnalysisTy() >= PointerAnalysis::PTATY::FSDATAFLOW_WPA && + pta->getAnalysisTy() <= PointerAnalysis::PTATY::FSCS_WPA) SVFStat::printStat("CallGraph Stats (Flow-sensitive analysis)"); - else if(pta->getAnalysisTy() >= PointerAnalysis::PTATY::CFLFICI_WPA && pta->getAnalysisTy() <= PointerAnalysis::PTATY::CFLFSCS_WPA) + else if (pta->getAnalysisTy() >= PointerAnalysis::PTATY::CFLFICI_WPA && + pta->getAnalysisTy() <= PointerAnalysis::PTATY::CFLFSCS_WPA) SVFStat::printStat("CallGraph Stats (CFL-R analysis)"); - else if(pta->getAnalysisTy() >= PointerAnalysis::PTATY::FieldS_DDA && pta->getAnalysisTy() <= PointerAnalysis::PTATY::Cxt_DDA) + else if (pta->getAnalysisTy() >= PointerAnalysis::PTATY::FieldS_DDA && + pta->getAnalysisTy() <= PointerAnalysis::PTATY::Cxt_DDA) SVFStat::printStat("CallGraph Stats (DDA analysis)"); else SVFStat::printStat("CallGraph Stats"); diff --git a/svf/lib/Util/SVFBugReport.cpp b/svf/lib/Util/SVFBugReport.cpp index fea0c3029..0c8e1ae13 100644 --- a/svf/lib/Util/SVFBugReport.cpp +++ b/svf/lib/Util/SVFBugReport.cpp @@ -20,7 +20,6 @@ // //===----------------------------------------------------------------------===// - // // Created by JoelYang on 2023/4/19. // @@ -35,8 +34,7 @@ using namespace std; using namespace SVF; -const std::map GenericBug::BugType2Str = -{ +const std::map GenericBug::BugType2Str = { {GenericBug::FULLBUFOVERFLOW, "Full Buffer Overflow"}, {GenericBug::PARTIALBUFOVERFLOW, "Partial Buffer Overflow"}, {GenericBug::NEVERFREE, "Never Free"}, @@ -45,28 +43,27 @@ const std::map GenericBug::BugType2Str = {GenericBug::FILEPARTIALCLOSE, "File Partial Close"}, {GenericBug::DOUBLEFREE, "Double Free"}, {GenericBug::FULLNULLPTRDEREFERENCE, "Full Null Ptr Dereference"}, - {GenericBug::PARTIALNULLPTRDEREFERENCE, "Partial Null Ptr Dereference"} -}; + {GenericBug::PARTIALNULLPTRDEREFERENCE, "Partial Null Ptr Dereference"}}; const std::string GenericBug::getLoc() const { - const SVFBugEvent&sourceInstEvent = bugEventStack.at(bugEventStack.size() -1); + const SVFBugEvent& sourceInstEvent = bugEventStack.at(bugEventStack.size() - 1); return sourceInstEvent.getEventLoc(); } const std::string GenericBug::getFuncName() const { - const SVFBugEvent&sourceInstEvent = bugEventStack.at(bugEventStack.size() -1); + const SVFBugEvent& sourceInstEvent = bugEventStack.at(bugEventStack.size() - 1); return sourceInstEvent.getFuncName(); } -cJSON *BufferOverflowBug::getBugDescription() const +cJSON* BufferOverflowBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); - cJSON *allocLB = cJSON_CreateNumber(allocLowerBound); - cJSON *allocUB = cJSON_CreateNumber(allocUpperBound); - cJSON *accessLB = cJSON_CreateNumber(accessLowerBound); - cJSON *accessUB = cJSON_CreateNumber(accessUpperBound); + cJSON* bugDescription = cJSON_CreateObject(); + cJSON* allocLB = cJSON_CreateNumber(allocLowerBound); + cJSON* allocUB = cJSON_CreateNumber(allocUpperBound); + cJSON* accessLB = cJSON_CreateNumber(accessLowerBound); + cJSON* accessUB = cJSON_CreateNumber(accessUpperBound); cJSON_AddItemToObject(bugDescription, "AllocLowerBound", allocLB); cJSON_AddItemToObject(bugDescription, "AllocUpperBound", allocUB); @@ -79,33 +76,30 @@ cJSON *BufferOverflowBug::getBugDescription() const void BufferOverflowBug::printBugToTerminal() const { stringstream bugInfo; - if(FullBufferOverflowBug::classof(this)) + if (FullBufferOverflowBug::classof(this)) { - SVFUtil::errs() << SVFUtil::bugMsg1("\t Full Overflow :") << " accessing at : (" - << GenericBug::getLoc() << ")\n"; - + SVFUtil::errs() << SVFUtil::bugMsg1("\t Full Overflow :") << " accessing at : (" << GenericBug::getLoc() + << ")\n"; } else { - SVFUtil::errs() << SVFUtil::bugMsg1("\t Partial Overflow :") << " accessing at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg1("\t Partial Overflow :") << " accessing at : (" << GenericBug::getLoc() + << ")\n"; } bugInfo << "\t\t allocate size : [" << allocLowerBound << ", " << allocUpperBound << "], "; bugInfo << "access size : [" << accessLowerBound << ", " << accessUpperBound << "]\n"; SVFUtil::errs() << "\t\t Info : \n" << bugInfo.str(); SVFUtil::errs() << "\t\t Events : \n"; - for(auto event : bugEventStack) + for (auto event : bugEventStack) { - switch(event.getEventType()) - { - case SVFBugEvent::CallSite: + switch (event.getEventType()) { + case SVFBugEvent::CallSite: { SVFUtil::errs() << "\t\t callsite at : ( " << event.getEventLoc() << " )\n"; break; } - default: - { + default: { // TODO: implement more events when needed break; } @@ -113,30 +107,30 @@ void BufferOverflowBug::printBugToTerminal() const } } -cJSON * NeverFreeBug::getBugDescription() const +cJSON* NeverFreeBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); + cJSON* bugDescription = cJSON_CreateObject(); return bugDescription; } void NeverFreeBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg1("\t NeverFree :") << " memory allocation at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg1("\t NeverFree :") << " memory allocation at : (" << GenericBug::getLoc() + << ")\n"; } -cJSON * PartialLeakBug::getBugDescription() const +cJSON* PartialLeakBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); - cJSON *pathInfo = cJSON_CreateArray(); + cJSON* bugDescription = cJSON_CreateObject(); + cJSON* pathInfo = cJSON_CreateArray(); auto lastBranchEventIt = bugEventStack.end() - 1; - for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) + for (auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) { - cJSON *newBranch = cJSON_CreateObject(); - cJSON *branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str()); - if(branchLoc == nullptr) branchLoc = cJSON_CreateObject(); + cJSON* newBranch = cJSON_CreateObject(); + cJSON* branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str()); + if (branchLoc == nullptr) branchLoc = cJSON_CreateObject(); - cJSON *branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str()); + cJSON* branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str()); cJSON_AddItemToObject(newBranch, "BranchLoc", branchLoc); cJSON_AddItemToObject(newBranch, "BranchCond", branchCondition); @@ -151,30 +145,31 @@ cJSON * PartialLeakBug::getBugDescription() const void PartialLeakBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg2("\t PartialLeak :") << " memory allocation at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg2("\t PartialLeak :") << " memory allocation at : (" << GenericBug::getLoc() + << ")\n"; SVFUtil::errs() << "\t\t conditional free path: \n"; auto lastBranchEventIt = bugEventStack.end() - 1; - for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) + for (auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) { - SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() << ") \n"; + SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() + << ") \n"; } SVFUtil::errs() << "\n"; } -cJSON * DoubleFreeBug::getBugDescription() const +cJSON* DoubleFreeBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); + cJSON* bugDescription = cJSON_CreateObject(); - cJSON *pathInfo = cJSON_CreateArray(); + cJSON* pathInfo = cJSON_CreateArray(); auto lastBranchEventIt = bugEventStack.end() - 1; - for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) + for (auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) { - cJSON *newBranch = cJSON_CreateObject(); - cJSON *branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str()); - if(branchLoc == nullptr) branchLoc = cJSON_CreateObject(); - cJSON *branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str()); + cJSON* newBranch = cJSON_CreateObject(); + cJSON* branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str()); + if (branchLoc == nullptr) branchLoc = cJSON_CreateObject(); + cJSON* branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str()); cJSON_AddItemToObject(newBranch, "BranchLoc", branchLoc); cJSON_AddItemToObject(newBranch, "BranchCond", branchCondition); @@ -188,43 +183,44 @@ cJSON * DoubleFreeBug::getBugDescription() const void DoubleFreeBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg2("\t Double Free :") << " memory allocation at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg2("\t Double Free :") << " memory allocation at : (" << GenericBug::getLoc() + << ")\n"; SVFUtil::errs() << "\t\t double free path: \n"; auto lastBranchEventIt = bugEventStack.end() - 1; - for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) + for (auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) { - SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() << ") \n"; + SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() + << ") \n"; } SVFUtil::errs() << "\n"; } -cJSON * FileNeverCloseBug::getBugDescription() const +cJSON* FileNeverCloseBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); + cJSON* bugDescription = cJSON_CreateObject(); return bugDescription; } void FileNeverCloseBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg1("\t FileNeverClose :") << " file open location at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg1("\t FileNeverClose :") << " file open location at : (" << GenericBug::getLoc() + << ")\n"; } -cJSON * FilePartialCloseBug::getBugDescription() const +cJSON* FilePartialCloseBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); + cJSON* bugDescription = cJSON_CreateObject(); - cJSON *pathInfo = cJSON_CreateArray(); + cJSON* pathInfo = cJSON_CreateArray(); auto lastBranchEventIt = bugEventStack.end() - 1; - for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) + for (auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) { - cJSON *newBranch = cJSON_CreateObject(); - cJSON *branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str()); - if(branchLoc == nullptr) branchLoc = cJSON_CreateObject(); - cJSON *branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str()); + cJSON* newBranch = cJSON_CreateObject(); + cJSON* branchLoc = cJSON_Parse((*eventIt).getEventLoc().c_str()); + if (branchLoc == nullptr) branchLoc = cJSON_CreateObject(); + cJSON* branchCondition = cJSON_CreateString((*eventIt).getEventDescription().c_str()); cJSON_AddItemToObject(newBranch, "BranchLoc", branchLoc); cJSON_AddItemToObject(newBranch, "BranchCond", branchCondition); @@ -238,39 +234,40 @@ cJSON * FilePartialCloseBug::getBugDescription() const void FilePartialCloseBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg2("\t PartialFileClose :") << " file open location at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg2("\t PartialFileClose :") << " file open location at : (" << GenericBug::getLoc() + << ")\n"; SVFUtil::errs() << "\t\t conditional file close path: \n"; auto lastBranchEventIt = bugEventStack.end() - 1; - for(auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) + for (auto eventIt = bugEventStack.begin(); eventIt != lastBranchEventIt; eventIt++) { - SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() << ") \n"; + SVFUtil::errs() << "\t\t --> (" << (*eventIt).getEventLoc() << "|" << (*eventIt).getEventDescription() + << ") \n"; } SVFUtil::errs() << "\n"; } -cJSON *FullNullPtrDereferenceBug::getBugDescription() const +cJSON* FullNullPtrDereferenceBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); + cJSON* bugDescription = cJSON_CreateObject(); return bugDescription; } void FullNullPtrDereferenceBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg2("\t FullNullPtrDereference :") << " dereference at : (" - << GenericBug::getLoc() << ")\n"; + SVFUtil::errs() << SVFUtil::bugMsg2("\t FullNullPtrDereference :") << " dereference at : (" << GenericBug::getLoc() + << ")\n"; } -cJSON *PartialNullPtrDereferenceBug::getBugDescription() const +cJSON* PartialNullPtrDereferenceBug::getBugDescription() const { - cJSON *bugDescription = cJSON_CreateObject(); + cJSON* bugDescription = cJSON_CreateObject(); return bugDescription; } void PartialNullPtrDereferenceBug::printBugToTerminal() const { - SVFUtil::errs() << SVFUtil::bugMsg2("\t PartialNullPtrDereference :") << " dereference at : (" + SVFUtil::errs() << SVFUtil::bugMsg2("\t PartialNullPtrDereference :") << " dereference at : (" << GenericBug::getLoc() << ")\n"; } @@ -286,10 +283,9 @@ const std::string SVFBugEvent::getEventLoc() const const std::string SVFBugEvent::getEventDescription() const { - switch(getEventType()) - { - case SVFBugEvent::Branch: + switch (getEventType()) { + case SVFBugEvent::Branch: { if (typeAndInfoFlag & BRANCHFLAGMASK) { return "True"; @@ -300,11 +296,10 @@ const std::string SVFBugEvent::getEventDescription() const } break; } - case SVFBugEvent::CallSite: - { + case SVFBugEvent::CallSite: { std::string description("calls "); - const SVFFunction *callee = SVFUtil::getCallee(eventInst); - if(callee == nullptr) + const SVFFunction* callee = SVFUtil::getCallee(eventInst); + if (callee == nullptr) { description += ""; } @@ -315,12 +310,10 @@ const std::string SVFBugEvent::getEventDescription() const return description; break; } - case SVFBugEvent::SourceInst: - { + case SVFBugEvent::SourceInst: { return "None"; } - default: - { + default: { assert(false && "No such type of event!"); abort(); } @@ -329,7 +322,7 @@ const std::string SVFBugEvent::getEventDescription() const SVFBugReport::~SVFBugReport() { - for(auto bugIt: bugSet) + for (auto bugIt : bugSet) { delete bugIt; } @@ -337,13 +330,10 @@ SVFBugReport::~SVFBugReport() void SVFBugReport::dumpToJsonFile(const std::string& filePath) const { - std::map eventType2Str = - { - {SVFBugEvent::CallSite, "call site"}, - {SVFBugEvent::Caller, "caller"}, - {SVFBugEvent::Loop, "loop"}, - {SVFBugEvent::Branch, "branch"} - }; + std::map eventType2Str = {{SVFBugEvent::CallSite, "call site"}, + {SVFBugEvent::Caller, "caller"}, + {SVFBugEvent::Loop, "loop"}, + {SVFBugEvent::Branch, "branch"}}; ofstream jsonFile(filePath, ios::out); @@ -354,59 +344,53 @@ void SVFBugReport::dumpToJsonFile(const std::string& filePath) const size_t commaCounter = bugSet.size() - 1; for (auto bugPtr : bugSet) { - cJSON *singleDefect = cJSON_CreateObject(); + cJSON* singleDefect = cJSON_CreateObject(); /// Add bug information to JSON - cJSON *bugType = cJSON_CreateString( - GenericBug::BugType2Str.at(bugPtr->getBugType()).c_str()); + cJSON* bugType = cJSON_CreateString(GenericBug::BugType2Str.at(bugPtr->getBugType()).c_str()); cJSON_AddItemToObject(singleDefect, "DefectType", bugType); - cJSON *bugLoc = cJSON_Parse(bugPtr->getLoc().c_str()); + cJSON* bugLoc = cJSON_Parse(bugPtr->getLoc().c_str()); if (bugLoc == nullptr) { bugLoc = cJSON_CreateObject(); } cJSON_AddItemToObject(singleDefect, "Location", bugLoc); - cJSON *bugFunction = cJSON_CreateString( - bugPtr->getFuncName().c_str()); + cJSON* bugFunction = cJSON_CreateString(bugPtr->getFuncName().c_str()); cJSON_AddItemToObject(singleDefect, "Function", bugFunction); - cJSON_AddItemToObject(singleDefect, "Description", - bugPtr->getBugDescription()); + cJSON_AddItemToObject(singleDefect, "Description", bugPtr->getBugDescription()); /// Add event information to JSON - cJSON *eventList = cJSON_CreateArray(); - const GenericBug::EventStack &bugEventStack = bugPtr->getEventStack(); + cJSON* eventList = cJSON_CreateArray(); + const GenericBug::EventStack& bugEventStack = bugPtr->getEventStack(); if (BufferOverflowBug::classof(bugPtr)) { // Add only when bug is context sensitive - for (const SVFBugEvent &event : bugEventStack) + for (const SVFBugEvent& event : bugEventStack) { if (event.getEventType() == SVFBugEvent::SourceInst) { continue; } - cJSON *singleEvent = cJSON_CreateObject(); + cJSON* singleEvent = cJSON_CreateObject(); // Event type - cJSON *eventType = cJSON_CreateString( - eventType2Str[event.getEventType()].c_str()); + cJSON* eventType = cJSON_CreateString(eventType2Str[event.getEventType()].c_str()); cJSON_AddItemToObject(singleEvent, "EventType", eventType); // Function name - cJSON *eventFunc = cJSON_CreateString( - event.getFuncName().c_str()); + cJSON* eventFunc = cJSON_CreateString(event.getFuncName().c_str()); cJSON_AddItemToObject(singleEvent, "Function", eventFunc); // Event loc - cJSON *eventLoc = cJSON_Parse(event.getEventLoc().c_str()); + cJSON* eventLoc = cJSON_Parse(event.getEventLoc().c_str()); if (eventLoc == nullptr) { eventLoc = cJSON_CreateObject(); } cJSON_AddItemToObject(singleEvent, "Location", eventLoc); // Event description - cJSON *eventDescription = cJSON_CreateString( - event.getEventDescription().c_str()); + cJSON* eventDescription = cJSON_CreateString(event.getEventDescription().c_str()); cJSON_AddItemToObject(singleEvent, "Description", eventDescription); cJSON_AddItemToArray(eventList, singleEvent); @@ -415,7 +399,7 @@ void SVFBugReport::dumpToJsonFile(const std::string& filePath) const cJSON_AddItemToObject(singleDefect, "Events", eventList); /// Dump single bug to JSON string and write to file - char *singleDefectStr = cJSON_Print(singleDefect); + char* singleDefectStr = cJSON_Print(singleDefect); jsonFile << singleDefectStr; if (commaCounter != 0) { diff --git a/svf/lib/Util/SVFStat.cpp b/svf/lib/Util/SVFStat.cpp index 7cab07720..5875547e7 100644 --- a/svf/lib/Util/SVFStat.cpp +++ b/svf/lib/Util/SVFStat.cpp @@ -40,8 +40,8 @@ bool SVFStat::printGeneralStats = true; SVFStat::SVFStat() : startTime(0), endTime(0) { - assert((Options::ClockType() == ClockType::Wall || Options::ClockType() == ClockType::CPU) - && "PTAStat: unknown clock type!"); + assert((Options::ClockType() == ClockType::Wall || Options::ClockType() == ClockType::CPU) && + "PTAStat: unknown clock type!"); } double SVFStat::getClk(bool mark) @@ -67,7 +67,7 @@ void SVFStat::printStat(string statname) { std::string moduleName(SVFIR::getPAG()->getModule()->getModuleIdentifier()); - std::vector names = SVFUtil::split(moduleName,'/'); + std::vector names = SVFUtil::split(moduleName, '/'); if (names.size() > 1) { moduleName = names[names.size() - 1]; @@ -78,23 +78,21 @@ void SVFStat::printStat(string statname) SVFUtil::outs().flags(std::ios::left); unsigned field_width = 20; - for(NUMStatMap::iterator it = generalNumMap.begin(), eit = generalNumMap.end(); it!=eit; ++it) + for (NUMStatMap::iterator it = generalNumMap.begin(), eit = generalNumMap.end(); it != eit; ++it) { // format out put with width 20 space std::cout << std::setw(field_width) << it->first << it->second << "\n"; } - if(!timeStatMap.empty()) - SVFUtil::outs() << "----------------Time and memory stats--------------------\n"; - for(TIMEStatMap::iterator it = timeStatMap.begin(), eit = timeStatMap.end(); it!=eit; ++it) + if (!timeStatMap.empty()) SVFUtil::outs() << "----------------Time and memory stats--------------------\n"; + for (TIMEStatMap::iterator it = timeStatMap.begin(), eit = timeStatMap.end(); it != eit; ++it) { // format out put with width 20 space SVFUtil::outs() << std::setw(field_width) << it->first << it->second << "\n"; } - if(!PTNumStatMap.empty()) - SVFUtil::outs() << "----------------Numbers stats----------------------------\n"; - for(NUMStatMap::iterator it = PTNumStatMap.begin(), eit = PTNumStatMap.end(); it!=eit; ++it) + if (!PTNumStatMap.empty()) SVFUtil::outs() << "----------------Numbers stats----------------------------\n"; + for (NUMStatMap::iterator it = PTNumStatMap.begin(), eit = PTNumStatMap.end(); it != eit; ++it) { // format out put with width 20 space SVFUtil::outs() << std::setw(field_width) << it->first << it->second << "\n"; @@ -110,8 +108,7 @@ void SVFStat::performStat() { /// SVF's general statistics are only printed once even if you run multiple anayses - if(printGeneralStats == false) - return; + if (printGeneralStats == false) return; SVFIR* pag = SVFIR::getPAG(); u32_t numOfFunction = 0; @@ -127,46 +124,31 @@ void SVFStat::performStat() u32_t fiObjNumber = 0; u32_t fsObjNumber = 0; Set memObjSet; - for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; ++it) + for (SVFIR::iterator it = pag->begin(), eit = pag->end(); it != eit; ++it) { PAGNode* node = it->second; - if(ObjVar* obj = SVFUtil::dyn_cast(node)) + if (ObjVar* obj = SVFUtil::dyn_cast(node)) { const MemObj* mem = obj->getMemObj(); - if (memObjSet.insert(mem->getId()).second == false) - continue; - if(mem->isBlackHoleObj()) - continue; - if(mem->isFunction()) - numOfFunction++; - if(mem->isGlobalObj()) - numOfGlobal++; - if(mem->isStack()) - numOfStack++; - if(mem->isHeap()) - numOfHeap++; - if(mem->isVarArray()) - numOfHasVarArray++; - if(mem->isVarStruct()) - numOfHasVarStruct++; - if(mem->isConstantArray()) - numOfHasConstArray++; - if(mem->isConstantStruct()) - numOfHasConstStruct++; - if(mem->getType()->isPointerTy() == false) - numOfScalar++; - if(mem->isConstDataOrConstGlobal()) - numOfConstant++; - - if (mem->isFieldInsensitive()) - fiObjNumber++; + if (memObjSet.insert(mem->getId()).second == false) continue; + if (mem->isBlackHoleObj()) continue; + if (mem->isFunction()) numOfFunction++; + if (mem->isGlobalObj()) numOfGlobal++; + if (mem->isStack()) numOfStack++; + if (mem->isHeap()) numOfHeap++; + if (mem->isVarArray()) numOfHasVarArray++; + if (mem->isVarStruct()) numOfHasVarStruct++; + if (mem->isConstantArray()) numOfHasConstArray++; + if (mem->isConstantStruct()) numOfHasConstStruct++; + if (mem->getType()->isPointerTy() == false) numOfScalar++; + if (mem->isConstDataOrConstGlobal()) numOfConstant++; + + if (mem->isFieldInsensitive()) fiObjNumber++; else fsObjNumber++; } } - - generalNumMap["TotalPointers"] = pag->getValueNodeNum() + pag->getFieldValNodeNum(); generalNumMap["TotalObjects"] = pag->getObjectNodeNum(); generalNumMap["TotalFieldObjects"] = pag->getFieldObjNodeNum(); @@ -179,14 +161,14 @@ void SVFStat::performStat() generalNumMap["AddrsNum"] = pag->getSVFStmtSet(SVFStmt::Addr).size(); generalNumMap["LoadsNum"] = pag->getSVFStmtSet(SVFStmt::Load).size(); generalNumMap["StoresNum"] = pag->getSVFStmtSet(SVFStmt::Store).size(); - generalNumMap["CopysNum"] = pag->getSVFStmtSet(SVFStmt::Copy).size(); - generalNumMap["GepsNum"] = pag->getSVFStmtSet(SVFStmt::Gep).size(); + generalNumMap["CopysNum"] = pag->getSVFStmtSet(SVFStmt::Copy).size(); + generalNumMap["GepsNum"] = pag->getSVFStmtSet(SVFStmt::Gep).size(); generalNumMap["CallsNum"] = pag->getSVFStmtSet(SVFStmt::Call).size(); generalNumMap["ReturnsNum"] = pag->getSVFStmtSet(SVFStmt::Ret).size(); generalNumMap["FunctionObjs"] = numOfFunction; generalNumMap["GlobalObjs"] = numOfGlobal; - generalNumMap["HeapObjs"] = numOfHeap; + generalNumMap["HeapObjs"] = numOfHeap; generalNumMap["StackObjs"] = numOfStack; generalNumMap["VarStructObj"] = numOfHasVarStruct; @@ -211,23 +193,19 @@ void SVFStat::performStat() printGeneralStats = false; } - void SVFStat::branchStat() { SVFModule* module = SVFIR::getPAG()->getModule(); u32_t numOfBB_2Succ = 0; u32_t numOfBB_3Succ = 0; - for (SVFModule::const_iterator funIter = module->begin(), funEiter = module->end(); - funIter != funEiter; ++funIter) + for (SVFModule::const_iterator funIter = module->begin(), funEiter = module->end(); funIter != funEiter; ++funIter) { const SVFFunction* func = *funIter; - for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end(); - bbIt != bbEit; ++bbIt) + for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end(); bbIt != bbEit; ++bbIt) { const SVFBasicBlock* bb = *bbIt; u32_t numOfSucc = bb->getNumSuccessors(); - if (numOfSucc == 2) - numOfBB_2Succ++; + if (numOfSucc == 2) numOfBB_2Succ++; else if (numOfSucc > 2) numOfBB_3Succ++; } diff --git a/svf/lib/Util/SVFUtil.cpp b/svf/lib/Util/SVFUtil.cpp index dd8a9a96b..53f05bb60 100644 --- a/svf/lib/Util/SVFUtil.cpp +++ b/svf/lib/Util/SVFUtil.cpp @@ -31,21 +31,19 @@ #include "Util/SVFUtil.h" #include "MemoryModel/PointsTo.h" -#include /// increase stack size +#include /// increase stack size using namespace SVF; /// Color for output format -#define KNRM "\x1B[1;0m" -#define KRED "\x1B[1;31m" -#define KGRN "\x1B[1;32m" -#define KYEL "\x1B[1;33m" -#define KBLU "\x1B[1;34m" -#define KPUR "\x1B[1;35m" -#define KCYA "\x1B[1;36m" -#define KWHT "\x1B[1;37m" - - +#define KNRM "\x1B[1;0m" +#define KRED "\x1B[1;31m" +#define KGRN "\x1B[1;32m" +#define KYEL "\x1B[1;33m" +#define KBLU "\x1B[1;34m" +#define KPUR "\x1B[1;35m" +#define KCYA "\x1B[1;36m" +#define KWHT "\x1B[1;37m" /*! * print successful message by converting a string into green string output @@ -65,8 +63,7 @@ std::string SVFUtil::wrnMsg(const std::string& msg) void SVFUtil::writeWrnMsg(const std::string& msg) { - if (Options::DisableWarn()) - return; + if (Options::DisableWarn()) return; outs() << wrnMsg(msg) << "\n"; } @@ -122,8 +119,7 @@ void SVFUtil::dumpSparseSet(const NodeBS& bs) void SVFUtil::dumpPointsToList(const PointsToList& ptl) { outs() << "{"; - for (PointsToList::const_iterator ii = ptl.begin(), ie = ptl.end(); - ii != ie; ii++) + for (PointsToList::const_iterator ii = ptl.begin(), ie = ptl.end(); ii != ie; ii++) { auto bs = *ii; dumpSet(bs); @@ -144,16 +140,15 @@ void SVFUtil::dumpAliasSet(unsigned node, NodeBS bs) /*! * Dump bit vector set */ -void SVFUtil::dumpSet(NodeBS bs, OutStream & O) +void SVFUtil::dumpSet(NodeBS bs, OutStream& O) { - for (NodeBS::iterator ii = bs.begin(), ie = bs.end(); - ii != ie; ii++) + for (NodeBS::iterator ii = bs.begin(), ie = bs.end(); ii != ie; ii++) { O << " " << *ii << " "; } } -void SVFUtil::dumpSet(PointsTo pt, OutStream &o) +void SVFUtil::dumpSet(PointsTo pt, OutStream& o) { for (NodeID n : pt) { @@ -164,11 +159,10 @@ void SVFUtil::dumpSet(PointsTo pt, OutStream &o) /*! * Print memory usage */ -void SVFUtil::reportMemoryUsageKB(const std::string& infor, OutStream & O) +void SVFUtil::reportMemoryUsageKB(const std::string& infor, OutStream& O) { u32_t vmrss, vmsize; - if (getMemoryUsageKB(&vmrss, &vmsize)) - O << infor << "\tVmRSS: " << vmrss << "\tVmSize: " << vmsize << "\n"; + if (getMemoryUsageKB(&vmrss, &vmsize)) O << infor << "\tVmRSS: " << vmrss << "\tVmSize: " << vmsize << "\n"; } /*! @@ -179,12 +173,12 @@ bool SVFUtil::getMemoryUsageKB(u32_t* vmrss_kb, u32_t* vmsize_kb) /* Get the current process' status file from the proc filesystem */ char buffer[8192]; FILE* procfile = fopen("/proc/self/status", "r"); - if(procfile) + if (procfile) { u32_t result = fread(buffer, sizeof(char), 8192, procfile); if (result == 0) { - fputs ("Reading error\n",stderr); + fputs("Reading error\n", stderr); } } else @@ -226,7 +220,7 @@ bool SVFUtil::getMemoryUsageKB(u32_t* vmrss_kb, u32_t* vmsize_kb) */ void SVFUtil::increaseStackSize() { - const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb + const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb struct rlimit rl; int result = getrlimit(RLIMIT_STACK, &rl); if (result == 0) @@ -235,15 +229,14 @@ void SVFUtil::increaseStackSize() { rl.rlim_cur = kStackSize; result = setrlimit(RLIMIT_STACK, &rl); - if (result != 0) - writeWrnMsg("setrlimit returned result !=0 \n"); + if (result != 0) writeWrnMsg("setrlimit returned result !=0 \n"); } } } /*! * Return true if it is an llvm intrinsic instruction -*/ + */ bool SVFUtil::isIntrinsicInst(const SVFInstruction* inst) { if (const SVFCallInst* call = SVFUtil::dyn_cast(inst)) diff --git a/svf/lib/Util/ThreadAPI.cpp b/svf/lib/Util/ThreadAPI.cpp index d5d0dbc50..b1d73199f 100644 --- a/svf/lib/Util/ThreadAPI.cpp +++ b/svf/lib/Util/ThreadAPI.cpp @@ -34,9 +34,9 @@ #include "Util/SVFUtil.h" #include "SVFIR/SVFIR.h" -#include /// std output +#include /// std output #include -#include /// for setw +#include /// for setw using namespace std; using namespace SVF; @@ -49,17 +49,16 @@ namespace /// string and type pair struct ei_pair { - const char *n; + const char* n; ThreadAPI::TD_TYPE t; }; } // End anonymous namespace -//Each (name, type) pair will be inserted into the map. -//All entries of the same type must occur together (for error detection). -static const ei_pair ei_pairs[]= -{ - //The current llvm-gcc puts in the \01. +// Each (name, type) pair will be inserted into the map. +// All entries of the same type must occur together (for error detection). +static const ei_pair ei_pairs[] = { + // The current llvm-gcc puts in the \01. {"pthread_create", ThreadAPI::TD_FORK}, {"apr_thread_create", ThreadAPI::TD_FORK}, {"pthread_join", ThreadAPI::TD_JOIN}, @@ -76,7 +75,7 @@ static const ei_pair ei_pairs[]= {"sem_post", ThreadAPI::TD_RELEASE}, {"_spin_unlock", ThreadAPI::TD_RELEASE}, {"SRE_SplSpecUnlockEx", ThreadAPI::TD_RELEASE}, -// {"pthread_cancel", ThreadAPI::TD_CANCEL}, + // {"pthread_cancel", ThreadAPI::TD_CANCEL}, {"pthread_exit", ThreadAPI::TD_EXIT}, {"pthread_detach", ThreadAPI::TD_DETACH}, {"pthread_cond_wait", ThreadAPI::TD_COND_WAIT}, @@ -92,9 +91,8 @@ static const ei_pair ei_pairs[]= // Hare APIs {"hare_parallel_for", ThreadAPI::HARE_PAR_FOR}, - //This must be the last entry. - {0, ThreadAPI::TD_DUMMY} -}; + // This must be the last entry. + {0, ThreadAPI::TD_DUMMY}}; /*! * initialize the map @@ -102,39 +100,39 @@ static const ei_pair ei_pairs[]= void ThreadAPI::init() { set t_seen; - TD_TYPE prev_t= TD_DUMMY; + TD_TYPE prev_t = TD_DUMMY; t_seen.insert(TD_DUMMY); - for(const ei_pair *p= ei_pairs; p->n; ++p) + for (const ei_pair* p = ei_pairs; p->n; ++p) { - if(p->t != prev_t) + if (p->t != prev_t) { - //This will detect if you move an entry to another block - // but forget to change the type. - if(t_seen.count(p->t)) + // This will detect if you move an entry to another block + // but forget to change the type. + if (t_seen.count(p->t)) { fputs(p->n, stderr); putc('\n', stderr); assert(!"ei_pairs not grouped by type"); } t_seen.insert(p->t); - prev_t= p->t; + prev_t = p->t; } - if(tdAPIMap.count(p->n)) + if (tdAPIMap.count(p->n)) { fputs(p->n, stderr); putc('\n', stderr); assert(!"duplicate name in ei_pairs"); } - tdAPIMap[p->n]= p->t; + tdAPIMap[p->n] = p->t; } } /*! * */ -const SVFFunction* ThreadAPI::getCallee(const ICFGNode *inst) const +const SVFFunction* ThreadAPI::getCallee(const ICFGNode* inst) const { - if(const CallICFGNode* call = SVFUtil::dyn_cast(inst)) + if (const CallICFGNode* call = SVFUtil::dyn_cast(inst)) return SVFUtil::getCallee(call->getCallSite()); else return nullptr; @@ -143,24 +141,24 @@ const SVFFunction* ThreadAPI::getCallee(const ICFGNode *inst) const /*! * */ -const SVFFunction* ThreadAPI::getCallee(const SVFInstruction *inst) const +const SVFFunction* ThreadAPI::getCallee(const SVFInstruction* inst) const { return SVFUtil::getCallee(inst); } - -const CallSite ThreadAPI::getSVFCallSite(const ICFGNode *inst) const +const CallSite ThreadAPI::getSVFCallSite(const ICFGNode* inst) const { assert(SVFUtil::isa(inst) && "not a callsite?"); CallSite cs(SVFUtil::cast(inst)->getCallSite()); return cs; } -const SVFValue* ThreadAPI::getLockVal(const ICFGNode *inst) const +const SVFValue* ThreadAPI::getLockVal(const ICFGNode* inst) const { const CallICFGNode* call = SVFUtil::dyn_cast(inst); assert(call && "not a call ICFGNode?"); - assert((isTDAcquire(call->getCallSite()) || isTDRelease(call->getCallSite())) && "not a lock acquire or release function"); + assert((isTDAcquire(call->getCallSite()) || isTDRelease(call->getCallSite())) && + "not a lock acquire or release function"); CallSite cs = getSVFCallSite(call->getCallSite()); return cs.getArgument(0); } @@ -168,24 +166,22 @@ const SVFValue* ThreadAPI::getLockVal(const ICFGNode *inst) const /*! * */ -const CallSite ThreadAPI::getSVFCallSite(const SVFInstruction *inst) const +const CallSite ThreadAPI::getSVFCallSite(const SVFInstruction* inst) const { return SVFUtil::getSVFCallSite(inst); } -const SVFValue* ThreadAPI::getJoinedThread(const ICFGNode *inst) const +const SVFValue* ThreadAPI::getJoinedThread(const ICFGNode* inst) const { assert(isTDJoin(inst) && "not a thread join function!"); CallSite cs = getSVFCallSite(inst); const SVFValue* join = cs.getArgument(0); const SVFVar* var = PAG::getPAG()->getGNode(PAG::getPAG()->getValueNode(join)); - for(const SVFStmt* stmt : var->getInEdges()) + for (const SVFStmt* stmt : var->getInEdges()) { - if(SVFUtil::isa(stmt)) - return stmt->getSrcNode()->getValue(); + if (SVFUtil::isa(stmt)) return stmt->getSrcNode()->getValue(); } - if(SVFUtil::isa(join)) - return join; + if (SVFUtil::isa(join)) return join; assert(false && "the value of the first argument at join is not a load instruction?"); return nullptr; @@ -249,134 +245,108 @@ void ThreadAPI::performAPIStat(SVFModule* module) for (SVFBasicBlock::const_iterator ii = bb->begin(), eii = bb->end(); ii != eii; ++ii) { const SVFInstruction* svfInst = *ii; - if (!SVFUtil::isCallSite(svfInst)) - continue; + if (!SVFUtil::isCallSite(svfInst)) continue; const SVFFunction* fun = SVFUtil::getCallee(svfInst); TD_TYPE type = getType(fun); switch (type) { - case TD_FORK: - { + case TD_FORK: { tdAPIStatMap["pthread_create"]++; break; } - case TD_JOIN: - { + case TD_JOIN: { tdAPIStatMap["pthread_join"]++; break; } - case TD_ACQUIRE: - { + case TD_ACQUIRE: { tdAPIStatMap["pthread_mutex_lock"]++; break; } - case TD_TRY_ACQUIRE: - { + case TD_TRY_ACQUIRE: { tdAPIStatMap["pthread_mutex_trylock"]++; break; } - case TD_RELEASE: - { + case TD_RELEASE: { tdAPIStatMap["pthread_mutex_unlock"]++; break; } - case TD_CANCEL: - { + case TD_CANCEL: { tdAPIStatMap["pthread_cancel"]++; break; } - case TD_EXIT: - { + case TD_EXIT: { tdAPIStatMap["pthread_exit"]++; break; } - case TD_DETACH: - { + case TD_DETACH: { tdAPIStatMap["pthread_detach"]++; break; } - case TD_COND_WAIT: - { + case TD_COND_WAIT: { tdAPIStatMap["pthread_cond_wait"]++; break; } - case TD_COND_SIGNAL: - { + case TD_COND_SIGNAL: { tdAPIStatMap["pthread_cond_signal"]++; break; } - case TD_COND_BROADCAST: - { + case TD_COND_BROADCAST: { tdAPIStatMap["pthread_cond_broadcast"]++; break; } - case TD_CONDVAR_INI: - { + case TD_CONDVAR_INI: { tdAPIStatMap["pthread_cond_init"]++; break; } - case TD_CONDVAR_DESTROY: - { + case TD_CONDVAR_DESTROY: { tdAPIStatMap["pthread_cond_destroy"]++; break; } - case TD_MUTEX_INI: - { + case TD_MUTEX_INI: { tdAPIStatMap["pthread_mutex_init"]++; break; } - case TD_MUTEX_DESTROY: - { + case TD_MUTEX_DESTROY: { tdAPIStatMap["pthread_mutex_destroy"]++; break; } - case TD_BAR_INIT: - { + case TD_BAR_INIT: { tdAPIStatMap["pthread_barrier_init"]++; break; } - case TD_BAR_WAIT: - { + case TD_BAR_WAIT: { tdAPIStatMap["pthread_barrier_wait"]++; break; } - case HARE_PAR_FOR: - { + case HARE_PAR_FOR: { tdAPIStatMap["hare_parallel_for"]++; break; } - case TD_DUMMY: - { + case TD_DUMMY: { break; } } } } - } std::string name(module->getModuleIdentifier()); - std::vector fullNames = SVFUtil::split(name,'/'); + std::vector fullNames = SVFUtil::split(name, '/'); if (fullNames.size() > 1) { name = fullNames[fullNames.size() - 1]; } - SVFUtil::outs() << "################ (program : " << name - << ")###############\n"; + SVFUtil::outs() << "################ (program : " << name << ")###############\n"; SVFUtil::outs().flags(std::ios::left); unsigned field_width = 20; - for (Map::iterator it = tdAPIStatMap.begin(), eit = - tdAPIStatMap.end(); it != eit; ++it) + for (Map::iterator it = tdAPIStatMap.begin(), eit = tdAPIStatMap.end(); it != eit; ++it) { std::string apiName = it->first; // format out put with width 20 space - SVFUtil::outs() << std::setw(field_width) << apiName << " : " << it->second - << "\n"; + SVFUtil::outs() << std::setw(field_width) << apiName << " : " << it->second << "\n"; } - SVFUtil::outs() << "#######################################################" - << std::endl; - + SVFUtil::outs() << "#######################################################" << std::endl; } #endif /* THREADAPI_CPP_ */ diff --git a/svf/lib/Util/Z3Expr.cpp b/svf/lib/Util/Z3Expr.cpp index b27242f3c..1426e3cb7 100644 --- a/svf/lib/Util/Z3Expr.cpp +++ b/svf/lib/Util/Z3Expr.cpp @@ -32,15 +32,13 @@ namespace SVF { -z3::context *Z3Expr::ctx = nullptr; +z3::context* Z3Expr::ctx = nullptr; z3::solver* Z3Expr::solver = nullptr; - /// release z3 context void Z3Expr::releaseContext() { - if(solver) - releaseSolver(); + if (solver) releaseSolver(); delete ctx; ctx = nullptr; } @@ -53,7 +51,7 @@ void Z3Expr::releaseSolver() } /// Get z3 solver, singleton design here to make sure we only have one context -z3::solver &Z3Expr::getSolver() +z3::solver& Z3Expr::getSolver() { if (solver == nullptr) { @@ -63,7 +61,7 @@ z3::solver &Z3Expr::getSolver() } /// Get z3 context, singleton design here to make sure we only have one context -z3::context &Z3Expr::getContext() +z3::context& Z3Expr::getContext() { if (ctx == nullptr) { @@ -73,7 +71,7 @@ z3::context &Z3Expr::getContext() } /// get the number of subexpression of a Z3 expression -u32_t Z3Expr::getExprSize(const Z3Expr &z3Expr) +u32_t Z3Expr::getExprSize(const Z3Expr& z3Expr) { u32_t res = 1; if (z3Expr.getExpr().num_args() == 0) @@ -89,7 +87,7 @@ u32_t Z3Expr::getExprSize(const Z3Expr &z3Expr) } /// compute AND, used for branch condition -Z3Expr Z3Expr::AND(const Z3Expr &lhs, const Z3Expr &rhs) +Z3Expr Z3Expr::AND(const Z3Expr& lhs, const Z3Expr& rhs) { if (eq(lhs, Z3Expr::getFalseCond()) || eq(rhs, Z3Expr::getFalseCond())) { @@ -127,7 +125,7 @@ Z3Expr Z3Expr::AND(const Z3Expr &lhs, const Z3Expr &rhs) } /// compute OR, used for branch condition -Z3Expr Z3Expr::OR(const Z3Expr &lhs, const Z3Expr &rhs) +Z3Expr Z3Expr::OR(const Z3Expr& lhs, const Z3Expr& rhs) { if (eq(lhs, Z3Expr::getTrueCond()) || eq(rhs, Z3Expr::getTrueCond())) { @@ -165,11 +163,10 @@ Z3Expr Z3Expr::OR(const Z3Expr &lhs, const Z3Expr &rhs) } /// output Z3 expression as a string -std::string Z3Expr::dumpStr(const Z3Expr &z3Expr) +std::string Z3Expr::dumpStr(const Z3Expr& z3Expr) { std::ostringstream out; out << z3Expr.getExpr(); return out.str(); } -} - +} // namespace SVF diff --git a/svf/lib/Util/cJSON.cpp b/svf/lib/Util/cJSON.cpp index 0cdf8c5d4..1ff364ffe 100644 --- a/svf/lib/Util/cJSON.cpp +++ b/svf/lib/Util/cJSON.cpp @@ -25,16 +25,16 @@ /* disable warnings about old C89 functions in MSVC */ #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) -#define _CRT_SECURE_NO_DEPRECATE +# define _CRT_SECURE_NO_DEPRECATE #endif #ifdef __GNUC__ -#pragma GCC visibility push(default) +# pragma GCC visibility push(default) #endif #if defined(_MSC_VER) -#pragma warning (push) +# pragma warning(push) /* disable warning about single line comments in system headers */ -#pragma warning (disable : 4001) +# pragma warning(disable : 4001) #endif #include @@ -46,58 +46,58 @@ #include #ifdef ENABLE_LOCALES -#include +# include #endif #if defined(_MSC_VER) -#pragma warning (pop) +# pragma warning(pop) #endif #ifdef __GNUC__ -#pragma GCC visibility pop +# pragma GCC visibility pop #endif #include "Util/cJSON.h" /* define our own boolean type */ #ifdef true -#undef true +# undef true #endif #define true ((cJSON_bool)1) #ifdef false -#undef false +# undef false #endif #define false ((cJSON_bool)0) /* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ #ifndef isinf -#define isinf(d) (isnan((d - d)) && !isnan(d)) +# define isinf(d) (isnan((d - d)) && !isnan(d)) #endif #ifndef isnan -#define isnan(d) (d != d) +# define isnan(d) (d != d) #endif #ifndef NAN -#ifdef _WIN32 -#define NAN sqrt(-1.0) -#else -#define NAN 0.0/0.0 -#endif +# ifdef _WIN32 +# define NAN sqrt(-1.0) +# else +# define NAN 0.0 / 0.0 +# endif #endif typedef struct { - const unsigned char *json; + const unsigned char* json; size_t position; } error; -static error global_error = { NULL, 0 }; +static error global_error = {NULL, 0}; -CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +CJSON_PUBLIC(const char*) cJSON_GetErrorPtr(void) { - return (const char*) (global_error.json + global_error.position); + return (const char*)(global_error.json + global_error.position); } -CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +CJSON_PUBLIC(char*) cJSON_GetStringValue(const cJSON* const item) { if (!cJSON_IsString(item)) { @@ -107,11 +107,11 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) return item->valuestring; } -CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON* const item) { if (!cJSON_IsNumber(item)) { - return (double) NAN; + return (double)NAN; } return item->valuedouble; @@ -119,7 +119,7 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ #if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 15) -#error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +# error cJSON.h and cJSON.c have different versions. Make sure that both have the same. #endif CJSON_PUBLIC(const char*) cJSON_Version(void) @@ -131,7 +131,7 @@ CJSON_PUBLIC(const char*) cJSON_Version(void) } /* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ -static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +static int case_insensitive_strcmp(const unsigned char* string1, const unsigned char* string2) { if ((string1 == NULL) || (string2 == NULL)) { @@ -143,7 +143,7 @@ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned return 0; } - for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + for (; tolower(*string1) == tolower(*string2); (void)string1++, string2++) { if (*string1 == '\0') { @@ -156,40 +156,40 @@ static int case_insensitive_strcmp(const unsigned char *string1, const unsigned typedef struct internal_hooks { - void *(CJSON_CDECL *allocate)(size_t size); - void (CJSON_CDECL *deallocate)(void *pointer); - void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); + void*(CJSON_CDECL* allocate)(size_t size); + void(CJSON_CDECL* deallocate)(void* pointer); + void*(CJSON_CDECL* reallocate)(void* pointer, size_t size); } internal_hooks; #if defined(_MSC_VER) /* work around MSVC error C2322: '...' address of dllimport '...' is not static */ -static void * CJSON_CDECL internal_malloc(size_t size) +static void* CJSON_CDECL internal_malloc(size_t size) { return malloc(size); } -static void CJSON_CDECL internal_free(void *pointer) +static void CJSON_CDECL internal_free(void* pointer) { free(pointer); } -static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +static void* CJSON_CDECL internal_realloc(void* pointer, size_t size) { return realloc(pointer, size); } #else -#define internal_malloc malloc -#define internal_free free -#define internal_realloc realloc +# define internal_malloc malloc +# define internal_free free +# define internal_realloc realloc #endif /* strlen of character literals resolved at compile time */ #define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) -static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; +static internal_hooks global_hooks = {internal_malloc, internal_free, internal_realloc}; -static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks* const hooks) { size_t length = 0; - unsigned char *copy = NULL; + unsigned char* copy = NULL; if (string == NULL) { @@ -239,7 +239,7 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) } /* Internal constructor. */ -static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +static cJSON* cJSON_New_Item(const internal_hooks* const hooks) { cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); if (node) @@ -251,9 +251,9 @@ static cJSON *cJSON_New_Item(const internal_hooks * const hooks) } /* Delete a cJSON structure. */ -CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +CJSON_PUBLIC(void) cJSON_Delete(cJSON* item) { - cJSON *next = NULL; + cJSON* next = NULL; while (item != NULL) { next = item->next; @@ -278,8 +278,8 @@ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) static unsigned char get_decimal_point(void) { #ifdef ENABLE_LOCALES - struct lconv *lconv = localeconv(); - return (unsigned char) lconv->decimal_point[0]; + struct lconv* lconv = localeconv(); + return (unsigned char)lconv->decimal_point[0]; #else return '.'; #endif @@ -287,7 +287,7 @@ static unsigned char get_decimal_point(void) typedef struct { - const unsigned char *content; + const unsigned char* content; size_t length; size_t offset; size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ @@ -303,10 +303,10 @@ typedef struct #define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) /* Parse the input text to generate a number, and populate the result into item. */ -static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +static cJSON_bool parse_number(cJSON* const item, parse_buffer* const input_buffer) { double number = 0; - unsigned char *after_end = NULL; + unsigned char* after_end = NULL; unsigned char number_c_string[64]; unsigned char decimal_point = get_decimal_point(); size_t i = 0; @@ -380,7 +380,7 @@ static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_bu } /* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ -CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON* object, double number) { if (number >= INT_MAX) { @@ -398,9 +398,9 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) return object->valuedouble = number; } -CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON* object, const char* valuestring) { - char *copy = NULL; + char* copy = NULL; /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) { @@ -411,7 +411,7 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) strcpy(object->valuestring, valuestring); return object->valuestring; } - copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + copy = (char*)cJSON_strdup((const unsigned char*)valuestring, &global_hooks); if (copy == NULL) { return NULL; @@ -427,7 +427,7 @@ CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) typedef struct { - unsigned char *buffer; + unsigned char* buffer; size_t length; size_t offset; size_t depth; /* current nesting depth (for formatted printing) */ @@ -437,9 +437,9 @@ typedef struct } printbuffer; /* realloc printbuffer if necessary to have at least "needed" bytes more */ -static unsigned char* ensure(printbuffer * const p, size_t needed) +static unsigned char* ensure(printbuffer* const p, size_t needed) { - unsigned char *newbuffer = NULL; + unsigned char* newbuffer = NULL; size_t newsize = 0; if ((p == NULL) || (p->buffer == NULL)) @@ -524,9 +524,9 @@ static unsigned char* ensure(printbuffer * const p, size_t needed) } /* calculate the new length of the string in a printbuffer and update the offset */ -static void update_offset(printbuffer * const buffer) +static void update_offset(printbuffer* const buffer) { - const unsigned char *buffer_pointer = NULL; + const unsigned char* buffer_pointer = NULL; if ((buffer == NULL) || (buffer->buffer == NULL)) { return; @@ -544,9 +544,9 @@ static cJSON_bool compare_double(double a, double b) } /* Render the number nicely from the given item into a string. */ -static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +static cJSON_bool print_number(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char *output_pointer = NULL; + unsigned char* output_pointer = NULL; double d = item->valuedouble; int length = 0; size_t i = 0; @@ -564,7 +564,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out { length = snprintf((char*)number_buffer, sizeof(number_buffer), "null"); } - else if(d == (double)item->valueint) + else if (d == (double)item->valueint) { length = snprintf((char*)number_buffer, sizeof(number_buffer), "%d", item->valueint); } @@ -614,7 +614,7 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out } /* parse 4 digit hexadecimal number */ -static unsigned parse_hex4(const unsigned char * const input) +static unsigned parse_hex4(const unsigned char* const input) { unsigned int h = 0; size_t i = 0; @@ -624,15 +624,15 @@ static unsigned parse_hex4(const unsigned char * const input) /* parse digit */ if ((input[i] >= '0') && (input[i] <= '9')) { - h += (unsigned int) input[i] - '0'; + h += (unsigned int)input[i] - '0'; } else if ((input[i] >= 'A') && (input[i] <= 'F')) { - h += (unsigned int) 10 + input[i] - 'A'; + h += (unsigned int)10 + input[i] - 'A'; } else if ((input[i] >= 'a') && (input[i] <= 'f')) { - h += (unsigned int) 10 + input[i] - 'a'; + h += (unsigned int)10 + input[i] - 'a'; } else /* invalid */ { @@ -651,11 +651,12 @@ static unsigned parse_hex4(const unsigned char * const input) /* converts a UTF-16 literal to UTF-8 * A literal can be one or two sequences of the form \uXXXX */ -static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +static unsigned char utf16_literal_to_utf8(const unsigned char* const input_pointer, + const unsigned char* const input_end, unsigned char** output_pointer) { long unsigned int codepoint = 0; unsigned int first_code = 0; - const unsigned char *first_sequence = input_pointer; + const unsigned char* first_sequence = input_pointer; unsigned char utf8_length = 0; unsigned char utf8_position = 0; unsigned char sequence_length = 0; @@ -679,7 +680,7 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi /* UTF16 surrogate pair */ if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) { - const unsigned char *second_sequence = first_sequence + 6; + const unsigned char* second_sequence = first_sequence + 6; unsigned int second_code = 0; sequence_length = 12; /* \uXXXX\uXXXX */ @@ -704,7 +705,6 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi goto fail; } - /* calculate the unicode codepoint from the surrogate pair */ codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); } @@ -772,12 +772,12 @@ static unsigned char utf16_literal_to_utf8(const unsigned char * const input_poi } /* Parse the input text into an unescaped cinput, and populate item. */ -static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +static cJSON_bool parse_string(cJSON* const item, parse_buffer* const input_buffer) { - const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; - const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; - unsigned char *output_pointer = NULL; - unsigned char *output = NULL; + const unsigned char* input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char* input_end = buffer_at_offset(input_buffer) + 1; + unsigned char* output_pointer = NULL; + unsigned char* output = NULL; /* not a string */ if (buffer_at_offset(input_buffer)[0] != '\"') @@ -810,7 +810,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu } /* This is at most how much we need for the output */ - allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + allocation_length = (size_t)(input_end - buffer_at_offset(input_buffer)) - skipped_bytes; output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); if (output == NULL) { @@ -881,7 +881,7 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu item->type = cJSON_String; item->valuestring = (char*)output; - input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset = (size_t)(input_end - input_buffer->content); input_buffer->offset++; return true; @@ -901,11 +901,11 @@ static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_bu } /* Render the cstring provided to an escaped version that can be printed. */ -static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +static cJSON_bool print_string_ptr(const unsigned char* const input, printbuffer* const output_buffer) { - const unsigned char *input_pointer = NULL; - unsigned char *output = NULL; - unsigned char *output_pointer = NULL; + const unsigned char* input_pointer = NULL; + unsigned char* output = NULL; + unsigned char* output_pointer = NULL; size_t output_length = 0; /* numbers of additional characters needed for escaping */ size_t escape_characters = 0; @@ -1023,21 +1023,21 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe } /* Invoke print_string_ptr (which is useful) on an item. */ -static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +static cJSON_bool print_string(const cJSON* const item, printbuffer* const p) { return print_string_ptr((unsigned char*)item->valuestring, p); } /* Predeclare these prototypes. */ -static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); -static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); -static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); -static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); -static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); -static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_value(cJSON* const item, parse_buffer* const input_buffer); +static cJSON_bool print_value(const cJSON* const item, printbuffer* const output_buffer); +static cJSON_bool parse_array(cJSON* const item, parse_buffer* const input_buffer); +static cJSON_bool print_array(const cJSON* const item, printbuffer* const output_buffer); +static cJSON_bool parse_object(cJSON* const item, parse_buffer* const input_buffer); +static cJSON_bool print_object(const cJSON* const item, printbuffer* const output_buffer); /* Utility to jump whitespace and cr/lf */ -static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +static parse_buffer* buffer_skip_whitespace(parse_buffer* const buffer) { if ((buffer == NULL) || (buffer->content == NULL)) { @@ -1063,7 +1063,7 @@ static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) } /* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ -static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +static parse_buffer* skip_utf8_bom(parse_buffer* const buffer) { if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) { @@ -1078,7 +1078,8 @@ static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) return buffer; } -CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +CJSON_PUBLIC(cJSON*) +cJSON_ParseWithOpts(const char* value, const char** return_parse_end, cJSON_bool require_null_terminated) { size_t buffer_length; @@ -1094,10 +1095,12 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return } /* Parse an object - create a new root, and populate. */ -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +CJSON_PUBLIC(cJSON*) +cJSON_ParseWithLengthOpts(const char* value, size_t buffer_length, const char** return_parse_end, + cJSON_bool require_null_terminated) { - parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; - cJSON *item = NULL; + parse_buffer buffer = {0, 0, 0, 0, {0, 0, 0}}; + cJSON* item = NULL; /* reset error position */ global_error.json = NULL; @@ -1174,28 +1177,28 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer } /* Default options for cJSON_Parse */ -CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +CJSON_PUBLIC(cJSON*) cJSON_Parse(const char* value) { return cJSON_ParseWithOpts(value, 0, 0); } -CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +CJSON_PUBLIC(cJSON*) cJSON_ParseWithLength(const char* value, size_t buffer_length) { return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); } #define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) -static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +static unsigned char* print(const cJSON* const item, cJSON_bool format, const internal_hooks* const hooks) { static const size_t default_buffer_size = 256; printbuffer buffer[1]; - unsigned char *printed = NULL; + unsigned char* printed = NULL; memset(buffer, 0, sizeof(buffer)); /* create buffer */ - buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->buffer = (unsigned char*)hooks->allocate(default_buffer_size); buffer->length = default_buffer_size; buffer->format = format; buffer->hooks = *hooks; @@ -1214,7 +1217,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i /* check if reallocate is available */ if (hooks->reallocate != NULL) { - printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + printed = (unsigned char*)hooks->reallocate(buffer->buffer, buffer->offset + 1); if (printed == NULL) { goto fail; @@ -1223,7 +1226,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i } else /* otherwise copy the JSON over to a new buffer */ { - printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + printed = (unsigned char*)hooks->allocate(buffer->offset + 1); if (printed == NULL) { goto fail; @@ -1252,19 +1255,19 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i } /* Render a cJSON item/entity/structure to text. */ -CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +CJSON_PUBLIC(char*) cJSON_Print(const cJSON* item) { return (char*)print(item, true, &global_hooks); } -CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +CJSON_PUBLIC(char*) cJSON_PrintUnformatted(const cJSON* item) { return (char*)print(item, false, &global_hooks); } -CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +CJSON_PUBLIC(char*) cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt) { - printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + printbuffer p = {0, 0, 0, 0, 0, 0, {0, 0, 0}}; if (prebuffer < 0) { @@ -1292,9 +1295,9 @@ CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON return (char*)p.buffer; } -CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format) { - printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + printbuffer p = {0, 0, 0, 0, 0, 0, {0, 0, 0}}; if ((length < 0) || (buffer == NULL)) { @@ -1312,7 +1315,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, cons } /* Parser core - when encountering text, process appropriately. */ -static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +static cJSON_bool parse_value(cJSON* const item, parse_buffer* const input_buffer) { if ((input_buffer == NULL) || (input_buffer->content == NULL)) { @@ -1348,7 +1351,9 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf return parse_string(item, input_buffer); } /* number */ - if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + if (can_access_at_index(input_buffer, 0) && + ((buffer_at_offset(input_buffer)[0] == '-') || + ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) { return parse_number(item, input_buffer); } @@ -1367,9 +1372,9 @@ static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buf } /* Render a value to text. */ -static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +static cJSON_bool print_value(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char *output = NULL; + unsigned char* output = NULL; if ((item == NULL) || (output_buffer == NULL)) { @@ -1408,8 +1413,7 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp case cJSON_Number: return print_number(item, output_buffer); - case cJSON_Raw: - { + case cJSON_Raw: { size_t raw_length = 0; if (item->valuestring == NULL) { @@ -1441,10 +1445,10 @@ static cJSON_bool print_value(const cJSON * const item, printbuffer * const outp } /* Build an array from input text. */ -static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +static cJSON_bool parse_array(cJSON* const item, parse_buffer* const input_buffer) { - cJSON *head = NULL; /* head of the linked list */ - cJSON *current_item = NULL; + cJSON* head = NULL; /* head of the linked list */ + cJSON* current_item = NULL; if (input_buffer->depth >= CJSON_NESTING_LIMIT) { @@ -1479,7 +1483,7 @@ static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buf do { /* allocate next item */ - cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + cJSON* new_item = cJSON_New_Item(&(input_buffer->hooks)); if (new_item == NULL) { goto fail; /* allocation failure */ @@ -1507,8 +1511,7 @@ static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buf goto fail; /* failed to parse value */ } buffer_skip_whitespace(input_buffer); - } - while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + } while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') { @@ -1540,11 +1543,11 @@ static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buf } /* Render an array to text */ -static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +static cJSON_bool print_array(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char *output_pointer = NULL; + unsigned char* output_pointer = NULL; size_t length = 0; - cJSON *current_element = item->child; + cJSON* current_element = item->child; if (output_buffer == NULL) { @@ -1572,14 +1575,14 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp update_offset(output_buffer); if (current_element->next) { - length = (size_t) (output_buffer->format ? 2 : 1); + length = (size_t)(output_buffer->format ? 2 : 1); output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) { return false; } *output_pointer++ = ','; - if(output_buffer->format) + if (output_buffer->format) { *output_pointer++ = ' '; } @@ -1602,10 +1605,10 @@ static cJSON_bool print_array(const cJSON * const item, printbuffer * const outp } /* Build an object from the text. */ -static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +static cJSON_bool parse_object(cJSON* const item, parse_buffer* const input_buffer) { - cJSON *head = NULL; /* linked list head */ - cJSON *current_item = NULL; + cJSON* head = NULL; /* linked list head */ + cJSON* current_item = NULL; if (input_buffer->depth >= CJSON_NESTING_LIMIT) { @@ -1638,7 +1641,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu do { /* allocate next item */ - cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + cJSON* new_item = cJSON_New_Item(&(input_buffer->hooks)); if (new_item == NULL) { goto fail; /* allocation failure */ @@ -1684,8 +1687,7 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu goto fail; /* failed to parse value */ } buffer_skip_whitespace(input_buffer); - } - while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + } while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) { @@ -1716,11 +1718,11 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu } /* Render an object to text. */ -static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +static cJSON_bool print_object(const cJSON* const item, printbuffer* const output_buffer) { - unsigned char *output_pointer = NULL; + unsigned char* output_pointer = NULL; size_t length = 0; - cJSON *current_item = item->child; + cJSON* current_item = item->child; if (output_buffer == NULL) { @@ -1728,7 +1730,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out } /* Compose the output: */ - length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + length = (size_t)(output_buffer->format ? 2 : 1); /* fmt: {\n */ output_pointer = ensure(output_buffer, length + 1); if (output_pointer == NULL) { @@ -1767,7 +1769,7 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out } update_offset(output_buffer); - length = (size_t) (output_buffer->format ? 2 : 1); + length = (size_t)(output_buffer->format ? 2 : 1); output_pointer = ensure(output_buffer, length); if (output_pointer == NULL) { @@ -1830,9 +1832,9 @@ static cJSON_bool print_object(const cJSON * const item, printbuffer * const out } /* Get Array size/item / object item. */ -CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON* array) { - cJSON *child = NULL; + cJSON* child = NULL; size_t size = 0; if (array == NULL) @@ -1842,7 +1844,7 @@ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) child = array->child; - while(child != NULL) + while (child != NULL) { size++; child = child->next; @@ -1853,9 +1855,9 @@ CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) return (int)size; } -static cJSON* get_array_item(const cJSON *array, size_t index) +static cJSON* get_array_item(const cJSON* array, size_t index) { - cJSON *current_child = NULL; + cJSON* current_child = NULL; if (array == NULL) { @@ -1872,7 +1874,7 @@ static cJSON* get_array_item(const cJSON *array, size_t index) return current_child; } -CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +CJSON_PUBLIC(cJSON*) cJSON_GetArrayItem(const cJSON* array, int index) { if (index < 0) { @@ -1882,9 +1884,9 @@ CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) return get_array_item(array, (size_t)index); } -static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +static cJSON* get_object_item(const cJSON* const object, const char* const name, const cJSON_bool case_sensitive) { - cJSON *current_element = NULL; + cJSON* current_element = NULL; if ((object == NULL) || (name == NULL)) { @@ -1894,14 +1896,17 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam current_element = object->child; if (case_sensitive) { - while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + while ((current_element != NULL) && (current_element->string != NULL) && + (strcmp(name, current_element->string) != 0)) { current_element = current_element->next; } } else { - while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + while ( + (current_element != NULL) && + (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) { current_element = current_element->next; } @@ -1915,32 +1920,32 @@ static cJSON *get_object_item(const cJSON * const object, const char * const nam return current_element; } -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char* const string) { return get_object_item(object, string, false); } -CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +CJSON_PUBLIC(cJSON*) cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string) { return get_object_item(object, string, true); } -CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON* object, const char* string) { return cJSON_GetObjectItem(object, string) ? 1 : 0; } /* Utility for array list handling. */ -static void suffix_object(cJSON *prev, cJSON *item) +static void suffix_object(cJSON* prev, cJSON* item) { prev->next = item; item->prev = prev; } /* Utility for handling references. */ -static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +static cJSON* create_reference(const cJSON* item, const internal_hooks* const hooks) { - cJSON *reference = NULL; + cJSON* reference = NULL; if (item == NULL) { return NULL; @@ -1959,9 +1964,9 @@ static cJSON *create_reference(const cJSON *item, const internal_hooks * const h return reference; } -static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +static cJSON_bool add_item_to_array(cJSON* array, cJSON* item) { - cJSON *child = NULL; + cJSON* child = NULL; if ((item == NULL) || (array == NULL) || (array == item)) { @@ -1993,30 +1998,30 @@ static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) } /* Add item to array/object. */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON* array, cJSON* item) { return add_item_to_array(array, item); } -#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) -#pragma GCC diagnostic push +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) +# pragma GCC diagnostic push #endif #ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wcast-qual" +# pragma GCC diagnostic ignored "-Wcast-qual" #endif /* helper function to cast away const */ static void* cast_away_const(const void* string) { return (void*)string; } -#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) -#pragma GCC diagnostic pop +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) +# pragma GCC diagnostic pop #endif - -static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +static cJSON_bool add_item_to_object(cJSON* const object, const char* const string, cJSON* const item, + const internal_hooks* const hooks, const cJSON_bool constant_key) { - char *new_key = NULL; + char* new_key = NULL; int new_type = cJSON_Invalid; if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) @@ -2051,18 +2056,18 @@ static cJSON_bool add_item_to_object(cJSON * const object, const char * const st return add_item_to_array(object, item); } -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item) { return add_item_to_object(object, string, item, &global_hooks, false); } /* Add an item to an object with constant string as key */ -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item) { return add_item_to_object(object, string, item, &global_hooks, true); } -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item) { if (array == NULL) { @@ -2072,7 +2077,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item return add_item_to_array(array, create_reference(item, &global_hooks)); } -CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item) { if ((object == NULL) || (string == NULL)) { @@ -2082,9 +2087,9 @@ CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const cha return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); } -CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON* const object, const char* const name) { - cJSON *null = cJSON_CreateNull(); + cJSON* null = cJSON_CreateNull(); if (add_item_to_object(object, name, null, &global_hooks, false)) { return null; @@ -2094,9 +2099,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * co return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON* const object, const char* const name) { - cJSON *true_item = cJSON_CreateTrue(); + cJSON* true_item = cJSON_CreateTrue(); if (add_item_to_object(object, name, true_item, &global_hooks, false)) { return true_item; @@ -2106,9 +2111,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * co return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON* const object, const char* const name) { - cJSON *false_item = cJSON_CreateFalse(); + cJSON* false_item = cJSON_CreateFalse(); if (add_item_to_object(object, name, false_item, &global_hooks, false)) { return false_item; @@ -2118,9 +2123,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * c return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON* const object, const char* const name, const cJSON_bool boolean) { - cJSON *bool_item = cJSON_CreateBool(boolean); + cJSON* bool_item = cJSON_CreateBool(boolean); if (add_item_to_object(object, name, bool_item, &global_hooks, false)) { return bool_item; @@ -2130,9 +2135,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * co return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON* const object, const char* const name, const double number) { - cJSON *number_item = cJSON_CreateNumber(number); + cJSON* number_item = cJSON_CreateNumber(number); if (add_item_to_object(object, name, number_item, &global_hooks, false)) { return number_item; @@ -2142,9 +2147,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON* const object, const char* const name, const char* const string) { - cJSON *string_item = cJSON_CreateString(string); + cJSON* string_item = cJSON_CreateString(string); if (add_item_to_object(object, name, string_item, &global_hooks, false)) { return string_item; @@ -2154,9 +2159,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON* const object, const char* const name, const char* const raw) { - cJSON *raw_item = cJSON_CreateRaw(raw); + cJSON* raw_item = cJSON_CreateRaw(raw); if (add_item_to_object(object, name, raw_item, &global_hooks, false)) { return raw_item; @@ -2166,9 +2171,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * con return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON* const object, const char* const name) { - cJSON *object_item = cJSON_CreateObject(); + cJSON* object_item = cJSON_CreateObject(); if (add_item_to_object(object, name, object_item, &global_hooks, false)) { return object_item; @@ -2178,9 +2183,9 @@ CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * return NULL; } -CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON* const object, const char* const name) { - cJSON *array = cJSON_CreateArray(); + cJSON* array = cJSON_CreateArray(); if (add_item_to_object(object, name, array, &global_hooks, false)) { return array; @@ -2190,7 +2195,7 @@ CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * c return NULL; } -CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +CJSON_PUBLIC(cJSON*) cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item) { if ((parent == NULL) || (item == NULL)) { @@ -2226,7 +2231,7 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const it return item; } -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromArray(cJSON* array, int which) { if (which < 0) { @@ -2236,39 +2241,39 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); } -CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON* array, int which) { cJSON_Delete(cJSON_DetachItemFromArray(array, which)); } -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObject(cJSON* object, const char* string) { - cJSON *to_detach = cJSON_GetObjectItem(object, string); + cJSON* to_detach = cJSON_GetObjectItem(object, string); return cJSON_DetachItemViaPointer(object, to_detach); } -CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string) { - cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + cJSON* to_detach = cJSON_GetObjectItemCaseSensitive(object, string); return cJSON_DetachItemViaPointer(object, to_detach); } -CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON* object, const char* string) { cJSON_Delete(cJSON_DetachItemFromObject(object, string)); } -CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string) { cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); } /* Replace array/object items with new ones. */ -CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON* array, int which, cJSON* newitem) { - cJSON *after_inserted = NULL; + cJSON* after_inserted = NULL; if (which < 0) { @@ -2295,7 +2300,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON return true; } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement) { if ((parent == NULL) || (replacement == NULL) || (item == NULL)) { @@ -2345,7 +2350,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON return true; } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem) { if (which < 0) { @@ -2355,7 +2360,8 @@ CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); } -static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +static cJSON_bool replace_item_in_object(cJSON* object, const char* string, cJSON* replacement, + cJSON_bool case_sensitive) { if ((replacement == NULL) || (string == NULL)) { @@ -2378,21 +2384,21 @@ static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSO return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem) { return replace_item_in_object(object, string, newitem, false); } -CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem) { return replace_item_in_object(object, string, newitem, true); } /* Create basic types: */ -CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +CJSON_PUBLIC(cJSON*) cJSON_CreateNull(void) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = cJSON_NULL; } @@ -2400,10 +2406,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +CJSON_PUBLIC(cJSON*) cJSON_CreateTrue(void) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = cJSON_True; } @@ -2411,10 +2417,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +CJSON_PUBLIC(cJSON*) cJSON_CreateFalse(void) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = cJSON_False; } @@ -2422,10 +2428,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +CJSON_PUBLIC(cJSON*) cJSON_CreateBool(cJSON_bool boolean) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = boolean ? cJSON_True : cJSON_False; } @@ -2433,10 +2439,10 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +CJSON_PUBLIC(cJSON*) cJSON_CreateNumber(double num) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = cJSON_Number; item->valuedouble = num; @@ -2459,14 +2465,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +CJSON_PUBLIC(cJSON*) cJSON_CreateString(const char* string) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = cJSON_String; item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); - if(!item->valuestring) + if (!item->valuestring) { cJSON_Delete(item); return NULL; @@ -2476,9 +2482,9 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +CJSON_PUBLIC(cJSON*) cJSON_CreateStringReference(const char* string) { - cJSON *item = cJSON_New_Item(&global_hooks); + cJSON* item = cJSON_New_Item(&global_hooks); if (item != NULL) { item->type = cJSON_String | cJSON_IsReference; @@ -2488,9 +2494,9 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +CJSON_PUBLIC(cJSON*) cJSON_CreateObjectReference(const cJSON* child) { - cJSON *item = cJSON_New_Item(&global_hooks); + cJSON* item = cJSON_New_Item(&global_hooks); if (item != NULL) { item->type = cJSON_Object | cJSON_IsReference; @@ -2500,9 +2506,9 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) +CJSON_PUBLIC(cJSON*) cJSON_CreateArrayReference(const cJSON* child) { - cJSON *item = cJSON_New_Item(&global_hooks); + cJSON* item = cJSON_New_Item(&global_hooks); if (item != NULL) { item->type = cJSON_Array | cJSON_IsReference; @@ -2512,14 +2518,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +CJSON_PUBLIC(cJSON*) cJSON_CreateRaw(const char* raw) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { item->type = cJSON_Raw; item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); - if(!item->valuestring) + if (!item->valuestring) { cJSON_Delete(item); return NULL; @@ -2529,20 +2535,20 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +CJSON_PUBLIC(cJSON*) cJSON_CreateArray(void) { - cJSON *item = cJSON_New_Item(&global_hooks); - if(item) + cJSON* item = cJSON_New_Item(&global_hooks); + if (item) { - item->type=cJSON_Array; + item->type = cJSON_Array; } return item; } -CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void) { - cJSON *item = cJSON_New_Item(&global_hooks); + cJSON* item = cJSON_New_Item(&global_hooks); if (item) { item->type = cJSON_Object; @@ -2552,12 +2558,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) } /* Create Arrays: */ -CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +CJSON_PUBLIC(cJSON*) cJSON_CreateIntArray(const int* numbers, int count) { size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; + cJSON* n = NULL; + cJSON* p = NULL; + cJSON* a = NULL; if ((count < 0) || (numbers == NULL)) { @@ -2566,7 +2572,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) a = cJSON_CreateArray(); - for(i = 0; a && (i < (size_t)count); i++) + for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); if (!n) @@ -2574,7 +2580,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) cJSON_Delete(a); return NULL; } - if(!i) + if (!i) { a->child = n; } @@ -2593,12 +2599,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) return a; } -CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +CJSON_PUBLIC(cJSON*) cJSON_CreateFloatArray(const float* numbers, int count) { size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; + cJSON* n = NULL; + cJSON* p = NULL; + cJSON* a = NULL; if ((count < 0) || (numbers == NULL)) { @@ -2607,15 +2613,15 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) a = cJSON_CreateArray(); - for(i = 0; a && (i < (size_t)count); i++) + for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber((double)numbers[i]); - if(!n) + if (!n) { cJSON_Delete(a); return NULL; } - if(!i) + if (!i) { a->child = n; } @@ -2634,12 +2640,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) return a; } -CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +CJSON_PUBLIC(cJSON*) cJSON_CreateDoubleArray(const double* numbers, int count) { size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; + cJSON* n = NULL; + cJSON* p = NULL; + cJSON* a = NULL; if ((count < 0) || (numbers == NULL)) { @@ -2648,15 +2654,15 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) a = cJSON_CreateArray(); - for(i = 0; a && (i < (size_t)count); i++) + for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateNumber(numbers[i]); - if(!n) + if (!n) { cJSON_Delete(a); return NULL; } - if(!i) + if (!i) { a->child = n; } @@ -2675,12 +2681,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) return a; } -CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +CJSON_PUBLIC(cJSON*) cJSON_CreateStringArray(const char* const* strings, int count) { size_t i = 0; - cJSON *n = NULL; - cJSON *p = NULL; - cJSON *a = NULL; + cJSON* n = NULL; + cJSON* p = NULL; + cJSON* a = NULL; if ((count < 0) || (strings == NULL)) { @@ -2692,18 +2698,18 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co for (i = 0; a && (i < (size_t)count); i++) { n = cJSON_CreateString(strings[i]); - if(!n) + if (!n) { cJSON_Delete(a); return NULL; } - if(!i) + if (!i) { a->child = n; } else { - suffix_object(p,n); + suffix_object(p, n); } p = n; } @@ -2717,12 +2723,12 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co } /* Duplication */ -CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +CJSON_PUBLIC(cJSON*) cJSON_Duplicate(const cJSON* item, cJSON_bool recurse) { - cJSON *newitem = NULL; - cJSON *child = NULL; - cJSON *next = NULL; - cJSON *newchild = NULL; + cJSON* newitem = NULL; + cJSON* child = NULL; + cJSON* next = NULL; + cJSON* newchild = NULL; /* Bail on bad ptr */ if (!item) @@ -2749,7 +2755,9 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) } if (item->string) { - newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + newitem->string = (item->type & cJSON_StringIsConst) + ? item->string + : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); if (!newitem->string) { goto fail; @@ -2800,7 +2808,7 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) return NULL; } -static void skip_oneline_comment(char **input) +static void skip_oneline_comment(char** input) { *input += static_strlen("//"); @@ -2814,7 +2822,7 @@ static void skip_oneline_comment(char **input) } } -static void skip_multiline_comment(char **input) +static void skip_multiline_comment(char** input) { *input += static_strlen("/*"); @@ -2828,13 +2836,12 @@ static void skip_multiline_comment(char **input) } } -static void minify_string(char **input, char **output) +static void minify_string(char** input, char** output) { (*output)[0] = (*input)[0]; *input += static_strlen("\""); *output += static_strlen("\""); - for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { (*output)[0] = (*input)[0]; @@ -2855,9 +2862,9 @@ static void minify_string(char **input, char **output) } } -CJSON_PUBLIC(void) cJSON_Minify(char *json) +CJSON_PUBLIC(void) cJSON_Minify(char* json) { - char *into = json; + char* into = json; if (json == NULL) { @@ -2905,7 +2912,7 @@ CJSON_PUBLIC(void) cJSON_Minify(char *json) *into = '\0'; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON* const item) { if (item == NULL) { @@ -2915,7 +2922,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) return (item->type & 0xFF) == cJSON_Invalid; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON* const item) { if (item == NULL) { @@ -2925,7 +2932,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) return (item->type & 0xFF) == cJSON_False; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON* const item) { if (item == NULL) { @@ -2935,8 +2942,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) return (item->type & 0xff) == cJSON_True; } - -CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON* const item) { if (item == NULL) { @@ -2945,7 +2951,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) return (item->type & (cJSON_True | cJSON_False)) != 0; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON* const item) { if (item == NULL) { @@ -2955,7 +2961,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) return (item->type & 0xFF) == cJSON_NULL; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON* const item) { if (item == NULL) { @@ -2965,7 +2971,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) return (item->type & 0xFF) == cJSON_Number; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON* const item) { if (item == NULL) { @@ -2975,7 +2981,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) return (item->type & 0xFF) == cJSON_String; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON* const item) { if (item == NULL) { @@ -2985,7 +2991,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) return (item->type & 0xFF) == cJSON_Array; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON* const item) { if (item == NULL) { @@ -2995,7 +3001,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) return (item->type & 0xFF) == cJSON_Object; } -CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON* const item) { if (item == NULL) { @@ -3005,7 +3011,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) return (item->type & 0xFF) == cJSON_Raw; } -CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive) { if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) { @@ -3063,10 +3069,9 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons return false; - case cJSON_Array: - { - cJSON *a_element = a->child; - cJSON *b_element = b->child; + case cJSON_Array: { + cJSON* a_element = a->child; + cJSON* b_element = b->child; for (; (a_element != NULL) && (b_element != NULL);) { @@ -3088,10 +3093,9 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons return true; } - case cJSON_Object: - { - cJSON *a_element = NULL; - cJSON *b_element = NULL; + case cJSON_Object: { + cJSON* a_element = NULL; + cJSON* b_element = NULL; cJSON_ArrayForEach(a_element, a) { /* TODO This has O(n^2) runtime, which is horrible! */ @@ -3131,12 +3135,12 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons } } -CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +CJSON_PUBLIC(void*) cJSON_malloc(size_t size) { return global_hooks.allocate(size); } -CJSON_PUBLIC(void) cJSON_free(void *object) +CJSON_PUBLIC(void) cJSON_free(void* object) { global_hooks.deallocate(object); } \ No newline at end of file diff --git a/svf/lib/WPA/Andersen.cpp b/svf/lib/WPA/Andersen.cpp index e054f5d99..d44d27964 100644 --- a/svf/lib/WPA/Andersen.cpp +++ b/svf/lib/WPA/Andersen.cpp @@ -38,7 +38,6 @@ using namespace SVF; using namespace SVFUtil; using namespace std; - u32_t AndersenBase::numOfProcessedAddr = 0; u32_t AndersenBase::numOfProcessedCopy = 0; u32_t AndersenBase::numOfProcessedGep = 0; @@ -79,8 +78,7 @@ void AndersenBase::initialize() /// Build Constraint Graph consCG = new ConstraintGraph(pag); setGraph(consCG); - if (Options::ConsCGDotGraph()) - consCG->dump("consCG_initial"); + if (Options::ConsCGDotGraph()) consCG->dump("consCG_initial"); } /*! @@ -89,11 +87,9 @@ void AndersenBase::initialize() void AndersenBase::finalize() { /// dump constraint graph if PAGDotGraph flag is enabled - if (Options::ConsCGDotGraph()) - consCG->dump("consCG_final"); + if (Options::ConsCGDotGraph()) consCG->dump("consCG_final"); - if (Options::PrintCGGraph()) - consCG->print(); + if (Options::PrintCGGraph()) consCG->print(); BVDataPTAImpl::finalize(); } @@ -108,18 +104,15 @@ void AndersenBase::solveConstraints() do { numOfIteration++; - if (0 == numOfIteration % iterationForPrintStat) - printStat(); + if (0 == numOfIteration % iterationForPrintStat) printStat(); reanalyze = false; solveWorklist(); - if (updateCallGraph(getIndirectCallsites())) - reanalyze = true; + if (updateCallGraph(getIndirectCallsites())) reanalyze = true; - } - while (reanalyze); + } while (reanalyze); // Analysis is finished, reset the alarm if we set it. SVFUtil::stopAnalysisLimitTimer(limitTimerSet); @@ -132,13 +125,13 @@ void AndersenBase::solveConstraints() */ void AndersenBase::analyze() { - if(!Options::ReadAnder().empty()) + if (!Options::ReadAnder().empty()) { readPtsFromFile(Options::ReadAnder()); } else { - if(Options::WriteAnder().empty()) + if (Options::WriteAnder().empty()) { initialize(); solveConstraints(); @@ -157,47 +150,45 @@ void AndersenBase::analyze() void AndersenBase::readPtsFromFile(const std::string& filename) { initialize(); - if (!filename.empty()) - this->readFromFile(filename); + if (!filename.empty()) this->readFromFile(filename); finalize(); } /*! * Andersen analysis: solve constraints and write pointer analysis result to file */ -void AndersenBase:: solveAndwritePtsToFile(const std::string& filename) +void AndersenBase::solveAndwritePtsToFile(const std::string& filename) { /// Initialization for the Solver initialize(); - if (!filename.empty()) - this->writeObjVarToFile(filename); + if (!filename.empty()) this->writeObjVarToFile(filename); solveConstraints(); - if (!filename.empty()) - this->writeToFile(filename); + if (!filename.empty()) this->writeToFile(filename); finalize(); } void AndersenBase::cleanConsCG(NodeID id) { consCG->resetSubs(consCG->getRep(id)); - for (NodeID sub: consCG->getSubs(id)) - consCG->resetRep(sub); + for (NodeID sub : consCG->getSubs(id)) consCG->resetRep(sub); consCG->resetSubs(id); consCG->resetRep(id); - assert(!consCG->hasGNode(id) && "this is either a rep nodeid or a sub nodeid should have already been merged to its field-insensitive base! "); + assert( + !consCG->hasGNode(id) && + "this is either a rep nodeid or a sub nodeid should have already been merged to its field-insensitive base! "); } void AndersenBase::normalizePointsTo() { - SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap(); - SVFIR::NodeOffsetMap &GepObjVarMap = pag->getGepObjNodeMap(); + SVFIR::MemObjToFieldsMap& memToFieldsMap = pag->getMemToFieldsMap(); + SVFIR::NodeOffsetMap& GepObjVarMap = pag->getGepObjNodeMap(); // clear GepObjVarMap/memToFieldsMap/nodeToSubsMap/nodeToRepMap // for redundant gepnodes and remove those nodes from pag - for (NodeID n: redundantGepNodes) + for (NodeID n : redundantGepNodes) { NodeID base = pag->getBaseObjVar(n); - GepObjVar *gepNode = SVFUtil::dyn_cast(pag->getGNode(n)); + GepObjVar* gepNode = SVFUtil::dyn_cast(pag->getGNode(n)); assert(gepNode && "Not a gep node in redundantGepNodes set"); const APOffset apOffset = gepNode->getConstantFieldIdx(); GepObjVarMap.erase(std::make_pair(base, apOffset)); @@ -232,7 +223,7 @@ void Andersen::finalize() if (Options::ClusterAnder()) { Map stats; - const PTDataTy *ptd = getPTDataTy(); + const PTDataTy* ptd = getPTDataTy(); // TODO: should we use liveOnly? // TODO: parameterise final arg. NodeIDAllocator::Clusterer::evaluate(*PointsTo::getCurrentBestNodeMapping(), ptd->getAllPts(true), stats, true); @@ -251,8 +242,7 @@ void Andersen::finalize() void Andersen::processNode(NodeID nodeId) { // sub nodes do not need to be processed - if (sccRepNode(nodeId) != nodeId) - return; + if (sccRepNode(nodeId) != nodeId) return; ConstraintNode* node = consCG->getConstraintNode(nodeId); double insertStart = stat->getClk(); @@ -276,12 +266,10 @@ void Andersen::handleCopyGep(ConstraintNode* node) if (!getDiffPts(nodeId).empty()) { - for (ConstraintEdge* edge : node->getCopyOutEdges()) - processCopy(nodeId, edge); + for (ConstraintEdge* edge : node->getCopyOutEdges()) processCopy(nodeId, edge); for (ConstraintEdge* edge : node->getGepOutEdges()) { - if (GepCGEdge* gepEdge = SVFUtil::dyn_cast(edge)) - processGep(nodeId, gepEdge); + if (GepCGEdge* gepEdge = SVFUtil::dyn_cast(edge)) processGep(nodeId, gepEdge); } } } @@ -289,27 +277,24 @@ void Andersen::handleCopyGep(ConstraintNode* node) /*! * Process load and store edges */ -void Andersen::handleLoadStore(ConstraintNode *node) +void Andersen::handleLoadStore(ConstraintNode* node) { NodeID nodeId = node->getId(); - for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = - getPts(nodeId).end(); piter != epiter; ++piter) + for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); piter != epiter; ++piter) { NodeID ptd = *piter; // handle load - for (ConstraintNode::const_iterator it = node->outgoingLoadsBegin(), - eit = node->outgoingLoadsEnd(); it != eit; ++it) + for (ConstraintNode::const_iterator it = node->outgoingLoadsBegin(), eit = node->outgoingLoadsEnd(); it != eit; + ++it) { - if (processLoad(ptd, *it)) - pushIntoWorklist(ptd); + if (processLoad(ptd, *it)) pushIntoWorklist(ptd); } // handle store - for (ConstraintNode::const_iterator it = node->incomingStoresBegin(), - eit = node->incomingStoresEnd(); it != eit; ++it) + for (ConstraintNode::const_iterator it = node->incomingStoresBegin(), eit = node->incomingStoresEnd(); + it != eit; ++it) { - if (processStore(ptd, *it)) - pushIntoWorklist((*it)->getSrcID()); + if (processStore(ptd, *it)) pushIntoWorklist((*it)->getSrcID()); } } } @@ -321,9 +306,9 @@ void Andersen::processAllAddr() { for (ConstraintGraph::const_iterator nodeIt = consCG->begin(), nodeEit = consCG->end(); nodeIt != nodeEit; nodeIt++) { - ConstraintNode * cgNode = nodeIt->second; + ConstraintNode* cgNode = nodeIt->second; for (ConstraintNode::const_iterator it = cgNode->incomingAddrsBegin(), eit = cgNode->incomingAddrsEnd(); - it != eit; ++it) + it != eit; ++it) processAddr(SVFUtil::cast(*it)); } } @@ -337,8 +322,7 @@ void Andersen::processAddr(const AddrCGEdge* addr) NodeID dst = addr->getDstID(); NodeID src = addr->getSrcID(); - if(addPts(dst,src)) - pushIntoWorklist(dst); + if (addPts(dst, src)) pushIntoWorklist(dst); } /*! @@ -351,9 +335,8 @@ bool Andersen::processLoad(NodeID node, const ConstraintEdge* load) /// TODO: New copy edges are also added for black hole obj node to /// make gcc in spec 2000 pass the flow-sensitive analysis. /// Try to handle black hole obj in an appropriate way. -// if (pag->isBlkObjOrConstantObj(node)) - if (pag->isConstantObj(node) || pag->getGNode(load->getDstID())->isPointer() == false) - return false; + // if (pag->isBlkObjOrConstantObj(node)) + if (pag->isConstantObj(node) || pag->getGNode(load->getDstID())->isPointer() == false) return false; numOfProcessedLoad++; @@ -371,9 +354,8 @@ bool Andersen::processStore(NodeID node, const ConstraintEdge* store) /// TODO: New copy edges are also added for black hole obj node to /// make gcc in spec 2000 pass the flow-sensitive analysis. /// Try to handle black hole obj in an appropriate way -// if (pag->isBlkObjOrConstantObj(node)) - if (pag->isConstantObj(node) || pag->getGNode(store->getSrcID())->isPointer() == false) - return false; + // if (pag->isBlkObjOrConstantObj(node)) + if (pag->isConstantObj(node) || pag->getGNode(store->getSrcID())->isPointer() == false) return false; numOfProcessedStore++; @@ -395,8 +377,7 @@ bool Andersen::processCopy(NodeID node, const ConstraintEdge* edge) const PointsTo& srcPts = getDiffPts(node); bool changed = unionPts(dst, srcPts); - if (changed) - pushIntoWorklist(dst); + if (changed) pushIntoWorklist(dst); return changed; } @@ -484,8 +465,7 @@ inline void Andersen::collapsePWCNode(NodeID nodeId) // If a node is a PWC node, collapse all its points-to target. // collapseNodePts() may change the points-to set of the nodes which have been processed // before, in this case, we may need to re-do the analysis. - if (consCG->isPWCNode(nodeId) && collapseNodePts(nodeId)) - reanalyze = true; + if (consCG->isPWCNode(nodeId) && collapseNodePts(nodeId)) reanalyze = true; } inline void Andersen::collapseFields() @@ -495,8 +475,7 @@ inline void Andersen::collapseFields() NodeID node = consCG->getNextCollapseNode(); // collapseField() may change the points-to set of the nodes which have been processed // before, in this case, we may need to re-do the analysis. - if (collapseField(node)) - reanalyze = true; + if (collapseField(node)) reanalyze = true; } } @@ -506,7 +485,7 @@ inline void Andersen::collapseFields() void Andersen::mergeSccCycle() { NodeStack revTopoOrder; - NodeStack & topoOrder = getSCCDetector()->topoNodeStack(); + NodeStack& topoOrder = getSCCDetector()->topoNodeStack(); while (!topoOrder.empty()) { NodeID repNodeId = topoOrder.top(); @@ -526,7 +505,6 @@ void Andersen::mergeSccCycle() } } - /** * Union points-to of subscc nodes into its rep nodes * Move incoming/outgoing direct edges of sub node to rep node @@ -554,11 +532,9 @@ bool Andersen::collapseNodePts(NodeID nodeId) PointsTo ptsClone = nodePts; for (PointsTo::iterator ptsIt = ptsClone.begin(), ptsEit = ptsClone.end(); ptsIt != ptsEit; ptsIt++) { - if (isFieldInsensitive(*ptsIt)) - continue; + if (isFieldInsensitive(*ptsIt)) continue; - if (collapseField(*ptsIt)) - changed = true; + if (collapseField(*ptsIt)) changed = true; } return changed; } @@ -572,8 +548,7 @@ bool Andersen::collapseField(NodeID nodeId) /// In later versions, instead of using base node to represent the struct, /// we'll create new field-insensitive node. To avoid creating a new "black hole" /// node, do not collapse field for black hole node. - if (consCG->isBlkObjOrConstantObj(nodeId)) - return false; + if (consCG->isBlkObjOrConstantObj(nodeId)) return false; bool changed = false; @@ -585,7 +560,7 @@ bool Andersen::collapseField(NodeID nodeId) // replace all occurrences of each field with the field-insensitive node NodeID baseId = consCG->getFIObjVar(nodeId); NodeID baseRepNodeId = consCG->sccRepNode(baseId); - NodeBS & allFields = consCG->getAllFieldsObjVars(baseId); + NodeBS& allFields = consCG->getAllFieldsObjVars(baseId); for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); fieldIt != fieldEit; fieldIt++) { NodeID fieldId = *fieldIt; @@ -615,8 +590,7 @@ bool Andersen::collapseField(NodeID nodeId) } if (consCG->isPWCNode(baseRepNodeId)) - if (collapseNodePts(baseRepNodeId)) - changed = true; + if (collapseNodePts(baseRepNodeId)) changed = true; double end = stat->getClk(); timeOfCollapse += (end - start) / TIMEINTERVAL; @@ -635,7 +609,7 @@ NodeStack& Andersen::SCCDetect() WPAConstraintSolver::SCCDetect(); double sccEnd = stat->getClk(); - timeOfSCCDetection += (sccEnd - sccStart)/TIMEINTERVAL; + timeOfSCCDetection += (sccEnd - sccStart) / TIMEINTERVAL; double mergeStart = stat->getClk(); @@ -643,7 +617,7 @@ NodeStack& Andersen::SCCDetect() double mergeEnd = stat->getClk(); - timeOfSCCMerges += (mergeEnd - mergeStart)/TIMEINTERVAL; + timeOfSCCMerges += (mergeEnd - mergeStart) / TIMEINTERVAL; return getSCCDetector()->topoNodeStack(); } @@ -657,17 +631,17 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites) double cgUpdateStart = stat->getClk(); CallEdgeMap newEdges; - onTheFlyCallGraphSolve(callsites,newEdges); - NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge - for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it ) + onTheFlyCallGraphSolve(callsites, newEdges); + NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge + for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it != eit; ++it) { CallSite cs = SVFUtil::getSVFCallSite(it->first->getCallSite()); - for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) + for (FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { - connectCaller2CalleeParams(cs,*cit,cpySrcNodes); + connectCaller2CalleeParams(cs, *cit, cpySrcNodes); } } - for(NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it!=eit; ++it) + for (NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it != eit; ++it) { pushIntoWorklist(it->first); } @@ -678,14 +652,14 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites) return (!newEdges.empty()); } -void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes) +void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes) { assert(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?"); RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs.getInstruction()); const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode); NodeID srcret; CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs); - if(it != callsite2DummyValPN.end()) + if (it != callsite2DummyValPN.end()) { srcret = sccRepNode(it->second); } @@ -693,33 +667,33 @@ void Andersen::heapAllocatorViaIndCall(CallSite cs, NodePairSet &cpySrcNodes) { NodeID valNode = pag->addDummyValNode(); NodeID objNode = pag->addDummyObjNode(cs.getType()); - addPts(valNode,objNode); - callsite2DummyValPN.insert(std::make_pair(cs,valNode)); - consCG->addConstraintNode(new ConstraintNode(valNode),valNode); - consCG->addConstraintNode(new ConstraintNode(objNode),objNode); + addPts(valNode, objNode); + callsite2DummyValPN.insert(std::make_pair(cs, valNode)); + consCG->addConstraintNode(new ConstraintNode(valNode), valNode); + consCG->addConstraintNode(new ConstraintNode(objNode), objNode); srcret = valNode; } NodeID dstrec = sccRepNode(cs_return->getId()); - if(addCopyEdge(srcret, dstrec)) - cpySrcNodes.insert(std::make_pair(srcret,dstrec)); + if (addCopyEdge(srcret, dstrec)) cpySrcNodes.insert(std::make_pair(srcret, dstrec)); } /*! * Connect formal and actual parameters for indirect callsites */ -void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet &cpySrcNodes) +void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet& cpySrcNodes) { assert(F); - DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() << " to callee " << *F << "\n"); + DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() + << " to callee " << *F << "\n"); CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(cs.getInstruction()); RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs.getInstruction()); - if(SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode)) + if (SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode)) { - heapAllocatorViaIndCall(cs,cpySrcNodes); + heapAllocatorViaIndCall(cs, cpySrcNodes); } if (pag->funHasRet(F) && pag->callsiteHasRet(retBlockNode)) @@ -730,9 +704,9 @@ void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, Nod { NodeID dstrec = sccRepNode(cs_return->getId()); NodeID srcret = sccRepNode(fun_return->getId()); - if(addCopyEdge(srcret, dstrec)) + if (addCopyEdge(srcret, dstrec)) { - cpySrcNodes.insert(std::make_pair(srcret,dstrec)); + cpySrcNodes.insert(std::make_pair(srcret, dstrec)); } } else @@ -747,52 +721,52 @@ void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, Nod // connect actual and formal param const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode); const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(F); - //Go through the fixed parameters. + // Go through the fixed parameters. DBOUT(DPAGBuild, outs() << " args:"); SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end(); - SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end(); + SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end(); for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt) { - //Some programs (e.g. Linux kernel) leave unneeded parameters empty. - if (csArgIt == csArgEit) + // Some programs (e.g. Linux kernel) leave unneeded parameters empty. + if (csArgIt == csArgEit) { DBOUT(DAndersen, outs() << " !! not enough args\n"); break; } - const PAGNode *cs_arg = *csArgIt ; - const PAGNode *fun_arg = *funArgIt; + const PAGNode* cs_arg = *csArgIt; + const PAGNode* fun_arg = *funArgIt; if (cs_arg->isPointer() && fun_arg->isPointer()) { DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n"); NodeID srcAA = sccRepNode(cs_arg->getId()); NodeID dstFA = sccRepNode(fun_arg->getId()); - if(addCopyEdge(srcAA, dstFA)) + if (addCopyEdge(srcAA, dstFA)) { - cpySrcNodes.insert(std::make_pair(srcAA,dstFA)); + cpySrcNodes.insert(std::make_pair(srcAA, dstFA)); } } } - //Any remaining actual args must be varargs. + // Any remaining actual args must be varargs. if (F->isVarArg()) { NodeID vaF = sccRepNode(pag->getVarargNode(F)); DBOUT(DPAGBuild, outs() << "\n varargs:"); for (; csArgIt != csArgEit; ++csArgIt) { - const PAGNode *cs_arg = *csArgIt; + const PAGNode* cs_arg = *csArgIt; if (cs_arg->isPointer()) { NodeID vnAA = sccRepNode(cs_arg->getId()); - if (addCopyEdge(vnAA,vaF)) + if (addCopyEdge(vnAA, vaF)) { - cpySrcNodes.insert(std::make_pair(vnAA,vaF)); + cpySrcNodes.insert(std::make_pair(vnAA, vaF)); } } } } - if(csArgIt != csArgEit) + if (csArgIt != csArgEit) { writeWrnMsg("too many args to non-vararg func."); writeWrnMsg("(" + cs.getInstruction()->getSourceLoc() + ")"); @@ -806,12 +780,11 @@ void Andersen::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, Nod bool Andersen::mergeSrcToTgt(NodeID nodeId, NodeID newRepId) { - if(nodeId==newRepId) - return false; + if (nodeId == newRepId) return false; /// union pts of node to rep updatePropaPts(newRepId, nodeId); - unionPts(newRepId,nodeId); + unionPts(newRepId, nodeId); /// move the edges from node to rep, and remove the node ConstraintNode* node = consCG->getConstraintNode(nodeId); @@ -821,11 +794,10 @@ bool Andersen::mergeSrcToTgt(NodeID nodeId, NodeID newRepId) /// its pts should be collapsed later. /// 2. if the node to be merged is already a PWC node, the rep node will also become /// a PWC node as it will have a self-cycle gep edge. - if(node->isPWCNode()) - pwc = true; + if (node->isPWCNode()) pwc = true; /// set rep and sub relations - updateNodeRepAndSubs(node->getId(),newRepId); + updateNodeRepAndSubs(node->getId(), newRepId); consCG->removeConstraintNode(node); @@ -834,11 +806,10 @@ bool Andersen::mergeSrcToTgt(NodeID nodeId, NodeID newRepId) /* * Merge a node to its rep node based on SCC detection */ -void Andersen::mergeNodeToRep(NodeID nodeId,NodeID newRepId) +void Andersen::mergeNodeToRep(NodeID nodeId, NodeID newRepId) { - if (mergeSrcToTgt(nodeId,newRepId)) - consCG->setPWCNode(newRepId); + if (mergeSrcToTgt(nodeId, newRepId)) consCG->setPWCNode(newRepId); } /* @@ -846,26 +817,27 @@ void Andersen::mergeNodeToRep(NodeID nodeId,NodeID newRepId) */ void Andersen::updateNodeRepAndSubs(NodeID nodeId, NodeID newRepId) { - consCG->setRep(nodeId,newRepId); + consCG->setRep(nodeId, newRepId); NodeBS repSubs; repSubs.set(nodeId); /// update nodeToRepMap, for each subs of current node updates its rep to newRepId // update nodeToSubsMap, union its subs with its rep Subs NodeBS& nodeSubs = consCG->sccSubNodes(nodeId); - for(NodeBS::iterator sit = nodeSubs.begin(), esit = nodeSubs.end(); sit!=esit; ++sit) + for (NodeBS::iterator sit = nodeSubs.begin(), esit = nodeSubs.end(); sit != esit; ++sit) { NodeID subId = *sit; - consCG->setRep(subId,newRepId); + consCG->setRep(subId, newRepId); } repSubs |= nodeSubs; - consCG->setSubs(newRepId,repSubs); + consCG->setSubs(newRepId, repSubs); consCG->resetSubs(nodeId); } void Andersen::cluster(void) const { - assert(Options::MaxFieldLimit() == 0 && "Andersen::cluster: clustering for Andersen's is currently only supported in field-insensitive analysis"); - Steensgaard *steens = Steensgaard::createSteensgaard(pag); + assert(Options::MaxFieldLimit() == 0 && + "Andersen::cluster: clustering for Andersen's is currently only supported in field-insensitive analysis"); + Steensgaard* steens = Steensgaard::createSteensgaard(pag); std::vector> keys; for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit) { @@ -873,8 +845,8 @@ void Andersen::cluster(void) const } std::vector>> candidates; - PointsTo::MappingPtr nodeMapping = - std::make_shared>(NodeIDAllocator::Clusterer::cluster(steens, keys, candidates, "aux-steens")); + PointsTo::MappingPtr nodeMapping = std::make_shared>( + NodeIDAllocator::Clusterer::cluster(steens, keys, candidates, "aux-steens")); PointsTo::MappingPtr reverseNodeMapping = std::make_shared>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping)); @@ -886,8 +858,8 @@ void Andersen::cluster(void) const */ void Andersen::dumpTopLevelPtsTo() { - for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); - nIter != this->getAllValidPtrs().end(); ++nIter) + for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin(); nIter != this->getAllValidPtrs().end(); + ++nIter) { const PAGNode* node = getPAG()->getGNode(*nIter); if (getPAG()->isValidTopLevelPtr(node)) @@ -904,14 +876,13 @@ void Andersen::dumpTopLevelPtsTo() outs() << "\t\tPointsTo: { "; multiset line; - for (PointsTo::iterator it = pts.begin(), eit = pts.end(); - it != eit; ++it) + for (PointsTo::iterator it = pts.begin(), eit = pts.end(); it != eit; ++it) { line.insert(*it); } for (multiset::const_iterator it = line.begin(); it != line.end(); ++it) { - if(Options::PrintFieldWithBasePrefix()) + if (Options::PrintFieldWithBasePrefix()) if (auto gepNode = SVFUtil::dyn_cast(pag->getGNode(*it))) outs() << gepNode->getBaseNode() << "_" << gepNode->getConstantFieldIdx() << " "; else @@ -926,4 +897,3 @@ void Andersen::dumpTopLevelPtsTo() outs().flush(); } - diff --git a/svf/lib/WPA/AndersenSCD.cpp b/svf/lib/WPA/AndersenSCD.cpp index e3a14e9c8..e7b61cf7b 100644 --- a/svf/lib/WPA/AndersenSCD.cpp +++ b/svf/lib/WPA/AndersenSCD.cpp @@ -37,7 +37,6 @@ using namespace std; AndersenSCD* AndersenSCD::scdAndersen = nullptr; - /*! * */ @@ -47,8 +46,7 @@ void AndersenSCD::solveWorklist() // Nodes in nodeStack are in topological order by default. NodeStack& nodeStack = SCCDetect(); - for (NodeID nId : sccCandidates) - pushIntoWorklist(nId); + for (NodeID nId : sccCandidates) pushIntoWorklist(nId); sccCandidates.clear(); // propagate point-to sets @@ -90,7 +88,6 @@ void AndersenSCD::solveWorklist() } } - /*! * SCC detection for SCD */ @@ -101,12 +98,12 @@ NodeStack& AndersenSCD::SCCDetect() double sccStart = stat->getClk(); getSCCDetector()->find(sccCandidates); double sccEnd = stat->getClk(); - timeOfSCCDetection += (sccEnd - sccStart)/TIMEINTERVAL; + timeOfSCCDetection += (sccEnd - sccStart) / TIMEINTERVAL; double mergeStart = stat->getClk(); mergeSccCycle(); double mergeEnd = stat->getClk(); - timeOfSCCMerges += (mergeEnd - mergeStart)/TIMEINTERVAL; + timeOfSCCMerges += (mergeEnd - mergeStart) / TIMEINTERVAL; if (!Options::DetectPWC()) { @@ -119,7 +116,6 @@ NodeStack& AndersenSCD::SCCDetect() return getSCCDetector()->topoNodeStack(); } - /*! * */ @@ -128,8 +124,7 @@ void AndersenSCD::PWCDetect() // replace scc candidates by their reps NodeSet tmpSccCandidates = sccCandidates; sccCandidates.clear(); - for (NodeID candidate : tmpSccCandidates) - sccCandidates.insert(sccRepNode(candidate)); + for (NodeID candidate : tmpSccCandidates) sccCandidates.insert(sccRepNode(candidate)); tmpSccCandidates.clear(); // set scc edge type as direct edge @@ -142,7 +137,6 @@ void AndersenSCD::PWCDetect() setDetectPWC(pwcFlag); } - /*! * Compute diff points-to set before propagation */ @@ -150,13 +144,11 @@ void AndersenSCD::handleCopyGep(ConstraintNode* node) { NodeID nodeId = node->getId(); - if (!Options::DetectPWC() && getSCCDetector()->subNodes(nodeId).count() > 1) - processPWC(node); - else if(isInWorklist(nodeId)) + if (!Options::DetectPWC() && getSCCDetector()->subNodes(nodeId).count() > 1) processPWC(node); + else if (isInWorklist(nodeId)) Andersen::handleCopyGep(node); } - /*! * */ @@ -165,13 +157,11 @@ void AndersenSCD::processPWC(ConstraintNode* rep) NodeID repId = rep->getId(); NodeSet pwcNodes; - for (NodeID nId : getSCCDetector()->subNodes(repId)) - pwcNodes.insert(nId); + for (NodeID nId : getSCCDetector()->subNodes(repId)) pwcNodes.insert(nId); WorkList tmpWorkList; for (NodeID subId : pwcNodes) - if (isInWorklist(subId)) - tmpWorkList.push(subId); + if (isInWorklist(subId)) tmpWorkList.push(subId); while (!tmpWorkList.empty()) { @@ -180,16 +170,15 @@ void AndersenSCD::processPWC(ConstraintNode* rep) if (!getDiffPts(nodeId).empty()) { - ConstraintNode *node = consCG->getConstraintNode(nodeId); + ConstraintNode* node = consCG->getConstraintNode(nodeId); for (ConstraintEdge* edge : node->getCopyOutEdges()) { bool changed = processCopy(nodeId, edge); - if (changed && pwcNodes.find(edge->getDstID()) != pwcNodes.end()) - tmpWorkList.push(edge->getDstID()); + if (changed && pwcNodes.find(edge->getDstID()) != pwcNodes.end()) tmpWorkList.push(edge->getDstID()); } for (ConstraintEdge* edge : node->getGepOutEdges()) { - if (GepCGEdge *gepEdge = SVFUtil::dyn_cast(edge)) + if (GepCGEdge* gepEdge = SVFUtil::dyn_cast(edge)) { bool changed = processGep(nodeId, gepEdge); if (changed && pwcNodes.find(edge->getDstID()) != pwcNodes.end()) @@ -200,7 +189,6 @@ void AndersenSCD::processPWC(ConstraintNode* rep) } } - /*! * Source nodes of new added edges are pushed into sccCandidates. * Source nodes of new added edges whose pts differ from those of dst nodes are pushed into worklist. @@ -211,10 +199,9 @@ void AndersenSCD::handleLoadStore(ConstraintNode* node) NodeID nodeId = node->getId(); // handle load - for (ConstraintNode::const_iterator it = node->outgoingLoadsBegin(), - eit = node->outgoingLoadsEnd(); it != eit; ++it) - for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = - getPts(nodeId).end(); piter != epiter; ++piter) + for (ConstraintNode::const_iterator it = node->outgoingLoadsBegin(), eit = node->outgoingLoadsEnd(); it != eit; + ++it) + for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); piter != epiter; ++piter) { NodeID ptd = *piter; if (processLoad(ptd, *it)) @@ -224,10 +211,9 @@ void AndersenSCD::handleLoadStore(ConstraintNode* node) } // handle store - for (ConstraintNode::const_iterator it = node->incomingStoresBegin(), - eit = node->incomingStoresEnd(); it != eit; ++it) - for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = - getPts(nodeId).end(); piter != epiter; ++piter) + for (ConstraintNode::const_iterator it = node->incomingStoresBegin(), eit = node->incomingStoresEnd(); it != eit; + ++it) + for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); piter != epiter; ++piter) { NodeID ptd = *piter; if (processStore(ptd, *it)) @@ -240,21 +226,19 @@ void AndersenSCD::handleLoadStore(ConstraintNode* node) timeOfProcessLoadStore += (insertEnd - insertStart) / TIMEINTERVAL; } - /*! * Initialize worklist via processing addrs */ -void AndersenSCD::processAddr(const AddrCGEdge *addr) +void AndersenSCD::processAddr(const AddrCGEdge* addr) { numOfProcessedAddr++; NodeID dst = addr->getDstID(); NodeID src = addr->getSrcID(); - addPts(dst,src); + addPts(dst, src); addSccCandidate(dst); } - /*! * If one copy edge is successful added, the src node should be added into SCC detection */ @@ -268,7 +252,6 @@ bool AndersenSCD::addCopyEdge(NodeID src, NodeID dst) return false; } - /*! * Update call graph for the input indirect callsites */ @@ -277,14 +260,14 @@ bool AndersenSCD::updateCallGraph(const PointerAnalysis::CallSiteToFunPtrMap& ca double cgUpdateStart = stat->getClk(); CallEdgeMap newEdges; - onTheFlyCallGraphSolve(callsites,newEdges); - NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge - for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it ) + onTheFlyCallGraphSolve(callsites, newEdges); + NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge + for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it != eit; ++it) { CallSite cs = SVFUtil::getSVFCallSite(it->first->getCallSite()); - for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) + for (FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { - connectCaller2CalleeParams(cs,*cit,cpySrcNodes); + connectCaller2CalleeParams(cs, *cit, cpySrcNodes); } } diff --git a/svf/lib/WPA/AndersenSFR.cpp b/svf/lib/WPA/AndersenSFR.cpp index 3b9a31629..3368f39c8 100644 --- a/svf/lib/WPA/AndersenSFR.cpp +++ b/svf/lib/WPA/AndersenSFR.cpp @@ -34,7 +34,7 @@ using namespace SVF; using namespace SVFUtil; using namespace std; -AndersenSFR *AndersenSFR::sfrAndersen = nullptr; +AndersenSFR* AndersenSFR::sfrAndersen = nullptr; /*! * @@ -42,17 +42,15 @@ AndersenSFR *AndersenSFR::sfrAndersen = nullptr; void AndersenSFR::initialize() { AndersenSCD::initialize(); - setDetectPWC(false); // SCC will detect only copy edges + setDetectPWC(false); // SCC will detect only copy edges - if (!csc) - csc = new CSC(_graph, scc.get()); + if (!csc) csc = new CSC(_graph, scc.get()); /// Detect and collapse cycles consisting of only copy edges getSCCDetector()->find(); mergeSccCycle(); } - /*! * Call the PWC stride calculation method of class CSC. */ @@ -62,7 +60,6 @@ void AndersenSFR::PWCDetect() csc->find(getSCCDetector()->topoNodeStack()); } - /*! * */ @@ -77,7 +74,6 @@ bool AndersenSFR::mergeSrcToTgt(NodeID nodeId, NodeID newRepId) return Andersen::mergeSrcToTgt(nodeId, newRepId); } - /*! * Propagate point-to set via a gep edge, using SFR */ @@ -86,7 +82,7 @@ bool AndersenSFR::processGepPts(const PointsTo& pts, const GepCGEdge* edge) ConstraintNode* dst = edge->getDstNode(); NodeID dstId = dst->getId(); - if (!dst->strides.empty() && SVFUtil::isa(edge)) // dst is in pwc + if (!dst->strides.empty() && SVFUtil::isa(edge)) // dst is in pwc { PointsTo tmpDstPts; PointsTo srcInits = pts - getPts(dstId); @@ -94,8 +90,7 @@ bool AndersenSFR::processGepPts(const PointsTo& pts, const GepCGEdge* edge) if (!srcInits.empty()) { NodeSet sortSrcInits; - for (NodeID ptd : srcInits) - sortSrcInits.insert(ptd); + for (NodeID ptd : srcInits) sortSrcInits.insert(ptd); APOffset offset = SVFUtil::dyn_cast(edge)->getConstantFieldIdx(); fieldExpand(sortSrcInits, offset, dst->strides, tmpDstPts); @@ -113,7 +108,6 @@ bool AndersenSFR::processGepPts(const PointsTo& pts, const GepCGEdge* edge) return Andersen::processGepPts(pts, edge); } - /*! * Expand field IDs in target pts based on the initials and offsets */ @@ -126,16 +120,14 @@ void AndersenSFR::fieldExpand(NodeSet& initials, APOffset offset, NodeBS& stride NodeID init = *initials.begin(); initials.erase(init); - if (consCG->isBlkObjOrConstantObj(init)) - expandPts.set(init); + if (consCG->isBlkObjOrConstantObj(init)) expandPts.set(init); else { PAGNode* initPN = pag->getGNode(init); const MemObj* obj = pag->getBaseObj(init); const u32_t maxLimit = obj->getMaxFieldOffsetLimit(); APOffset initOffset; - if (GepObjVar *gepNode = SVFUtil::dyn_cast(initPN)) - initOffset = gepNode->getConstantFieldIdx(); + if (GepObjVar* gepNode = SVFUtil::dyn_cast(initPN)) initOffset = gepNode->getConstantFieldIdx(); else if (SVFUtil::isa(initPN)) initOffset = 0; else @@ -156,9 +148,8 @@ void AndersenSFR::fieldExpand(NodeSet& initials, APOffset offset, NodeBS& stride for (auto _s : strides) { APOffset _f1 = _f + _s; - loopFlag = (offsets.find(_f1) == offsets.end()) && ( (u32_t)(initOffset + _f1) < maxLimit); - if (loopFlag) - offsets.insert(_f1); + loopFlag = (offsets.find(_f1) == offsets.end()) && ((u32_t)(initOffset + _f1) < maxLimit); + if (loopFlag) offsets.insert(_f1); } } @@ -166,7 +157,7 @@ void AndersenSFR::fieldExpand(NodeSet& initials, APOffset offset, NodeBS& stride for (APOffset _f : offsets) { NodeID gepId = consCG->getGepObjVar(init, _f); - initials.erase(gepId); // gep id in initials should be removed to avoid redundant derivation + initials.erase(gepId); // gep id in initials should be removed to avoid redundant derivation expandPts.set(gepId); } } diff --git a/svf/lib/WPA/AndersenStat.cpp b/svf/lib/WPA/AndersenStat.cpp index 0b1c787a9..02e753dcb 100644 --- a/svf/lib/WPA/AndersenStat.cpp +++ b/svf/lib/WPA/AndersenStat.cpp @@ -46,10 +46,10 @@ const char* AndersenStat::CollapseTime = "CollapseTime"; /*! * Constructor */ -AndersenStat::AndersenStat(AndersenBase* p): PTAStat(p),pta(p) +AndersenStat::AndersenStat(AndersenBase* p) : PTAStat(p), pta(p) { _NumOfNullPtr = 0; - _NumOfConstantPtr= 0; + _NumOfConstantPtr = 0; _NumOfBlackholePtr = 0; startClk(); } @@ -64,7 +64,7 @@ void AndersenStat::collectCycleInfo(ConstraintGraph* consCG) _NumOfNodesInCycles = 0; NodeSet repNodes; repNodes.clear(); - for(ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it!=eit; ++it) + for (ConstraintGraph::iterator it = consCG->begin(), eit = consCG->end(); it != eit; ++it) { // sub nodes have been removed from the constraint graph, only rep nodes are left. NodeID repNode = consCG->sccRepNode(it->first); @@ -84,14 +84,12 @@ void AndersenStat::collectCycleInfo(ConstraintGraph* consCG) u32_t num = clone.count(); if (num > 1) { - if(repNodes.insert(repNode).second) + if (repNodes.insert(repNode).second) { _NumOfNodesInCycles += num; - if(consCG->isPWCNode(repNode)) - _NumOfPWCCycles ++; + if (consCG->isPWCNode(repNode)) _NumOfPWCCycles++; } - if( num > _MaxNumOfNodesInSCC) - _MaxNumOfNodesInSCC = num; + if (num > _MaxNumOfNodesInSCC) _MaxNumOfNodesInSCC = num; } } _NumOfCycles += repNodes.size(); @@ -100,18 +98,17 @@ void AndersenStat::collectCycleInfo(ConstraintGraph* consCG) void AndersenStat::constraintGraphStat() { - ConstraintGraph* consCG = pta->getConstraintGraph(); u32_t numOfCopys = 0; u32_t numOfGeps = 0; // collect copy and gep edges - for(ConstraintEdge::ConstraintEdgeSetTy::iterator it = consCG->getDirectCGEdges().begin(), - eit = consCG->getDirectCGEdges().end(); it!=eit; ++it) + for (ConstraintEdge::ConstraintEdgeSetTy::iterator it = consCG->getDirectCGEdges().begin(), + eit = consCG->getDirectCGEdges().end(); + it != eit; ++it) { - if(SVFUtil::isa(*it)) - numOfCopys++; - else if(SVFUtil::isa(*it)) + if (SVFUtil::isa(*it)) numOfCopys++; + else if (SVFUtil::isa(*it)) numOfGeps++; else assert(false && "what else!!"); @@ -133,61 +130,49 @@ void AndersenStat::constraintGraphStat() u32_t storemaxIn = 0; u32_t storemaxOut = 0; - for (ConstraintGraph::ConstraintNodeIDToNodeMapTy::iterator nodeIt = consCG->begin(), nodeEit = consCG->end(); - nodeIt != nodeEit; nodeIt++) + nodeIt != nodeEit; nodeIt++) { totalNodeNumber++; - if(nodeIt->second->getInEdges().empty() && nodeIt->second->getOutEdges().empty()) - continue; + if (nodeIt->second->getInEdges().empty() && nodeIt->second->getOutEdges().empty()) continue; cgNodeNumber++; - if(SVFUtil::isa(pta->getPAG()->getGNode(nodeIt->first))) - objNodeNumber++; + if (SVFUtil::isa(pta->getPAG()->getGNode(nodeIt->first))) objNodeNumber++; u32_t nCopyIn = nodeIt->second->getDirectInEdges().size(); - if(nCopyIn > copymaxIn) - copymaxIn = nCopyIn; - copytotalIn +=nCopyIn; + if (nCopyIn > copymaxIn) copymaxIn = nCopyIn; + copytotalIn += nCopyIn; u32_t nCopyOut = nodeIt->second->getDirectOutEdges().size(); - if(nCopyOut > copymaxOut) - copymaxOut = nCopyOut; + if (nCopyOut > copymaxOut) copymaxOut = nCopyOut; u32_t nLoadIn = nodeIt->second->getLoadInEdges().size(); - if(nLoadIn > loadmaxIn) - loadmaxIn = nLoadIn; - loadtotalIn +=nLoadIn; + if (nLoadIn > loadmaxIn) loadmaxIn = nLoadIn; + loadtotalIn += nLoadIn; u32_t nLoadOut = nodeIt->second->getLoadOutEdges().size(); - if(nLoadOut > loadmaxOut) - loadmaxOut = nLoadOut; + if (nLoadOut > loadmaxOut) loadmaxOut = nLoadOut; u32_t nStoreIn = nodeIt->second->getStoreInEdges().size(); - if(nStoreIn > storemaxIn) - storemaxIn = nStoreIn; - storetotalIn +=nStoreIn; + if (nStoreIn > storemaxIn) storemaxIn = nStoreIn; + storetotalIn += nStoreIn; u32_t nStoreOut = nodeIt->second->getStoreOutEdges().size(); - if(nStoreOut > storemaxOut) - storemaxOut = nStoreOut; + if (nStoreOut > storemaxOut) storemaxOut = nStoreOut; u32_t nAddrIn = nodeIt->second->getAddrInEdges().size(); - if(nAddrIn > addrmaxIn) - addrmaxIn = nAddrIn; - addrtotalIn +=nAddrIn; + if (nAddrIn > addrmaxIn) addrmaxIn = nAddrIn; + addrtotalIn += nAddrIn; u32_t nAddrOut = nodeIt->second->getAddrOutEdges().size(); - if(nAddrOut > addrmaxOut) - addrmaxOut = nAddrOut; + if (nAddrOut > addrmaxOut) addrmaxOut = nAddrOut; } - double storeavgIn = (double)storetotalIn/cgNodeNumber; - double loadavgIn = (double)loadtotalIn/cgNodeNumber; - double copyavgIn = (double)copytotalIn/cgNodeNumber; - double addravgIn = (double)addrtotalIn/cgNodeNumber; - double avgIn = (double)(addrtotalIn + copytotalIn + loadtotalIn + storetotalIn)/cgNodeNumber; - + double storeavgIn = (double)storetotalIn / cgNodeNumber; + double loadavgIn = (double)loadtotalIn / cgNodeNumber; + double copyavgIn = (double)copytotalIn / cgNodeNumber; + double addravgIn = (double)addrtotalIn / cgNodeNumber; + double avgIn = (double)(addrtotalIn + copytotalIn + loadtotalIn + storetotalIn) / cgNodeNumber; PTNumStatMap["NumOfCGNode"] = totalNodeNumber; PTNumStatMap["NumOfValidNode"] = cgNodeNumber; PTNumStatMap["NumOfValidObjNode"] = objNodeNumber; - PTNumStatMap["NumOfCGEdge"] = consCG->getLoadCGEdges().size() + consCG->getStoreCGEdges().size() - + numOfCopys + numOfGeps; - PTNumStatMap["NumOfAddrs"] = consCG->getAddrCGEdges().size(); + PTNumStatMap["NumOfCGEdge"] = + consCG->getLoadCGEdges().size() + consCG->getStoreCGEdges().size() + numOfCopys + numOfGeps; + PTNumStatMap["NumOfAddrs"] = consCG->getAddrCGEdges().size(); PTNumStatMap["NumOfCopys"] = numOfCopys; - PTNumStatMap["NumOfGeps"] = numOfGeps; + PTNumStatMap["NumOfGeps"] = numOfGeps; PTNumStatMap["NumOfLoads"] = consCG->getLoadCGEdges().size(); PTNumStatMap["NumOfStores"] = consCG->getStoreCGEdges().size(); PTNumStatMap["MaxInCopyEdge"] = copymaxIn; @@ -211,39 +196,35 @@ void AndersenStat::statNullPtr() { _NumOfNullPtr = 0; - for (SVFIR::iterator iter = pta->getPAG()->begin(), eiter = pta->getPAG()->end(); - iter != eiter; ++iter) + for (SVFIR::iterator iter = pta->getPAG()->begin(), eiter = pta->getPAG()->end(); iter != eiter; ++iter) { NodeID pagNodeId = iter->first; PAGNode* pagNode = iter->second; - if (SVFUtil::isa(pagNode) == false) - continue; + if (SVFUtil::isa(pagNode) == false) continue; SVFStmt::SVFStmtSetTy& inComingStore = pagNode->getIncomingEdges(SVFStmt::Store); SVFStmt::SVFStmtSetTy& outGoingLoad = pagNode->getOutgoingEdges(SVFStmt::Load); - if (inComingStore.empty()==false || outGoingLoad.empty()==false) + if (inComingStore.empty() == false || outGoingLoad.empty() == false) { - ///TODO: change the condition here to fetch the points-to set + /// TODO: change the condition here to fetch the points-to set const PointsTo& pts = pta->getPts(pagNodeId); - if (pta->containBlackHoleNode(pts)) - _NumOfBlackholePtr++; + if (pta->containBlackHoleNode(pts)) _NumOfBlackholePtr++; - if (pta->containConstantNode(pts)) - _NumOfConstantPtr++; + if (pta->containConstantNode(pts)) _NumOfConstantPtr++; - if(pts.empty()) + if (pts.empty()) { std::string str; std::stringstream rawstr(str); - if (!SVFUtil::isa(pagNode) && !SVFUtil::isa(pagNode) ) + if (!SVFUtil::isa(pagNode) && !SVFUtil::isa(pagNode)) { // if a pointer is in dead function, we do not care - if(pagNode->getValue()->ptrInUncalledFunction() == false) + if (pagNode->getValue()->ptrInUncalledFunction() == false) { _NumOfNullPtr++; rawstr << "##Null Pointer : (NodeID " << pagNode->getId() << ") PtrName:" << pagNode->getValue()->getName(); writeWrnMsg(rawstr.str()); - //pagNode->getValue()->dump(); + // pagNode->getValue()->dump(); } } else @@ -255,7 +236,6 @@ void AndersenStat::statNullPtr() } } } - } /*! @@ -280,43 +260,39 @@ void AndersenStat::performStat() u32_t totalTopLevPointers = 0; u32_t totalPtsSize = 0; u32_t totalTopLevPtsSize = 0; - for (SVFIR::iterator iter = pta->getPAG()->begin(), eiter = pta->getPAG()->end(); - iter != eiter; ++iter) + for (SVFIR::iterator iter = pta->getPAG()->begin(), eiter = pta->getPAG()->end(); iter != eiter; ++iter) { NodeID node = iter->first; const PointsTo& pts = pta->getPts(node); u32_t size = pts.count(); totalPointers++; - totalPtsSize+=size; + totalPtsSize += size; - if(pta->getPAG()->isValidTopLevelPtr(pta->getPAG()->getGNode(node))) + if (pta->getPAG()->isValidTopLevelPtr(pta->getPAG()->getGNode(node))) { totalTopLevPointers++; - totalTopLevPtsSize+=size; + totalTopLevPtsSize += size; } - if(size > _MaxPtsSize ) - _MaxPtsSize = size; + if (size > _MaxPtsSize) _MaxPtsSize = size; } - PTAStat::performStat(); constraintGraphStat(); - timeStatMap["TotalTime"] = (endTime - startTime)/TIMEINTERVAL; + timeStatMap["TotalTime"] = (endTime - startTime) / TIMEINTERVAL; timeStatMap["SCCDetectTime"] = Andersen::timeOfSCCDetection; - timeStatMap["SCCMergeTime"] = Andersen::timeOfSCCMerges; - timeStatMap[CollapseTime] = Andersen::timeOfCollapse; + timeStatMap["SCCMergeTime"] = Andersen::timeOfSCCMerges; + timeStatMap[CollapseTime] = Andersen::timeOfCollapse; - timeStatMap["LoadStoreTime"] = Andersen::timeOfProcessLoadStore; - timeStatMap["CopyGepTime"] = Andersen::timeOfProcessCopyGep; - timeStatMap["UpdateCGTime"] = Andersen::timeOfUpdateCallGraph; + timeStatMap["LoadStoreTime"] = Andersen::timeOfProcessLoadStore; + timeStatMap["CopyGepTime"] = Andersen::timeOfProcessCopyGep; + timeStatMap["UpdateCGTime"] = Andersen::timeOfUpdateCallGraph; PTNumStatMap["TotalPointers"] = pag->getValueNodeNum() + pag->getFieldValNodeNum(); PTNumStatMap["TotalObjects"] = pag->getObjectNodeNum() + pag->getFieldObjNodeNum(); - PTNumStatMap["AddrProcessed"] = Andersen::numOfProcessedAddr; PTNumStatMap["CopyProcessed"] = Andersen::numOfProcessedCopy; PTNumStatMap["GepProcessed"] = Andersen::numOfProcessedGep; @@ -331,8 +307,10 @@ void AndersenStat::performStat() PTNumStatMap["DummyFieldPtrs"] = pag->getFieldValNodeNum(); PTNumStatMap["FieldObjs"] = pag->getFieldObjNodeNum(); - timeStatMap["AvgPtsSetSize"] = (double)totalPtsSize/totalPointers;; - timeStatMap["AvgTopLvlPtsSize"] = (double)totalTopLevPtsSize/totalTopLevPointers;; + timeStatMap["AvgPtsSetSize"] = (double)totalPtsSize / totalPointers; + ; + timeStatMap["AvgTopLvlPtsSize"] = (double)totalTopLevPtsSize / totalTopLevPointers; + ; PTNumStatMap["MaxPtsSetSize"] = _MaxPtsSize; @@ -352,4 +330,3 @@ void AndersenStat::performStat() PTAStat::printStat("Andersen Pointer Analysis Stats"); } - diff --git a/svf/lib/WPA/AndersenWaveDiff.cpp b/svf/lib/WPA/AndersenWaveDiff.cpp index 539c0b689..ddc052e73 100644 --- a/svf/lib/WPA/AndersenWaveDiff.cpp +++ b/svf/lib/WPA/AndersenWaveDiff.cpp @@ -42,7 +42,7 @@ AndersenWaveDiff* AndersenWaveDiff::diffWave = nullptr; void AndersenWaveDiff::initialize() { Andersen::initialize(); - setDetectPWC(true); // Standard wave propagation always collapses PWCs + setDetectPWC(true); // Standard wave propagation always collapses PWCs } /*! @@ -81,8 +81,7 @@ void AndersenWaveDiff::processNode(NodeID nodeId) { // This node may be merged during collapseNodePts() which means it is no longer a rep node // in the graph. Only rep node needs to be handled. - if (sccRepNode(nodeId) != nodeId) - return; + if (sccRepNode(nodeId) != nodeId) return; double propStart = stat->getClk(); ConstraintNode* node = consCG->getConstraintNode(nodeId); @@ -101,18 +100,16 @@ void AndersenWaveDiff::postProcessNode(NodeID nodeId) ConstraintNode* node = consCG->getConstraintNode(nodeId); // handle load - for (ConstraintNode::const_iterator it = node->outgoingLoadsBegin(), eit = node->outgoingLoadsEnd(); - it != eit; ++it) + for (ConstraintNode::const_iterator it = node->outgoingLoadsBegin(), eit = node->outgoingLoadsEnd(); it != eit; + ++it) { - if (handleLoad(nodeId, *it)) - reanalyze = true; + if (handleLoad(nodeId, *it)) reanalyze = true; } // handle store - for (ConstraintNode::const_iterator it = node->incomingStoresBegin(), eit = node->incomingStoresEnd(); - it != eit; ++it) + for (ConstraintNode::const_iterator it = node->incomingStoresBegin(), eit = node->incomingStoresEnd(); it != eit; + ++it) { - if (handleStore(nodeId, *it)) - reanalyze = true; + if (handleStore(nodeId, *it)) reanalyze = true; } double insertEnd = stat->getClk(); @@ -125,8 +122,7 @@ void AndersenWaveDiff::postProcessNode(NodeID nodeId) bool AndersenWaveDiff::handleLoad(NodeID nodeId, const ConstraintEdge* edge) { bool changed = false; - for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); - piter != epiter; ++piter) + for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); piter != epiter; ++piter) { if (processLoad(*piter, edge)) { @@ -142,8 +138,7 @@ bool AndersenWaveDiff::handleLoad(NodeID nodeId, const ConstraintEdge* edge) bool AndersenWaveDiff::handleStore(NodeID nodeId, const ConstraintEdge* edge) { bool changed = false; - for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); - piter != epiter; ++piter) + for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter = getPts(nodeId).end(); piter != epiter; ++piter) { if (processStore(*piter, edge)) { diff --git a/svf/lib/WPA/CSC.cpp b/svf/lib/WPA/CSC.cpp index 513f33776..55e64d688 100644 --- a/svf/lib/WPA/CSC.cpp +++ b/svf/lib/WPA/CSC.cpp @@ -32,7 +32,6 @@ using namespace SVF; using namespace SVFUtil; - /*! * */ @@ -42,7 +41,6 @@ void CSC::clear() _D.clear(); } - /*! * */ @@ -57,7 +55,7 @@ void CSC::find(NodeStack& candidates) revCandidates.push(nId); candidates.pop(); - if (_scc->subNodes(nId).count()>1 && !isVisited(nId)) // node is actually in a cycle + if (_scc->subNodes(nId).count() > 1 && !isVisited(nId)) // node is actually in a cycle visit(nId, 0); } @@ -69,13 +67,12 @@ void CSC::find(NodeStack& candidates) } } - /*! * */ void CSC::visit(NodeID nodeId, s32_t _w) { -// pwcReps[nodeId] = _scc->repNode(nodeId); + // pwcReps[nodeId] = _scc->repNode(nodeId); setVisited(nodeId); _I += _w; @@ -91,8 +88,7 @@ void CSC::visit(NodeID nodeId, s32_t _w) else offset = 0; NodeID dstId = (*eit)->getDstID(); - if (_scc->repNode(nodeId) == _scc->repNode(dstId) && !isVisited(dstId)) - visit(dstId, offset); + if (_scc->repNode(nodeId) == _scc->repNode(dstId) && !isVisited(dstId)) visit(dstId, offset); } NodeStack _revS; @@ -106,20 +102,19 @@ void CSC::visit(NodeID nodeId, s32_t _w) ConstraintNode* backNode = _consG->getConstraintNode(backNodeId); if (_consG->hasEdge(node, backNode, ConstraintEdge::NormalGep)) { - NormalGepCGEdge* normalGep = SVFUtil::dyn_cast(_consG->getEdge(node, backNode, ConstraintEdge::NormalGep)); + NormalGepCGEdge* normalGep = + SVFUtil::dyn_cast(_consG->getEdge(node, backNode, ConstraintEdge::NormalGep)); s32_t _w = normalGep->getConstantFieldIdx(); - s32_t _l = _D[nodeId] +_w - _D[backNodeId]; + s32_t _l = _D[nodeId] + _w - _D[backNodeId]; backNode->strides.set(_l); - for (auto cNodeId : _C) - _consG->getConstraintNode(cNodeId)->strides.set(_l); + for (auto cNodeId : _C) _consG->getConstraintNode(cNodeId)->strides.set(_l); } else if (_consG->hasEdge(node, backNode, ConstraintEdge::VariantGep) || _consG->hasEdge(node, backNode, ConstraintEdge::Copy)) { s32_t _l = _D[nodeId] - _D[backNodeId]; backNode->strides.set(_l); - for (auto cNodeId : _C) - _consG->getConstraintNode(cNodeId)->strides.set(_l); + for (auto cNodeId : _C) _consG->getConstraintNode(cNodeId)->strides.set(_l); } _C.insert(backNodeId); } @@ -131,5 +126,5 @@ void CSC::visit(NodeID nodeId, s32_t _w) _revS.pop(); } - _S.pop(); // after checking all the edges of the top node of _S, remove the node + _S.pop(); // after checking all the edges of the top node of _S, remove the node } diff --git a/svf/lib/WPA/FlowSensitive.cpp b/svf/lib/WPA/FlowSensitive.cpp index 9d523c35d..fee328081 100644 --- a/svf/lib/WPA/FlowSensitive.cpp +++ b/svf/lib/WPA/FlowSensitive.cpp @@ -53,8 +53,8 @@ void FlowSensitive::initialize() ander = AndersenWaveDiff::createAndersenWaveDiff(getPAG()); // If cluster option is not set, it will give us a no-mapping points-to set. - assert(!(Options::ClusterFs() && Options::PlainMappingFs()) - && "FS::init: plain-mapping and cluster-fs are mutually exclusive."); + assert(!(Options::ClusterFs() && Options::PlainMappingFs()) && + "FS::init: plain-mapping and cluster-fs are mutually exclusive."); if (Options::ClusterFs()) { cluster(); @@ -72,7 +72,7 @@ void FlowSensitive::initialize() svfg = memSSA.buildPTROnlySVFG(ander); setGraph(svfg); - //AndersenWaveDiff::releaseAndersenWaveDiff(); + // AndersenWaveDiff::releaseAndersenWaveDiff(); } void FlowSensitive::solveConstraints() { @@ -86,15 +86,13 @@ void FlowSensitive::solveConstraints() { numOfIteration++; - if(0 == numOfIteration % OnTheFlyIterBudgetForStat) - dumpStat(); + if (0 == numOfIteration % OnTheFlyIterBudgetForStat) dumpStat(); callGraphSCC->find(); initWorklist(); solveWorklist(); - } - while (updateCallGraph(getIndirectCallsites())); + } while (updateCallGraph(getIndirectCallsites())); DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Finish Solving Constraints\n")); @@ -103,7 +101,6 @@ void FlowSensitive::solveConstraints() double end = stat->getClk(true); solveTime += (end - start) / TIMEINTERVAL; - } /*! @@ -113,11 +110,9 @@ void FlowSensitive::solveAndwritePtsToFile(const std::string& filename) { /// Initialization for the Solver initialize(); - if(!filename.empty()) - writeObjVarToFile(filename); + if (!filename.empty()) writeObjVarToFile(filename); solveConstraints(); - if(!filename.empty()) - writeToFile(filename); + if (!filename.empty()) writeToFile(filename); /// finalize the analysis finalize(); } @@ -127,13 +122,13 @@ void FlowSensitive::solveAndwritePtsToFile(const std::string& filename) */ void FlowSensitive::analyze() { - if(!Options::ReadAnder().empty()) + if (!Options::ReadAnder().empty()) { readPtsFromFile(Options::ReadAnder()); } else { - if(Options::WriteAnder().empty()) + if (Options::WriteAnder().empty()) { initialize(); solveConstraints(); @@ -151,8 +146,7 @@ void FlowSensitive::readPtsFromFile(const std::string& filename) /// Initialization for the Solver initialize(); /// Load the pts from file - if(!filename.empty()) - this->readFromFile(filename); + if (!filename.empty()) this->readFromFile(filename); /// finalize the analysis finalize(); } @@ -162,8 +156,7 @@ void FlowSensitive::readPtsFromFile(const std::string& filename) */ void FlowSensitive::finalize() { - if(Options::DumpVFG()) - svfg->dump("fs_solved", true); + if (Options::DumpVFG()) svfg->dump("fs_solved", true); NodeStack& nodeStack = WPASolver::SCCDetect(); while (nodeStack.empty() == false) @@ -171,8 +164,7 @@ void FlowSensitive::finalize() NodeID rep = nodeStack.top(); nodeStack.pop(); const NodeBS& subNodes = getSCCDetector()->subNodes(rep); - if (subNodes.count() > maxSCCSize) - maxSCCSize = subNodes.count(); + if (subNodes.count() > maxSCCSize) maxSCCSize = subNodes.count(); if (subNodes.count() > 1) { numOfNodesInSCC += subNodes.count(); @@ -184,7 +176,7 @@ void FlowSensitive::finalize() if (Options::ClusterFs()) { Map stats; - const PTDataTy *ptd = getPTDataTy(); + const PTDataTy* ptd = getPTDataTy(); // TODO: should we use liveOnly? Map allPts = ptd->getAllPts(true); // TODO: parameterise final arg. @@ -192,11 +184,12 @@ void FlowSensitive::finalize() NodeIDAllocator::Clusterer::printStats("post-main: best", stats); // Do the same for the candidates. TODO: probably temporary for eval. purposes. - for (std::pair> &candidate : candidateMappings) + for (std::pair>& candidate : candidateMappings) { // Can reuse stats, since we're always filling it with `evaluate`, it will always be overwritten. NodeIDAllocator::Clusterer::evaluate(candidate.second, allPts, stats, true); - NodeIDAllocator::Clusterer::printStats("post-main: candidate " + SVFUtil::hclustMethodToString(candidate.first), stats); + NodeIDAllocator::Clusterer::printStats( + "post-main: candidate " + SVFUtil::hclustMethodToString(candidate.first), stats); } } @@ -221,8 +214,7 @@ NodeStack& FlowSensitive::SCCDetect() void FlowSensitive::processNode(NodeID nodeId) { SVFGNode* node = svfg->getSVFGNode(nodeId); - if (processSVFGNode(node)) - propagate(&node); + if (processSVFGNode(node)) propagate(&node); clearAllDFOutVarFlag(node); } @@ -237,54 +229,45 @@ bool FlowSensitive::processSVFGNode(SVFGNode* node) if (AddrSVFGNode* addr = SVFUtil::dyn_cast(node)) { numOfProcessedAddr++; - if (processAddr(addr)) - changed = true; + if (processAddr(addr)) changed = true; } else if (CopySVFGNode* copy = SVFUtil::dyn_cast(node)) { numOfProcessedCopy++; - if (processCopy(copy)) - changed = true; + if (processCopy(copy)) changed = true; } else if (GepSVFGNode* gep = SVFUtil::dyn_cast(node)) { numOfProcessedGep++; - if(processGep(gep)) - changed = true; + if (processGep(gep)) changed = true; } else if (LoadSVFGNode* load = SVFUtil::dyn_cast(node)) { numOfProcessedLoad++; - if(processLoad(load)) - changed = true; + if (processLoad(load)) changed = true; } else if (StoreSVFGNode* store = SVFUtil::dyn_cast(node)) { numOfProcessedStore++; - if (processStore(store)) - changed = true; + if (processStore(store)) changed = true; } else if (PHISVFGNode* phi = SVFUtil::dyn_cast(node)) { numOfProcessedPhi++; - if (processPhi(phi)) - changed = true; + if (processPhi(phi)) changed = true; } - else if (SVFUtil::isa(node)) + else if (SVFUtil::isa( + node)) { numOfProcessedMSSANode++; changed = true; } - else if (SVFUtil::isa(node)) + else if (SVFUtil::isa(node)) { changed = true; } - else if (SVFUtil::isa(node) || - SVFUtil::dyn_cast(node)) + else if (SVFUtil::isa(node) || SVFUtil::dyn_cast(node)) { } else @@ -311,15 +294,14 @@ bool FlowSensitive::propFromSrcToDst(SVFGEdge* edge) double start = stat->getClk(); bool changed = false; - if (DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast(edge)) - changed = propAlongDirectEdge(dirEdge); + if (DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast(edge)) changed = propAlongDirectEdge(dirEdge); else if (IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast(edge)) changed = propAlongIndirectEdge(indEdge); else assert(false && "new kind of svfg edge?"); double end = stat->getClk(); - propagationTime += (end - start) /TIMEINTERVAL; + propagationTime += (end - start) / TIMEINTERVAL; return changed; } @@ -335,8 +317,7 @@ bool FlowSensitive::propAlongDirectEdge(const DirectSVFGEdge* edge) SVFGNode* dst = edge->getDstNode(); // If this is an actual-param or formal-ret, top-level pointer's pts must be // propagated from src to dst. - if (ActualParmSVFGNode* ap = SVFUtil::dyn_cast(src)) - changed = propagateFromAPToFP(ap, dst); + if (ActualParmSVFGNode* ap = SVFUtil::dyn_cast(src)) changed = propagateFromAPToFP(ap, dst); else if (FormalRetSVFGNode* fp = SVFUtil::dyn_cast(src)) changed = propagateFromFRToAR(fp, dst); else @@ -363,7 +344,7 @@ bool FlowSensitive::propagateFromAPToFP(const ActualParmSVFGNode* ap, const SVFG assert(fp && "expecting a formal param node"); NodeID pagDst = fp->getParam()->getId(); - const PointsTo &srcCPts = getPts(ap->getParam()->getId()); + const PointsTo& srcCPts = getPts(ap->getParam()->getId()); bool changed = unionPts(pagDst, srcCPts); return changed; @@ -379,7 +360,7 @@ bool FlowSensitive::propagateFromFRToAR(const FormalRetSVFGNode* fr, const SVFGN assert(ar && "expecting an actual return node"); NodeID pagDst = ar->getRev()->getId(); - const PointsTo & srcCPts = getPts(fr->getRet()->getId()); + const PointsTo& srcCPts = getPts(fr->getRet()->getId()); bool changed = unionPts(pagDst, srcCPts); return changed; @@ -404,18 +385,16 @@ bool FlowSensitive::propAlongIndirectEdge(const IndirectSVFGEdge* edge) { NodeID ptd = *ptdIt; - if (propVarPtsFromSrcToDst(ptd, src, dst)) - changed = true; + if (propVarPtsFromSrcToDst(ptd, src, dst)) changed = true; if (isFieldInsensitive(ptd)) { /// If this is a field-insensitive obj, propagate all field node's pts const NodeBS& allFields = getAllFieldsObjVars(ptd); - for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); - fieldIt != fieldEit; ++fieldIt) + for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); fieldIt != fieldEit; + ++fieldIt) { - if (propVarPtsFromSrcToDst(*fieldIt, src, dst)) - changed = true; + if (propVarPtsFromSrcToDst(*fieldIt, src, dst)) changed = true; } } } @@ -433,13 +412,11 @@ bool FlowSensitive::propVarPtsFromSrcToDst(NodeID var, const SVFGNode* src, cons bool changed = false; if (SVFUtil::isa(src)) { - if (updateInFromOut(src, var, dst, var)) - changed = true; + if (updateInFromOut(src, var, dst, var)) changed = true; } else { - if (updateInFromIn(src, var, dst, var)) - changed = true; + if (updateInFromIn(src, var, dst, var)) changed = true; } return changed; } @@ -453,8 +430,7 @@ bool FlowSensitive::processAddr(const AddrSVFGNode* addr) NodeID srcID = addr->getPAGSrcNodeID(); /// TODO: If this object has been set as field-insensitive, just /// add the insensitive object node into dst pointer's pts. - if (isFieldInsensitive(srcID)) - srcID = getFIObjVar(srcID); + if (isFieldInsensitive(srcID)) srcID = getFIObjVar(srcID); bool changed = addPts(addr->getPAGDstNodeID(), srcID); double end = stat->getClk(); addrTime += (end - start) / TIMEINTERVAL; @@ -481,12 +457,11 @@ bool FlowSensitive::processPhi(const PHISVFGNode* phi) double start = stat->getClk(); bool changed = false; NodeID pagDst = phi->getRes()->getId(); - for (PHISVFGNode::OPVers::const_iterator it = phi->opVerBegin(), eit = phi->opVerEnd(); it != eit; ++it) + for (PHISVFGNode::OPVers::const_iterator it = phi->opVerBegin(), eit = phi->opVerEnd(); it != eit; ++it) { NodeID src = it->second->getId(); const PointsTo& srcPts = getPts(src); - if (unionPts(pagDst, srcPts)) - changed = true; + if (unionPts(pagDst, srcPts)) changed = true; } double end = stat->getClk(); @@ -534,15 +509,13 @@ bool FlowSensitive::processGep(const GepSVFGNode* edge) } } - if (unionPts(edge->getPAGDstNodeID(), tmpDstPts)) - changed = true; + if (unionPts(edge->getPAGDstNodeID(), tmpDstPts)) changed = true; double end = stat->getClk(); gepTime += (end - start) / TIMEINTERVAL; return changed; } - /*! * Process load node * @@ -559,28 +532,25 @@ bool FlowSensitive::processLoad(const LoadSVFGNode* load) const PointsTo& srcPts = getPts(load->getPAGSrcNodeID()); // p = *q, the type of p must be a pointer - if(load->getPAGDstNode()->isPointer()) + if (load->getPAGDstNode()->isPointer()) { for (PointsTo::iterator ptdIt = srcPts.begin(); ptdIt != srcPts.end(); ++ptdIt) { NodeID ptd = *ptdIt; - if (pag->isConstantObj(ptd)) - continue; + if (pag->isConstantObj(ptd)) continue; - if (unionPtsFromIn(load, ptd, dstVar)) - changed = true; + if (unionPtsFromIn(load, ptd, dstVar)) changed = true; if (isFieldInsensitive(ptd)) { /// If the ptd is a field-insensitive node, we should also get all field nodes' /// points-to sets and pass them to pagDst. const NodeBS& allFields = getAllFieldsObjVars(ptd); - for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); - fieldIt != fieldEit; ++fieldIt) + for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); fieldIt != fieldEit; + ++fieldIt) { - if (unionPtsFromIn(load, *fieldIt, dstVar)) - changed = true; + if (unionPtsFromIn(load, *fieldIt, dstVar)) changed = true; } } } @@ -599,7 +569,7 @@ bool FlowSensitive::processLoad(const LoadSVFGNode* load) bool FlowSensitive::processStore(const StoreSVFGNode* store) { - const PointsTo & dstPts = getPts(store->getPAGDstNodeID()); + const PointsTo& dstPts = getPts(store->getPAGDstNodeID()); /// STORE statement can only be processed if the pointer on the LHS /// points to something. If we handle STORE with an empty points-to @@ -607,24 +577,21 @@ bool FlowSensitive::processStore(const StoreSVFGNode* store) /// points-to one target and it has been identified as a strong /// update, we can't remove those points-to information computed /// before this strong update from the OUT set. - if (dstPts.empty()) - return false; + if (dstPts.empty()) return false; double start = stat->getClk(); bool changed = false; // *p = q, the type of q must be a pointer - if(getPts(store->getPAGSrcNodeID()).empty() == false && store->getPAGSrcNode()->isPointer()) + if (getPts(store->getPAGSrcNodeID()).empty() == false && store->getPAGSrcNode()->isPointer()) { for (PointsTo::iterator it = dstPts.begin(), eit = dstPts.end(); it != eit; ++it) { NodeID ptd = *it; - if (pag->isConstantObj(ptd)) - continue; + if (pag->isConstantObj(ptd)) continue; - if (unionPtsFromTop(store, store->getPAGSrcNodeID(), ptd)) - changed = true; + if (unionPtsFromTop(store, store->getPAGSrcNodeID(), ptd)) changed = true; } } @@ -639,14 +606,12 @@ bool FlowSensitive::processStore(const StoreSVFGNode* store) if (isSU) { svfgHasSU.set(store->getId()); - if (strongUpdateOutFromIn(store, singleton)) - changed = true; + if (strongUpdateOutFromIn(store, singleton)) changed = true; } else { svfgHasSU.reset(store->getId()); - if (weakUpdateOutFromIn(store)) - changed = true; + if (weakUpdateOutFromIn(store)) changed = true; } double updateEnd = stat->getClk(); updateTime += (updateEnd - updateStart) / TIMEINTERVAL; @@ -670,9 +635,8 @@ bool FlowSensitive::isStrongUpdate(const SVFGNode* node, NodeID& singleton) singleton = *it; // Strong update can be made if this points-to target is not heap, array or field-insensitive. - if (!isHeapMemObj(singleton) && !isArrayMemObj(singleton) - && pag->getBaseObj(singleton)->isFieldInsensitive() == false - && !isLocalVarInRecursiveFun(singleton)) + if (!isHeapMemObj(singleton) && !isArrayMemObj(singleton) && + pag->getBaseObj(singleton)->isFieldInsensitive() == false && !isLocalVarInRecursiveFun(singleton)) { isSU = true; } @@ -692,25 +656,24 @@ bool FlowSensitive::updateCallGraph(const CallSiteToFunPtrMap& callsites) // Bound the new edges by the Andersen's call graph. // TODO: we want this to be an assertion eventually. - const CallEdgeMap &andersCallEdgeMap = ander->getIndCallMap(); - for (typename CallEdgeMap::value_type &csfs : newEdges) + const CallEdgeMap& andersCallEdgeMap = ander->getIndCallMap(); + for (typename CallEdgeMap::value_type& csfs : newEdges) { - const CallICFGNode *potentialCallSite = csfs.first; - FunctionSet &potentialFunctionSet = csfs.second; + const CallICFGNode* potentialCallSite = csfs.first; + FunctionSet& potentialFunctionSet = csfs.second; // Check this callsite even calls anything per Andersen's. - typename CallEdgeMap::const_iterator andersFunctionSetIt - = andersCallEdgeMap.find(potentialCallSite); + typename CallEdgeMap::const_iterator andersFunctionSetIt = andersCallEdgeMap.find(potentialCallSite); if (andersFunctionSetIt == andersCallEdgeMap.end()) { potentialFunctionSet.clear(); } - const FunctionSet &andersFunctionSet = andersFunctionSetIt->second; + const FunctionSet& andersFunctionSet = andersFunctionSetIt->second; for (FunctionSet::iterator potentialFunctionIt = potentialFunctionSet.begin(); - potentialFunctionIt != potentialFunctionSet.end(); ) + potentialFunctionIt != potentialFunctionSet.end();) { - const SVFFunction *potentialFunction = *potentialFunctionIt; + const SVFFunction* potentialFunction = *potentialFunctionIt; if (andersFunctionSet.find(potentialFunction) == andersFunctionSet.end()) { // potentialFunction is not in the Andersen's call graph -- remove it. @@ -744,10 +707,10 @@ void FlowSensitive::connectCallerAndCallee(const CallEdgeMap& newEdges, SVFGEdge for (; iter != eiter; iter++) { const CallICFGNode* cs = iter->first; - const FunctionSet & functions = iter->second; + const FunctionSet& functions = iter->second; for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* func = *func_iter; + const SVFFunction* func = *func_iter; svfg->connectCallerAndCallee(cs, func, edges); } } @@ -781,29 +744,25 @@ void FlowSensitive::updateConnectedNodes(const SVFGEdgeSetTy& edges) { NodeID ptd = *ptdIt; - if (propVarPtsAfterCGUpdated(ptd, srcNode, dstNode)) - changed = true; + if (propVarPtsAfterCGUpdated(ptd, srcNode, dstNode)) changed = true; if (isFieldInsensitive(ptd)) { /// If this is a field-insensitive obj, propagate all field node's pts const NodeBS& allFields = getAllFieldsObjVars(ptd); - for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); - fieldIt != fieldEit; ++fieldIt) + for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); fieldIt != fieldEit; + ++fieldIt) { - if (propVarPtsAfterCGUpdated(*fieldIt, srcNode, dstNode)) - changed = true; + if (propVarPtsAfterCGUpdated(*fieldIt, srcNode, dstNode)) changed = true; } } } - if (changed) - pushIntoWorklist(dstNode->getId()); + if (changed) pushIntoWorklist(dstNode->getId()); } } } - /*! * Propagate points-to information of a certain variable from src to dst. */ @@ -811,13 +770,11 @@ bool FlowSensitive::propVarPtsAfterCGUpdated(NodeID var, const SVFGNode* src, co { if (SVFUtil::isa(src)) { - if (propDFOutToIn(src, var, dst, var)) - return true; + if (propDFOutToIn(src, var, dst, var)) return true; } else { - if (propDFInToIn(src, var, dst, var)) - return true; + if (propDFInToIn(src, var, dst, var)) return true; } return false; } @@ -825,11 +782,10 @@ bool FlowSensitive::propVarPtsAfterCGUpdated(NodeID var, const SVFGNode* src, co void FlowSensitive::cluster(void) { std::vector> keys; - for (const auto& pair : *pag) - keys.emplace_back(pair.first, 1); + for (const auto& pair : *pag) keys.emplace_back(pair.first, 1); - PointsTo::MappingPtr nodeMapping = - std::make_shared>(NodeIDAllocator::Clusterer::cluster(ander, keys, candidateMappings, "aux-ander")); + PointsTo::MappingPtr nodeMapping = std::make_shared>( + NodeIDAllocator::Clusterer::cluster(ander, keys, candidateMappings, "aux-ander")); PointsTo::MappingPtr reverseNodeMapping = std::make_shared>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping)); @@ -838,8 +794,8 @@ void FlowSensitive::cluster(void) void FlowSensitive::plainMap(void) const { - assert(Options::NodeAllocStrat() == NodeIDAllocator::Strategy::DENSE - && "FS::cluster: plain mapping requires dense allocation strategy."); + assert(Options::NodeAllocStrat() == NodeIDAllocator::Strategy::DENSE && + "FS::cluster: plain mapping requires dense allocation strategy."); const size_t numObjects = NodeIDAllocator::get()->getNumObjects(); PointsTo::MappingPtr plainMapping = std::make_shared>(numObjects); @@ -853,7 +809,7 @@ void FlowSensitive::plainMap(void) const PointsTo::setCurrentBestNodeMapping(plainMapping, reversePlainMapping); } -void FlowSensitive::countAliases(Set> cmp, unsigned *mayAliases, unsigned *noAliases) +void FlowSensitive::countAliases(Set> cmp, unsigned* mayAliases, unsigned* noAliases) { for (std::pair locPA : cmp) { @@ -878,5 +834,4 @@ void FlowSensitive::countAliases(Set> cmp, unsigned *m } } } - } diff --git a/svf/lib/WPA/FlowSensitiveStat.cpp b/svf/lib/WPA/FlowSensitiveStat.cpp index ef98c4190..bb176cb1c 100644 --- a/svf/lib/WPA/FlowSensitiveStat.cpp +++ b/svf/lib/WPA/FlowSensitiveStat.cpp @@ -49,7 +49,7 @@ void FlowSensitiveStat::clearStat() _MaxAddrTakenVarPts = 0; _TotalPtsSize = 0; - for (int i=IN; i<=OUT; i++) + for (int i = IN; i <= OUT; i++) { /// SVFG nodes _NumOfSVFGNodesHaveInOut[i] = 0; @@ -65,7 +65,8 @@ void FlowSensitiveStat::clearStat() _NumOfVarHaveINOUTPts[i] = 0; _NumOfVarHaveEmptyINOUTPts[i] = 0; _NumOfVarHaveINOUTPtsInFormalIn[i] = 0; - _NumOfVarHaveINOUTPtsInFormalOut[i] = 0;; + _NumOfVarHaveINOUTPtsInFormalOut[i] = 0; + ; _NumOfVarHaveINOUTPtsInActualIn[i] = 0; _NumOfVarHaveINOUTPtsInActualOut[i] = 0; _NumOfVarHaveINOUTPtsInLoad[i] = 0; @@ -106,14 +107,13 @@ void FlowSensitiveStat::performStat() { NodeID nodeId = nodeIt->first; PAGNode* pagNode = nodeIt->second; - if(SVFUtil::isa(pagNode)) + if (SVFUtil::isa(pagNode)) { - const MemObj * memObj = pag->getBaseObj(nodeId); + const MemObj* memObj = pag->getBaseObj(nodeId); SymID baseId = memObj->getId(); if (nodeSet.insert(baseId).second) { - if (memObj->isFieldInsensitive()) - fiObjNumber++; + if (memObj->isFieldInsensitive()) fiObjNumber++; else fsObjNumber++; } @@ -130,15 +130,14 @@ void FlowSensitiveStat::performStat() for (; svfgNodeIt != svfgNodeEit; ++svfgNodeIt) { SVFGNode* svfgNode = svfgNodeIt->second; - if (SVFUtil::isa(svfgNode)) - numOfCopy++; + if (SVFUtil::isa(svfgNode)) numOfCopy++; else if (SVFUtil::isa(svfgNode)) numOfStore++; } PTAStat::performStat(); - timeStatMap["TotalTime"] = (endTime - startTime)/TIMEINTERVAL; + timeStatMap["TotalTime"] = (endTime - startTime) / TIMEINTERVAL; timeStatMap["SolveTime"] = fspta->solveTime; timeStatMap["SCCTime"] = fspta->sccTime; timeStatMap["ProcessTime"] = fspta->processTime; @@ -241,8 +240,8 @@ void FlowSensitiveStat::performStat() timeStatMap["AvgTopLvlPtsSize"] = _AvgTopLvlPtsSize; PTNumStatMap["NumOfAddrTakenVar"] = _NumOfAddrTakeVar; - timeStatMap["AvgAddrTakenVarPts"] = (_NumOfAddrTakeVar == 0) ? - 0 : ((double)_AvgAddrTakenVarPtsSize / _NumOfAddrTakeVar); + timeStatMap["AvgAddrTakenVarPts"] = + (_NumOfAddrTakeVar == 0) ? 0 : ((double)_AvgAddrTakenVarPtsSize / _NumOfAddrTakeVar); PTNumStatMap["MaxAddrTakenVarPts"] = _MaxAddrTakenVarPts; timeStatMap["AvgINPtsSize"] = _AvgInOutPtsSize[IN]; @@ -261,8 +260,7 @@ void FlowSensitiveStat::performStat() PTNumStatMap["NumOfNodesInSCC"] = fspta->numOfNodesInSCC; PTNumStatMap["MaxSCCSize"] = fspta->maxSCCSize; PTNumStatMap["NumOfSCC"] = fspta->numOfSCC; - timeStatMap["AverageSCCSize"] = (fspta->numOfSCC == 0) ? 0 : - ((double)fspta->numOfNodesInSCC / fspta->numOfSCC); + timeStatMap["AverageSCCSize"] = (fspta->numOfSCC == 0) ? 0 : ((double)fspta->numOfNodesInSCC / fspta->numOfSCC); PTAStat::printStat("Flow-Sensitive Pointer Analysis Statistics"); } @@ -270,33 +268,32 @@ void FlowSensitiveStat::performStat() void FlowSensitiveStat::statNullPtr() { _NumOfNullPtr = 0; - for (SVFIR::iterator iter = fspta->getPAG()->begin(), eiter = fspta->getPAG()->end(); - iter != eiter; ++iter) + for (SVFIR::iterator iter = fspta->getPAG()->begin(), eiter = fspta->getPAG()->end(); iter != eiter; ++iter) { NodeID pagNodeId = iter->first; PAGNode* pagNode = iter->second; SVFStmt::SVFStmtSetTy& inComingStore = pagNode->getIncomingEdges(SVFStmt::Store); SVFStmt::SVFStmtSetTy& outGoingLoad = pagNode->getOutgoingEdges(SVFStmt::Load); - if (inComingStore.empty()==false || outGoingLoad.empty()==false) + if (inComingStore.empty() == false || outGoingLoad.empty() == false) { - ///TODO: change the condition here to fetch the points-to set + /// TODO: change the condition here to fetch the points-to set const PointsTo& pts = fspta->getPts(pagNodeId); - if(fspta->containBlackHoleNode(pts)) + if (fspta->containBlackHoleNode(pts)) { _NumOfConstantPtr++; } - if(fspta->containConstantNode(pts)) + if (fspta->containConstantNode(pts)) { _NumOfBlackholePtr++; } - if(pts.empty()) + if (pts.empty()) { std::string str; - std::stringstream rawstr(str); + std::stringstream rawstr(str); if (!SVFUtil::isa(pagNode) && !SVFUtil::isa(pagNode)) { // if a pointer is in dead function, we do not care - if(pagNode->getValue()->ptrInUncalledFunction() == false) + if (pagNode->getValue()->ptrInUncalledFunction() == false) { _NumOfNullPtr++; rawstr << "##Null Pointer : (NodeID " << pagNode->getId() @@ -332,29 +329,25 @@ void FlowSensitiveStat::statPtsSize() /// get points-to set size information for top-level pointers. u32_t totalValidTopLvlPointers = 0; u32_t topTopLvlPtsSize = 0; - for (SVFIR::iterator iter = fspta->getPAG()->begin(), eiter = fspta->getPAG()->end(); - iter != eiter; ++iter) + for (SVFIR::iterator iter = fspta->getPAG()->begin(), eiter = fspta->getPAG()->end(); iter != eiter; ++iter) { NodeID node = iter->first; - if (fspta->getPAG()->isValidTopLevelPtr(iter->second) == false) - continue; + if (fspta->getPAG()->isValidTopLevelPtr(iter->second) == false) continue; u32_t size = fspta->getPts(node).count(); totalValidTopLvlPointers++; - topTopLvlPtsSize+=size; + topTopLvlPtsSize += size; - if(size > _MaxPtsSize) _MaxPtsSize = size; + if (size > _MaxPtsSize) _MaxPtsSize = size; - if (size > _MaxTopLvlPtsSize) _MaxTopLvlPtsSize = size; + if (size > _MaxTopLvlPtsSize) _MaxTopLvlPtsSize = size; } - if (totalValidTopLvlPointers != 0) - _AvgTopLvlPtsSize = (double)topTopLvlPtsSize/totalValidTopLvlPointers; + if (totalValidTopLvlPointers != 0) _AvgTopLvlPtsSize = (double)topTopLvlPtsSize / totalValidTopLvlPointers; _TotalPtsSize += topTopLvlPtsSize; u32_t totalPointer = totalValidTopLvlPointers + _NumOfVarHaveINOUTPts[IN] + _NumOfVarHaveINOUTPts[OUT]; - if (totalPointer != 0) - _AvgPtsSize = (double) _TotalPtsSize / totalPointer; + if (totalPointer != 0) _AvgPtsSize = (double)_TotalPtsSize / totalPointer; } void FlowSensitiveStat::statInOutPtsSize(const DFInOutMap& data, ENUM_INOUT inOrOut) @@ -370,8 +363,7 @@ void FlowSensitiveStat::statInOutPtsSize(const DFInOutMap& data, ENUM_INOUT inOr const SVFGNode* node = fspta->svfg->getSVFGNode(it->first); // Count number of SVFG nodes have IN/OUT set. - if (SVFUtil::isa(node)) - _NumOfFormalInSVFGNodesHaveInOut[inOrOut]++; + if (SVFUtil::isa(node)) _NumOfFormalInSVFGNodesHaveInOut[inOrOut]++; else if (SVFUtil::isa(node)) _NumOfFormalOutSVFGNodesHaveInOut[inOrOut]++; else if (SVFUtil::isa(node)) @@ -401,13 +393,12 @@ void FlowSensitiveStat::statInOutPtsSize(const DFInOutMap& data, ENUM_INOUT inOr continue; } - u32_t ptsNum = ptsIt->second.count(); /// points-to target number + u32_t ptsNum = ptsIt->second.count(); /// points-to target number // Only node with non-empty points-to set are counted. _NumOfVarHaveINOUTPts[inOrOut]++; - if (SVFUtil::isa(node)) - _NumOfVarHaveINOUTPtsInFormalIn[inOrOut]++; + if (SVFUtil::isa(node)) _NumOfVarHaveINOUTPtsInFormalIn[inOrOut]++; else if (SVFUtil::isa(node)) _NumOfVarHaveINOUTPtsInFormalOut[inOrOut]++; else if (SVFUtil::isa(node)) @@ -425,8 +416,7 @@ void FlowSensitiveStat::statInOutPtsSize(const DFInOutMap& data, ENUM_INOUT inOr inOutPtsSize += ptsNum; - if (ptsNum > _MaxInOutPtsSize[inOrOut]) - _MaxInOutPtsSize[inOrOut] = ptsNum; + if (ptsNum > _MaxInOutPtsSize[inOrOut]) _MaxInOutPtsSize[inOrOut] = ptsNum; if (ptsNum > _MaxPtsSize) _MaxPtsSize = ptsNum; } @@ -441,23 +431,23 @@ void FlowSensitiveStat::statInOutPtsSize(const DFInOutMap& data, ENUM_INOUT inOr // l'-o->l, l''-o->l, ..., means there is a possibility of 1 IN PTS. // *p = q && { o } in pts_ander(p) means there is a possibility of 1 OUT PTS. // For OUTs at stores, we must also account for WU/SUs. - const SVFG *svfg = fspta->svfg; + const SVFG* svfg = fspta->svfg; for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it) { - const SVFGNode *sn = it->second; + const SVFGNode* sn = it->second; // Unique objects coming into s. NodeBS incomingObjects; - for (const SVFGEdge *e : sn->getInEdges()) + for (const SVFGEdge* e : sn->getInEdges()) { - const IndirectSVFGEdge *ie = SVFUtil::dyn_cast(e); + const IndirectSVFGEdge* ie = SVFUtil::dyn_cast(e); if (!ie) continue; for (NodeID o : ie->getPointsTo()) incomingObjects.set(o); } _PotentialNumOfVarHaveINOUTPts[IN] += incomingObjects.count(); - if (const StoreSVFGNode *store = SVFUtil::dyn_cast(sn)) + if (const StoreSVFGNode* store = SVFUtil::dyn_cast(sn)) { NodeID p = store->getPAGDstNodeID(); // Reuse incomingObjects; what's already in there will be propagated forwarded @@ -501,9 +491,6 @@ void FlowSensitiveStat::calculateAddrVarPts(NodeID pointer, const SVFGNode* svfg const PointsTo& cpts = fspta->getDFOutPtsSet(svfg_node, ptd); _AvgAddrTakenVarPtsSize += cpts.count(); - if (cpts.count() > _MaxAddrTakenVarPts) - _MaxAddrTakenVarPts = cpts.count(); + if (cpts.count() > _MaxAddrTakenVarPts) _MaxAddrTakenVarPts = cpts.count(); } } - - diff --git a/svf/lib/WPA/Steensgaard.cpp b/svf/lib/WPA/Steensgaard.cpp index fd4d4336f..fe09f9ba9 100644 --- a/svf/lib/WPA/Steensgaard.cpp +++ b/svf/lib/WPA/Steensgaard.cpp @@ -94,8 +94,7 @@ void Steensgaard::setEC(NodeID node, NodeID rep) /// merge node into equiv class and merge node's pts into ec's pts void Steensgaard::ecUnion(NodeID node, NodeID ec) { - if (unionPts(ec, node)) - pushIntoWorklist(ec); + if (unionPts(ec, node)) pushIntoWorklist(ec); setEC(node, ec); } @@ -104,22 +103,18 @@ void Steensgaard::ecUnion(NodeID node, NodeID ec) */ void Steensgaard::processAllAddr() { - for (ConstraintGraph::const_iterator nodeIt = consCG->begin(), - nodeEit = consCG->end(); - nodeIt != nodeEit; nodeIt++) + for (ConstraintGraph::const_iterator nodeIt = consCG->begin(), nodeEit = consCG->end(); nodeIt != nodeEit; nodeIt++) { ConstraintNode* cgNode = nodeIt->second; - for (ConstraintNode::const_iterator it = cgNode->incomingAddrsBegin(), - eit = cgNode->incomingAddrsEnd(); - it != eit; ++it) + for (ConstraintNode::const_iterator it = cgNode->incomingAddrsBegin(), eit = cgNode->incomingAddrsEnd(); + it != eit; ++it) { numOfProcessedAddr++; const AddrCGEdge* addr = cast(*it); NodeID dst = addr->getDstID(); NodeID src = addr->getSrcID(); - if (addPts(dst, src)) - pushIntoWorklist(dst); + if (addPts(dst, src)) pushIntoWorklist(dst); } } } @@ -132,20 +127,15 @@ bool Steensgaard::updateCallGraph(const CallSiteToFunPtrMap& callsites) CallEdgeMap newEdges; onTheFlyCallGraphSolve(callsites, newEdges); NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge - for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); - it != eit; ++it) + for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it != eit; ++it) { CallSite cs = SVFUtil::getSVFCallSite(it->first->getCallSite()); - for (FunctionSet::iterator cit = it->second.begin(), - ecit = it->second.end(); - cit != ecit; ++cit) + for (FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit != ecit; ++cit) { connectCaller2CalleeParams(cs, *cit, cpySrcNodes); } } - for (NodePairSet::iterator it = cpySrcNodes.begin(), - eit = cpySrcNodes.end(); - it != eit; ++it) + for (NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it != eit; ++it) { pushIntoWorklist(it->first); } @@ -159,8 +149,7 @@ bool Steensgaard::updateCallGraph(const CallSiteToFunPtrMap& callsites) void Steensgaard::heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes) { assert(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?"); - RetICFGNode* retBlockNode = - pag->getICFG()->getRetICFGNode(cs.getInstruction()); + RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs.getInstruction()); const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode); NodeID srcret; CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs); @@ -180,29 +169,23 @@ void Steensgaard::heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes) } NodeID dstrec = getEC(cs_return->getId()); - if (addCopyEdge(srcret, dstrec)) - cpySrcNodes.insert(std::make_pair(srcret, dstrec)); + if (addCopyEdge(srcret, dstrec)) cpySrcNodes.insert(std::make_pair(srcret, dstrec)); } /*! * Connect formal and actual parameters for indirect callsites */ -void Steensgaard::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, - NodePairSet& cpySrcNodes) +void Steensgaard::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet& cpySrcNodes) { assert(F); - DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " - << cs.getInstruction()->toString() << " to callee " - << *F << "\n"); + DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() + << " to callee " << *F << "\n"); - CallICFGNode* callBlockNode = - pag->getICFG()->getCallICFGNode(cs.getInstruction()); - RetICFGNode* retBlockNode = - pag->getICFG()->getRetICFGNode(cs.getInstruction()); + CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(cs.getInstruction()); + RetICFGNode* retBlockNode = pag->getICFG()->getRetICFGNode(cs.getInstruction()); - if (SVFUtil::isHeapAllocExtFunViaRet(F) && - pag->callsiteHasRet(retBlockNode)) + if (SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode)) { heapAllocatorViaIndCall(cs, cpySrcNodes); } @@ -230,15 +213,12 @@ void Steensgaard::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, { // connect actual and formal param - const SVFIR::SVFVarList& csArgList = - pag->getCallSiteArgsList(callBlockNode); + const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode); const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(F); // Go through the fixed parameters. DBOUT(DPAGBuild, outs() << " args:"); - SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), - funArgEit = funArgList.end(); - SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), - csArgEit = csArgList.end(); + SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end(); + SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end(); for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt) { // Some programs (e.g. Linux kernel) leave unneeded parameters @@ -253,8 +233,7 @@ void Steensgaard::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, if (cs_arg->isPointer() && fun_arg->isPointer()) { - DBOUT(DAndersen, outs() << "process actual parm " - << cs_arg->toString() << " \n"); + DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n"); NodeID srcAA = getEC(cs_arg->getId()); NodeID dstFA = getEC(fun_arg->getId()); if (addCopyEdge(srcAA, dstFA)) diff --git a/svf/lib/WPA/TypeAnalysis.cpp b/svf/lib/WPA/TypeAnalysis.cpp index e19235164..d40776d69 100644 --- a/svf/lib/WPA/TypeAnalysis.cpp +++ b/svf/lib/WPA/TypeAnalysis.cpp @@ -38,7 +38,6 @@ using namespace SVF; using namespace SVFUtil; using namespace std; - /// Initialize analysis void TypeAnalysis::initialize() { @@ -60,8 +59,7 @@ void TypeAnalysis::initialize() void TypeAnalysis::finalize() { AndersenBase::finalize(); - if (print_stat) - dumpCHAStats(); + if (print_stat) dumpCHAStats(); } void TypeAnalysis::analyze() @@ -74,7 +72,7 @@ void TypeAnalysis::analyze() void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites, CallEdgeMap& newEdges) { - for(CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter!=eiter; ++iter) + for (CallSiteToFunPtrMap::const_iterator iter = callsites.begin(), eiter = callsites.end(); iter != eiter; ++iter) { const CallICFGNode* cbn = iter->first; CallSite cs = SVFUtil::getSVFCallSite(cbn->getCallSite()); @@ -90,28 +88,23 @@ void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites } } - void TypeAnalysis::dumpCHAStats() { - const CHGraph *chgraph = SVFUtil::dyn_cast(getCHGraph()); + const CHGraph* chgraph = SVFUtil::dyn_cast(getCHGraph()); if (chgraph == nullptr) { SVFUtil::errs() << "dumpCHAStats only implemented for standard CHGraph.\n"; return; } - u32_t pure_abstract_class_num = 0, - multi_inheritance_class_num = 0; - for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end(); - it != eit; ++it) + u32_t pure_abstract_class_num = 0, multi_inheritance_class_num = 0; + for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end(); it != eit; ++it) { - CHNode *node = it->second; + CHNode* node = it->second; outs() << "class " << node->getName() << "\n"; - if (node->isPureAbstract()) - pure_abstract_class_num++; - if (node->isMultiInheritance()) - multi_inheritance_class_num++; + if (node->isPureAbstract()) pure_abstract_class_num++; + if (node->isMultiInheritance()) multi_inheritance_class_num++; } outs() << "class_num:\t" << chgraph->getTotalNodeNum() << '\n'; outs() << "pure_abstract_class_num:\t" << pure_abstract_class_num << '\n'; @@ -124,26 +117,20 @@ void TypeAnalysis::dumpCHAStats() * vtbl max vfunction * pure abstract class */ - u32_t vtblnum = 0, - vfunc_total = 0, - vtbl_max = 0, - pure_abstract = 0; + u32_t vtblnum = 0, vfunc_total = 0, vtbl_max = 0, pure_abstract = 0; set allVirtualFunctions; - for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end(); - it != eit; ++it) + for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end(); it != eit; ++it) { - CHNode *node = it->second; - if (node->isPureAbstract()) - pure_abstract++; + CHNode* node = it->second; + if (node->isPureAbstract()) pure_abstract++; u32_t vfuncs_size = 0; const vector& vecs = node->getVirtualFunctionVectors(); - for (vector::const_iterator vit = vecs.begin(), - veit = vecs.end(); vit != veit; ++vit) + for (vector::const_iterator vit = vecs.begin(), veit = vecs.end(); vit != veit; ++vit) { vfuncs_size += (*vit).size(); - for (vector::const_iterator fit = (*vit).begin(), - feit = (*vit).end(); fit != feit; ++fit) + for (vector::const_iterator fit = (*vit).begin(), feit = (*vit).end(); fit != feit; + ++fit) { const SVFFunction* func = *fit; allVirtualFunctions.insert(func); @@ -161,9 +148,7 @@ void TypeAnalysis::dumpCHAStats() vfunc_total = allVirtualFunctions.size(); outs() << "vtblnum:\t" << vtblnum << '\n'; - outs() << "vtbl_average:\t" << (double)(vfunc_total)/vtblnum << '\n'; + outs() << "vtbl_average:\t" << (double)(vfunc_total) / vtblnum << '\n'; outs() << "vtbl_max:\t" << vtbl_max << '\n'; outs() << "pure_abstract:\t" << pure_abstract << '\n'; } - - diff --git a/svf/lib/WPA/VersionedFlowSensitive.cpp b/svf/lib/WPA/VersionedFlowSensitive.cpp index 9b279442a..68e717562 100644 --- a/svf/lib/WPA/VersionedFlowSensitive.cpp +++ b/svf/lib/WPA/VersionedFlowSensitive.cpp @@ -19,7 +19,7 @@ using namespace SVF; const Version VersionedFlowSensitive::invalidVersion = 0; -VersionedFlowSensitive *VersionedFlowSensitive::vfspta = nullptr; +VersionedFlowSensitive* VersionedFlowSensitive::vfspta = nullptr; VersionedVar VersionedFlowSensitive::atKey(NodeID var, Version version) { @@ -27,8 +27,7 @@ VersionedVar VersionedFlowSensitive::atKey(NodeID var, Version version) return std::make_pair(var, version); } -VersionedFlowSensitive::VersionedFlowSensitive(SVFIR *_pag, PTATY type) - : FlowSensitive(_pag, type) +VersionedFlowSensitive::VersionedFlowSensitive(SVFIR* _pag, PTATY type) : FlowSensitive(_pag, type) { numPrelabeledNodes = numPrelabelVersions = 0; prelabelingTime = meldLabelingTime = versionPropTime = 0.0; @@ -76,9 +75,9 @@ void VersionedFlowSensitive::prelabel(void) for (SVFG::iterator it = svfg->begin(); it != svfg->end(); ++it) { NodeID l = it->first; - const SVFGNode *ln = it->second; + const SVFGNode* ln = it->second; - if (const StoreSVFGNode *stn = SVFUtil::dyn_cast(ln)) + if (const StoreSVFGNode* stn = SVFUtil::dyn_cast(ln)) { // l: *p = q. // If p points to o (Andersen's), l yields a new version for o. @@ -98,7 +97,7 @@ void VersionedFlowSensitive::prelabel(void) // move around nodes such that there can be an MRSVFGNode with no incoming or // outgoing edges which will be added at runtime. In essence, we can no // longer rely on the outgoing edges of a delta node when SVFGOPT is enabled. - const MRSVFGNode *mr = SVFUtil::dyn_cast(ln); + const MRSVFGNode* mr = SVFUtil::dyn_cast(ln); if (mr != nullptr) { for (const NodeID o : mr->getPointsTo()) @@ -129,7 +128,7 @@ void VersionedFlowSensitive::meldLabel(void) // TODO: preferably we cache both for ease and to avoid the dyn_cast/isa, but Andersen's points-to // sets are PointsTo and MR's sets are NodeBS, which are incompatible types. Maybe when we can // use std::option. - std::vector> prelabeledNodes; + std::vector> prelabeledNodes; // Fast query for the above. std::vector isPrelabeled(svfg->getTotalNodeNum(), false); while (!vWorklist.empty()) @@ -137,9 +136,9 @@ void VersionedFlowSensitive::meldLabel(void) const NodeID n = vWorklist.pop(); isPrelabeled[n] = true; - const SVFGNode *sn = svfg->getSVFGNode(n); - const PointsTo *nPts = nullptr; - if (const StoreSVFGNode *store = SVFUtil::dyn_cast(sn)) + const SVFGNode* sn = svfg->getSVFGNode(n); + const PointsTo* nPts = nullptr; + if (const StoreSVFGNode* store = SVFUtil::dyn_cast(sn)) { const NodeID p = store->getPAGDstNodeID(); nPts = &(this->ander->getPts(p)); @@ -157,10 +156,10 @@ void VersionedFlowSensitive::meldLabel(void) if (delta(n) || deltaSource(n) || isStore(n) || isLoad(n)) nodesWhichNeedVersions.push_back(n); } - std::mutex *versionMutexes = new std::mutex[nodesWhichNeedVersions.size()]; + std::mutex* versionMutexes = new std::mutex[nodesWhichNeedVersions.size()]; // Map of footprints to the canonical object "owning" the footprint. - Map, NodeID> footprintOwner; + Map, NodeID> footprintOwner; std::queue objectQueue; for (const NodeID o : prelabeledObjects) @@ -174,11 +173,9 @@ void VersionedFlowSensitive::meldLabel(void) std::mutex objectQueueMutex; std::mutex footprintOwnerMutex; - auto meldVersionWorker = [this, &footprintOwner, &objectQueue, - &objectQueueMutex, &footprintOwnerMutex, &versionMutexes, - &prelabeledNodes, &isPrelabeled, &nodesWhichNeedVersions] - (const unsigned thread) - { + auto meldVersionWorker = [this, &footprintOwner, &objectQueue, &objectQueueMutex, &footprintOwnerMutex, + &versionMutexes, &prelabeledNodes, &isPrelabeled, + &nodesWhichNeedVersions](const unsigned thread) { while (true) { NodeID o; @@ -193,16 +190,16 @@ void VersionedFlowSensitive::meldLabel(void) // 1. Compute the SCCs for the nodes on the graph overlay of o. // For starting nodes, we only need those which did prelabeling for o specifically. // TODO: maybe we should move this to prelabel with a map (o -> starting nodes). - std::vector osStartingNodes; - for (std::pair snPts : prelabeledNodes) + std::vector osStartingNodes; + for (std::pair snPts : prelabeledNodes) { - const SVFGNode *sn = snPts.first; - const PointsTo *pts = snPts.second; + const SVFGNode* sn = snPts.first; + const PointsTo* pts = snPts.second; if (pts != nullptr) { if (pts->test(o)) osStartingNodes.push_back(sn); } - else if (const MRSVFGNode *mr = SVFUtil::dyn_cast(sn)) + else if (const MRSVFGNode* mr = SVFUtil::dyn_cast(sn)) { if (mr->getPointsTo().test(o)) osStartingNodes.push_back(sn); } @@ -213,14 +210,14 @@ void VersionedFlowSensitive::meldLabel(void) } std::vector partOf; - std::vector footprint; + std::vector footprint; unsigned numSCCs = SCC::detectSCCs(this, this->svfg, o, osStartingNodes, partOf, footprint); // 2. Skip any further processing of a footprint we have seen before. { std::lock_guard guard(footprintOwnerMutex); - const Map, NodeID>::const_iterator canonOwner - = footprintOwner.find(footprint); + const Map, NodeID>::const_iterator canonOwner = + footprintOwner.find(footprint); if (canonOwner == footprintOwner.end()) { this->equivalentObject[o] = o; @@ -255,8 +252,8 @@ void VersionedFlowSensitive::meldLabel(void) // the starting nodes (incase such nodes have no edges). // TODO: should be able to do this better: too many redundant inserts. Set reachableNodes; - for (const SVFGNode *sn : osStartingNodes) reachableNodes.insert(sn->getId()); - for (const SVFGEdge *se : footprint) + for (const SVFGNode* sn : osStartingNodes) reachableNodes.insert(sn->getId()); + for (const SVFGEdge* se : footprint) { reachableNodes.insert(se->getSrcNode()->getId()); reachableNodes.insert(se->getDstNode()->getId()); @@ -267,7 +264,8 @@ void VersionedFlowSensitive::meldLabel(void) if (isPrelabeled[n]) { if (this->isStore(n)) storesYieldedMeldVersion[n].set(bit); - else sccToMeldVersion[partOf[n]].set(bit); + else + sccToMeldVersion[partOf[n]].set(bit); ++bit; } @@ -275,10 +273,7 @@ void VersionedFlowSensitive::meldLabel(void) } // Sort topologically so each nodes is only visited once. - auto cmp = [&partOf](const NodeID a, const NodeID b) - { - return partOf[a] > partOf[b]; - }; + auto cmp = [&partOf](const NodeID a, const NodeID b) { return partOf[a] > partOf[b]; }; std::sort(todoList.begin(), todoList.end(), cmp); // 4. a. Do meld versioning. @@ -294,7 +289,7 @@ void VersionedFlowSensitive::meldLabel(void) for (size_t i = 0; i < todoList.size(); ++i) { const NodeID n = todoList[i]; - const SVFGNode *sn = this->svfg->getSVFGNode(n); + const SVFGNode* sn = this->svfg->getSVFGNode(n); const bool nIsStore = this->isStore(n); int nSCC = partOf[n]; @@ -303,10 +298,10 @@ void VersionedFlowSensitive::meldLabel(void) // Given n -> m, the yielded version of n will be melded into m. // For stores, that is in storesYieldedMeldVersion, otherwise, consume == yield and // we can just use sccToMeldVersion. - const MeldVersion &nMV = nIsStore ? storesYieldedMeldVersion[n] : sccToMeldVersion[nSCC]; - for (const SVFGEdge *e : sn->getOutEdges()) + const MeldVersion& nMV = nIsStore ? storesYieldedMeldVersion[n] : sccToMeldVersion[nSCC]; + for (const SVFGEdge* e : sn->getOutEdges()) { - const IndirectSVFGEdge *ie = SVFUtil::dyn_cast(e); + const IndirectSVFGEdge* ie = SVFUtil::dyn_cast(e); if (!ie) continue; const NodeID m = ie->getDstNode()->getId(); @@ -336,7 +331,7 @@ void VersionedFlowSensitive::meldLabel(void) Version curVersion = 0; for (u32_t scc = 0; scc < sccToMeldVersion.size(); ++scc) { - const MeldVersion &mv = sccToMeldVersion[scc]; + const MeldVersion& mv = sccToMeldVersion[scc]; Map::const_iterator foundVersion = mvv.find(mv); Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second; sccToVersion[scc] = v; @@ -349,7 +344,7 @@ void VersionedFlowSensitive::meldLabel(void) for (auto const& nmv : storesYieldedMeldVersion) { const NodeID n = nmv.first; - const MeldVersion &mv = nmv.second; + const MeldVersion& mv = nmv.second; Map::const_iterator foundVersion = mvv.find(mv); Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second; @@ -361,17 +356,16 @@ void VersionedFlowSensitive::meldLabel(void) mvv.clear(); // 6. From SCC reliance, determine version reliances. - Map> &osVersionReliance = this->versionReliance.at(o); + Map>& osVersionReliance = this->versionReliance.at(o); for (u32_t scc = 0; scc < numSCCs; ++scc) { if (sccReliance[scc].empty()) continue; // Some consume relies on a yield. When it's a store, we need to pick whether to // use the consume or yield unlike when it is not because they are the same. - const Version version - = storeSCC[scc] != -1 ? storesYieldedVersion[storeSCC[scc]] : sccToVersion[scc]; + const Version version = storeSCC[scc] != -1 ? storesYieldedVersion[storeSCC[scc]] : sccToVersion[scc]; - std::vector &reliantVersions = osVersionReliance[version]; + std::vector& reliantVersions = osVersionReliance[version]; for (const int reliantSCC : sccReliance[scc]) { const Version reliantVersion = sccToVersion[reliantSCC]; @@ -386,11 +380,11 @@ void VersionedFlowSensitive::meldLabel(void) // 7. a. Save versions for nodes which need them. // b. Fill in stmtReliance. // TODO: maybe randomize iteration order for less contention? Needs profiling. - Map &osStmtReliance = this->stmtReliance.at(o); + Map& osStmtReliance = this->stmtReliance.at(o); for (size_t i = 0; i < nodesWhichNeedVersions.size(); ++i) { const NodeID n = nodesWhichNeedVersions[i]; - std::mutex &mutex = versionMutexes[i]; + std::mutex& mutex = versionMutexes[i]; const int scc = partOf[n]; if (scc == -1) continue; @@ -415,7 +409,7 @@ void VersionedFlowSensitive::meldLabel(void) std::vector workers; for (unsigned i = 0; i < Options::VersioningThreads(); ++i) workers.push_back(std::thread(meldVersionWorker, i)); - for (std::thread &worker : workers) worker.join(); + for (std::thread& worker : workers) worker.join(); delete[] versionMutexes; @@ -423,7 +417,7 @@ void VersionedFlowSensitive::meldLabel(void) meldLabelingTime = (end - start) / TIMEINTERVAL; } -bool VersionedFlowSensitive::meld(MeldVersion &mv1, const MeldVersion &mv2) +bool VersionedFlowSensitive::meld(MeldVersion& mv1, const MeldVersion& mv2) { // Meld operator is union of bit vectors. return mv1 |= mv2; @@ -448,7 +442,8 @@ void VersionedFlowSensitive::buildIsStoreLoadMaps(void) for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it) { if (SVFUtil::isa(it->second)) isStoreMap[it->first] = true; - else if (SVFUtil::isa(it->second)) isLoadMap[it->first] = true; + else if (SVFUtil::isa(it->second)) + isLoadMap[it->first] = true; } } @@ -469,19 +464,19 @@ void VersionedFlowSensitive::buildDeltaMaps(void) deltaMap.resize(svfg->getTotalNodeNum(), false); // Call block nodes corresponding to all delta nodes. - Set deltaCBNs; + Set deltaCBNs; for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it) { const NodeID l = it->first; - const SVFGNode *s = it->second; + const SVFGNode* s = it->second; // Cases: // * Function entry: can get new incoming indirect edges through ind. callsites. // * Callsite returns: can get new incoming indirect edges if the callsite is indirect. // * Otherwise: static. bool isDelta = false; - if (const SVFFunction *fn = svfg->isFunEntrySVFGNode(s)) + if (const SVFFunction* fn = svfg->isFunEntrySVFGNode(s)) { CallGraphEdge::CallInstSet callsites; /// use pre-analysis call graph to approximate all potential callsites @@ -491,10 +486,10 @@ void VersionedFlowSensitive::buildDeltaMaps(void) if (isDelta) { // TODO: could we use deltaCBNs in the call above, avoiding this loop? - for (const CallICFGNode *cbn : callsites) deltaCBNs.insert(cbn); + for (const CallICFGNode* cbn : callsites) deltaCBNs.insert(cbn); } } - else if (const CallICFGNode *cbn = svfg->isCallSiteRetSVFGNode(s)) + else if (const CallICFGNode* cbn = svfg->isCallSiteRetSVFGNode(s)) { isDelta = cbn->isIndirectCall(); if (isDelta) deltaCBNs.insert(cbn); @@ -508,9 +503,9 @@ void VersionedFlowSensitive::buildDeltaMaps(void) for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it) { const NodeID l = it->first; - const SVFGNode *s = it->second; + const SVFGNode* s = it->second; - if (const CallICFGNode *cbn = SVFUtil::dyn_cast(s->getICFGNode())) + if (const CallICFGNode* cbn = SVFUtil::dyn_cast(s->getICFGNode())) { if (deltaCBNs.find(cbn) != deltaCBNs.end()) deltaSourceMap[l] = true; } @@ -525,16 +520,16 @@ void VersionedFlowSensitive::removeAllIndirectSVFGEdges(void) { for (SVFG::iterator nodeIt = svfg->begin(); nodeIt != svfg->end(); ++nodeIt) { - SVFGNode *sn = nodeIt->second; + SVFGNode* sn = nodeIt->second; - const SVFGEdgeSetTy &inEdges = sn->getInEdges(); - std::vector toDeleteFromIn; - for (SVFGEdge *e : inEdges) + const SVFGEdgeSetTy& inEdges = sn->getInEdges(); + std::vector toDeleteFromIn; + for (SVFGEdge* e : inEdges) { if (SVFUtil::isa(e)) toDeleteFromIn.push_back(e); } - for (SVFGEdge *e : toDeleteFromIn) svfg->removeSVFGEdge(e); + for (SVFGEdge* e : toDeleteFromIn) svfg->removeSVFGEdge(e); // Only need to iterate over incoming edges for each node because edges // will be deleted from in/out through removeSVFGEdge. @@ -547,7 +542,7 @@ void VersionedFlowSensitive::propagateVersion(NodeID o, Version v) { double start = stat->getClk(); - const std::vector &reliantVersions = getReliantVersions(o, v); + const std::vector& reliantVersions = getReliantVersions(o, v); for (Version r : reliantVersions) { propagateVersion(o, v, r, false); @@ -557,7 +552,7 @@ void VersionedFlowSensitive::propagateVersion(NodeID o, Version v) versionPropTime += (end - start) / TIMEINTERVAL; } -void VersionedFlowSensitive::propagateVersion(const NodeID o, const Version v, const Version vp, bool time/*=true*/) +void VersionedFlowSensitive::propagateVersion(const NodeID o, const Version v, const Version vp, bool time /*=true*/) { double start = time ? stat->getClk() : 0.0; @@ -567,14 +562,15 @@ void VersionedFlowSensitive::propagateVersion(const NodeID o, const Version v, c { // o:vp has changed. // Add the dummy propagation node to tell the solver to propagate it later. - const DummyVersionPropSVFGNode *dvp = nullptr; + const DummyVersionPropSVFGNode* dvp = nullptr; VarToPropNodeMap::const_iterator dvpIt = versionedVarToPropNode.find(dstVar); if (dvpIt == versionedVarToPropNode.end()) { dvp = svfg->addDummyVersionPropSVFGNode(o, vp); versionedVarToPropNode[dstVar] = dvp; } - else dvp = dvpIt->second; + else + dvp = dvpIt->second; assert(dvp != nullptr && "VFS::propagateVersion: propagation dummy node not found?"); pushIntoWorklist(dvp->getId()); @@ -592,7 +588,7 @@ void VersionedFlowSensitive::processNode(NodeID n) SVFGNode* sn = svfg->getSVFGNode(n); // Handle DummyVersPropSVFGNode here so we don't have to override the long // processSVFGNode. We also don't call propagate based on its result. - if (const DummyVersionPropSVFGNode *dvp = SVFUtil::dyn_cast(sn)) + if (const DummyVersionPropSVFGNode* dvp = SVFUtil::dyn_cast(sn)) { propagateVersion(dvp->getObject(), dvp->getVersion()); } @@ -604,27 +600,27 @@ void VersionedFlowSensitive::processNode(NodeID n) void VersionedFlowSensitive::updateConnectedNodes(const SVFGEdgeSetTy& newEdges) { - for (const SVFGEdge *e : newEdges) + for (const SVFGEdge* e : newEdges) { - SVFGNode *dstNode = e->getDstNode(); + SVFGNode* dstNode = e->getDstNode(); NodeID src = e->getSrcNode()->getId(); NodeID dst = dstNode->getId(); - if (SVFUtil::isa(dstNode) - || SVFUtil::isa(dstNode) - || SVFUtil::isa(dstNode)) + if (SVFUtil::isa(dstNode) || SVFUtil::isa(dstNode) || + SVFUtil::isa(dstNode)) { pushIntoWorklist(dst); } else { - const IndirectSVFGEdge *ie = SVFUtil::dyn_cast(e); + const IndirectSVFGEdge* ie = SVFUtil::dyn_cast(e); assert(ie != nullptr && "VFS::updateConnectedNodes: given direct edge?"); assert(delta(dst) && "VFS::updateConnectedNodes: new edges should be to delta nodes!"); - assert(deltaSource(src) && "VFS::updateConnectedNodes: new indirect edges should be from delta source nodes!"); + assert(deltaSource(src) && + "VFS::updateConnectedNodes: new indirect edges should be from delta source nodes!"); - const NodeBS &ept = ie->getPointsTo(); + const NodeBS& ept = ie->getPointsTo(); // For every o, such that src --o--> dst, we need to set up reliance (and propagate). for (const NodeID o : ept) { @@ -633,8 +629,9 @@ void VersionedFlowSensitive::updateConnectedNodes(const SVFGEdgeSetTy& newEdges) Version dstC = getConsume(dst, o); if (dstC == invalidVersion) continue; - std::vector &versionsRelyingOnSrcY = getReliantVersions(o, srcY); - if (std::find(versionsRelyingOnSrcY.begin(), versionsRelyingOnSrcY.end(), dstC) == versionsRelyingOnSrcY.end()) + std::vector& versionsRelyingOnSrcY = getReliantVersions(o, srcY); + if (std::find(versionsRelyingOnSrcY.begin(), versionsRelyingOnSrcY.end(), dstC) == + versionsRelyingOnSrcY.end()) { versionsRelyingOnSrcY.push_back(dstC); propagateVersion(o, srcY, dstC); @@ -693,12 +690,12 @@ bool VersionedFlowSensitive::processLoad(const LoadSVFGNode* load) bool VersionedFlowSensitive::processStore(const StoreSVFGNode* store) { NodeID p = store->getPAGDstNodeID(); - const PointsTo &ppt = getPts(p); + const PointsTo& ppt = getPts(p); if (ppt.empty()) return false; NodeID q = store->getPAGSrcNodeID(); - const PointsTo &qpt = getPts(q); + const PointsTo& qpt = getPts(q); NodeID l = store->getId(); // l: *p = q @@ -735,11 +732,12 @@ bool VersionedFlowSensitive::processStore(const StoreSVFGNode* store) NodeID singleton = 0; bool isSU = isStrongUpdate(store, singleton); if (isSU) svfgHasSU.set(l); - else svfgHasSU.reset(l); + else + svfgHasSU.reset(l); // For all objects, perform pts(o:y) = pts(o:y) U pts(o:c) at loc, // except when a strong update is taking place. - for (const ObjToVersionMap::value_type &oc : consume[l]) + for (const ObjToVersionMap::value_type& oc : consume[l]) { const NodeID o = oc.first; const Version c = oc.second; @@ -789,20 +787,20 @@ void VersionedFlowSensitive::cluster(void) keys.push_back(std::make_pair(v, occ)); } - PointsTo::MappingPtr nodeMapping = - std::make_shared>(NodeIDAllocator::Clusterer::cluster(ander, keys, candidateMappings, "aux-ander")); + PointsTo::MappingPtr nodeMapping = std::make_shared>( + NodeIDAllocator::Clusterer::cluster(ander, keys, candidateMappings, "aux-ander")); PointsTo::MappingPtr reverseNodeMapping = std::make_shared>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping)); PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping); } -Version VersionedFlowSensitive::getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const +Version VersionedFlowSensitive::getVersion(const NodeID l, const NodeID o, const LocVersionMap& lvm) const { const Map::const_iterator canonObjectIt = equivalentObject.find(o); const NodeID op = canonObjectIt == equivalentObject.end() ? o : canonObjectIt->second; - const ObjToVersionMap &ovm = lvm[l]; + const ObjToVersionMap& ovm = lvm[l]; const ObjToVersionMap::const_iterator foundVersion = ovm.find(op); return foundVersion == ovm.end() ? invalidVersion : foundVersion->second; } @@ -816,12 +814,13 @@ Version VersionedFlowSensitive::getYield(const NodeID l, const NodeID o) const { // Non-store: consume == yield. if (isStore(l)) return getVersion(l, o, yield); - else return getVersion(l, o, consume); + else + return getVersion(l, o, consume); } -void VersionedFlowSensitive::setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm) +void VersionedFlowSensitive::setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap& lvm) { - ObjToVersionMap &ovm = lvm[l]; + ObjToVersionMap& ovm = lvm[l]; ovm[o] = v; } @@ -834,15 +833,16 @@ void VersionedFlowSensitive::setYield(const NodeID l, const NodeID o, const Vers { // Non-store: consume == yield. if (isStore(l)) setVersion(l, o, v, yield); - else setVersion(l, o, v, consume); + else + setVersion(l, o, v, consume); } -std::vector &VersionedFlowSensitive::getReliantVersions(const NodeID o, const Version v) +std::vector& VersionedFlowSensitive::getReliantVersions(const NodeID o, const Version v) { return versionReliance[o][v]; } -NodeBS &VersionedFlowSensitive::getStmtReliance(const NodeID o, const Version v) +NodeBS& VersionedFlowSensitive::getStmtReliance(const NodeID o, const Version v) { return stmtReliance[o][v]; } @@ -850,7 +850,7 @@ NodeBS &VersionedFlowSensitive::getStmtReliance(const NodeID o, const Version v) void VersionedFlowSensitive::dumpReliances(void) const { SVFUtil::outs() << "# Version reliances\n"; - for (const Map>>::value_type &ovrv : versionReliance) + for (const Map>>::value_type& ovrv : versionReliance) { NodeID o = ovrv.first; SVFUtil::outs() << " Object " << o << "\n"; @@ -876,17 +876,17 @@ void VersionedFlowSensitive::dumpReliances(void) const } SVFUtil::outs() << "# Statement reliances\n"; - for (const Map>::value_type &ovss : stmtReliance) + for (const Map>::value_type& ovss : stmtReliance) { NodeID o = ovss.first; SVFUtil::outs() << " Object " << o << "\n"; - for (const Map::value_type &vss : ovss.second) + for (const Map::value_type& vss : ovss.second) { Version v = vss.first; SVFUtil::outs() << " Version " << v << " is a reliance for statements: "; - const NodeBS &ss = vss.second; + const NodeBS& ss = vss.second; bool first = true; for (NodeID s : ss) { @@ -911,22 +911,20 @@ void VersionedFlowSensitive::dumpLocVersionMaps(void) const { const NodeID loc = it->first; bool locPrinted = false; - for (const LocVersionMap *lvm : - { - &consume, &yield - }) + for (const LocVersionMap* lvm : {&consume, &yield}) { if (lvm->at(loc).empty()) continue; if (!locPrinted) { - SVFUtil::outs() << " " << "SVFG node " << loc << "\n"; + SVFUtil::outs() << " " + << "SVFG node " << loc << "\n"; locPrinted = true; } SVFUtil::outs() << " " << (lvm == &consume ? "Consume " : "Yield ") << ": "; bool first = true; - for (const ObjToVersionMap::value_type &ov : lvm->at(loc)) + for (const ObjToVersionMap::value_type& ov : lvm->at(loc)) { const NodeID o = ov.first; const Version v = ov.second; @@ -937,10 +935,9 @@ void VersionedFlowSensitive::dumpLocVersionMaps(void) const SVFUtil::outs() << "\n"; } } - } -void VersionedFlowSensitive::dumpMeldVersion(MeldVersion &v) +void VersionedFlowSensitive::dumpMeldVersion(MeldVersion& v) { SVFUtil::outs() << "[ "; bool first = true; @@ -963,7 +960,7 @@ void VersionedFlowSensitive::readPtsFromFile(const std::string& filename) /// Initialization for the Solver initialize(); /// Load the pts from file - if(!filename.empty()) + if (!filename.empty()) { SVFUtil::outs() << "Loading versioned pointer analysis results from '" << filename << "'..."; @@ -971,9 +968,9 @@ void VersionedFlowSensitive::readPtsFromFile(const std::string& filename) if (!F.is_open()) { SVFUtil::outs() << " error opening file for reading!\n"; - return ; + return; } - readAndSetObjFieldSensitivity(F,"------"); + readAndSetObjFieldSensitivity(F, "------"); readVersionedAnalysisResultFromFile(F); @@ -981,7 +978,7 @@ void VersionedFlowSensitive::readPtsFromFile(const std::string& filename) readGepObjVarMapFromFile(F); - readAndSetObjFieldSensitivity(F,""); + readAndSetObjFieldSensitivity(F, ""); // Update callgraph updateCallGraph(pag->getIndirectCallsites()); @@ -998,10 +995,9 @@ void VersionedFlowSensitive::solveAndwritePtsToFile(const std::string& filename) { /// Initialization for the Solver initialize(); - if(!filename.empty()) - writeObjVarToFile(filename); + if (!filename.empty()) writeObjVarToFile(filename); solveConstraints(); - if(!filename.empty()) + if (!filename.empty()) { writeVersionedAnalysisResultToFile(filename); writeToFile(filename); @@ -1021,24 +1017,22 @@ void VersionedFlowSensitive::writeVersionedAnalysisResultToFile(const std::strin return; } - for (const VersionedFlowSensitive::LocVersionMap *lvm : - { - &this->consume, &this->yield - }) + for (const VersionedFlowSensitive::LocVersionMap* lvm : {&this->consume, &this->yield}) { - for (const VersionedFlowSensitive::ObjToVersionMap &lov : *lvm) + for (const VersionedFlowSensitive::ObjToVersionMap& lov : *lvm) { - for (const VersionedFlowSensitive::ObjToVersionMap::value_type &ov : lov) + for (const VersionedFlowSensitive::ObjToVersionMap::value_type& ov : lov) { const NodeID o = ov.first; const Version v = ov.second; if (vPtD->getPts(atKey(o, v)).empty()) continue; - f <<"[ " < { "; - const PointsTo &ovPts = vPtD->getPts(atKey(o, v)); + f << "[ " << o << " " << v << " ]" + << " -> { "; + const PointsTo& ovPts = vPtD->getPts(atKey(o, v)); if (!ovPts.empty()) { - for (NodeID n: ovPts) + for (NodeID n : ovPts) { f << n << " "; } @@ -1071,20 +1065,20 @@ void VersionedFlowSensitive::readVersionedAnalysisResultFromFile(std::ifstream& { // Parse a single line in the form of "[ var version ] -> { obj1 obj2 obj3 }" getline(F, line); - if (line == "---VERSIONED---") break; - std::string pair = line.substr(line.find("[ ")+1, line.find(" ]")); + if (line == "---VERSIONED---") break; + std::string pair = line.substr(line.find("[ ") + 1, line.find(" ]")); // Parse VersionKey std::istringstream ss(pair); NodeID nodeID; Version nodeVersion; - ss>> nodeID >> nodeVersion; - VersionedVar keyPair = atKey(nodeID,nodeVersion); + ss >> nodeID >> nodeVersion; + VersionedVar keyPair = atKey(nodeID, nodeVersion); // Parse Point-to set size_t pos = line.find(delimiter1); - if (pos == std::string::npos) break; - if (line.back() != '}') break; + if (pos == std::string::npos) break; + if (line.back() != '}') break; pos = pos + delimiter1.length(); size_t len = line.length() - pos - delimiter2.length(); std::string objs = line.substr(pos, len); @@ -1103,26 +1097,24 @@ void VersionedFlowSensitive::readVersionedAnalysisResultFromFile(std::ifstream& // union point-to reuslt vPtD->unionPts(keyPair, dstPts); } - } -unsigned VersionedFlowSensitive::SCC::detectSCCs(VersionedFlowSensitive *vfs, - const SVFG *svfg, const NodeID object, - const std::vector &startingNodes, - std::vector &partOf, - std::vector &footprint) +unsigned VersionedFlowSensitive::SCC::detectSCCs(VersionedFlowSensitive* vfs, const SVFG* svfg, const NodeID object, + const std::vector& startingNodes, + std::vector& partOf, + std::vector& footprint) { partOf.resize(svfg->getTotalNodeNum()); std::fill(partOf.begin(), partOf.end(), -1); footprint.clear(); - std::vector nodeData(svfg->getTotalNodeNum(), { -1, -1, false}); - std::stack stack; + std::vector nodeData(svfg->getTotalNodeNum(), {-1, -1, false}); + std::stack stack; int index = 0; int currentSCC = 0; - for (const SVFGNode *v : startingNodes) + for (const SVFGNode* v : startingNodes) { if (nodeData[v->getId()].index == -1) { @@ -1136,15 +1128,10 @@ unsigned VersionedFlowSensitive::SCC::detectSCCs(VersionedFlowSensitive *vfs, return currentSCC; } -void VersionedFlowSensitive::SCC::visit(VersionedFlowSensitive *vfs, - const NodeID object, - std::vector &partOf, - std::vector &footprint, - std::vector &nodeData, - std::stack &stack, - int &index, - int ¤tSCC, - const SVFGNode *v) +void VersionedFlowSensitive::SCC::visit(VersionedFlowSensitive* vfs, const NodeID object, std::vector& partOf, + std::vector& footprint, + std::vector& nodeData, std::stack& stack, int& index, + int& currentSCC, const SVFGNode* v) { const NodeID vId = v->getId(); @@ -1155,12 +1142,12 @@ void VersionedFlowSensitive::SCC::visit(VersionedFlowSensitive *vfs, stack.push(v); nodeData[vId].onStack = true; - for (const SVFGEdge *e : v->getOutEdges()) + for (const SVFGEdge* e : v->getOutEdges()) { - const IndirectSVFGEdge *ie = SVFUtil::dyn_cast(e); + const IndirectSVFGEdge* ie = SVFUtil::dyn_cast(e); if (!ie) continue; - const SVFGNode *w = ie->getDstNode(); + const SVFGNode* w = ie->getDstNode(); const NodeID wId = w->getId(); // If object is not part of the edge, there is no edge from v to w. @@ -1188,7 +1175,7 @@ void VersionedFlowSensitive::SCC::visit(VersionedFlowSensitive *vfs, if (nodeData[vId].lowlink == nodeData[vId].index) { - const SVFGNode *w = nullptr; + const SVFGNode* w = nullptr; do { w = stack.top(); @@ -1196,8 +1183,7 @@ void VersionedFlowSensitive::SCC::visit(VersionedFlowSensitive *vfs, const NodeID wId = w->getId(); nodeData[wId].onStack = false; partOf[wId] = currentSCC; - } - while (w != v); + } while (w != v); // For the next SCC. ++currentSCC; diff --git a/svf/lib/WPA/VersionedFlowSensitiveStat.cpp b/svf/lib/WPA/VersionedFlowSensitiveStat.cpp index 042652cd7..73f6d9ba7 100644 --- a/svf/lib/WPA/VersionedFlowSensitiveStat.cpp +++ b/svf/lib/WPA/VersionedFlowSensitiveStat.cpp @@ -17,19 +17,19 @@ using namespace SVFUtil; void VersionedFlowSensitiveStat::clearStat() { - _NumVersions = 0; - _MaxVersions = 0; + _NumVersions = 0; + _MaxVersions = 0; _NumNonEmptyVersions = 0; - _NumSingleVersion = 0; - _NumUsedVersions = 0; - _NumEmptyVersions = 0; - _MaxPtsSize = 0; - _MaxTopLvlPtsSize = 0; - _MaxVersionPtsSize = 0; - _TotalPtsSize = 0; - _AvgPtsSize = 0.0; - _AvgTopLvlPtsSize = 0.0; - _AvgVersionPtsSize = 0.0; + _NumSingleVersion = 0; + _NumUsedVersions = 0; + _NumEmptyVersions = 0; + _MaxPtsSize = 0; + _MaxTopLvlPtsSize = 0; + _MaxVersionPtsSize = 0; + _TotalPtsSize = 0; + _AvgPtsSize = 0.0; + _AvgTopLvlPtsSize = 0.0; + _AvgVersionPtsSize = 0.0; } void VersionedFlowSensitiveStat::performStat() @@ -41,7 +41,7 @@ void VersionedFlowSensitiveStat::performStat() clearStat(); - SVFIR *pag = vfspta->getPAG(); + SVFIR* pag = vfspta->getPAG(); versionStat(); ptsSizeStat(); @@ -55,12 +55,13 @@ void VersionedFlowSensitiveStat::performStat() PAGNode* pagNode = it->second; if (SVFUtil::isa(pagNode)) { - const MemObj *memObj = pag->getBaseObj(nodeId); + const MemObj* memObj = pag->getBaseObj(nodeId); SymID baseId = memObj->getId(); if (nodeSet.insert(baseId).second) { if (memObj->isFieldInsensitive()) fiObjNumber++; - else fsObjNumber++; + else + fsObjNumber++; } } } @@ -74,46 +75,47 @@ void VersionedFlowSensitiveStat::performStat() { SVFGNode* svfgNode = it->second; if (SVFUtil::isa(svfgNode)) numOfCopy++; - else if (SVFUtil::isa(svfgNode)) numOfStore++; + else if (SVFUtil::isa(svfgNode)) + numOfStore++; } PTAStat::performStat(); - timeStatMap["TotalTime"] = (endTime - startTime)/TIMEINTERVAL; - timeStatMap["SolveTime"] = vfspta->solveTime; - timeStatMap["SCCTime"] = vfspta->sccTime; - timeStatMap["ProcessTime"] = vfspta->processTime; - timeStatMap["PropagationTime"] = vfspta->propagationTime; - timeStatMap["DirectPropaTime"] = vfspta->directPropaTime; - timeStatMap["IndirectPropaTime"] = vfspta->indirectPropaTime; + timeStatMap["TotalTime"] = (endTime - startTime) / TIMEINTERVAL; + timeStatMap["SolveTime"] = vfspta->solveTime; + timeStatMap["SCCTime"] = vfspta->sccTime; + timeStatMap["ProcessTime"] = vfspta->processTime; + timeStatMap["PropagationTime"] = vfspta->propagationTime; + timeStatMap["DirectPropaTime"] = vfspta->directPropaTime; + timeStatMap["IndirectPropaTime"] = vfspta->indirectPropaTime; timeStatMap["Strong/WeakUpdTime"] = vfspta->updateTime; - timeStatMap["AddrTime"] = vfspta->addrTime; - timeStatMap["CopyTime"] = vfspta->copyTime; - timeStatMap["GepTime"] = vfspta->gepTime; - timeStatMap["LoadTime"] = vfspta->loadTime; - timeStatMap["StoreTime"] = vfspta->storeTime; - timeStatMap["UpdateCGTime"] = vfspta->updateCallGraphTime; - timeStatMap["PhiTime"] = vfspta->phiTime; - timeStatMap["meldLabelingTime"] = vfspta->meldLabelingTime; - timeStatMap["PrelabelingTime"] = vfspta->prelabelingTime; - timeStatMap["VersionPropTime"] = vfspta->versionPropTime; - - PTNumStatMap["TotalPointers"] = pag->getValueNodeNum() + pag->getFieldValNodeNum(); - PTNumStatMap["TotalObjects"] = pag->getObjectNodeNum() + pag->getFieldObjNodeNum(); - - PTNumStatMap["Pointers"] = pag->getValueNodeNum(); - PTNumStatMap["MemObjects"] = pag->getObjectNodeNum(); + timeStatMap["AddrTime"] = vfspta->addrTime; + timeStatMap["CopyTime"] = vfspta->copyTime; + timeStatMap["GepTime"] = vfspta->gepTime; + timeStatMap["LoadTime"] = vfspta->loadTime; + timeStatMap["StoreTime"] = vfspta->storeTime; + timeStatMap["UpdateCGTime"] = vfspta->updateCallGraphTime; + timeStatMap["PhiTime"] = vfspta->phiTime; + timeStatMap["meldLabelingTime"] = vfspta->meldLabelingTime; + timeStatMap["PrelabelingTime"] = vfspta->prelabelingTime; + timeStatMap["VersionPropTime"] = vfspta->versionPropTime; + + PTNumStatMap["TotalPointers"] = pag->getValueNodeNum() + pag->getFieldValNodeNum(); + PTNumStatMap["TotalObjects"] = pag->getObjectNodeNum() + pag->getFieldObjNodeNum(); + + PTNumStatMap["Pointers"] = pag->getValueNodeNum(); + PTNumStatMap["MemObjects"] = pag->getObjectNodeNum(); PTNumStatMap["DummyFieldPtrs"] = pag->getFieldValNodeNum(); - PTNumStatMap["FieldObjs"] = pag->getFieldObjNodeNum(); + PTNumStatMap["FieldObjs"] = pag->getFieldObjNodeNum(); - PTNumStatMap["TotalVersions"] = _NumVersions; + PTNumStatMap["TotalVersions"] = _NumVersions; PTNumStatMap["MaxVersionsForObj"] = _MaxVersions; PTNumStatMap["TotalNonEmptyVPts"] = _NumNonEmptyVersions; - PTNumStatMap["TotalEmptyVPts"] = _NumEmptyVersions; + PTNumStatMap["TotalEmptyVPts"] = _NumEmptyVersions; PTNumStatMap["TotalExistingVPts"] = _NumUsedVersions; - PTNumStatMap["TotalSingleVObjs"] = _NumSingleVersion; + PTNumStatMap["TotalSingleVObjs"] = _NumSingleVersion; - PTNumStatMap["CopysNum"] = numOfCopy; + PTNumStatMap["CopysNum"] = numOfCopy; PTNumStatMap["StoresNum"] = numOfStore; PTNumStatMap["SolveIterations"] = vfspta->numOfIteration; @@ -122,29 +124,28 @@ void VersionedFlowSensitiveStat::performStat() PTNumStatMap["StrongUpdates"] = vfspta->svfgHasSU.count(); - PTNumStatMap["MaxPtsSize"] = _MaxPtsSize; - PTNumStatMap["MaxTopLvlPtsSize"] = _MaxTopLvlPtsSize; + PTNumStatMap["MaxPtsSize"] = _MaxPtsSize; + PTNumStatMap["MaxTopLvlPtsSize"] = _MaxTopLvlPtsSize; PTNumStatMap["MaxVersionPtsSize"] = _MaxVersionPtsSize; - timeStatMap["AvgPtsSize"] = _AvgPtsSize; - timeStatMap["AvgTopLvlPtsSize"] = _AvgTopLvlPtsSize; + timeStatMap["AvgPtsSize"] = _AvgPtsSize; + timeStatMap["AvgTopLvlPtsSize"] = _AvgTopLvlPtsSize; timeStatMap["AvgVersionPtsSize"] = _AvgVersionPtsSize; - PTNumStatMap["ProcessedAddr"] = vfspta->numOfProcessedAddr; - PTNumStatMap["ProcessedCopy"] = vfspta->numOfProcessedCopy; - PTNumStatMap["ProcessedGep"] = vfspta->numOfProcessedGep; - PTNumStatMap["ProcessedLoad"] = vfspta->numOfProcessedLoad; - PTNumStatMap["ProcessedStore"] = vfspta->numOfProcessedStore; - PTNumStatMap["ProcessedPhi"] = vfspta->numOfProcessedPhi; - PTNumStatMap["ProcessedAParam"] = vfspta->numOfProcessedActualParam; - PTNumStatMap["ProcessedFRet"] = vfspta->numOfProcessedFormalRet; + PTNumStatMap["ProcessedAddr"] = vfspta->numOfProcessedAddr; + PTNumStatMap["ProcessedCopy"] = vfspta->numOfProcessedCopy; + PTNumStatMap["ProcessedGep"] = vfspta->numOfProcessedGep; + PTNumStatMap["ProcessedLoad"] = vfspta->numOfProcessedLoad; + PTNumStatMap["ProcessedStore"] = vfspta->numOfProcessedStore; + PTNumStatMap["ProcessedPhi"] = vfspta->numOfProcessedPhi; + PTNumStatMap["ProcessedAParam"] = vfspta->numOfProcessedActualParam; + PTNumStatMap["ProcessedFRet"] = vfspta->numOfProcessedFormalRet; PTNumStatMap["ProcessedMSSANode"] = vfspta->numOfProcessedMSSANode; PTNumStatMap["NumOfNodesInSCC"] = vfspta->numOfNodesInSCC; - PTNumStatMap["MaxSCCSize"] = vfspta->maxSCCSize; - PTNumStatMap["NumOfSCC"] = vfspta->numOfSCC; - timeStatMap["AverageSCCSize"] = (vfspta->numOfSCC == 0) ? 0 : - ((double)vfspta->numOfNodesInSCC / vfspta->numOfSCC); + PTNumStatMap["MaxSCCSize"] = vfspta->maxSCCSize; + PTNumStatMap["NumOfSCC"] = vfspta->numOfSCC; + timeStatMap["AverageSCCSize"] = (vfspta->numOfSCC == 0) ? 0 : ((double)vfspta->numOfNodesInSCC / vfspta->numOfSCC); PTAStat::printStat("Versioned Flow-Sensitive Pointer Analysis Statistics"); } @@ -156,14 +157,11 @@ void VersionedFlowSensitiveStat::versionStat(void) _MaxVersions = 0; u32_t totalVersionPtsSize = 0; - for (const VersionedFlowSensitive::LocVersionMap *lvm : - { - &vfspta->consume, &vfspta->yield - }) + for (const VersionedFlowSensitive::LocVersionMap* lvm : {&vfspta->consume, &vfspta->yield}) { - for (const VersionedFlowSensitive::ObjToVersionMap &lov : *lvm) + for (const VersionedFlowSensitive::ObjToVersionMap& lov : *lvm) { - for (const VersionedFlowSensitive::ObjToVersionMap::value_type &ov : lov) + for (const VersionedFlowSensitive::ObjToVersionMap::value_type& ov : lov) { const NodeID o = ov.first; const Version v = ov.second; @@ -175,9 +173,10 @@ void VersionedFlowSensitiveStat::versionStat(void) // exists; an emptiness check is *not* an existence check. if (vfspta->vPtD->getPts(vfspta->atKey(o, v)).empty()) continue; - const PointsTo &ovPts = vfspta->vPtD->getPts(vfspta->atKey(o, v)); + const PointsTo& ovPts = vfspta->vPtD->getPts(vfspta->atKey(o, v)); if (!ovPts.empty()) ++_NumNonEmptyVersions; - else ++_NumEmptyVersions; + else + ++_NumEmptyVersions; _TotalPtsSize += ovPts.count(); totalVersionPtsSize += ovPts.count(); @@ -210,7 +209,8 @@ void VersionedFlowSensitiveStat::ptsSizeStat() if (size > _MaxTopLvlPtsSize) _MaxTopLvlPtsSize = size; } - if (totalValidTopLvlPointers != 0) _AvgTopLvlPtsSize = (double)totalTopLvlPtsSize / (double)totalValidTopLvlPointers; + if (totalValidTopLvlPointers != 0) + _AvgTopLvlPtsSize = (double)totalTopLvlPtsSize / (double)totalValidTopLvlPointers; _TotalPtsSize += totalTopLvlPtsSize; diff --git a/svf/lib/WPA/WPAPass.cpp b/svf/lib/WPA/WPAPass.cpp index 7b3601e09..27c478abf 100644 --- a/svf/lib/WPA/WPAPass.cpp +++ b/svf/lib/WPA/WPAPass.cpp @@ -32,7 +32,6 @@ * */ - #include "Util/Options.h" #include "SVFIR/SVFModule.h" #include "MemoryModel/PointerAnalysisImpl.h" @@ -68,11 +67,10 @@ WPAPass::~WPAPass() */ void WPAPass::runOnModule(SVFIR* pag) { - for (u32_t i = 0; i<= PointerAnalysis::Default_PTA; i++) + for (u32_t i = 0; i <= PointerAnalysis::Default_PTA; i++) { PointerAnalysis::PTATY iPtaTy = static_cast(i); - if (Options::PASelected(iPtaTy)) - runPointerAnalysis(pag, i); + if (Options::PASelected(iPtaTy)) runPointerAnalysis(pag, i); } assert(!ptaVector.empty() && "No pointer analysis is specified.\n"); } @@ -120,14 +118,12 @@ void WPAPass::runPointerAnalysis(SVFIR* pag, u32_t kind) { SVFGBuilder memSSA(true); assert(SVFUtil::isa(_pta) && "supports only andersen/steensgaard for pre-computed SVFG"); - SVFG *svfg = memSSA.buildFullSVFG((BVDataPTAImpl*)_pta); + SVFG* svfg = memSSA.buildFullSVFG((BVDataPTAImpl*)_pta); /// support mod-ref queries only for -ander - if (Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA)) - _svfg = svfg; + if (Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA)) _svfg = svfg; } - if (Options::PrintAliases()) - PrintAliasPairs(_pta); + if (Options::PrintAliases()) PrintAliasPairs(_pta); } void WPAPass::PrintAliasPairs(PointerAnalysis* pta) @@ -140,16 +136,14 @@ void WPAPass::PrintAliasPairs(PointerAnalysis* pta) for (SVFIR::iterator rit = lit, erit = pag->end(); rit != erit; ++rit) { node2 = rit->second; - if(node1==node2) - continue; + if (node1 == node2) continue; const SVFFunction* fun1 = node1->getFunction(); const SVFFunction* fun2 = node2->getFunction(); AliasResult result = pta->alias(node1->getId(), node2->getId()); - SVFUtil::outs() << (result == AliasResult::NoAlias ? "NoAlias" : "MayAlias") - << " var" << node1->getId() << "[" << node1->getValueName() - << "@" << (fun1==nullptr?"":fun1->getName()) << "] --" - << " var" << node2->getId() << "[" << node2->getValueName() - << "@" << (fun2==nullptr?"":fun2->getName()) << "]\n"; + SVFUtil::outs() << (result == AliasResult::NoAlias ? "NoAlias" : "MayAlias") << " var" << node1->getId() + << "[" << node1->getValueName() << "@" << (fun1 == nullptr ? "" : fun1->getName()) << "] --" + << " var" << node2->getId() << "[" << node2->getValueName() << "@" + << (fun2 == nullptr ? "" : fun2->getName()) << "]\n"; } } } @@ -191,11 +185,9 @@ AliasResult WPAPass::alias(const SVFValue* V1, const SVFValue* V2) /// Return NoAlias if any PTA gives NoAlias result result = AliasResult::MayAlias; - for (PTAVector::const_iterator it = ptaVector.begin(), eit = ptaVector.end(); - it != eit; ++it) + for (PTAVector::const_iterator it = ptaVector.begin(), eit = ptaVector.end(); it != eit; ++it) { - if ((*it)->alias(V1, V2) == AliasResult::NoAlias) - result = AliasResult::NoAlias; + if ((*it)->alias(V1, V2) == AliasResult::NoAlias) result = AliasResult::NoAlias; } } else if (Options::AliasRule(Conservative)) @@ -203,11 +195,9 @@ AliasResult WPAPass::alias(const SVFValue* V1, const SVFValue* V2) /// Return MayAlias if any PTA gives MayAlias result result = AliasResult::NoAlias; - for (PTAVector::const_iterator it = ptaVector.begin(), eit = ptaVector.end(); - it != eit; ++it) + for (PTAVector::const_iterator it = ptaVector.begin(), eit = ptaVector.end(); it != eit; ++it) { - if ((*it)->alias(V1, V2) == AliasResult::MayAlias) - result = AliasResult::MayAlias; + if ((*it)->alias(V1, V2) == AliasResult::MayAlias) result = AliasResult::MayAlias; } } } @@ -220,7 +210,8 @@ AliasResult WPAPass::alias(const SVFValue* V1, const SVFValue* V2) */ ModRefInfo WPAPass::getModRefInfo(const CallSite callInst) { - assert(Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA) && Options::AnderSVFG() && "mod-ref query is only support with -ander and -svfg turned on"); + assert(Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA) && Options::AnderSVFG() && + "mod-ref query is only support with -ander and -svfg turned on"); ICFG* icfg = _svfg->getPAG()->getICFG(); const CallICFGNode* cbn = icfg->getCallICFGNode(callInst.getInstruction()); return _svfg->getMSSA()->getMRGenerator()->getModRefInfo(cbn); @@ -231,7 +222,8 @@ ModRefInfo WPAPass::getModRefInfo(const CallSite callInst) */ ModRefInfo WPAPass::getModRefInfo(const CallSite callInst, const SVFValue* V) { - assert(Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA) && Options::AnderSVFG() && "mod-ref query is only support with -ander and -svfg turned on"); + assert(Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA) && Options::AnderSVFG() && + "mod-ref query is only support with -ander and -svfg turned on"); ICFG* icfg = _svfg->getPAG()->getICFG(); const CallICFGNode* cbn = icfg->getCallICFGNode(callInst.getInstruction()); return _svfg->getMSSA()->getMRGenerator()->getModRefInfo(cbn, V); @@ -242,7 +234,8 @@ ModRefInfo WPAPass::getModRefInfo(const CallSite callInst, const SVFValue* V) */ ModRefInfo WPAPass::getModRefInfo(const CallSite callInst1, const CallSite callInst2) { - assert(Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA) && Options::AnderSVFG() && "mod-ref query is only support with -ander and -svfg turned on"); + assert(Options::PASelected(PointerAnalysis::AndersenWaveDiff_WPA) && Options::AnderSVFG() && + "mod-ref query is only support with -ander and -svfg turned on"); ICFG* icfg = _svfg->getPAG()->getICFG(); const CallICFGNode* cbn1 = icfg->getCallICFGNode(callInst1.getInstruction()); const CallICFGNode* cbn2 = icfg->getCallICFGNode(callInst2.getInstruction());