我正在尝试用LLVM和C++编写一个玩具编译器.但每当我尝试使用多个索引创建一个GetElementPtrInst时,就会出现一个Segfault.关于这条指令的文档对我没有帮助(API-文档 语言 - 文档)
我的llvm版本是3.1,这是在Arch Linux上.刚刚在另一台Arch机器上测试它并得到了同样的错误.
难道我做错了什么?
这是一个小工作程序来说明我的问题.它可以编译为:
g++ -o segfault_example segfault_example.cpp -Wall -Wextra -pedantic \
`llvm-config --libs core jit native --cxxflags --ldflags`
Run Code Online (Sandbox Code Playgroud)
#include <llvm/Module.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/LLVMContext.h>
#include <llvm/Instructions.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/ADT/ArrayRef.h>
#include <string>
#include <iostream>
static llvm::LLVMContext& global = llvm::getGlobalContext();
static llvm::Type* int32ty = llvm::Type::getInt32Ty(global);
llvm::ConstantInt* getInt32(int n)
{
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(global), n);
}
int main()
{
//setup everything for a minimal example
llvm::Module* mainModule = new llvm::Module("main", global);
llvm::FunctionType* ftype = llvm::FunctionType::get(int32ty, false);
llvm::Function* mainFunction = llvm::Function::Create(
ftype, llvm::GlobalValue::InternalLinkage, "main", mainModule);
llvm::BasicBlock* bblock = llvm::BasicBlock::Create(
global, "entry", mainFunction, 0);
llvm::AllocaInst* mem = new llvm::AllocaInst(llvm::Type::getInt32PtrTy(global, 0x1000)
, getInt32(0x1000), 0x1000, "mem", bblock);
//tests
//this works
std::cout << "Testing with one element vector" << std::endl;
std::vector<llvm::Value*> vect_1;
vect_1.push_back(getInt32(0));
llvm::GetElementPtrInst* gep1 =
llvm::GetElementPtrInst::CreateInBounds(mem, llvm::ArrayRef<llvm::Value*>(vect_1)
, "retval", bblock);
std::cout << "done" << std::endl;
//this works too, but I can't find this signature in the documentation
std::cout << "Testing with Value* instead of ArrayRef" << std::endl;
llvm::GetElementPtrInst::CreateInBounds(mem, getInt32(0), "retval", bblock);
std::cout << "done" << std::endl;
//this segfaults
std::cout << "Filling two element vector" << std::endl;
std::vector<llvm::Value*> vect_2;
vect_2.push_back(getInt32(0));
vect_2.push_back(getInt32(1));
std::cout << "Testing with two element vector" << std::endl;
//segfault
llvm::GetElementPtrInst* gep2 =
llvm::GetElementPtrInst::CreateInBounds(mem, llvm::ArrayRef<llvm::Value*>(vect_2)
, "retval", bblock);
std::cout << "done" << std::endl;
mainModule->dump();
llvm::verifyFunction(*mainFunction);
}
Run Code Online (Sandbox Code Playgroud)
发现错误.我将尝试解释原因和我的解决方案,但解释可能是错误的.
这种类型mem错了.(在我的情况下)它需要声明使用new llvm::AllocaInst(llvm::ArrayType::get(int32ty, 100), "mem", bblock);.创建两个间接层(解释为什么有两个间接).前一种类型只有一个间接并用它取消引用,GetElementPtrInst因此两个元素向量不起作用.
当我在浏览器中使用llvm并发出LLVM C++ Api代码时,我注意到了这一点.
您可以在命令行上为C示例文件创建C++ Api代码,如下所示:
clang -c -emit-llvm -o ex.bf example.c
llc -march=cpp -o ex.cpp ex.bf
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1592 次 |
| 最近记录: |