6 #include <gtest/gtest.h>
14 #include <llvm/IR/BasicBlock.h>
15 #include <llvm/IR/IRBuilder.h>
16 #include <llvm/IR/Module.h>
18 TEST(FunctionCallTests, test_function_call)
20 auto setup = [](llvm::LLVMContext & ctx)
24 std::unique_ptr<Module> module(
new Module(
"module", ctx));
26 auto int64 = Type::getIntNTy(ctx, 64);
27 auto clrtype = FunctionType::get(Type::getVoidTy(ctx), {},
false);
28 auto caller = Function::Create(clrtype, GlobalValue::ExternalLinkage,
"caller", module.get());
30 auto bb = BasicBlock::Create(ctx,
"bb", caller);
32 auto c = ConstantInt::get(int64, 45);
33 auto cletype = FunctionType::get(int64, ArrayRef<Type *>(std::vector<Type *>(2, int64)),
false);
34 auto callee = module->getOrInsertFunction(
"callee", cletype);
36 IRBuilder<> builder(bb);
37 builder.CreateCall(callee, ArrayRef<Value *>(std::vector<Value *>(2, c)));
38 builder.CreateRetVoid();
48 for (
auto & node : module.ipgraph())
50 if (node.name() ==
"caller")
58 EXPECT_TRUE(is<CallOperation>(*std::next(bb->rbegin(), 2)));
61 llvm::LLVMContext ctx;
62 auto llvmModule = setup(ctx);
63 llvmModule->print(llvm::errs(),
nullptr);
66 print(*ipgmod, stdout);
71 TEST(FunctionCallTests, test_malloc_call)
73 auto setup = [](llvm::LLVMContext & ctx)
77 std::unique_ptr<Module> module(
new Module(
"module", ctx));
79 auto int8 = Type::getIntNTy(ctx, 8);
80 auto int64 = Type::getIntNTy(ctx, 64);
81 auto ptrint8 = PointerType::get(int8, 0);
83 auto clrtype = FunctionType::get(Type::getVoidTy(ctx), {},
false);
84 auto caller = Function::Create(clrtype, GlobalValue::ExternalLinkage,
"caller", module.get());
86 auto bb = BasicBlock::Create(ctx,
"bb", caller);
88 auto c = ConstantInt::get(int64, 45);
89 auto malloctype = FunctionType::get(ptrint8, ArrayRef<Type *>(int64),
false);
90 auto malloc = module->getOrInsertFunction(
"malloc", malloctype);
92 IRBuilder<> builder(bb);
93 builder.CreateCall(malloc, ArrayRef<Value *>(c));
94 builder.CreateRetVoid();
104 for (
auto & node : module.ipgraph())
106 if (node.name() ==
"caller")
114 EXPECT_TRUE(is<MemoryStateMergeOperation>(*std::next(bb->rbegin())));
115 EXPECT_TRUE(is<MallocOperation>((*std::next(bb->rbegin(), 3))));
118 llvm::LLVMContext ctx;
119 auto llvmModule = setup(ctx);
120 llvmModule->print(llvm::errs(),
nullptr);
123 print(*ipgmod, stdout);
128 TEST(FunctionCallTests, test_free_call)
130 auto setup = [](llvm::LLVMContext & ctx)
132 using namespace llvm;
134 std::unique_ptr<Module> module(
new Module(
"module", ctx));
136 auto int8 = Type::getIntNTy(ctx, 8);
137 auto ptrint8 = PointerType::get(int8, 0);
139 auto clrtype = FunctionType::get(Type::getVoidTy(ctx), { ptrint8 },
false);
140 auto caller = Function::Create(clrtype, GlobalValue::ExternalLinkage,
"caller", module.get());
142 auto bb = BasicBlock::Create(ctx,
"bb", caller);
144 auto freetype = FunctionType::get(Type::getVoidTy(ctx), ArrayRef<Type *>(ptrint8),
false);
145 auto free = module->getOrInsertFunction(
"free", freetype);
147 IRBuilder<> builder(bb);
148 builder.CreateCall(free, ArrayRef<Value *>(caller->getArg(0)));
149 builder.CreateRetVoid();
159 for (
auto & node : module.ipgraph())
161 if (node.name() ==
"caller")
169 EXPECT_TRUE(is<AssignmentOperation>(*bb->rbegin()));
170 EXPECT_TRUE(is<AssignmentOperation>(*std::next(bb->rbegin())));
171 EXPECT_TRUE(is<FreeOperation>(*std::next(bb->rbegin(), 2)));
174 llvm::LLVMContext ctx;
175 auto llvmModule = setup(ctx);
176 llvmModule->print(llvm::errs(),
nullptr);
179 print(*ipgmod, stdout);
TEST(FunctionCallTests, test_function_call)
ControlFlowGraphNode * sink() const noexcept
ControlFlowGraphEdge * OutEdge(size_t n) const
EntryNode * entry() const noexcept
Global memory state passed between functions.
void print(const AggregationNode &n, const AnnotationMap &dm, FILE *out)
std::unique_ptr< InterProceduralGraphModule > ConvertLlvmModule(::llvm::Module &llvmModule)