From 63b3c95c8c51318e8aa446a84b28989cbf642938 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Fri, 21 Aug 2026 14:35:35 +1000 Subject: [PATCH 1/7] restructure README.md --- README.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 44c7ee3f08..6a56580c99 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ * Modernize SVF's CMake (Contributed by [Johannes](https://github.com/Johanmyst)). * SVF now supports LLVM-13.0.0 (Thank [Shengjie Xu](https://github.com/xushengj) for his help!). * [Object clustering](https://github.com/SVF-tools/SVF/wiki/Object-Clustering) published in our [OOPSLA paper](https://yuleisui.github.io/publications/oopsla21.pdf) is now available in SVF + +
+Older news + * [Hash-Consed Points-To Sets](https://github.com/SVF-tools/SVF/wiki/Hash-Consed-Points-To-Sets) published in our [SAS paper](https://yuleisui.github.io/publications/sas21.pdf) is now available in SVF * Learning or teaching Software Analysis? Check out [SVF-Teaching](https://github.com/SVF-tools/SVF-Teaching)! * SVF now supports LLVM-12.0.0 (Thank [Xiyu Yang](https://github.com/sherlly/) for her help!). @@ -26,34 +30,33 @@ * SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). * SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) * SVF now supports analysis for C++ programs. -
-## Documentation +

-SVF is a static value-flow analysis tool for LLVM-based languages. SVF ([CC'16](https://yuleisui.github.io/publications/cc16.pdf)) is able to perform -* [AE](https://github.com/SVF-tools/SVF/tree/master/svf/include/AE) (abstract execution): cross-domain execution ([ICSE'24](https://yuleisui.github.io/publications/icse24a.pdf)), recursion analysis ([ECOOP'25](https://yuleisui.github.io/publications/ecoop25.pdf)) typestate analysis ([FSE'24](https://yuleisui.github.io/publications/fse24a.pdf)); -* [WPA](https://github.com/SVF-tools/SVF/tree/master/svf/include/WPA) (whole program analysis): field-sensitive ([SAS'19](https://yuleisui.github.io/publications/sas2019a.pdf)), flow-sensitive ([CGO'21](https://yuleisui.github.io/publications/cgo21.pdf), [OOPSLA'21](https://yuleisui.github.io/publications/oopsla21.pdf)) analysis; -* [DDA](https://github.com/SVF-tools/SVF/tree/master/svf/include/DDA) (demand-driven analysis): flow-sensitive, context-sensitive points-to analysis ([FSE'16](https://yuleisui.github.io/publications/fse16.pdf), [TSE'18](https://yuleisui.github.io/publications/tse18.pdf)); -* [MSSA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MSSA) (memory SSA form construction): memory regions, side-effects, SSA form ([JSS'18](https://yuleisui.github.io/publications/jss18.pdf)); -* [SABER](https://github.com/SVF-tools/SVF/tree/master/svf/include/SABER) (memory error checking): memory leaks and double-frees ([ISSTA'12](https://yuleisui.github.io/publications/issta12.pdf), [TSE'14](https://yuleisui.github.io/publications/tse14.pdf), [ICSE'18](https://yuleisui.github.io/publications/icse18a.pdf)); -* [MTA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) (analysis of multithreaded programs): value-flows for multithreaded programs ([CGO'16](https://yuleisui.github.io/publications/cgo16.pdf)); -* [CFL](https://github.com/SVF-tools/SVF/tree/master/svf/include/CFL) (context-free-reachability analysis): standard CFL solver, graph and grammar ([OOPSLA'22](https://yuleisui.github.io/publications/oopsla22.pdf), [PLDI'23](https://yuleisui.github.io/publications/pldi23.pdf)); -* [SVFIR](https://github.com/SVF-tools/SVF/tree/master/svf/include/SVFIR) and [MemoryModel](https://github.com/SVF-tools/SVF/tree/master/svf/include/MemoryModel) (SVFIR): SVFIR, memory abstraction and points-to data structure ([SAS'21](https://yuleisui.github.io/publications/sas21.pdf)); -* [Graphs](https://github.com/SVF-tools/SVF/tree/master/svf/include/Graphs): generating a variety of graphs, including call graph, ICFG, class hierarchy graph, constraint graph, value-flow graph for static analyses and code embedding ([OOPSLA'20](https://yuleisui.github.io/publications/oopsla20.pdf), [TOSEM'21](https://yuleisui.github.io/publications/tosem21.pdf)) - -

We release the SVF source code with the hope of benefiting the open-source community. You are kindly requested to acknowledge usage of the tool by referring to or citing relevant publications above.

- -SVF's doxygen document is available [here](https://svf-tools.github.io/SVF-doxygen/html). - -
+## Documentation | About SVF | Setup Guide | User Guide | Developer Guide | | ------------- |:-------------:| -----:|-----:| -| ![About](https://github.com/svf-tools/SVF/blob/master/docs/images/help.png?raw=true)| ![Setup](https://github.com/svf-tools/SVF/blob/master/docs/images/tools.png?raw=true) | ![User](https://github.com/svf-tools/SVF/blob/master/docs/images/users.png?raw=true) | ![Developer](https://github.com/svf-tools/SVF/blob/master/docs/images/database.png?raw=true) +| ![About](https://github.com/svf-tools/SVF/blob/master/docs/images/help.png?raw=true)| ![Setup](https://github.com/svf-tools/SVF/blob/master/docs/images/tools.png?raw=true) | ![User](https://github.com/svf-tools/SVF/blob/master/docs/images/users.png?raw=true) | ![Developer](https://github.com/svf-tools/SVF/blob/master/docs/images/database.png?raw=true) | Introducing SVF -- [what it does](https://github.com/svf-tools/SVF/wiki/About#what-is-svf) and [how we design it](https://github.com/svf-tools/SVF/wiki/SVF-Design#svf-design) | A step by step [setup guide](https://github.com/svf-tools/SVF/wiki/Setup-Guide#getting-started) to build SVF | Command-line options to [run SVF](https://github.com/svf-tools/SVF/wiki/User-Guide#quick-start), get [analysis outputs](https://github.com/svf-tools/SVF/wiki/User-Guide#analysis-outputs), and test SVF with [an example](https://github.com/svf-tools/SVF/wiki/Analyze-a-Simple-C-Program) or [PTABen](https://github.com/SVF-tools/PTABen) | Detailed [technical documentation](https://github.com/svf-tools/SVF/wiki/Technical-documentation) and how to [write your own analyses](https://github.com/svf-tools/SVF/wiki/Write-your-own-analysis-in-SVF) in SVF or [use SVF as a lib](https://github.com/SVF-tools/SVF-example) for your tool, and the [course](https://github.com/SVF-tools/Software-Security-Analysis) on SVF | +SVF's doxygen document is available [here](https://svf-tools.github.io/SVF-doxygen/html). +
+## Features + +SVF is a static value-flow analysis tool for LLVM-based languages. SVF ([CC'16](https://dl.acm.org/doi/10.1145/2892208.2892235)) is able to perform +* [AE](https://github.com/SVF-tools/SVF/tree/master/svf/include/AE) (abstract execution): cross-domain execution ([ICSE'24](https://dl.acm.org/doi/10.1145/3597503.3639220)), recursion analysis ([ECOOP'25](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2025.34)) typestate analysis ([FSE'24](https://dl.acm.org/doi/10.1145/3643749)); +* [WPA](https://github.com/SVF-tools/SVF/tree/master/svf/include/WPA) (whole program analysis): field-sensitive ([SAS'19](https://link.springer.com/chapter/10.1007/978-3-030-32304-2_3)), flow-sensitive ([CGO'21](https://ieeexplore.ieee.org/document/9370334), [OOPSLA'21](https://dl.acm.org/doi/10.1145/3485547)) analysis; +* [DDA](https://github.com/SVF-tools/SVF/tree/master/svf/include/DDA) (demand-driven analysis): flow-sensitive, context-sensitive points-to analysis ([FSE'16](https://dl.acm.org/doi/10.1145/2950290.2950296), [TSE'18](https://doi.org/10.1109/TSE.2018.2869336)); +* [MSSA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MSSA) (memory SSA form construction): memory regions, side-effects, SSA form ([JSS'18](https://doi.org/10.1016/j.jss.2018.09.038)); +* [SABER](https://github.com/SVF-tools/SVF/tree/master/svf/include/SABER) (memory error checking): memory leaks and double-frees ([ISSTA'12](https://dl.acm.org/doi/10.1145/2338965.2336784), [TSE'14](https://doi.org/10.1109/TSE.2014.2302311), [ICSE'18](https://dl.acm.org/doi/10.1145/3180155.3180178)); +* [MTA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) (analysis of multithreaded programs): value-flows for multithreaded programs ([CGO'16](https://dl.acm.org/doi/10.1145/2854038.2854043)); +* [CFL](https://github.com/SVF-tools/SVF/tree/master/svf/include/CFL) (context-free-reachability analysis): standard CFL solver, graph and grammar ([OOPSLA'22](https://dl.acm.org/doi/10.1145/3563343), [PLDI'23](https://dl.acm.org/doi/10.1145/3591233)); +* [SVFIR](https://github.com/SVF-tools/SVF/tree/master/svf/include/SVFIR) and [MemoryModel](https://github.com/SVF-tools/SVF/tree/master/svf/include/MemoryModel) (SVFIR): SVFIR, memory abstraction and points-to data structure ([SAS'21](https://link.springer.com/chapter/10.1007/978-3-030-88806-0_2)); +* [Graphs](https://github.com/SVF-tools/SVF/tree/master/svf/include/Graphs): generating a variety of graphs, including call graph, ICFG, class hierarchy graph, constraint graph, value-flow graph for static analyses and code embedding ([OOPSLA'20](https://dl.acm.org/doi/10.1145/3428301), [TOSEM'21](https://dl.acm.org/doi/10.1145/3436877)) +

We release the SVF source code with the hope of benefiting the open-source community. You are kindly requested to acknowledge usage of the tool by referring to or citing relevant publications above.

From 6617ffe2896685392b876852998efaf1de322fe7 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Fri, 21 Aug 2026 16:06:48 +1000 Subject: [PATCH 2/7] update README content --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6a56580c99..83bb80e37e 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,20 @@ ## News +* [On-demand program slicing](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) published in our [ISSTA paper](https://joelyyoung.github.io/pdf/issta26.pdf) is now available in SVF +* SVF now supports [LLVM-22](https://github.com/SVF-tools/SVF/pull/1876) (Contributed by [Giorgio](https://github.com/dg1474)). * SVF now supports [LLVM-21](https://github.com/SVF-tools/SVF/pull/1815) (Contributed by [cjsrxzdyzds](https://github.com/cjsrxzdyzds)). * SVF now supports new [build system](https://github.com/SVF-tools/SVF/pull/1703) (Thank [Johannes](https://github.com/Johanmyst) for his help!). * [SVF-Python](https://github.com/SVF-tools/SVF-Python) is now available, enabling developers to write static analyzers in Python by leveraging the SVF library (Contributed by [Jiawei Wang](https://github.com/bjjwwang)). * New course [Software Security Analysis](https://github.com/SVF-tools/Software-Security-Analysis) for learning code analysis and verification with SVF for fun and expertise! * SVF now supports LLVM-16.0.0 with opaque pointers (Contributed by [Xiao Cheng](https://github.com/jumormt)). * Modernize SVF's CMake (Contributed by [Johannes](https://github.com/Johanmyst)). -* SVF now supports LLVM-13.0.0 (Thank [Shengjie Xu](https://github.com/xushengj) for his help!). -* [Object clustering](https://github.com/SVF-tools/SVF/wiki/Object-Clustering) published in our [OOPSLA paper](https://yuleisui.github.io/publications/oopsla21.pdf) is now available in SVF
Older news +* SVF now supports LLVM-13.0.0 (Thank [Shengjie Xu](https://github.com/xushengj) for his help!). +* [Object clustering](https://github.com/SVF-tools/SVF/wiki/Object-Clustering) published in our [OOPSLA paper](https://yuleisui.github.io/publications/oopsla21.pdf) is now available in SVF * [Hash-Consed Points-To Sets](https://github.com/SVF-tools/SVF/wiki/Hash-Consed-Points-To-Sets) published in our [SAS paper](https://yuleisui.github.io/publications/sas21.pdf) is now available in SVF * Learning or teaching Software Analysis? Check out [SVF-Teaching](https://github.com/SVF-tools/SVF-Teaching)! * SVF now supports LLVM-12.0.0 (Thank [Xiyu Yang](https://github.com/sherlly/) for her help!). @@ -49,12 +51,12 @@ ## Features SVF is a static value-flow analysis tool for LLVM-based languages. SVF ([CC'16](https://dl.acm.org/doi/10.1145/2892208.2892235)) is able to perform -* [AE](https://github.com/SVF-tools/SVF/tree/master/svf/include/AE) (abstract execution): cross-domain execution ([ICSE'24](https://dl.acm.org/doi/10.1145/3597503.3639220)), recursion analysis ([ECOOP'25](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2025.34)) typestate analysis ([FSE'24](https://dl.acm.org/doi/10.1145/3643749)); +* [AE](https://github.com/SVF-tools/SVF/tree/master/svf/include/AE) (abstract execution): cross-domain execution ([ICSE'24](https://dl.acm.org/doi/10.1145/3597503.3639220)), selective widening ([OOPSLA'25](https://dl.acm.org/doi/10.1145/3763083)), recursion analysis ([ECOOP'25](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2025.34)), typestate analysis ([FSE'24](https://dl.acm.org/doi/10.1145/3643749)); * [WPA](https://github.com/SVF-tools/SVF/tree/master/svf/include/WPA) (whole program analysis): field-sensitive ([SAS'19](https://link.springer.com/chapter/10.1007/978-3-030-32304-2_3)), flow-sensitive ([CGO'21](https://ieeexplore.ieee.org/document/9370334), [OOPSLA'21](https://dl.acm.org/doi/10.1145/3485547)) analysis; * [DDA](https://github.com/SVF-tools/SVF/tree/master/svf/include/DDA) (demand-driven analysis): flow-sensitive, context-sensitive points-to analysis ([FSE'16](https://dl.acm.org/doi/10.1145/2950290.2950296), [TSE'18](https://doi.org/10.1109/TSE.2018.2869336)); * [MSSA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MSSA) (memory SSA form construction): memory regions, side-effects, SSA form ([JSS'18](https://doi.org/10.1016/j.jss.2018.09.038)); * [SABER](https://github.com/SVF-tools/SVF/tree/master/svf/include/SABER) (memory error checking): memory leaks and double-frees ([ISSTA'12](https://dl.acm.org/doi/10.1145/2338965.2336784), [TSE'14](https://doi.org/10.1109/TSE.2014.2302311), [ICSE'18](https://dl.acm.org/doi/10.1145/3180155.3180178)); -* [MTA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) (analysis of multithreaded programs): value-flows for multithreaded programs ([CGO'16](https://dl.acm.org/doi/10.1145/2854038.2854043)); +* [MTA](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) (analysis of multithreaded programs): value-flows for multithreaded programs ([CGO'16](https://dl.acm.org/doi/10.1145/2854038.2854043)), on-demand program slicing ([ISSTA'26](https://joelyyoung.github.io/pdf/issta26.pdf)); * [CFL](https://github.com/SVF-tools/SVF/tree/master/svf/include/CFL) (context-free-reachability analysis): standard CFL solver, graph and grammar ([OOPSLA'22](https://dl.acm.org/doi/10.1145/3563343), [PLDI'23](https://dl.acm.org/doi/10.1145/3591233)); * [SVFIR](https://github.com/SVF-tools/SVF/tree/master/svf/include/SVFIR) and [MemoryModel](https://github.com/SVF-tools/SVF/tree/master/svf/include/MemoryModel) (SVFIR): SVFIR, memory abstraction and points-to data structure ([SAS'21](https://link.springer.com/chapter/10.1007/978-3-030-88806-0_2)); * [Graphs](https://github.com/SVF-tools/SVF/tree/master/svf/include/Graphs): generating a variety of graphs, including call graph, ICFG, class hierarchy graph, constraint graph, value-flow graph for static analyses and code embedding ([OOPSLA'20](https://dl.acm.org/doi/10.1145/3428301), [TOSEM'21](https://dl.acm.org/doi/10.1145/3436877)) From a9807c06a673f3b02f4ac89656d37c9e47d4825e Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Sat, 22 Aug 2026 14:49:12 +1000 Subject: [PATCH 3/7] Refine README structure --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 83bb80e37e..fe6a5c876e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ +SVF is a static value-flow analysis tool for LLVM-based languages. ## News * [On-demand program slicing](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) published in our [ISSTA paper](https://joelyyoung.github.io/pdf/issta26.pdf) is now available in SVF @@ -35,8 +36,6 @@
-
- ## Documentation | About SVF | Setup Guide | User Guide | Developer Guide | @@ -46,11 +45,9 @@ SVF's doxygen document is available [here](https://svf-tools.github.io/SVF-doxygen/html). -
- -## Features +## Features and Publications -SVF is a static value-flow analysis tool for LLVM-based languages. SVF ([CC'16](https://dl.acm.org/doi/10.1145/2892208.2892235)) is able to perform +SVF ([CC'16](https://dl.acm.org/doi/10.1145/2892208.2892235)) is able to perform * [AE](https://github.com/SVF-tools/SVF/tree/master/svf/include/AE) (abstract execution): cross-domain execution ([ICSE'24](https://dl.acm.org/doi/10.1145/3597503.3639220)), selective widening ([OOPSLA'25](https://dl.acm.org/doi/10.1145/3763083)), recursion analysis ([ECOOP'25](https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.ECOOP.2025.34)), typestate analysis ([FSE'24](https://dl.acm.org/doi/10.1145/3643749)); * [WPA](https://github.com/SVF-tools/SVF/tree/master/svf/include/WPA) (whole program analysis): field-sensitive ([SAS'19](https://link.springer.com/chapter/10.1007/978-3-030-32304-2_3)), flow-sensitive ([CGO'21](https://ieeexplore.ieee.org/document/9370334), [OOPSLA'21](https://dl.acm.org/doi/10.1145/3485547)) analysis; * [DDA](https://github.com/SVF-tools/SVF/tree/master/svf/include/DDA) (demand-driven analysis): flow-sensitive, context-sensitive points-to analysis ([FSE'16](https://dl.acm.org/doi/10.1145/2950290.2950296), [TSE'18](https://doi.org/10.1109/TSE.2018.2869336)); From f98988473b308f5e681b75725a79580d7e5aaf0f Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Sat, 22 Aug 2026 14:56:01 +1000 Subject: [PATCH 4/7] Refine README introduction --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe6a5c876e..d9a66f25aa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -SVF is a static value-flow analysis tool for LLVM-based languages. +SVF provides reusable abstractions, graphs, and solvers for analyzing LLVM IR. ## News * [On-demand program slicing](https://github.com/SVF-tools/SVF/tree/master/svf/include/MTA) published in our [ISSTA paper](https://joelyyoung.github.io/pdf/issta26.pdf) is now available in SVF From d4d6605a9c9c32db9bbd91c976fc47914793abee Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 24 Aug 2026 11:44:34 +1000 Subject: [PATCH 5/7] Apply SVF code formatting --- .../include/SVF-LLVM/GEPTypeBridgeIterator.h | 4 +- svf-llvm/lib/ObjTypeInference.cpp | 4 +- svf/include/AE/Core/NumericValue.h | 2 +- svf/include/Graphs/CDG.h | 2 +- svf/include/Graphs/SlicedGraphs.h | 532 ++++++++++++++---- svf/include/Graphs/ThreadCallGraph.h | 4 +- svf/include/Graphs/VFG.h | 2 +- svf/include/MTA/MTASVFGBuilder.h | 9 +- svf/include/MTA/MTASlicer.h | 6 +- svf/include/MTA/TCT.h | 2 +- svf/include/Util/SparseBitVector.h | 4 +- svf/lib/Graphs/SlicedGraphs.cpp | 54 +- svf/lib/MTA/FSMPTA.cpp | 14 +- svf/lib/MTA/LockAnalysis.cpp | 6 +- svf/lib/MTA/MHP.cpp | 34 +- svf/lib/MTA/MTA.cpp | 80 +-- svf/lib/MTA/MTASVFGBuilder.cpp | 38 +- svf/lib/MTA/MTASlicer.cpp | 20 +- 18 files changed, 582 insertions(+), 235 deletions(-) diff --git a/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h b/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h index 8ef79893f2..0997bf219b 100644 --- a/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h +++ b/svf-llvm/include/SVF-LLVM/GEPTypeBridgeIterator.h @@ -92,8 +92,8 @@ class generic_bridge_gep_type_iterator #endif } - // non-standard operators, these may not need be bridged but seems it's - // prudent to do so... +// non-standard operators, these may not need be bridged but seems it's +// prudent to do so... Type* operator->() const { return operator*(); diff --git a/svf-llvm/lib/ObjTypeInference.cpp b/svf-llvm/lib/ObjTypeInference.cpp index cf31988b48..6bbfeb0905 100644 --- a/svf-llvm/lib/ObjTypeInference.cpp +++ b/svf-llvm/lib/ObjTypeInference.cpp @@ -788,7 +788,7 @@ Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) for (const auto &name : extractClsNamesFromFunc(func)) names.insert(name); }; - // Lambda for getting callee & extracting class name for calls to constructors/destructors/template funcs +// Lambda for getting callee & extracting class name for calls to constructors/destructors/template funcs auto addNamesFromCall = [&names, &addNamesFromFunc](const CallBase *call) -> void { ABORT_IFNOT(isClsNameSource(call), "Call is invalid class name source: " + dumpValueAndDbgInfo(call)); @@ -798,7 +798,7 @@ Set &ObjTypeInference::inferThisPtrClsName(const Value *thisPtr) else addNamesFromFunc(func); }; - // Walk backwards to find all valid source sites for the pointer (e.g. stack/global/heap variables) +// Walk backwards to find all valid source sites for the pointer (e.g. stack/global/heap variables) for (const auto &val: bwFindAllocOrClsNameSources(thisPtr)) { // A source site is either a constructor/destructor/template function from which the class name can be diff --git a/svf/include/AE/Core/NumericValue.h b/svf/include/AE/Core/NumericValue.h index 98a96bed6d..d52df3b161 100644 --- a/svf/include/AE/Core/NumericValue.h +++ b/svf/include/AE/Core/NumericValue.h @@ -697,7 +697,7 @@ class BoundedInt return std::to_string(_iVal); } - //%} +//%} bool is_real() const { diff --git a/svf/include/Graphs/CDG.h b/svf/include/Graphs/CDG.h index d4c25dc7c0..772b2fde96 100644 --- a/svf/include/Graphs/CDG.h +++ b/svf/include/Graphs/CDG.h @@ -197,7 +197,7 @@ class CDG : public GenericCDGTy return getGNode(id); } - /// Whether has the CDGNode +/// Whether has the CDGNode inline bool hasCDGNode(NodeID id) const { return hasGNode(id); diff --git a/svf/include/Graphs/SlicedGraphs.h b/svf/include/Graphs/SlicedGraphs.h index 2c37f228d0..bd4fd501eb 100644 --- a/svf/include/Graphs/SlicedGraphs.h +++ b/svf/include/Graphs/SlicedGraphs.h @@ -395,13 +395,19 @@ struct SlicedNodeRef SlicedNodeRef() = default; SlicedNodeRef(const ViewT* v, const RawNodeT* r) : view(v), raw(r) {} - explicit operator bool() const { return raw != nullptr; } + explicit operator bool() const + { + return raw != nullptr; + } friend bool operator==(SlicedNodeRef lhs, SlicedNodeRef rhs) { return lhs.view == rhs.view && lhs.raw == rhs.raw; } - friend bool operator!=(SlicedNodeRef lhs, SlicedNodeRef rhs) { return !(lhs == rhs); } + friend bool operator!=(SlicedNodeRef lhs, SlicedNodeRef rhs) + { + return !(lhs == rhs); + } }; using SlicedICFGNodeRef = SlicedNodeRef; @@ -455,20 +461,41 @@ class SlicedICFGEdgeIterImpl return it; } - reference operator*() const { return cur; } - pointer operator->() const { return &cur; } + reference operator*() const + { + return cur; + } + pointer operator->() const + { + return &cur; + } // The node this edge traverses to (successor for Forward, predecessor for Inverse). - SlicedICFGNodeRef target() const { return Forward ? cur.dst : cur.src; } + SlicedICFGNodeRef target() const + { + return Forward ? cur.dst : cur.src; + } SlicedICFGEdgeIterImpl& operator++() { - if (realIt != realEnd) { ++realIt; skipNonKeptReal(); } - else if (brIt != brEnd) { ++brIt; } + if (realIt != realEnd) + { + ++realIt; + skipNonKeptReal(); + } + else if (brIt != brEnd) + { + ++brIt; + } refresh(); return *this; } - SlicedICFGEdgeIterImpl operator++(int) { SlicedICFGEdgeIterImpl t = *this; ++*this; return t; } + SlicedICFGEdgeIterImpl operator++(int) + { + SlicedICFGEdgeIterImpl t = *this; + ++*this; + return t; + } friend bool operator==(const SlicedICFGEdgeIterImpl& a, const SlicedICFGEdgeIterImpl& b) { @@ -517,7 +544,8 @@ class SlicedICFGEdgeIterImpl { SlicedICFGNodeRef self{view, src}, adj{view, *brIt}; cur = Forward ? SlicedICFGEdgeRef{self, adj, nullptr, true} - : SlicedICFGEdgeRef{adj, self, nullptr, true}; + : + SlicedICFGEdgeRef{adj, self, nullptr, true}; } else { @@ -541,11 +569,26 @@ class SlicedICFGChildIterImpl SlicedICFGChildIterImpl() = default; explicit SlicedICFGChildIterImpl(SlicedICFGEdgeIterImpl it) : e(it) {} - reference operator*() const { return e.target(); } - const SlicedICFGEdgeRef& currentEdge() const { return *e; } + reference operator*() const + { + return e.target(); + } + const SlicedICFGEdgeRef& currentEdge() const + { + return *e; + } - SlicedICFGChildIterImpl& operator++() { ++e; return *this; } - SlicedICFGChildIterImpl operator++(int) { SlicedICFGChildIterImpl t = *this; ++e; return t; } + SlicedICFGChildIterImpl& operator++() + { + ++e; + return *this; + } + SlicedICFGChildIterImpl operator++(int) + { + SlicedICFGChildIterImpl t = *this; + ++e; + return t; + } friend bool operator==(const SlicedICFGChildIterImpl& a, const SlicedICFGChildIterImpl& b) { @@ -574,9 +617,21 @@ class SlicedICFGNodeIter SlicedICFGNodeIter(const SlicedICFGView* v, OrderedSet::const_iterator i) : view(v), it(i) {} - reference operator*() const { return SlicedICFGNodeRef{view, *it}; } - SlicedICFGNodeIter& operator++() { ++it; return *this; } - SlicedICFGNodeIter operator++(int) { SlicedICFGNodeIter t = *this; ++it; return t; } + reference operator*() const + { + return SlicedICFGNodeRef{view, *it}; + } + SlicedICFGNodeIter& operator++() + { + ++it; + return *this; + } + SlicedICFGNodeIter operator++(int) + { + SlicedICFGNodeIter t = *this; + ++it; + return t; + } friend bool operator==(const SlicedICFGNodeIter& a, const SlicedICFGNodeIter& b) { @@ -639,23 +694,44 @@ class SlicedCGEdgeIterImpl return it; } - reference operator*() const { return cur; } - pointer operator->() const { return &cur; } - SlicedCallGraphNodeRef target() const { return Forward ? cur.dst : cur.src; } + reference operator*() const + { + return cur; + } + pointer operator->() const + { + return &cur; + } + SlicedCallGraphNodeRef target() const + { + return Forward ? cur.dst : cur.src; + } SlicedCGEdgeIterImpl& operator++() { - if (realIt != realEnd) { ++realIt; skipNonKept(); } + if (realIt != realEnd) + { + ++realIt; + skipNonKept(); + } refresh(); return *this; } - SlicedCGEdgeIterImpl operator++(int) { SlicedCGEdgeIterImpl t = *this; ++*this; return t; } + SlicedCGEdgeIterImpl operator++(int) + { + SlicedCGEdgeIterImpl t = *this; + ++*this; + return t; + } friend bool operator==(const SlicedCGEdgeIterImpl& a, const SlicedCGEdgeIterImpl& b) { return a.view == b.view && a.src == b.src && a.realIt == b.realIt; } - friend bool operator!=(const SlicedCGEdgeIterImpl& a, const SlicedCGEdgeIterImpl& b) { return !(a == b); } + friend bool operator!=(const SlicedCGEdgeIterImpl& a, const SlicedCGEdgeIterImpl& b) + { + return !(a == b); + } private: using EdgeIt = CallGraphNode::const_iterator; @@ -697,12 +773,33 @@ class SlicedCGChildIterImpl SlicedCGChildIterImpl() = default; explicit SlicedCGChildIterImpl(SlicedCGEdgeIterImpl it) : e(it) {} - reference operator*() const { return e.target(); } - const SlicedCallGraphEdgeRef& currentEdge() const { return *e; } - SlicedCGChildIterImpl& operator++() { ++e; return *this; } - SlicedCGChildIterImpl operator++(int) { SlicedCGChildIterImpl t = *this; ++e; return t; } - friend bool operator==(const SlicedCGChildIterImpl& a, const SlicedCGChildIterImpl& b) { return a.e == b.e; } - friend bool operator!=(const SlicedCGChildIterImpl& a, const SlicedCGChildIterImpl& b) { return !(a == b); } + reference operator*() const + { + return e.target(); + } + const SlicedCallGraphEdgeRef& currentEdge() const + { + return *e; + } + SlicedCGChildIterImpl& operator++() + { + ++e; + return *this; + } + SlicedCGChildIterImpl operator++(int) + { + SlicedCGChildIterImpl t = *this; + ++e; + return t; + } + friend bool operator==(const SlicedCGChildIterImpl& a, const SlicedCGChildIterImpl& b) + { + return a.e == b.e; + } + friend bool operator!=(const SlicedCGChildIterImpl& a, const SlicedCGChildIterImpl& b) + { + return !(a == b); + } private: SlicedCGEdgeIterImpl e{}; @@ -721,14 +818,29 @@ class SlicedCGNodeIter SlicedCGNodeIter(const SlicedThreadCallGraphView* v, OrderedSet::const_iterator i) : view(v), it(i) {} - reference operator*() const { return SlicedCallGraphNodeRef{view, *it}; } - SlicedCGNodeIter& operator++() { ++it; return *this; } - SlicedCGNodeIter operator++(int) { SlicedCGNodeIter t = *this; ++it; return t; } + reference operator*() const + { + return SlicedCallGraphNodeRef{view, *it}; + } + SlicedCGNodeIter& operator++() + { + ++it; + return *this; + } + SlicedCGNodeIter operator++(int) + { + SlicedCGNodeIter t = *this; + ++it; + return t; + } friend bool operator==(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b) { return a.view == b.view && a.it == b.it; } - friend bool operator!=(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b) { return !(a == b); } + friend bool operator!=(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b) + { + return !(a == b); + } private: const SlicedThreadCallGraphView* view = nullptr; @@ -782,23 +894,44 @@ class SlicedPAGEdgeIterImpl return it; } - reference operator*() const { return cur; } - pointer operator->() const { return &cur; } - SlicedPAGNodeRef target() const { return Forward ? cur.dst : cur.src; } + reference operator*() const + { + return cur; + } + pointer operator->() const + { + return &cur; + } + SlicedPAGNodeRef target() const + { + return Forward ? cur.dst : cur.src; + } SlicedPAGEdgeIterImpl& operator++() { - if (realIt != realEnd) { ++realIt; skipNonKept(); } + if (realIt != realEnd) + { + ++realIt; + skipNonKept(); + } refresh(); return *this; } - SlicedPAGEdgeIterImpl operator++(int) { SlicedPAGEdgeIterImpl t = *this; ++*this; return t; } + SlicedPAGEdgeIterImpl operator++(int) + { + SlicedPAGEdgeIterImpl t = *this; + ++*this; + return t; + } friend bool operator==(const SlicedPAGEdgeIterImpl& a, const SlicedPAGEdgeIterImpl& b) { return a.view == b.view && a.src == b.src && a.realIt == b.realIt; } - friend bool operator!=(const SlicedPAGEdgeIterImpl& a, const SlicedPAGEdgeIterImpl& b) { return !(a == b); } + friend bool operator!=(const SlicedPAGEdgeIterImpl& a, const SlicedPAGEdgeIterImpl& b) + { + return !(a == b); + } private: using EdgeIt = SVFVar::const_iterator; @@ -840,12 +973,33 @@ class SlicedPAGChildIterImpl SlicedPAGChildIterImpl() = default; explicit SlicedPAGChildIterImpl(SlicedPAGEdgeIterImpl it) : e(it) {} - reference operator*() const { return e.target(); } - const SlicedPAGEdgeRef& currentEdge() const { return *e; } - SlicedPAGChildIterImpl& operator++() { ++e; return *this; } - SlicedPAGChildIterImpl operator++(int) { SlicedPAGChildIterImpl t = *this; ++e; return t; } - friend bool operator==(const SlicedPAGChildIterImpl& a, const SlicedPAGChildIterImpl& b) { return a.e == b.e; } - friend bool operator!=(const SlicedPAGChildIterImpl& a, const SlicedPAGChildIterImpl& b) { return !(a == b); } + reference operator*() const + { + return e.target(); + } + const SlicedPAGEdgeRef& currentEdge() const + { + return *e; + } + SlicedPAGChildIterImpl& operator++() + { + ++e; + return *this; + } + SlicedPAGChildIterImpl operator++(int) + { + SlicedPAGChildIterImpl t = *this; + ++e; + return t; + } + friend bool operator==(const SlicedPAGChildIterImpl& a, const SlicedPAGChildIterImpl& b) + { + return a.e == b.e; + } + friend bool operator!=(const SlicedPAGChildIterImpl& a, const SlicedPAGChildIterImpl& b) + { + return !(a == b); + } private: SlicedPAGEdgeIterImpl e{}; @@ -869,13 +1023,25 @@ class SlicedPAGNodeIter { return SlicedPAGNodeRef{view, view->getSVFIR()->getGNode(*it)}; } - SlicedPAGNodeIter& operator++() { ++it; return *this; } - SlicedPAGNodeIter operator++(int) { SlicedPAGNodeIter t = *this; ++it; return t; } + SlicedPAGNodeIter& operator++() + { + ++it; + return *this; + } + SlicedPAGNodeIter operator++(int) + { + SlicedPAGNodeIter t = *this; + ++it; + return t; + } friend bool operator==(const SlicedPAGNodeIter& a, const SlicedPAGNodeIter& b) { return a.view == b.view && a.it == b.it; } - friend bool operator!=(const SlicedPAGNodeIter& a, const SlicedPAGNodeIter& b) { return !(a == b); } + friend bool operator!=(const SlicedPAGNodeIter& a, const SlicedPAGNodeIter& b) + { + return !(a == b); + } private: const SlicedPAGView* view = nullptr; @@ -928,23 +1094,44 @@ class SlicedSVFGEdgeIterImpl return it; } - reference operator*() const { return cur; } - pointer operator->() const { return &cur; } - SlicedSVFGNodeRef target() const { return Forward ? cur.dst : cur.src; } + reference operator*() const + { + return cur; + } + pointer operator->() const + { + return &cur; + } + SlicedSVFGNodeRef target() const + { + return Forward ? cur.dst : cur.src; + } SlicedSVFGEdgeIterImpl& operator++() { - if (realIt != realEnd) { ++realIt; skipNonKept(); } + if (realIt != realEnd) + { + ++realIt; + skipNonKept(); + } refresh(); return *this; } - SlicedSVFGEdgeIterImpl operator++(int) { SlicedSVFGEdgeIterImpl t = *this; ++*this; return t; } + SlicedSVFGEdgeIterImpl operator++(int) + { + SlicedSVFGEdgeIterImpl t = *this; + ++*this; + return t; + } friend bool operator==(const SlicedSVFGEdgeIterImpl& a, const SlicedSVFGEdgeIterImpl& b) { return a.view == b.view && a.src == b.src && a.realIt == b.realIt; } - friend bool operator!=(const SlicedSVFGEdgeIterImpl& a, const SlicedSVFGEdgeIterImpl& b) { return !(a == b); } + friend bool operator!=(const SlicedSVFGEdgeIterImpl& a, const SlicedSVFGEdgeIterImpl& b) + { + return !(a == b); + } private: using EdgeIt = SVFGNode::const_iterator; @@ -958,7 +1145,7 @@ class SlicedSVFGEdgeIterImpl void skipNonKept() { while (realIt != realEnd && - !view->isKeptNode(Forward ? (*realIt)->getDstNode() : (*realIt)->getSrcNode())) + !view->isKeptNode(Forward ? (*realIt)->getDstNode() : (*realIt)->getSrcNode())) ++realIt; } void refresh() @@ -988,12 +1175,33 @@ class SlicedSVFGChildIterImpl SlicedSVFGChildIterImpl() = default; explicit SlicedSVFGChildIterImpl(SlicedSVFGEdgeIterImpl it) : e(it) {} - reference operator*() const { return e.target(); } - const SlicedSVFGEdgeRef& currentEdge() const { return *e; } - SlicedSVFGChildIterImpl& operator++() { ++e; return *this; } - SlicedSVFGChildIterImpl operator++(int) { SlicedSVFGChildIterImpl t = *this; ++e; return t; } - friend bool operator==(const SlicedSVFGChildIterImpl& a, const SlicedSVFGChildIterImpl& b) { return a.e == b.e; } - friend bool operator!=(const SlicedSVFGChildIterImpl& a, const SlicedSVFGChildIterImpl& b) { return !(a == b); } + reference operator*() const + { + return e.target(); + } + const SlicedSVFGEdgeRef& currentEdge() const + { + return *e; + } + SlicedSVFGChildIterImpl& operator++() + { + ++e; + return *this; + } + SlicedSVFGChildIterImpl operator++(int) + { + SlicedSVFGChildIterImpl t = *this; + ++e; + return t; + } + friend bool operator==(const SlicedSVFGChildIterImpl& a, const SlicedSVFGChildIterImpl& b) + { + return a.e == b.e; + } + friend bool operator!=(const SlicedSVFGChildIterImpl& a, const SlicedSVFGChildIterImpl& b) + { + return !(a == b); + } private: SlicedSVFGEdgeIterImpl e{}; @@ -1016,14 +1224,30 @@ class SlicedSVFGNodeIter skipNonKept(); } - reference operator*() const { return SlicedSVFGNodeRef{view, it->second}; } - SlicedSVFGNodeIter& operator++() { ++it; skipNonKept(); return *this; } - SlicedSVFGNodeIter operator++(int) { SlicedSVFGNodeIter t = *this; ++*this; return t; } + reference operator*() const + { + return SlicedSVFGNodeRef{view, it->second}; + } + SlicedSVFGNodeIter& operator++() + { + ++it; + skipNonKept(); + return *this; + } + SlicedSVFGNodeIter operator++(int) + { + SlicedSVFGNodeIter t = *this; + ++*this; + return t; + } friend bool operator==(const SlicedSVFGNodeIter& a, const SlicedSVFGNodeIter& b) { return a.view == b.view && a.it == b.it; } - friend bool operator!=(const SlicedSVFGNodeIter& a, const SlicedSVFGNodeIter& b) { return !(a == b); } + friend bool operator!=(const SlicedSVFGNodeIter& a, const SlicedSVFGNodeIter& b) + { + return !(a == b); + } private: const SlicedSVFGView* view = nullptr; @@ -1055,7 +1279,10 @@ struct GenericGraphTraits // Escape hatch to the underlying node so graph-generic algorithms can reach // domain data (getFun/getSVFStmts) uniformly. Full-ICFG traits return the node. - static const ICFGNode* getRawNode(NodeRef n) { return n.raw; } + static const ICFGNode* getRawNode(NodeRef n) + { + return n.raw; + } // Graph-intrinsic queries mirroring GenericGraphTraits, so a // graph-parameterised analysis resolves the right behaviour from the type. @@ -1089,7 +1316,10 @@ struct GenericGraphTraits } //@} - static NodeRef getEntryNode(const SlicedICFGView*) { return NodeRef{}; } + static NodeRef getEntryNode(const SlicedICFGView*) + { + return NodeRef{}; + } static nodes_iterator nodes_begin(const SlicedICFGView* v) { @@ -1108,8 +1338,14 @@ struct GenericGraphTraits { return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw)); } - static ChildIteratorType direct_child_begin(NodeRef n) { return child_begin(n); } - static ChildIteratorType direct_child_end(NodeRef n) { return child_end(n); } + static ChildIteratorType direct_child_begin(NodeRef n) + { + return child_begin(n); + } + static ChildIteratorType direct_child_end(NodeRef n) + { + return child_end(n); + } static ChildEdgeIteratorType child_edge_begin(NodeRef n) { @@ -1120,13 +1356,19 @@ struct GenericGraphTraits return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.dst; } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.dst; + } static unsigned graphSize(const SlicedICFGView* v) { return static_cast(v->getKeptNodes().size()); } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } static NodeRef getNode(const SlicedICFGView* v, NodeID id) { const ICFGNode* raw = v->getOriginalICFG()->getGNode(id); @@ -1143,7 +1385,10 @@ struct GenericGraphTraits> using ChildIteratorType = SlicedICFGChildIterImpl; using ChildEdgeIteratorType = SlicedICFGEdgeIterImpl; - static NodeRef getEntryNode(Inverse) { return NodeRef{}; } + static NodeRef getEntryNode(Inverse) + { + return NodeRef{}; + } static ChildIteratorType child_begin(NodeRef n) { @@ -1164,8 +1409,14 @@ struct GenericGraphTraits> } // Inverse: the traversed "child" is the predecessor -> the edge source. - static NodeRef edge_dest(const EdgeRef& e) { return e.src; } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.src; + } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } }; // Forward traits for SlicedThreadCallGraphView. @@ -1178,7 +1429,10 @@ struct GenericGraphTraits using ChildIteratorType = SlicedCGChildIterImpl; using ChildEdgeIteratorType = SlicedCGEdgeIterImpl; - static const CallGraphNode* getRawNode(NodeRef n) { return n.raw; } + static const CallGraphNode* getRawNode(NodeRef n) + { + return n.raw; + } // Graph-intrinsic queries mirroring GenericGraphTraits. //@{ @@ -1230,7 +1484,10 @@ struct GenericGraphTraits } //@} - static NodeRef getEntryNode(const SlicedThreadCallGraphView*) { return NodeRef{}; } + static NodeRef getEntryNode(const SlicedThreadCallGraphView*) + { + return NodeRef{}; + } static nodes_iterator nodes_begin(const SlicedThreadCallGraphView* v) { @@ -1249,8 +1506,14 @@ struct GenericGraphTraits { return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw)); } - static ChildIteratorType direct_child_begin(NodeRef n) { return child_begin(n); } - static ChildIteratorType direct_child_end(NodeRef n) { return child_end(n); } + static ChildIteratorType direct_child_begin(NodeRef n) + { + return child_begin(n); + } + static ChildIteratorType direct_child_end(NodeRef n) + { + return child_end(n); + } static ChildEdgeIteratorType child_edge_begin(NodeRef n) { @@ -1261,13 +1524,19 @@ struct GenericGraphTraits return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.dst; } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.dst; + } static unsigned graphSize(const SlicedThreadCallGraphView* v) { return static_cast(v->getKeptNodes().size()); } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } static NodeRef getNode(const SlicedThreadCallGraphView* v, NodeID id) { const CallGraphNode* raw = v->getBackingCallGraph()->getGNode(id); @@ -1284,7 +1553,10 @@ struct GenericGraphTraits> using ChildIteratorType = SlicedCGChildIterImpl; using ChildEdgeIteratorType = SlicedCGEdgeIterImpl; - static NodeRef getEntryNode(Inverse) { return NodeRef{}; } + static NodeRef getEntryNode(Inverse) + { + return NodeRef{}; + } static ChildIteratorType child_begin(NodeRef n) { @@ -1303,8 +1575,14 @@ struct GenericGraphTraits> return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.src; } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.src; + } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } }; // Forward traits for SlicedPAGView. @@ -1317,9 +1595,15 @@ struct GenericGraphTraits using ChildIteratorType = SlicedPAGChildIterImpl; using ChildEdgeIteratorType = SlicedPAGEdgeIterImpl; - static const SVFVar* getRawNode(NodeRef n) { return n.raw; } + static const SVFVar* getRawNode(NodeRef n) + { + return n.raw; + } - static NodeRef getEntryNode(const SlicedPAGView*) { return NodeRef{}; } + static NodeRef getEntryNode(const SlicedPAGView*) + { + return NodeRef{}; + } static nodes_iterator nodes_begin(const SlicedPAGView* v) { @@ -1338,8 +1622,14 @@ struct GenericGraphTraits { return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw)); } - static ChildIteratorType direct_child_begin(NodeRef n) { return child_begin(n); } - static ChildIteratorType direct_child_end(NodeRef n) { return child_end(n); } + static ChildIteratorType direct_child_begin(NodeRef n) + { + return child_begin(n); + } + static ChildIteratorType direct_child_end(NodeRef n) + { + return child_end(n); + } static ChildEdgeIteratorType child_edge_begin(NodeRef n) { @@ -1350,13 +1640,19 @@ struct GenericGraphTraits return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.dst; } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.dst; + } static unsigned graphSize(const SlicedPAGView* v) { return static_cast(v->getKeptNodeIds().size()); } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } static NodeRef getNode(const SlicedPAGView* v, NodeID id) { const bool kept = v->getKeptNodeIds().count(id) > 0; @@ -1373,7 +1669,10 @@ struct GenericGraphTraits> using ChildIteratorType = SlicedPAGChildIterImpl; using ChildEdgeIteratorType = SlicedPAGEdgeIterImpl; - static NodeRef getEntryNode(Inverse) { return NodeRef{}; } + static NodeRef getEntryNode(Inverse) + { + return NodeRef{}; + } static ChildIteratorType child_begin(NodeRef n) { @@ -1392,8 +1691,14 @@ struct GenericGraphTraits> return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.src; } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.src; + } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } }; // Forward traits for SlicedSVFGView. @@ -1407,7 +1712,10 @@ struct GenericGraphTraits using ChildEdgeIteratorType = SlicedSVFGEdgeIterImpl; static constexpr bool isFilteredGraph = true; - static const SVFGNode* getRawNode(NodeRef n) { return n.raw; } + static const SVFGNode* getRawNode(NodeRef n) + { + return n.raw; + } /// Whether n is retained by this sliced SVFG (the solver's restriction test). static bool containsNode(const SlicedSVFGView* g, const SVFGNode* n) @@ -1420,7 +1728,10 @@ struct GenericGraphTraits return g->isKeptEdge(e); } - static NodeRef getEntryNode(const SlicedSVFGView*) { return NodeRef{}; } + static NodeRef getEntryNode(const SlicedSVFGView*) + { + return NodeRef{}; + } static nodes_iterator nodes_begin(const SlicedSVFGView* v) { @@ -1441,8 +1752,14 @@ struct GenericGraphTraits { return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw)); } - static ChildIteratorType direct_child_begin(NodeRef n) { return child_begin(n); } - static ChildIteratorType direct_child_end(NodeRef n) { return child_end(n); } + static ChildIteratorType direct_child_begin(NodeRef n) + { + return child_begin(n); + } + static ChildIteratorType direct_child_end(NodeRef n) + { + return child_end(n); + } static ChildEdgeIteratorType child_edge_begin(NodeRef n) { @@ -1453,8 +1770,14 @@ struct GenericGraphTraits return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.dst; } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.dst; + } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } static unsigned graphSize(const SlicedSVFGView* v) { return static_cast(v->getKeptNodeCount()); @@ -1476,7 +1799,10 @@ struct GenericGraphTraits> using ChildIteratorType = SlicedSVFGChildIterImpl; using ChildEdgeIteratorType = SlicedSVFGEdgeIterImpl; - static NodeRef getEntryNode(Inverse) { return NodeRef{}; } + static NodeRef getEntryNode(Inverse) + { + return NodeRef{}; + } static ChildIteratorType child_begin(NodeRef n) { @@ -1495,8 +1821,14 @@ struct GenericGraphTraits> return ChildEdgeIteratorType::end(n.view, n.raw); } - static NodeRef edge_dest(const EdgeRef& e) { return e.src; } - static inline unsigned getNodeID(NodeRef n) { return n.raw->getId(); } + static NodeRef edge_dest(const EdgeRef& e) + { + return e.src; + } + static inline unsigned getNodeID(NodeRef n) + { + return n.raw->getId(); + } }; } // End namespace SVF diff --git a/svf/include/Graphs/ThreadCallGraph.h b/svf/include/Graphs/ThreadCallGraph.h index 87d7af268e..ce44f2a4a3 100644 --- a/svf/include/Graphs/ThreadCallGraph.h +++ b/svf/include/Graphs/ThreadCallGraph.h @@ -423,7 +423,7 @@ struct GenericGraphTraits if (!graph->hasThreadForkEdge(callSite)) return; for (auto it = graph->getForkEdgeBegin(callSite), - end = graph->getForkEdgeEnd(callSite); it != end; ++it) + end = graph->getForkEdgeEnd(callSite); it != end; ++it) out.push_back(*it); } @@ -435,7 +435,7 @@ struct GenericGraphTraits if (!graph->hasThreadJoinEdge(callSite)) return; for (auto it = graph->getJoinEdgeBegin(callSite), - end = graph->getJoinEdgeEnd(callSite); it != end; ++it) + end = graph->getJoinEdgeEnd(callSite); it != end; ++it) out.push_back(*it); } }; diff --git a/svf/include/Graphs/VFG.h b/svf/include/Graphs/VFG.h index 10f8372442..90fc43b3f2 100644 --- a/svf/include/Graphs/VFG.h +++ b/svf/include/Graphs/VFG.h @@ -511,7 +511,7 @@ class VFG : public GenericVFGTy return true; } - /// Create edges between VFG nodes within a function +/// Create edges between VFG nodes within a function void connectDirectVFGEdges(); /// Create edges between VFG nodes across functions diff --git a/svf/include/MTA/MTASVFGBuilder.h b/svf/include/MTA/MTASVFGBuilder.h index 4026d51262..a1bc7a2bfe 100644 --- a/svf/include/MTA/MTASVFGBuilder.h +++ b/svf/include/MTA/MTASVFGBuilder.h @@ -86,7 +86,9 @@ class MTASVFGBuilder : public SVFGBuilder /// ICFG nodes are implicit in the key and consumers must add them back. using ThreadVFQueryMap = Map>; const ThreadVFQueryMap& getThreadVFQueryMap() const - { return threadVFQueryMap; } + { + return threadVFQueryMap; + } struct ThreadVFCandidate { @@ -152,7 +154,10 @@ class MTASVFGBuilder : public SVFGBuilder /// Remove all currently attached thread-aware interference edges. void clearThreadAwareOverlay(); - size_t getThreadAwareEdgeCount() const { return threadAwareEdges.size(); } + size_t getThreadAwareEdgeCount() const + { + return threadAwareEdges.size(); + } protected: /// Rewrite the SVFG build hook: build the stock SVFG, then add MHP edges. diff --git a/svf/include/MTA/MTASlicer.h b/svf/include/MTA/MTASlicer.h index a02458f12a..48194f0605 100644 --- a/svf/include/MTA/MTASlicer.h +++ b/svf/include/MTA/MTASlicer.h @@ -122,7 +122,7 @@ class MTASlicerBase { public: MTASlicerBase(SVFIR* svfir, AndersenBase* pta, MHP* mhp, - LockAnalysis* lockAnalysis, SVFG* svfg = nullptr); + LockAnalysis* lockAnalysis, SVFG* svfg = nullptr); protected: SVFIR* svfir; @@ -166,7 +166,7 @@ class MTASlicerBase * @return Pair of (pthreadCallNodes, mutexCallNodes) */ std::pair, OrderedSet> - collectCommonThreadStatements(const OrderedSet& sourceNodes); + collectCommonThreadStatements(const OrderedSet& sourceNodes); /// Add synchronization primitives and the control-flow anchors required by /// the sliced MHP/lock analyses. @@ -202,7 +202,7 @@ class MultiStageSlicer : public MTASlicerBase { public: MultiStageSlicer(SVFIR* svfir, AndersenBase* pta, MHP* mhp, - LockAnalysis* lockAnalysis, SVFG* svfg = nullptr); + LockAnalysis* lockAnalysis, SVFG* svfg = nullptr); /** * Stage 1: the ILA slice (synchronization + function expansion for the IRView). diff --git a/svf/include/MTA/TCT.h b/svf/include/MTA/TCT.h index 5e370c4591..5008d0bd32 100644 --- a/svf/include/MTA/TCT.h +++ b/svf/include/MTA/TCT.h @@ -555,7 +555,7 @@ class TCT: public GenericThreadCreateTreeTy /// treated like the null (main) case -- otherwise isInLoopInstruction would /// look up a call-graph node that does not exist. if(ct.getThread() != nullptr && - dummyForkSites.find(ct.getThread()) == dummyForkSites.end()) + dummyForkSites.find(ct.getThread()) == dummyForkSites.end()) { const ICFGNode* svfInst = ct.getThread(); ct.setInloop(isInLoopInstruction(svfInst)); diff --git a/svf/include/Util/SparseBitVector.h b/svf/include/Util/SparseBitVector.h index 3fea289961..05976338a9 100644 --- a/svf/include/Util/SparseBitVector.h +++ b/svf/include/Util/SparseBitVector.h @@ -1130,7 +1130,7 @@ class SparseBitVector return (First.index() * ElementSize) + First.find_first(); } - // Return the last set bit in the bitmap. Return -1 if no bits are set. +// Return the last set bit in the bitmap. Return -1 if no bits are set. int find_last() const { if (Elements.empty()) @@ -1139,7 +1139,7 @@ class SparseBitVector return (Last.index() * ElementSize) + Last.find_last(); } - // Return true if the SparseBitVector is empty +// Return true if the SparseBitVector is empty bool empty() const { return Elements.empty(); diff --git a/svf/lib/Graphs/SlicedGraphs.cpp b/svf/lib/Graphs/SlicedGraphs.cpp index 3c4bcee595..ebabe71f3e 100644 --- a/svf/lib/Graphs/SlicedGraphs.cpp +++ b/svf/lib/Graphs/SlicedGraphs.cpp @@ -339,7 +339,7 @@ void SlicedICFGView::buildBridgedEdges() std::vector removed; Map removedNodeIndex; for (ICFG::iterator it = icfg->begin(), eit = icfg->end(); - it != eit; ++it) + it != eit; ++it) { const ICFGNode* node = it->second; if (node == nullptr || keptNodesSet.count(node)) @@ -354,14 +354,14 @@ void SlicedICFGView::buildBridgedEdges() // removed ones. ret_i is in the same caller, so the seed stays intra-procedural. Map seedRet; for (ICFG::iterator it = icfg->begin(), eit = icfg->end(); - it != eit; ++it) + it != eit; ++it) { const CallICFGNode* call = SVFUtil::dyn_cast(it->second); if (call == nullptr || call->getRetICFGNode() == nullptr) continue; for (const ICFGEdge* edge : call->getOutEdges()) if (edge != nullptr && SVFUtil::isa(edge) && - keptNodesSet.count(edge->getDstNode()) == 0) + keptNodesSet.count(edge->getDstNode()) == 0) { seedRet[call] = call->getRetICFGNode(); break; @@ -371,7 +371,7 @@ void SlicedICFGView::buildBridgedEdges() // contraction may traverse. Original call/ret edges are excluded. std::vector> removedSuccessors(removedNodeCount); std::vector> - keptSuccessors(removedNodeCount); + keptSuccessors(removedNodeCount); std::vector successors; for (int nodeIndex = 0; nodeIndex < removedNodeCount; ++nodeIndex) { @@ -427,7 +427,7 @@ void SlicedICFGView::buildBridgedEdges() break; } if (onStack[successorIndex] && - discoveryIndex[successorIndex] < lowLink[nodeIndex]) + discoveryIndex[successorIndex] < lowLink[nodeIndex]) lowLink[nodeIndex] = discoveryIndex[successorIndex]; } if (descend) @@ -471,9 +471,9 @@ void SlicedICFGView::buildBridgedEdges() // Propagate reachKept in ascending comp order (successors have smaller ids). std::vector> - reachableKeptNodes(componentCount); + reachableKeptNodes(componentCount); for (int componentIndex = 0; componentIndex < componentCount; - ++componentIndex) + ++componentIndex) { OrderedSet& reachable = reachableKeptNodes[componentIndex]; @@ -497,7 +497,7 @@ void SlicedICFGView::buildBridgedEdges() // Kept seed target: no real edge exists, so record the bridge; a // kept intra target is a real edge handled by getSuccNodes. if (seedReturn != seedRet.end() && - seedReturn->second == successor) + seedReturn->second == successor) { bridgedEdges[source].insert(successor); bridgedPreds[successor].insert(source); @@ -508,11 +508,11 @@ void SlicedICFGView::buildBridgedEdges() if (removedIndex == removedNodeIndex.end()) { SVFUtil::errs() - << "[ERROR] Local ICFG successor is neither kept nor indexed\n"; + << "[ERROR] Local ICFG successor is neither kept nor indexed\n"; std::abort(); } for (const ICFGNode* target : - reachableKeptNodes[component[removedIndex->second]]) + reachableKeptNodes[component[removedIndex->second]]) { bridgedEdges[source].insert(target); bridgedPreds[target].insert(source); @@ -536,7 +536,7 @@ void SlicedICFGView::getLocalSuccessors( successors.clear(); for (const ICFGEdge* edge : node->getOutEdges()) if (edge != nullptr && SVFUtil::isa(edge) && - edge->getDstNode() != nullptr) + edge->getDstNode() != nullptr) successors.push_back(edge->getDstNode()); const auto returnNode = callsiteReturnNodes.find(node); @@ -567,7 +567,7 @@ void SlicedPAGView::buildKeptNodeIds() continue; } if (const MultiOpndStmt* multi = - SVFUtil::dyn_cast(stmt)) + SVFUtil::dyn_cast(stmt)) { keptNodeIds.insert(multi->getResID()); for (u32_t i = 0; i < multi->getOpVarNum(); ++i) @@ -589,8 +589,8 @@ void SlicedPAGView::dump(const std::string& filename) const //===----------------------------------------------------------------------===// SlicedThreadCallGraphView::SlicedThreadCallGraphView(ThreadCallGraph* tcg, - const OrderedSet& keptFunctions, - const OrderedSet& extendedKeptNodes) + const OrderedSet& keptFunctions, + const OrderedSet& extendedKeptNodes) : tcg(tcg) { for (const FunObjVar* fun : keptFunctions) @@ -607,11 +607,11 @@ SlicedThreadCallGraphView::SlicedThreadCallGraphView(ThreadCallGraph* tcg, void SlicedThreadCallGraphView::buildKeptNodes() { for (CallGraph::iterator it = tcg->begin(), eit = tcg->end(); - it != eit; ++it) + it != eit; ++it) { const CallGraphNode* node = it->second; if (node != nullptr && node->getFunction() != nullptr && - keptFunctionsSet.count(node->getFunction())) + keptFunctionsSet.count(node->getFunction())) { keptNodes.insert(node); } @@ -682,12 +682,18 @@ void SlicedThreadCallGraphView::getCalleesOf( callees.clear(); const CallGraphNode* caller = tcg->getCallGraphNode(callSite->getFun()); if (!isKeptNode(caller)) + { return; + } std::vector outEdges; getOutEdgesOf(caller, outEdges); for (const CallGraphEdge* edge : outEdges) + { if (containsCallSite(edge, callSite)) + { callees.insert(edge->getDstNode()->getFunction()); + } + } } void SlicedThreadCallGraphView::getForkEdgesOf( @@ -696,15 +702,15 @@ void SlicedThreadCallGraphView::getForkEdgesOf( { out.clear(); if (!extendedKeptNodes.count(callSite) || - !tcg->hasThreadForkEdge(callSite)) + !tcg->hasThreadForkEdge(callSite)) return; for (auto it = tcg->getForkEdgeBegin(callSite), - end = tcg->getForkEdgeEnd(callSite); it != end; ++it) + end = tcg->getForkEdgeEnd(callSite); it != end; ++it) { const CallGraphEdge* edge = *it; if (isKeptNode(edge->getSrcNode()) && - isKeptNode(edge->getDstNode()) && - containsCallSite(edge, callSite)) + isKeptNode(edge->getDstNode()) && + containsCallSite(edge, callSite)) out.push_back(edge); } } @@ -715,14 +721,14 @@ void SlicedThreadCallGraphView::getJoinEdgesOf( { out.clear(); if (!extendedKeptNodes.count(callSite) || - !tcg->hasThreadJoinEdge(callSite)) + !tcg->hasThreadJoinEdge(callSite)) return; for (auto it = tcg->getJoinEdgeBegin(callSite), - end = tcg->getJoinEdgeEnd(callSite); it != end; ++it) + end = tcg->getJoinEdgeEnd(callSite); it != end; ++it) { const CallGraphEdge* edge = *it; if (isKeptNode(edge->getSrcNode()) && - isKeptNode(edge->getDstNode())) + isKeptNode(edge->getDstNode())) out.push_back(edge); } } @@ -866,7 +872,7 @@ void SlicedSVFIRView::dumpStats(const std::string& prefix) const if (!getIndirectSitesWithEmptyTargets().empty()) { SVFUtil::outs() << " Indirect callsites that lost all targets: " - << getIndirectSitesWithEmptyTargets().size() << "\n"; + << getIndirectSitesWithEmptyTargets().size() << "\n"; } } diff --git a/svf/lib/MTA/FSMPTA.cpp b/svf/lib/MTA/FSMPTA.cpp index 1b67169ee9..bf4b6d054f 100644 --- a/svf/lib/MTA/FSMPTA.cpp +++ b/svf/lib/MTA/FSMPTA.cpp @@ -155,12 +155,12 @@ NodeBS FSMPTA::buildExecutionDependencyClosure( // One backing-SVFG pass collects both kinds of solver-global roots: // updateCallGraph boundary nodes and variant-GEP side effects. for (SVFG::const_iterator it = graph->begin(), eit = graph->end(); - it != eit; ++it) + it != eit; ++it) { const SVFGNode* node = it->second; bool boundary = false; if (const ActualParmSVFGNode* actual = - SVFUtil::dyn_cast(node)) + SVFUtil::dyn_cast(node)) boundary = indirectSites.count(actual->getCallSite()) > 0; else if (const ActualRetSVFGNode* actual = SVFUtil::dyn_cast(node)) @@ -180,16 +180,16 @@ NodeBS FSMPTA::buildExecutionDependencyClosure( else if (const FormalINSVFGNode* formal = SVFUtil::dyn_cast(node)) boundary = indirectTargets.count( - formal->getFunEntryNode()->getFun()) > 0; + formal->getFunEntryNode()->getFun()) > 0; else if (const FormalOUTSVFGNode* formal = SVFUtil::dyn_cast(node)) boundary = indirectTargets.count( - formal->getFunExitNode()->getFun()) > 0; + formal->getFunExitNode()->getFun()) > 0; else if (const InterMSSAPHISVFGNode* phi = SVFUtil::dyn_cast(node)) boundary = phi->isFormalINPHI() - ? indirectTargets.count(phi->getFun()) > 0 - : indirectSites.count(phi->getCallSite()) > 0; + ? indirectTargets.count(phi->getFun()) > 0 + : indirectSites.count(phi->getCallSite()) > 0; if (boundary) enqueueSVFGNode(node, dependencyNodes, nodeWorklist); @@ -263,7 +263,7 @@ template void FSMPTA::cacheRetainedEdge(SVFGEdge* edge) { if (SolveGraphTraits::containsEdge(solveGraph, edge) && - retainedEdgeSet.insert(edge).second) + retainedEdgeSet.insert(edge).second) retainedOutEdges[edge->getSrcID()].push_back(edge); } diff --git a/svf/lib/MTA/LockAnalysis.cpp b/svf/lib/MTA/LockAnalysis.cpp index 50a610ebc2..a66b466777 100644 --- a/svf/lib/MTA/LockAnalysis.cpp +++ b/svf/lib/MTA/LockAnalysis.cpp @@ -77,7 +77,7 @@ void LockAnalysis::collectLockUnlockSites(ICFGGraph icfg, CGGraph cg) using CGTraits = GenericGraphTraits; for (auto nodeIt = CGTraits::nodes_begin(cg), - nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt) + nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt) { const FunObjVar* F = CGTraits::getRawNode(*nodeIt)->getFunction(); for (auto it : *F) @@ -470,7 +470,7 @@ void LockAnalysis::handleFork(ICFGGraph icfg, CGGraph cg, const CxtStmt& cts) for (const CallGraphEdge* edge : outEdges) { if (!SVFUtil::isa(edge) || - !GenericGraphTraits::containsCallSite(cg, edge, call)) + !GenericGraphTraits::containsCallSite(cg, edge, call)) continue; const FunObjVar* svfcallee = edge->getDstNode()->getFunction(); CallStrCxt newCxt = curCxt; @@ -498,7 +498,7 @@ void LockAnalysis::handleCall(ICFGGraph icfg, CGGraph cg, const CxtStmt& cts) for (const CallGraphEdge* edge : outEdges) { if (edge->getEdgeKind() != CallGraphEdge::CallRetEdge || - !GenericGraphTraits::containsCallSite(cg, edge, call)) + !GenericGraphTraits::containsCallSite(cg, edge, call)) continue; const FunObjVar* svfcallee = edge->getDstNode()->getFunction(); if (SVFUtil::isExtCall(svfcallee)) diff --git a/svf/lib/MTA/MHP.cpp b/svf/lib/MTA/MHP.cpp index 2ac05cf604..b175aeda05 100644 --- a/svf/lib/MTA/MHP.cpp +++ b/svf/lib/MTA/MHP.cpp @@ -226,7 +226,7 @@ void MHP::buildQuerySummaries(ICFGGraph icfg, CGGraph cg) // creating one CxtThreadStmt and one NodeBS per context at every node. using CGTraits = GenericGraphTraits; for (auto nodeIt = CGTraits::nodes_begin(cg), - nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt) + nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt) { const CallGraphNode* callGraphNode = CGTraits::getRawNode(*nodeIt); const FunObjVar* fun = callGraphNode->getFunction(); @@ -279,7 +279,7 @@ void MHP::updateNonCandidateFunInterleaving(ICFGGraph icfg, CGGraph cg) // addInterleavingThread's push is inert. using CGTraits = GenericGraphTraits; for (auto nodeIt = CGTraits::nodes_begin(cg), - nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt) + nodeEnd = CGTraits::nodes_end(cg); nodeIt != nodeEnd; ++nodeIt) { const CallGraphNode* callGraphNode = CGTraits::getRawNode(*nodeIt); const FunObjVar* fun = callGraphNode->getFunction(); @@ -352,7 +352,7 @@ void MHP::handleFork(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt& cts, NodeI for (const CallGraphEdge* edge : outEdges) { if (edge->getEdgeKind() != CallGraphEdge::TDForkEdge || - !GenericGraphTraits::containsCallSite(cg, edge, cbn)) + !GenericGraphTraits::containsCallSite(cg, edge, cbn)) continue; const FunObjVar* svfroutine = edge->getDstNode()->getFunction(); CallStrCxt newCxt = curCxt; @@ -447,7 +447,7 @@ void MHP::handleCall(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt& cts, NodeI for (const CallGraphEdge* edge : outEdges) { if (edge->getEdgeKind() != CallGraphEdge::CallRetEdge || - !GenericGraphTraits::containsCallSite(cg, edge, cbn)) + !GenericGraphTraits::containsCallSite(cg, edge, cbn)) continue; const FunObjVar* svfcallee = edge->getDstNode()->getFunction(); if (isExtCall(svfcallee)) @@ -472,7 +472,7 @@ void MHP::handleCall(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt& cts, NodeI continue; CxtThreadStmt exitCts(cts.getTid(), newCxt, exitInst); if (threadStmtToThreadInterLeav.find(exitCts) != - threadStmtToThreadInterLeav.end()) + threadStmtToThreadInterLeav.end()) { CxtThreadStmt retCts(cts.getTid(), curCxt, cbn->getRetICFGNode()); @@ -530,7 +530,7 @@ void MHP::handleRet(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt& cts) if (!hasThreadStmtSet(callSite)) continue; for (const CxtThreadStmt& cxtThreadStmt: - getThreadStmtSet(callSite)) + getThreadStmtSet(callSite)) { CallStrCxt callSiteCxt = cxtThreadStmt.getContext(); // If new context is a suffix of the call site context @@ -561,7 +561,7 @@ void MHP::handleRet(ICFGGraph icfg, CGGraph cg, const CxtThreadStmt& cts) if (!hasThreadStmtSet(callSite)) continue; for (const CxtThreadStmt& cxtThreadStmt: - getThreadStmtSet(callSite)) + getThreadStmtSet(callSite)) { CallStrCxt callSiteCxt = cxtThreadStmt.getContext(); // If new context is a suffix of the call site context @@ -1036,7 +1036,7 @@ void ForkJoinAnalysis::analyzeForkJoinPair(ICFGGraph icfg, CGGraph cg) const CxtThread& parentCxtThread = tct->getTCTNode(parentTid)->getCxtThread(); const FunObjVar* parentRoutine = tct->getStartRoutineOfCxtThread(parentCxtThread); if (curInst == GenericGraphTraits::getFunExit( - icfg, parentRoutine)) + icfg, parentRoutine)) { if (getMarkedFlag(cts) != TDAlive) addToFullJoin(parentTid, rootTid); @@ -1065,7 +1065,7 @@ void ForkJoinAnalysis::handleFork(ICFGGraph icfg, CGGraph cg, for (const CallGraphEdge* edge : outEdges) { if (edge->getEdgeKind() != CallGraphEdge::TDForkEdge || - !GenericGraphTraits::containsCallSite(cg, edge, cbn)) + !GenericGraphTraits::containsCallSite(cg, edge, cbn)) continue; const FunObjVar* callee = edge->getDstNode()->getFunction(); CallStrCxt newCxt = curCxt; @@ -1111,9 +1111,9 @@ void ForkJoinAnalysis::handleJoin(ICFGGraph icfg, CGGraph cg, if (hasJoinLoop(SVFUtil::cast(joinSite))) { if (isAliasedForkJoin(SVFUtil::cast(forkSite), - SVFUtil::cast(joinSite)) && + SVFUtil::cast(joinSite)) && isSameSCEV(forkSite,joinSite) - ) + ) { LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast(joinSite)); std::vector exitbbs; @@ -1153,7 +1153,7 @@ void ForkJoinAnalysis::handleJoin(ICFGGraph icfg, CGGraph cg, else { if (isAliasedForkJoin(SVFUtil::cast(forkSite), - SVFUtil::cast(joinSite))) + SVFUtil::cast(joinSite))) { markCxtStmtFlag(cts, TDDead); addDirectlyJoinTID(cts, rootTid); @@ -1178,7 +1178,7 @@ void ForkJoinAnalysis::handleCall(ICFGGraph icfg, CGGraph cg, for (const CallGraphEdge* edge : outEdges) { if (edge->getEdgeKind() != CallGraphEdge::CallRetEdge || - !GenericGraphTraits::containsCallSite(cg, edge, cbn)) + !GenericGraphTraits::containsCallSite(cg, edge, cbn)) continue; const FunObjVar* svfcallee = edge->getDstNode()->getFunction(); if (isExtCall(svfcallee)) @@ -1228,7 +1228,7 @@ void ForkJoinAnalysis::handleRet(ICFGGraph icfg, CGGraph cg, if (!hasCxtStmtsFromInst(callSite)) continue; for (const CxtStmt& cxtStmt: - getCxtStmtsFromInst(callSite)) + getCxtStmtsFromInst(callSite)) { CallStrCxt callSiteCxt = cxtStmt.getContext(); // If new context is a suffix of the call site context @@ -1261,7 +1261,7 @@ void ForkJoinAnalysis::handleRet(ICFGGraph icfg, CGGraph cg, if (!hasCxtStmtsFromInst(callSite)) continue; for (const CxtStmt& cxtStmt: - getCxtStmtsFromInst(callSite)) + getCxtStmtsFromInst(callSite)) { CallStrCxt callSiteCxt = cxtStmt.getContext(); // If new context is a suffix of the call site context @@ -1429,10 +1429,10 @@ bool ForkJoinAnalysis::sameLoopTripCount(const ICFGNode* forkSite, const ICFGNod } bool ForkJoinAnalysis::isAliasedForkJoin(const CallICFGNode* forkSite, - const CallICFGNode* joinSite) + const CallICFGNode* joinSite) { return getTCG()->getThreadAPI()->isAliasedForkJoin(tct->getPTA(), - getForkedThread(forkSite), getJoinedThread(joinSite), forkJoinAliasCache); + getForkedThread(forkSite), getJoinedThread(joinSite), forkJoinAliasCache); } template void ForkJoinAnalysis::analyzeForkJoinPair( diff --git a/svf/lib/MTA/MTA.cpp b/svf/lib/MTA/MTA.cpp index d96523dd5a..efca7a8e9c 100644 --- a/svf/lib/MTA/MTA.cpp +++ b/svf/lib/MTA/MTA.cpp @@ -117,8 +117,8 @@ MHP* MTA::computeMHP(TCT* tct) DOTIMESTAT(double mhpStart = stat->getClk()); std::unique_ptr mhp = MHP::create( - tct, PAG::getPAG()->getICFG(), - const_cast(PAG::getPAG()->getCallGraph())); + tct, PAG::getPAG()->getICFG(), + const_cast(PAG::getPAG()->getCallGraph())); mhp->analyze(PAG::getPAG()->getICFG(), const_cast(PAG::getPAG()->getCallGraph())); DOTIMESTAT(double mhpEnd = stat->getClk()); DOTIMESTAT(stat->MHPTime += (mhpEnd - mhpStart) / TIMEINTERVAL); @@ -272,13 +272,14 @@ void MTA::collectRaceOccurrences( lockAnalysis->isProtectedByCommonLock(node, node); const size_t firstNewOccurrence = occurrences.size(); for (const auto& tidAndInterleaving : - threadSummary->interleavingByTid) + threadSummary->interleavingByTid) occurrences.push_back( - {stmt, node, isStore, tidAndInterleaving.first, - &tidAndInterleaving.second, locked}); + { + stmt, node, isStore, tidAndInterleaving.first, + &tidAndInterleaving.second, locked}); for (NodeID object : objects) for (size_t index = firstNewOccurrence; - index < occurrences.size(); ++index) + index < occurrences.size(); ++index) objectToOccurrences[object].push_back(index); } } @@ -294,7 +295,8 @@ std::vector MTA::buildRaceClasses( for (size_t occurrenceIndex : occurrenceIndices) { const RaceOccurrence& occurrence = occurrences[occurrenceIndex]; - const RaceClassKey key{ + const RaceClassKey key + { occurrence.tid, occurrence.isStore, occurrence.interleaving, occurrence.locked, occurrence.locked ? occurrence.node->getId() : 0}; @@ -303,8 +305,9 @@ std::vector MTA::buildRaceClasses( { keyToClass[key] = classes.size(); classes.push_back( - {occurrence.isStore, occurrence.locked, occurrenceIndex, - {occurrenceIndex}}); + { + occurrence.isStore, occurrence.locked, occurrenceIndex, + {occurrenceIndex}}); } else classes[found->second].members.push_back(occurrenceIndex); @@ -320,7 +323,7 @@ void MTA::emitRacePairs( { for (size_t firstIndex = 0; firstIndex < classes.size(); ++firstIndex) for (size_t secondIndex = firstIndex; - secondIndex < classes.size(); ++secondIndex) + secondIndex < classes.size(); ++secondIndex) { const RaceClass& firstClass = classes[firstIndex]; const RaceClass& secondClass = classes[secondIndex]; @@ -332,14 +335,14 @@ void MTA::emitRacePairs( const RaceOccurrence& secondRepresentative = occurrences[secondClass.representative]; if (!occurrencesRace( - mhp, firstRepresentative, secondRepresentative)) + mhp, firstRepresentative, secondRepresentative)) continue; if (firstIndex != secondIndex) { if (firstClass.locked && secondClass.locked && - lockAnalysis->isProtectedByCommonLock( - firstRepresentative.node, secondRepresentative.node)) + lockAnalysis->isProtectedByCommonLock( + firstRepresentative.node, secondRepresentative.node)) continue; for (size_t memberIndex : firstClass.members) for (size_t otherIndex : secondClass.members) @@ -350,13 +353,13 @@ void MTA::emitRacePairs( { const std::vector& members = firstClass.members; if (firstClass.locked && - lockAnalysis->isProtectedByCommonLock( - firstRepresentative.node, firstRepresentative.node)) + lockAnalysis->isProtectedByCommonLock( + firstRepresentative.node, firstRepresentative.node)) continue; for (size_t firstPosition = 0; - firstPosition < members.size(); ++firstPosition) + firstPosition < members.size(); ++firstPosition) for (size_t secondPosition = firstPosition; - secondPosition < members.size(); ++secondPosition) + secondPosition < members.size(); ++secondPosition) commitRacePair( outRacePairs, occurrences[members[firstPosition]], occurrences[members[secondPosition]]); @@ -451,7 +454,7 @@ void SlicedMTA::reportOriginalStatistics(SVFIR* svfir) size_t pagStmtCount = 0; for (ICFG::iterator it = svfir->getICFG()->begin(), - eit = svfir->getICFG()->end(); it != eit; ++it) + eit = svfir->getICFG()->end(); it != eit; ++it) { const ICFGNode* node = it->second; if (svfir->hasSVFStmtList(node)) @@ -473,7 +476,7 @@ std::set SlicedMTA::collectICFGNodes( if (!svfg->hasSVFGNode(id)) continue; if (const StmtVFGNode* stmtNode = - SVFUtil::dyn_cast(svfg->getSVFGNode(id))) + SVFUtil::dyn_cast(svfg->getSVFGNode(id))) if (stmtNode->getICFGNode() != nullptr) nodes.insert(stmtNode->getICFGNode()); } @@ -506,7 +509,8 @@ std::string SlicedMTA::raceStatementKey(const SVFStmt* statement) const SVFBasicBlock* block = statement->getBB(); const SVFVar* value = statement->getValue(); - const std::string fields[] = { + const std::string fields[] = + { std::to_string(statement->getEdgeKind()), function == nullptr ? std::string() : function->getName(), block == nullptr ? std::string() : block->getName(), @@ -514,7 +518,7 @@ std::string SlicedMTA::raceStatementKey(const SVFStmt* statement) value == nullptr ? std::string() : value->getName(), value == nullptr ? std::string() : value->getSourceLoc(), value != nullptr && value->hasLLVMValue() - ? value->valueOnlyToString() : std::string() + ? value->valueOnlyToString() : std::string() }; for (const std::string& field : fields) { @@ -683,8 +687,8 @@ bool SlicedMTA::runPreAnalysis() { ScopedPhaseTimer timer("ILA: construct MHP/ForkJoin"); mhp = MHP::create( - tct.get(), svfir->getICFG(), - const_cast(svfir->getCallGraph())); + tct.get(), svfir->getICFG(), + const_cast(svfir->getCallGraph())); } { ScopedPhaseTimer timer("ILA: MHP propagation"); @@ -773,7 +777,7 @@ bool SlicedMTA::runMTASlicingAndAnalysis() { SVFUtil::outs() << "[Slicing Mode] Differential slices (separate ILA + FSPTA)\n"; multiStageSlicer = std::make_unique( - svfir, preAndersen, mhp.get(), lockAnalysis.get(), preSVFG); + svfir, preAndersen, mhp.get(), lockAnalysis.get(), preSVFG); // ILA slicing sources = [INIT] race statements + [THREAD-VF] sources. Keep // a candidate edge's query (see MTASVFGBuilder::getThreadVFQueryMap) only if @@ -792,17 +796,17 @@ bool SlicedMTA::runMTASlicingAndAnalysis() FSMPTA::buildExecutionDependencyClosure( preSVFG, preAndersen, preCandidate.nodeIds()); if (preCandidateSolveNodeIds.empty() && - !preCandidate.svfgNodes.empty()) + !preCandidate.svfgNodes.empty()) { SVFUtil::errs() << "[ERROR] Failed to execution-close VFG'_pre\n"; return false; } if (isMTAStatEnabled()) SVFUtil::outs() - << "[VFG'_pre] " << preCandidate.svfgNodes.size() - << " dependency nodes, " - << preCandidateSolveNodeIds.count() - << " execution-closure nodes\n"; + << "[VFG'_pre] " << preCandidate.svfgNodes.size() + << " dependency nodes, " + << preCandidateSolveNodeIds.count() + << " execution-closure nodes\n"; // The query map can be large; use node-ID membership rather than // two ordered-set lookups for every candidate edge. @@ -810,7 +814,7 @@ bool SlicedMTA::runMTASlicingAndAnalysis() { const MTASVFGBuilder::ThreadVFEdge& edge = entry.first; if (preCandidateSolveNodeIds.test(edge.first->getId()) && - preCandidateSolveNodeIds.test(edge.second->getId())) + preCandidateSolveNodeIds.test(edge.second->getId())) { selectedThreadVFCandidates.emplace_back( edge.first->getId(), edge.second->getId()); @@ -920,7 +924,7 @@ bool SlicedMTA::runPTASlicingAndAnalysis() NodeBS finalSVFGNodeIds; if (slicedMHP == nullptr || slicedLockAnalysis == nullptr || - preSVFGBuilder == nullptr || preSVFG == nullptr) + preSVFGBuilder == nullptr || preSVFG == nullptr) { SVFUtil::outs() << "[Main FSMPTA] Base SVFG or sliced ILA unavailable\n"; return false; @@ -933,8 +937,8 @@ bool SlicedMTA::runPTASlicingAndAnalysis() SVFUtil::outs() << "[Slicing Mode] Reusing unified slice (V_Single) for FSPTA\n"; finalSVFGNodeIds = FSMPTA::buildExecutionDependencyClosure( - preSVFG, preAndersen, - singleSlicedSVFGNodeIds); + preSVFG, preAndersen, + singleSlicedSVFGNodeIds); if (finalSVFGNodeIds.empty() && !singleSlicedSVFGNodeIds.empty()) { SVFUtil::errs() << "[ERROR] Single-slice FSMPTA execution closure failed\n"; @@ -1186,7 +1190,7 @@ bool SlicedMTA::runWholeProgramDetection() ScopedPhaseTimer timer("Build Whole-program View"); std::set allNodes; for (ICFG::iterator it = svfir->getICFG()->begin(), - eit = svfir->getICFG()->end(); it != eit; ++it) + eit = svfir->getICFG()->end(); it != eit; ++it) allNodes.insert(it->second); ptaSlicedView = std::make_unique( svfir, *threadCallGraph, svfir->getICFG(), allNodes); @@ -1322,13 +1326,13 @@ bool SlicedMTA::runOnModule(SVFIR* pag, AndersenWaveDiff& preAnalysis) bool MTA::hasThreadFunctions(CallGraph* callGraph) { for (CallGraph::iterator it = callGraph->begin(), eit = callGraph->end(); - it != eit; ++it) + it != eit; ++it) { const CallGraphNode* node = it->second; for (const CallGraphEdge* edge : node->getOutEdges()) { if (edge->getEdgeKind() == CallGraphEdge::TDForkEdge && - edge->getDstNode()->getFunction() != nullptr) + edge->getDstNode()->getFunction() != nullptr) { return true; } @@ -1363,7 +1367,7 @@ std::set SlicedMTA::detectRacePairsOnSlicedGraph( PointsTo pts1, pts2; if (const LoadStmt* ldStmt1 = - SVFUtil::dyn_cast(pair.stmt1)) + SVFUtil::dyn_cast(pair.stmt1)) { pts1 = slicedPTA->getPts(ldStmt1->getRHSVarID()); } @@ -1378,7 +1382,7 @@ std::set SlicedMTA::detectRacePairsOnSlicedGraph( } if (const LoadStmt* ldStmt2 = - SVFUtil::dyn_cast(pair.stmt2)) + SVFUtil::dyn_cast(pair.stmt2)) { pts2 = slicedPTA->getPts(ldStmt2->getRHSVarID()); } diff --git a/svf/lib/MTA/MTASVFGBuilder.cpp b/svf/lib/MTA/MTASVFGBuilder.cpp index 1584214168..151d366648 100644 --- a/svf/lib/MTA/MTASVFGBuilder.cpp +++ b/svf/lib/MTA/MTASVFGBuilder.cpp @@ -183,7 +183,7 @@ void MTASVFGBuilder::addJoinRetEdge(const FormalOUTSVFGNode* formalOut, SVFGNode* src = svfg->getSVFGNode(formalOut->getId()); SVFGNode* dst = svfg->getSVFGNode(actualOut->getId()); if (SVFGEdge* edge = svfg->hasInterVFGEdge( - src, dst, SVFGEdge::RetIndVF, callSiteId)) + src, dst, SVFGEdge::RetIndVF, callSiteId)) { SVFUtil::cast(edge)->addPointsTo(cpts); } @@ -322,11 +322,11 @@ MTASVFGBuilder::SVFGNodeIDSet MTASVFGBuilder::getPredecessorNodes( Set visited; for (SVFGEdge::SVFGEdgeSetTy::iterator iter = node->InEdgeBegin(); - iter != node->InEdgeEnd(); ++iter) + iter != node->InEdgeEnd(); ++iter) { SVFGEdge* edge = *iter; if (edge->isIndirectVFGEdge() && !edge->isThreadMHPIndirectVFGEdge() && - isInOverlayScope(edge->getSrcNode())) + isInOverlayScope(edge->getSrcNode())) worklist.insert(edge->getSrcNode()); } @@ -343,9 +343,9 @@ MTASVFGBuilder::SVFGNodeIDSet MTASVFGBuilder::getPredecessorNodes( { SVFGEdge* edge = *iter; if (edge->isIndirectVFGEdge() && - !edge->isThreadMHPIndirectVFGEdge() && - isInOverlayScope(edge->getSrcNode()) && - visited.find(edge->getSrcNode()) == visited.end()) + !edge->isThreadMHPIndirectVFGEdge() && + isInOverlayScope(edge->getSrcNode()) && + visited.find(edge->getSrcNode()) == visited.end()) worklist.insert(edge->getSrcNode()); } } @@ -369,11 +369,11 @@ MTASVFGBuilder::SVFGNodeIDSet MTASVFGBuilder::getSuccessorNodes( Set visited; for (SVFGEdge::SVFGEdgeSetTy::iterator iter = node->OutEdgeBegin(); - iter != node->OutEdgeEnd(); ++iter) + iter != node->OutEdgeEnd(); ++iter) { SVFGEdge* edge = *iter; if (edge->isIndirectVFGEdge() && !edge->isThreadMHPIndirectVFGEdge() && - isInOverlayScope(edge->getDstNode())) + isInOverlayScope(edge->getDstNode())) worklist.insert(edge->getDstNode()); } @@ -390,9 +390,9 @@ MTASVFGBuilder::SVFGNodeIDSet MTASVFGBuilder::getSuccessorNodes( { SVFGEdge* edge = *iter; if (edge->isIndirectVFGEdge() && - !edge->isThreadMHPIndirectVFGEdge() && - isInOverlayScope(edge->getDstNode()) && - visited.find(edge->getDstNode()) == visited.end()) + !edge->isThreadMHPIndirectVFGEdge() && + isInOverlayScope(edge->getDstNode()) && + visited.find(edge->getDstNode()) == visited.end()) worklist.insert(edge->getDstNode()); } } @@ -415,7 +415,7 @@ bool MTASVFGBuilder::isHeadOfSpan(const StmtSVFGNode* node) { const StmtSVFGNode* prevNode = SVFUtil::dyn_cast(svfg->getSVFGNode(id)); if (prevNode != nullptr && lockAnalysis->isInSameSpan( - prevNode->getICFGNode(), node->getICFGNode())) + prevNode->getICFGNode(), node->getICFGNode())) { spanHeadCache[node] = false; return false; @@ -446,7 +446,7 @@ bool MTASVFGBuilder::isTailOfSpan(const StmtSVFGNode* node) const StmtSVFGNode* successorStatement = SVFUtil::dyn_cast(successor); if (successorStatement != nullptr && lockAnalysis->isInSameSpan( - successorStatement->getICFGNode(), node->getICFGNode())) + successorStatement->getICFGNode(), node->getICFGNode())) { spanTailCache[node] = false; return false; @@ -470,7 +470,7 @@ void MTASVFGBuilder::recordThreadVFSource( // they are recoverable from the map key -- so the value holds only the // additional in-span witnesses below (empty for the common lock-free case). Set& query = - threadVFQueryMap[{source, destination}]; + threadVFQueryMap[ {source, destination}]; if (!commonLock) return; @@ -484,7 +484,7 @@ void MTASVFGBuilder::recordThreadVFSource( const StmtSVFGNode* successorStatement = SVFUtil::cast(successor); if (lockAnalysis->isInSameSpan( - successorStatement->getICFGNode(), source->getICFGNode())) + successorStatement->getICFGNode(), source->getICFGNode())) query.insert(successorStatement->getICFGNode()); } @@ -494,7 +494,7 @@ void MTASVFGBuilder::recordThreadVFSource( const StmtSVFGNode* prevNode = SVFUtil::dyn_cast(svfg->getSVFGNode(id)); if (prevNode != nullptr && lockAnalysis->isInSameSpan( - prevNode->getICFGNode(), destination->getICFGNode())) + prevNode->getICFGNode(), destination->getICFGNode())) query.insert(prevNode->getICFGNode()); } } @@ -626,9 +626,9 @@ void MTASVFGBuilder::connectMHPEdges(PointerAnalysis* pta) { const ThreadVFCandidate canonicalPair = candidate.sourceNodeId < candidate.destinationNodeId - ? candidate - : ThreadVFCandidate(candidate.destinationNodeId, - candidate.sourceNodeId); + ? candidate + : ThreadVFCandidate(candidate.destinationNodeId, + candidate.sourceNodeId); if (processedStorePairs.insert(canonicalPair).second) // Main ILA re-decides the unordered pair once; the handler // emits whichever directed edges pass the lock-span rules. diff --git a/svf/lib/MTA/MTASlicer.cpp b/svf/lib/MTA/MTASlicer.cpp index d01872b85f..7a97f32733 100644 --- a/svf/lib/MTA/MTASlicer.cpp +++ b/svf/lib/MTA/MTASlicer.cpp @@ -468,7 +468,7 @@ OrderedSet MTASlicerBase::svfgNodesToICFGNodes( OrderedSet result; for (const SVFGNode* node : nodes) if (const StmtVFGNode* statementNode = - SVFUtil::dyn_cast(node)) + SVFUtil::dyn_cast(node)) if (statementNode->getICFGNode() != nullptr) result.insert(statementNode->getICFGNode()); for (const SVFStmt* stmt : seeds) @@ -504,7 +504,7 @@ OrderedSet MTASlicerBase::collectPthreadStatements( // Second pass: find corresponding pthread_join nodes ICFG* icfg = svfir->getICFG(); for (ICFG::iterator it = icfg->begin(), eit = icfg->end(); - it != eit; ++it) + it != eit; ++it) { const ICFGNode* node = it->second; const CallICFGNode* callNode = SVFUtil::dyn_cast(node); @@ -517,8 +517,8 @@ OrderedSet MTASlicerBase::collectPthreadStatements( { const SVFVar* forkedThread = threadAPI->getForkedThread(createCallNode); if (forkedThread != nullptr && - threadAPI->isAliasedForkJoin( - pta, forkedThread, joinThread)) + threadAPI->isAliasedForkJoin( + pta, forkedThread, joinThread)) { pthreadCallNodes.insert(callNode); } @@ -551,7 +551,7 @@ OrderedSet MTASlicerBase::collectMutexStatements( const CallICFGNode* lockCallNode = SVFUtil::dyn_cast(lockNode); if (lockCallNode != nullptr && - threadAPI->isTDAcquire(lockCallNode)) + threadAPI->isTDAcquire(lockCallNode)) { mutexCallNodes.insert(lockCallNode); mutexLockCallNodes.insert(lockCallNode); @@ -562,7 +562,7 @@ OrderedSet MTASlicerBase::collectMutexStatements( // Second pass: find corresponding mutex_unlock nodes ICFG* icfg = svfir->getICFG(); for (ICFG::iterator it = icfg->begin(), eit = icfg->end(); - it != eit; ++it) + it != eit; ++it) { const ICFGNode* node = it->second; const CallICFGNode* callNode = SVFUtil::dyn_cast(node); @@ -577,7 +577,7 @@ OrderedSet MTASlicerBase::collectMutexStatements( { const SVFVar* lockVar = threadAPI->getLockVal(lockCallNode); if (lockVar != nullptr && - pta->alias(unlockVar->getId(), lockVar->getId())) + pta->alias(unlockVar->getId(), lockVar->getId())) { mutexCallNodes.insert(callNode); } @@ -592,8 +592,8 @@ OrderedSet MTASlicerBase::collectMutexStatements( // Helper: Collect common pthread and mutex statements (shared by PTA and MTA slicing) std::pair, OrderedSet> -MTASlicerBase::collectCommonThreadStatements( - const OrderedSet& sourceNodes) + MTASlicerBase::collectCommonThreadStatements( + const OrderedSet& sourceNodes) { // Step 1: Collect pthread-related statements, i.e., pthread_create and pthread_join OrderedSet pthreadCallNodes = @@ -689,7 +689,7 @@ OrderedSet MTASlicerBase::expandCallDependence( Map functionToNode; for (auto it = callGraph->begin(), eit = callGraph->end(); - it != eit; ++it) + it != eit; ++it) { const CallGraphNode* node = it->second; if (node != nullptr && node->getFunction() != nullptr) From 7d91fde8bfa75f04f5346ecf7dfc203b7fbb54ae Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 24 Aug 2026 11:44:53 +1000 Subject: [PATCH 6/7] Refine publication acknowledgement --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9a66f25aa..d0929152fe 100644 --- a/README.md +++ b/README.md @@ -58,4 +58,4 @@ SVF provides reusable abstractions, graphs, and solvers for analyzing LLVM IR. * [SVFIR](https://github.com/SVF-tools/SVF/tree/master/svf/include/SVFIR) and [MemoryModel](https://github.com/SVF-tools/SVF/tree/master/svf/include/MemoryModel) (SVFIR): SVFIR, memory abstraction and points-to data structure ([SAS'21](https://link.springer.com/chapter/10.1007/978-3-030-88806-0_2)); * [Graphs](https://github.com/SVF-tools/SVF/tree/master/svf/include/Graphs): generating a variety of graphs, including call graph, ICFG, class hierarchy graph, constraint graph, value-flow graph for static analyses and code embedding ([OOPSLA'20](https://dl.acm.org/doi/10.1145/3428301), [TOSEM'21](https://dl.acm.org/doi/10.1145/3436877)) -

We release the SVF source code with the hope of benefiting the open-source community. You are kindly requested to acknowledge usage of the tool by referring to or citing relevant publications above.

+

We release the SVF source code with the hope of benefiting the open-source community. If you find SVF helpful, please kindly acknowledge the use of the tool or the relevant publications above.

From 56fe2e5cf7ebce7607952d7ebcba680c8708f929 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 24 Aug 2026 11:46:55 +1000 Subject: [PATCH 7/7] Use readable MTA wiki link --- svf/lib/MTA/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svf/lib/MTA/README.md b/svf/lib/MTA/README.md index e6ff10b5fe..8203784762 100644 --- a/svf/lib/MTA/README.md +++ b/svf/lib/MTA/README.md @@ -1,6 +1,6 @@ # MTA and MSli This directory contains SVF's multithreaded analysis (MTA) and the MSli -multi-stage slicing implementation. See the [MTA-MSli wiki page](https://github.com/SVF-tools/SVF/wiki/MTA-%E2%80%90-MSli) +multi-stage slicing implementation. See the [MTA-MSli wiki page](https://github.com/SVF-tools/SVF/wiki/MTA-‐-MSli) for build instructions, command examples, and measured small- and large-program results.