svf-tools 1.0.1238 → 1.0.1239
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +1 -1
- package/build.sh +3 -3
- package/package.json +1 -1
- package/setup.sh +1 -1
- package/svf-llvm/CMakeLists.txt +15 -0
- package/svf-llvm/include/SVF-LLVM/BasicTypes.h +4 -0
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +4 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +2 -0
- package/svf-llvm/lib/LLVMModule.cpp +13 -7
- package/svf-llvm/lib/LLVMUtil.cpp +1 -0
- package/svf-llvm/lib/SVFIRBuilder.cpp +151 -23
- package/svf-llvm/lib/SVFIRExtAPI.cpp +136 -1
- package/svf-llvm/tools/Example/svf-ex.cpp +2 -1
- package/SVF-doxygen/doxygen.config +0 -2548
- package/SVF-doxygen/wiki/PAG.png +0 -0
- package/SVF-doxygen/wiki/andersen.png +0 -0
- package/SVF-doxygen/wiki/callgraph.png +0 -0
- package/SVF-doxygen/wiki/consG.png +0 -0
- package/SVF-doxygen/wiki/cpu2000-flto +0 -432
- package/SVF-doxygen/wiki/cpu2006-flto +0 -417
- package/SVF-doxygen/wiki/cpu2017-wllvm.cfg +0 -999
- package/SVF-doxygen/wiki/database.png +0 -0
- package/SVF-doxygen/wiki/framework.png +0 -0
- package/SVF-doxygen/wiki/help.png +0 -0
- package/SVF-doxygen/wiki/icfg.png +0 -0
- package/SVF-doxygen/wiki/mssa-cha.png +0 -0
- package/SVF-doxygen/wiki/pagedge.png +0 -0
- package/SVF-doxygen/wiki/pagnode.png +0 -0
- package/SVF-doxygen/wiki/pt.png +0 -0
- package/SVF-doxygen/wiki/setupcmake.png +0 -0
- package/SVF-doxygen/wiki/setupconfiguration.png +0 -0
- package/SVF-doxygen/wiki/setupdashboard.png +0 -0
- package/SVF-doxygen/wiki/setupdebug.png +0 -0
- package/SVF-doxygen/wiki/setupenv.png +0 -0
- package/SVF-doxygen/wiki/startup.png +0 -0
- package/SVF-doxygen/wiki/svf-stat.pdf +0 -0
- package/SVF-doxygen/wiki/svfg-framework.png +0 -0
- package/SVF-doxygen/wiki/svfg.png +0 -0
- package/SVF-doxygen/wiki/svfg_opt.png +0 -0
- package/SVF-doxygen/wiki/svfgedge-cha.png +0 -0
- package/SVF-doxygen/wiki/svfgnode-cha.png +0 -0
- package/SVF-doxygen/wiki/svfpic/README.md +0 -6
- package/SVF-doxygen/wiki/svfpic/ass-1debug1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/ass-1debug2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/build.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/cmd.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect1.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/connect2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect3.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect4.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/connect5.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/connect6.png +0 -0
- package/SVF-doxygen/wiki/svfpic/connect7.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/continue.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug-new.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug-new2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug1.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/debug2.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/debug3.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug4.png +0 -0
- package/SVF-doxygen/wiki/svfpic/debug5.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/debug6.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/docker_sys_requirement.png +0 -0
- package/SVF-doxygen/wiki/svfpic/docker_sys_requirements.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild2.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild3.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild4.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuild5.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerbuildimage.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockercmd.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockercmd2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockercontainer.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb1.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb10.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb2.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb3.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb4.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb5.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb6.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb7.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb8.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerdb9.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerfinshbuilt.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerimage.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockernameImage.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerpull.png +0 -0
- package/SVF-doxygen/wiki/svfpic/dockerpull2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/download.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/extension1.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/extension2.jpeg +0 -0
- package/SVF-doxygen/wiki/svfpic/graphviz.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hellodb.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hellodb2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hviz_0.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hviz_1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/hviz_2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installC:C++Ext.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installCMakeExt.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installRCext.png +0 -0
- package/SVF-doxygen/wiki/svfpic/installdockerext.png +0 -0
- package/SVF-doxygen/wiki/svfpic/launch1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/openfile.png +0 -0
- package/SVF-doxygen/wiki/svfpic/pathfolder.png +0 -0
- package/SVF-doxygen/wiki/svfpic/restart.png +0 -0
- package/SVF-doxygen/wiki/svfpic/rundocker.png +0 -0
- package/SVF-doxygen/wiki/svfpic/runinCLI.png +0 -0
- package/SVF-doxygen/wiki/svfpic/screen.png +0 -0
- package/SVF-doxygen/wiki/svfpic/settings1.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/settings2.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/settings3.jpg +0 -0
- package/SVF-doxygen/wiki/svfpic/shortlists.png +0 -0
- package/SVF-doxygen/wiki/svfpic/start.png +0 -0
- package/SVF-doxygen/wiki/svfpic/start1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/update0.png +0 -0
- package/SVF-doxygen/wiki/svfpic/verify_docker.png +0 -0
- package/SVF-doxygen/wiki/svfpic/vs_entry_window.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl_1.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl_2.png +0 -0
- package/SVF-doxygen/wiki/svfpic/wsl_3.png +0 -0
- package/SVF-doxygen/wiki/tools.png +0 -0
- package/SVF-doxygen/wiki/users.png +0 -0
- package/SVF-doxygen/wiki/vm1.png +0 -0
- package/SVF-doxygen/wiki/vm2.png +0 -0
- package/SVF-doxygen/wiki/vm3.png +0 -0
- package/SVF-doxygen/wiki/vm4.png +0 -0
- package/SVF-doxygen/wiki/vm5.png +0 -0
- package/SVF-doxygen/wiki/vscode_build_tasks.png +0 -0
- package/SVF-doxygen/wiki/vscode_cpp_extension.png +0 -0
- package/SVF-doxygen/wiki/vscode_debug_list.png +0 -0
- package/SVF-doxygen/wiki/vscode_dir_structure.png +0 -0
package/Dockerfile
CHANGED
package/build.sh
CHANGED
|
@@ -23,11 +23,11 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|
|
23
23
|
SVFHOME="${SCRIPT_DIR}"
|
|
24
24
|
sysOS=$(uname -s)
|
|
25
25
|
arch=$(uname -m)
|
|
26
|
-
MajorLLVMVer=
|
|
26
|
+
MajorLLVMVer=21
|
|
27
27
|
LLVMVer=${MajorLLVMVer}.1.0
|
|
28
|
-
UbuntuArmLLVM_RTTI="https://github.com/SVF-
|
|
28
|
+
UbuntuArmLLVM_RTTI="https://github.com/bjjwwang/SVF-LLVM/releases/download/${LLVMVer}/llvm-${LLVMVer}-ubuntu22-rtti-aarch64.tar.gz"
|
|
29
29
|
UbuntuArmLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-aarch64-linux-gnu.tar.xz"
|
|
30
|
-
UbuntuLLVM_RTTI="https://github.com/SVF-
|
|
30
|
+
UbuntuLLVM_RTTI="https://github.com/bjjwwang/SVF-LLVM/releases/download/${LLVMVer}/llvm-${LLVMVer}-ubuntu22-rtti-x86-64.tar.gz"
|
|
31
31
|
UbuntuLLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVMVer}/clang+llvm-${LLVMVer}-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
|
|
32
32
|
SourceLLVM="https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-${LLVMVer}.zip"
|
|
33
33
|
UbuntuZ3="https://github.com/Z3Prover/z3/releases/download/z3-4.8.8/z3-4.8.8-x64-ubuntu-16.04.zip"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1239",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
package/setup.sh
CHANGED
package/svf-llvm/CMakeLists.txt
CHANGED
|
@@ -65,6 +65,11 @@ else()
|
|
|
65
65
|
demangle
|
|
66
66
|
Passes
|
|
67
67
|
)
|
|
68
|
+
# When the host LLVM tree already contains an in-tree SVF integration,
|
|
69
|
+
# llvm_map_components_to_libnames() can pull in those LLVMSvf* libraries
|
|
70
|
+
# transitively. Exclude them so the standalone SVF build links only against
|
|
71
|
+
# its own SvfCore/SvfLLVM targets.
|
|
72
|
+
list(FILTER LLVM_LIBRARIES EXCLUDE REGEX "^LLVMSvf(Core|LLVM)$|^LLVMSVFAnalysis$")
|
|
68
73
|
endif()
|
|
69
74
|
|
|
70
75
|
# Search in the executables dir for this LLVM's clang instance
|
|
@@ -153,6 +158,16 @@ target_sources(
|
|
|
153
158
|
PRIVATE ${SVF_LLVM_SOURCES}
|
|
154
159
|
)
|
|
155
160
|
|
|
161
|
+
# GCC can report false-positive -Wmaybe-uninitialized warnings from LLVM's
|
|
162
|
+
# ValueMap/DenseMap internals when compiling this translation unit with heavy
|
|
163
|
+
# inlining. Keep the suppression scoped to the affected file.
|
|
164
|
+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
165
|
+
set_source_files_properties(
|
|
166
|
+
${CMAKE_CURRENT_LIST_DIR}/lib/LLVMModule.cpp
|
|
167
|
+
PROPERTIES COMPILE_OPTIONS "-Wno-maybe-uninitialized"
|
|
168
|
+
)
|
|
169
|
+
endif()
|
|
170
|
+
|
|
156
171
|
# Only expose the headers in the source tree to in-tree users of SVF
|
|
157
172
|
target_include_directories(SvfLLVM PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
|
|
158
173
|
|
|
@@ -208,17 +208,21 @@ typedef llvm::MinMaxIntrinsic MinMaxIntrinsic;
|
|
|
208
208
|
typedef llvm::BinaryOpIntrinsic BinaryOpIntrinsic;
|
|
209
209
|
typedef llvm::WithOverflowInst WithOverflowInst;
|
|
210
210
|
typedef llvm::SaturatingInst SaturatingInst;
|
|
211
|
+
#if LLVM_VERSION_MAJOR < 20
|
|
211
212
|
typedef llvm::AtomicMemIntrinsic AtomicMemIntrinsic;
|
|
212
213
|
typedef llvm::AtomicMemSetInst AtomicMemSetInst;
|
|
213
214
|
typedef llvm::AtomicMemTransferInst AtomicMemTransferInst;
|
|
214
215
|
typedef llvm::AtomicMemCpyInst AtomicMemCpyInst;
|
|
215
216
|
typedef llvm::AtomicMemMoveInst AtomicMemMoveInst;
|
|
217
|
+
#endif
|
|
216
218
|
typedef llvm::MemIntrinsic MemIntrinsic;
|
|
217
219
|
typedef llvm::MemSetInst MemSetInst;
|
|
218
220
|
typedef llvm::MemTransferInst MemTransferInst;
|
|
219
221
|
typedef llvm::MemCpyInst MemCpyInst;
|
|
220
222
|
typedef llvm::MemMoveInst MemMoveInst;
|
|
223
|
+
#if LLVM_VERSION_MAJOR < 20
|
|
221
224
|
typedef llvm::MemCpyInlineInst MemCpyInlineInst;
|
|
225
|
+
#endif
|
|
222
226
|
typedef llvm::AnyMemIntrinsic AnyMemIntrinsic;
|
|
223
227
|
typedef llvm::AnyMemSetInst AnyMemSetInst;
|
|
224
228
|
typedef llvm::AnyMemTransferInst AnyMemTransferInst;
|
|
@@ -314,7 +314,11 @@ inline static DataLayout* getDataLayout(Module* mod)
|
|
|
314
314
|
{
|
|
315
315
|
static DataLayout *dl = nullptr;
|
|
316
316
|
if (dl == nullptr)
|
|
317
|
+
#if LLVM_VERSION_MAJOR >= 19
|
|
318
|
+
dl = new DataLayout(mod->getDataLayout());
|
|
319
|
+
#else
|
|
317
320
|
dl = new DataLayout(mod);
|
|
321
|
+
#endif
|
|
318
322
|
return dl;
|
|
319
323
|
}
|
|
320
324
|
|
|
@@ -290,6 +290,8 @@ protected:
|
|
|
290
290
|
|
|
291
291
|
NodeID getGepValVar(const Value* val, const AccessPath& ap, const SVFType* elementType);
|
|
292
292
|
|
|
293
|
+
NodeID getDirectAccessFieldZeroValVar(const Value* ptr, const Type* accessTy);
|
|
294
|
+
|
|
293
295
|
void setCurrentBBAndValueForPAGEdge(PAGEdge* edge);
|
|
294
296
|
|
|
295
297
|
inline void addBlackHoleAddrEdge(NodeID node)
|
|
@@ -285,7 +285,7 @@ void LLVMModuleSet::prePassSchedule()
|
|
|
285
285
|
PB.registerLoopAnalyses(LAM);
|
|
286
286
|
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
|
|
287
287
|
llvm::FunctionPassManager FPM;
|
|
288
|
-
|
|
288
|
+
FPM.addPass(llvm::UnifyFunctionExitNodesPass());
|
|
289
289
|
FPM.run(fun, FAM);
|
|
290
290
|
#endif
|
|
291
291
|
}
|
|
@@ -518,11 +518,11 @@ void LLVMModuleSet::addSVFMain()
|
|
|
518
518
|
// Collect ctor and dtor functions
|
|
519
519
|
for (const GlobalVariable& global : mod.globals())
|
|
520
520
|
{
|
|
521
|
-
if (global.getName()
|
|
521
|
+
if (global.getName() == SVF_GLOBAL_CTORS && global.hasInitializer())
|
|
522
522
|
{
|
|
523
523
|
ctor_funcs = getLLVMGlobalFunctions(&global);
|
|
524
524
|
}
|
|
525
|
-
else if (global.getName()
|
|
525
|
+
else if (global.getName() == SVF_GLOBAL_DTORS && global.hasInitializer())
|
|
526
526
|
{
|
|
527
527
|
dtor_funcs = getLLVMGlobalFunctions(&global);
|
|
528
528
|
}
|
|
@@ -533,9 +533,9 @@ void LLVMModuleSet::addSVFMain()
|
|
|
533
533
|
{
|
|
534
534
|
auto funName = func.getName();
|
|
535
535
|
|
|
536
|
-
assert(!funName
|
|
536
|
+
assert(!(funName == SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
|
|
537
537
|
|
|
538
|
-
if (funName
|
|
538
|
+
if (funName == "main")
|
|
539
539
|
{
|
|
540
540
|
orgMain = &func;
|
|
541
541
|
mainMod = &mod;
|
|
@@ -737,8 +737,9 @@ void LLVMModuleSet::buildFunToFunMap()
|
|
|
737
737
|
{
|
|
738
738
|
appModule = appFunToReplace->getParent();
|
|
739
739
|
}
|
|
740
|
-
|
|
741
|
-
|
|
740
|
+
Function* clonedFunction = Function::Create(extFunToClone->getFunctionType(),
|
|
741
|
+
Function::ExternalLinkage,
|
|
742
|
+
extFunToClone->getName());
|
|
742
743
|
// Map the arguments of the new function to the arguments of extFunToClone
|
|
743
744
|
llvm::ValueToValueMapTy valueMap;
|
|
744
745
|
Function::arg_iterator destArg = clonedFunction->arg_begin();
|
|
@@ -821,8 +822,13 @@ void LLVMModuleSet::buildFunToFunMap()
|
|
|
821
822
|
std::string oldFunctionName = appFunToReplace->getName().str();
|
|
822
823
|
// Delete the old function
|
|
823
824
|
appFunToReplace->eraseFromParent();
|
|
825
|
+
appModule->getFunctionList().push_back(clonedFunction);
|
|
824
826
|
clonedFunction->setName(oldFunctionName);
|
|
825
827
|
}
|
|
828
|
+
else
|
|
829
|
+
{
|
|
830
|
+
appModule->getFunctionList().push_back(clonedFunction);
|
|
831
|
+
}
|
|
826
832
|
return clonedFunction;
|
|
827
833
|
};
|
|
828
834
|
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
#include "SVF-LLVM/CppUtil.h"
|
|
36
36
|
#include "SVF-LLVM/LLVMLoopAnalysis.h"
|
|
37
37
|
#include "SVF-LLVM/LLVMUtil.h"
|
|
38
|
+
#include "SVF-LLVM/ObjTypeInference.h"
|
|
38
39
|
#include "SVF-LLVM/SymbolTableBuilder.h"
|
|
39
40
|
#include "SVFIR/PAGBuilderFromFile.h"
|
|
40
41
|
#include "Util/CallGraphBuilder.h"
|
|
@@ -666,7 +667,24 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
|
|
|
666
667
|
if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
|
|
667
668
|
const Value* offsetVal = gi.getOperand();
|
|
668
669
|
assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
|
|
669
|
-
|
|
670
|
+
|
|
671
|
+
const ArrayType* inferredPtrArrayTy = nullptr;
|
|
672
|
+
const SVFType* idxGepTy = svfGepTy;
|
|
673
|
+
if (svfGepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
|
|
674
|
+
{
|
|
675
|
+
const Type* baseObjType =
|
|
676
|
+
LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(gepOp->getPointerOperand());
|
|
677
|
+
if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
|
|
678
|
+
{
|
|
679
|
+
if (arrTy->getElementType()->isPointerTy())
|
|
680
|
+
{
|
|
681
|
+
inferredPtrArrayTy = arrTy;
|
|
682
|
+
idxGepTy = llvmModuleSet()->getSVFType(arrTy);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
ap.addOffsetVarAndGepTypePair(getPAG()->getValVar(llvmModuleSet()->getValueNode(offsetVal)), idxGepTy);
|
|
670
688
|
|
|
671
689
|
//The int value of the current index operand
|
|
672
690
|
const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
|
|
@@ -675,6 +693,8 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
|
|
|
675
693
|
// but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
|
|
676
694
|
if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
|
|
677
695
|
{
|
|
696
|
+
if (!Options::ModelArrays() && arrTy->getElementType()->isPointerTy())
|
|
697
|
+
continue;
|
|
678
698
|
if(!op || (arrTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
|
|
679
699
|
continue;
|
|
680
700
|
APOffset idx = (u32_t)LLVMUtil::getIntegerValue(op).first;
|
|
@@ -700,6 +720,15 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
|
|
|
700
720
|
}
|
|
701
721
|
else if (gepTy->isSingleValueType())
|
|
702
722
|
{
|
|
723
|
+
if (inferredPtrArrayTy)
|
|
724
|
+
{
|
|
725
|
+
if (!op || (inferredPtrArrayTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
|
|
726
|
+
continue;
|
|
727
|
+
APOffset idx = (u32_t)LLVMUtil::getIntegerValue(op).first;
|
|
728
|
+
u32_t offset = pag->getFlattenedElemIdx(llvmModuleSet()->getSVFType(inferredPtrArrayTy), idx);
|
|
729
|
+
ap.setFldIdx(ap.getConstantStructFldIdx() + offset);
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
703
732
|
// If it's a non-constant offset access
|
|
704
733
|
// If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
|
|
705
734
|
// If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
|
|
@@ -1061,6 +1090,9 @@ void SVFIRBuilder::visitLoadInst(LoadInst &inst)
|
|
|
1061
1090
|
NodeID dst = getValueNode(&inst);
|
|
1062
1091
|
|
|
1063
1092
|
NodeID src = getValueNode(inst.getPointerOperand());
|
|
1093
|
+
const Type* loadedTy = inst.getType();
|
|
1094
|
+
if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), loadedTy))
|
|
1095
|
+
src = fieldZero;
|
|
1064
1096
|
|
|
1065
1097
|
addLoadEdge(src, dst);
|
|
1066
1098
|
}
|
|
@@ -1076,6 +1108,9 @@ void SVFIRBuilder::visitStoreInst(StoreInst &inst)
|
|
|
1076
1108
|
DBOUT(DPAGBuild, outs() << "process store " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
|
|
1077
1109
|
|
|
1078
1110
|
NodeID dst = getValueNode(inst.getPointerOperand());
|
|
1111
|
+
const Type* storedTy = inst.getValueOperand()->getType();
|
|
1112
|
+
if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), storedTy))
|
|
1113
|
+
dst = fieldZero;
|
|
1079
1114
|
|
|
1080
1115
|
NodeID src = getValueNode(inst.getValueOperand());
|
|
1081
1116
|
|
|
@@ -1106,6 +1141,19 @@ void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst)
|
|
|
1106
1141
|
|
|
1107
1142
|
AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
|
|
1108
1143
|
bool constGep = computeGepOffset(&inst, ap);
|
|
1144
|
+
if (constGep && ap.getConstantStructFldIdx() == 0 && !Options::ModelArrays())
|
|
1145
|
+
{
|
|
1146
|
+
const Type* baseObjType =
|
|
1147
|
+
LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(inst.getPointerOperand());
|
|
1148
|
+
if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
|
|
1149
|
+
{
|
|
1150
|
+
if (arrTy->getElementType()->isPointerTy())
|
|
1151
|
+
{
|
|
1152
|
+
addCopyEdge(src, dst, CopyStmt::COPYVAL);
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1109
1157
|
addGepEdge(src, dst, ap, constGep);
|
|
1110
1158
|
}
|
|
1111
1159
|
|
|
@@ -1548,6 +1596,32 @@ const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
|
|
|
1548
1596
|
{
|
|
1549
1597
|
const Value* value = stripAllCasts(V);
|
|
1550
1598
|
assert(value && "null ptr?");
|
|
1599
|
+
auto getGlobalFieldFromByteOffset =
|
|
1600
|
+
[this](const GlobalVariable* glob, int64_t byteOffset) -> const Value*
|
|
1601
|
+
{
|
|
1602
|
+
if (!glob || !glob->hasInitializer())
|
|
1603
|
+
return nullptr;
|
|
1604
|
+
|
|
1605
|
+
auto* initializer = SVFUtil::dyn_cast<ConstantStruct>(glob->getInitializer());
|
|
1606
|
+
auto* structType = SVFUtil::dyn_cast<StructType>(glob->getValueType());
|
|
1607
|
+
if (!initializer || !structType)
|
|
1608
|
+
return nullptr;
|
|
1609
|
+
|
|
1610
|
+
DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
|
|
1611
|
+
const StructLayout* layout =
|
|
1612
|
+
dataLayout->getStructLayout(const_cast<StructType*>(structType));
|
|
1613
|
+
for (u32_t fieldIdx = 0; fieldIdx < initializer->getNumOperands(); ++fieldIdx)
|
|
1614
|
+
{
|
|
1615
|
+
if (layout->getElementOffset(fieldIdx) != static_cast<uint64_t>(byteOffset))
|
|
1616
|
+
continue;
|
|
1617
|
+
if (auto* ptrValue =
|
|
1618
|
+
SVFUtil::dyn_cast<llvm::GlobalVariable>(initializer->getOperand(fieldIdx)))
|
|
1619
|
+
return ptrValue;
|
|
1620
|
+
return nullptr;
|
|
1621
|
+
}
|
|
1622
|
+
return nullptr;
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1551
1625
|
if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
|
|
1552
1626
|
{
|
|
1553
1627
|
APOffset totalidx = 0;
|
|
@@ -1564,34 +1638,72 @@ const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
|
|
|
1564
1638
|
const Value* loadP = load->getPointerOperand();
|
|
1565
1639
|
if (const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(loadP))
|
|
1566
1640
|
{
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
totalidx += LLVMUtil::getIntegerValue(op).first;
|
|
1572
|
-
}
|
|
1641
|
+
DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
|
|
1642
|
+
llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gep->getPointerAddressSpace()), 0, true);
|
|
1643
|
+
const bool hasByteOffset = dataLayout && gep->accumulateConstantOffset(*dataLayout, byteOffset);
|
|
1644
|
+
|
|
1573
1645
|
const Value * pointer_operand = gep->getPointerOperand();
|
|
1574
1646
|
if (auto *glob = SVFUtil::dyn_cast<GlobalVariable>(pointer_operand))
|
|
1575
1647
|
{
|
|
1576
|
-
if (
|
|
1648
|
+
if (hasByteOffset)
|
|
1649
|
+
{
|
|
1650
|
+
if (const Value* ptrValue = getGlobalFieldFromByteOffset(glob, byteOffset.getSExtValue()))
|
|
1651
|
+
return ptrValue;
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
else if (hasByteOffset && !byteOffset.isNegative() &&
|
|
1655
|
+
SVFUtil::isa<AllocaInst>(pointer_operand) && load->getType()->isPointerTy())
|
|
1656
|
+
{
|
|
1657
|
+
const u64_t offset = byteOffset.getZExtValue();
|
|
1658
|
+
const u64_t accessBytes = dataLayout->getPointerSize(gep->getPointerAddressSpace());
|
|
1659
|
+
|
|
1660
|
+
auto isCoveredByMemcpy = [offset, accessBytes](const CallBase* cs) -> bool
|
|
1661
|
+
{
|
|
1662
|
+
if (cs->arg_size() < 3)
|
|
1663
|
+
return false;
|
|
1664
|
+
|
|
1665
|
+
const auto* copySize = SVFUtil::dyn_cast<ConstantInt>(cs->getArgOperand(2));
|
|
1666
|
+
if (!copySize)
|
|
1667
|
+
return false;
|
|
1668
|
+
|
|
1669
|
+
const u64_t copyBytes = copySize->getZExtValue();
|
|
1670
|
+
return copyBytes >= accessBytes && copyBytes - accessBytes >= offset;
|
|
1671
|
+
};
|
|
1672
|
+
|
|
1673
|
+
auto hasInterveningWrite = [load](const Instruction* from) -> bool
|
|
1577
1674
|
{
|
|
1578
|
-
if (
|
|
1579
|
-
|
|
1675
|
+
if (from->getParent() != load->getParent() || !from->comesBefore(load))
|
|
1676
|
+
return true;
|
|
1677
|
+
|
|
1678
|
+
auto it = from->getIterator();
|
|
1679
|
+
const auto end = load->getIterator();
|
|
1680
|
+
while (++it != end)
|
|
1580
1681
|
{
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1682
|
+
if (it->mayWriteToMemory())
|
|
1683
|
+
return true;
|
|
1684
|
+
}
|
|
1685
|
+
return false;
|
|
1686
|
+
};
|
|
1687
|
+
|
|
1688
|
+
for (const auto& use : pointer_operand->users())
|
|
1689
|
+
{
|
|
1690
|
+
const auto* cs = SVFUtil::dyn_cast<CallBase>(use);
|
|
1691
|
+
if (!cs || cs->getParent() != load->getParent() ||
|
|
1692
|
+
cs->arg_size() < 1 ||
|
|
1693
|
+
stripAllCasts(cs->getArgOperand(0)) != pointer_operand)
|
|
1694
|
+
continue;
|
|
1695
|
+
|
|
1696
|
+
const Function* calledFun = cs->getCalledFunction();
|
|
1697
|
+
if (!LLVMUtil::isMemcpyExtFun(calledFun) || !isCoveredByMemcpy(cs) ||
|
|
1698
|
+
hasInterveningWrite(cs))
|
|
1699
|
+
continue;
|
|
1700
|
+
|
|
1701
|
+
const Value* copiedFrom = getBaseValueForExtArg(cs->getArgOperand(1));
|
|
1702
|
+
if (const auto* copiedGlob = SVFUtil::dyn_cast<GlobalVariable>(copiedFrom))
|
|
1703
|
+
{
|
|
1704
|
+
if (const Value* ptrValue =
|
|
1705
|
+
getGlobalFieldFromByteOffset(copiedGlob, byteOffset.getSExtValue()))
|
|
1593
1706
|
return ptrValue;
|
|
1594
|
-
}
|
|
1595
1707
|
}
|
|
1596
1708
|
}
|
|
1597
1709
|
}
|
|
@@ -1721,6 +1833,22 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const
|
|
|
1721
1833
|
return gepval;
|
|
1722
1834
|
}
|
|
1723
1835
|
|
|
1836
|
+
NodeID SVFIRBuilder::getDirectAccessFieldZeroValVar(const Value* ptr, const Type* accessTy)
|
|
1837
|
+
{
|
|
1838
|
+
if (!Options::ModelArrays() || SVFUtil::isa<llvm::GEPOperator>(ptr))
|
|
1839
|
+
return 0;
|
|
1840
|
+
|
|
1841
|
+
const Type* objTy =
|
|
1842
|
+
LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(ptr);
|
|
1843
|
+
const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(objTy);
|
|
1844
|
+
if (!arrTy || !arrTy->getElementType()->isPointerTy() ||
|
|
1845
|
+
arrTy->getElementType() != accessTy)
|
|
1846
|
+
return 0;
|
|
1847
|
+
|
|
1848
|
+
AccessPath ap(0, llvmModuleSet()->getSVFType(arrTy));
|
|
1849
|
+
return getGepValVar(ptr, ap, llvmModuleSet()->getSVFType(accessTy));
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1724
1852
|
|
|
1725
1853
|
/*
|
|
1726
1854
|
* curVal <--------> PAGEdge
|
|
@@ -38,6 +38,89 @@ using namespace SVF;
|
|
|
38
38
|
using namespace SVFUtil;
|
|
39
39
|
using namespace LLVMUtil;
|
|
40
40
|
|
|
41
|
+
namespace
|
|
42
|
+
{
|
|
43
|
+
|
|
44
|
+
struct MemcpyField
|
|
45
|
+
{
|
|
46
|
+
APOffset byteOffset;
|
|
47
|
+
AccessPath accessPath;
|
|
48
|
+
const SVFType* elementType;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
void collectMemcpyFields(
|
|
52
|
+
const Type* llvmType,
|
|
53
|
+
const SVFType* svfType,
|
|
54
|
+
const DataLayout& dl,
|
|
55
|
+
IRGraph* pag,
|
|
56
|
+
std::vector<MemcpyField>& fields,
|
|
57
|
+
APOffset baseByteOffset = 0,
|
|
58
|
+
APOffset baseFldIdx = 0)
|
|
59
|
+
{
|
|
60
|
+
if (llvmType == nullptr || svfType == nullptr)
|
|
61
|
+
return;
|
|
62
|
+
|
|
63
|
+
if (svfType->isPointerTy())
|
|
64
|
+
{
|
|
65
|
+
fields.push_back({baseByteOffset, AccessPath(baseFldIdx), svfType});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (const auto* structType = SVFUtil::dyn_cast<StructType>(llvmType))
|
|
70
|
+
{
|
|
71
|
+
const StructLayout* layout = dl.getStructLayout(const_cast<StructType*>(structType));
|
|
72
|
+
for (u32_t i = 0; i < structType->getNumElements(); ++i)
|
|
73
|
+
{
|
|
74
|
+
const Type* elemLLVMType = structType->getElementType(i);
|
|
75
|
+
const SVFType* elemSVFType = pag->getOriginalElemType(svfType, i);
|
|
76
|
+
if (elemSVFType == nullptr)
|
|
77
|
+
return;
|
|
78
|
+
APOffset elemByteOffset = baseByteOffset + static_cast<APOffset>(layout->getElementOffset(i));
|
|
79
|
+
APOffset elemFldIdx = baseFldIdx + pag->getFlattenedElemIdx(svfType, i);
|
|
80
|
+
collectMemcpyFields(elemLLVMType, elemSVFType, dl, pag, fields, elemByteOffset, elemFldIdx);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (const auto* arrayType = SVFUtil::dyn_cast<ArrayType>(llvmType))
|
|
86
|
+
{
|
|
87
|
+
const Type* elemLLVMType = arrayType->getElementType();
|
|
88
|
+
const SVFType* elemSVFType = pag->getOriginalElemType(svfType, 0);
|
|
89
|
+
if (elemSVFType == nullptr)
|
|
90
|
+
return;
|
|
91
|
+
const APOffset elemByteSize = static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(elemLLVMType)));
|
|
92
|
+
for (u32_t i = 0; i < arrayType->getNumElements(); ++i)
|
|
93
|
+
{
|
|
94
|
+
APOffset elemByteOffset = baseByteOffset + i * elemByteSize;
|
|
95
|
+
APOffset elemFldIdx = baseFldIdx + pag->getFlattenedElemIdx(svfType, i);
|
|
96
|
+
collectMemcpyFields(elemLLVMType, elemSVFType, dl, pag, fields, elemByteOffset, elemFldIdx);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
std::vector<MemcpyField> getMemcpyFields(const Value* value, const Type* llvmType, const SVFType* svfType)
|
|
102
|
+
{
|
|
103
|
+
std::vector<MemcpyField> fields;
|
|
104
|
+
auto* mset = LLVMModuleSet::getLLVMModuleSet();
|
|
105
|
+
auto* pag = PAG::getPAG();
|
|
106
|
+
const DataLayout& dl = mset->getMainLLVMModule()->getDataLayout();
|
|
107
|
+
collectMemcpyFields(llvmType, svfType, dl, pag, fields);
|
|
108
|
+
return fields;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const Type* getMemcpyLayoutType(const Value* baseValue, const Type* fallbackType)
|
|
112
|
+
{
|
|
113
|
+
if (const auto* allocaInst = llvm::dyn_cast_or_null<AllocaInst>(baseValue))
|
|
114
|
+
return allocaInst->getAllocatedType();
|
|
115
|
+
|
|
116
|
+
if (const auto* global = llvm::dyn_cast_or_null<GlobalVariable>(baseValue))
|
|
117
|
+
return global->getValueType();
|
|
118
|
+
|
|
119
|
+
return fallbackType;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
|
|
41
124
|
/*!
|
|
42
125
|
* Find the base type and the max possible offset of an object pointed to by (V).
|
|
43
126
|
*/
|
|
@@ -109,6 +192,58 @@ void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue
|
|
|
109
192
|
return;
|
|
110
193
|
}
|
|
111
194
|
|
|
195
|
+
const Value* dstBase = getBaseValueForExtArg(D);
|
|
196
|
+
const Value* srcBase = getBaseValueForExtArg(S);
|
|
197
|
+
Value* dstFieldBase = LLVMUtil::isObject(dstBase) ? const_cast<Value*>(dstBase) : D;
|
|
198
|
+
Value* srcFieldBase = LLVMUtil::isObject(srcBase) ? const_cast<Value*>(srcBase) : S;
|
|
199
|
+
const Type* dstLayoutType = getMemcpyLayoutType(dstBase, dtype);
|
|
200
|
+
const Type* srcLayoutType = getMemcpyLayoutType(srcBase, stype);
|
|
201
|
+
const bool hasRemappedGlobalBase =
|
|
202
|
+
(dstFieldBase != D && SVFUtil::isa<GlobalVariable>(dstFieldBase)) ||
|
|
203
|
+
(srcFieldBase != S && SVFUtil::isa<GlobalVariable>(srcFieldBase));
|
|
204
|
+
const bool useByteLayoutMemcpy =
|
|
205
|
+
hasRemappedGlobalBase || (dstLayoutType != dtype) || (srcLayoutType != stype);
|
|
206
|
+
if (useByteLayoutMemcpy)
|
|
207
|
+
{
|
|
208
|
+
const SVFType* dstSVFType = llvmModuleSet()->getSVFType(dstLayoutType);
|
|
209
|
+
const SVFType* srcSVFType = llvmModuleSet()->getSVFType(srcLayoutType);
|
|
210
|
+
std::vector<MemcpyField> dstMemcpyFields = getMemcpyFields(D, dstLayoutType, dstSVFType);
|
|
211
|
+
std::vector<MemcpyField> srcMemcpyFields = getMemcpyFields(S, srcLayoutType, srcSVFType);
|
|
212
|
+
if (dstMemcpyFields.empty() || srcMemcpyFields.empty())
|
|
213
|
+
goto fallback_memcpy_copy;
|
|
214
|
+
|
|
215
|
+
std::unordered_map<APOffset, MemcpyField> srcFieldsByByteOffset;
|
|
216
|
+
for (const auto& field : srcMemcpyFields)
|
|
217
|
+
srcFieldsByByteOffset.emplace(field.byteOffset, field);
|
|
218
|
+
|
|
219
|
+
const DataLayout& dl = llvmModuleSet()->getMainLLVMModule()->getDataLayout();
|
|
220
|
+
APOffset copyBytes = std::min<APOffset>(
|
|
221
|
+
static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(dstLayoutType))),
|
|
222
|
+
static_cast<APOffset>(dl.getTypeAllocSize(const_cast<Type*>(srcLayoutType))));
|
|
223
|
+
if (szValue && SVFUtil::isa<ConstantInt>(szValue))
|
|
224
|
+
{
|
|
225
|
+
auto szIntVal = LLVMUtil::getIntegerValue(SVFUtil::cast<ConstantInt>(szValue));
|
|
226
|
+
copyBytes = std::min(copyBytes, static_cast<APOffset>(szIntVal.first));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (const auto& dstField : dstMemcpyFields)
|
|
230
|
+
{
|
|
231
|
+
if (dstField.byteOffset >= copyBytes)
|
|
232
|
+
continue;
|
|
233
|
+
auto it = srcFieldsByByteOffset.find(dstField.byteOffset);
|
|
234
|
+
if (it == srcFieldsByByteOffset.end())
|
|
235
|
+
continue;
|
|
236
|
+
|
|
237
|
+
NodeID dField = getGepValVar(dstFieldBase, dstField.accessPath, dstField.elementType);
|
|
238
|
+
NodeID sField = getGepValVar(srcFieldBase, it->second.accessPath, it->second.elementType);
|
|
239
|
+
NodeID dummy = pag->addDummyValNode();
|
|
240
|
+
addLoadEdge(sField, dummy);
|
|
241
|
+
addStoreEdge(dummy, dField);
|
|
242
|
+
}
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
fallback_memcpy_copy:
|
|
112
247
|
//For each field (i), add (Ti = *S + i) and (*D + i = Ti).
|
|
113
248
|
for (u32_t index = 0; index < sz; index++)
|
|
114
249
|
{
|
|
@@ -290,4 +425,4 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const Function* callee)
|
|
|
290
425
|
}
|
|
291
426
|
|
|
292
427
|
/// TODO: inter-procedural SVFIR edges for thread joins
|
|
293
|
-
}
|
|
428
|
+
}
|