Я уверен, что это действительно просто, но я пытался разобраться в этом больше часа и не могу понять.
Следующий код дает мне ошибку сегментации:
Value *newArray = mBuilder.CreateGEP(alloca, value); // alloca is a `StructType`
но это не
Value *newArray = mBuilder.CreateGEP(alloca, ConstantInt::get(mContext, APInt(32, 0)));
Значение value
%bar1 = load double, double* %bar
%3 = fptoui double %bar1 to i32
Отладка
Когда я отлаживаю его с помощью lldb, я получаю:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001000b9e6e a.out`llvm::PointerType::get(llvm::Type*, unsigned int) + 20
a.out`llvm::PointerType::get:
-> 0x1000b9e6e <+20>: movq (%rdi), %rax
Вопрос
Почему у меня возникает ошибка сегментации и как ее исправить?
Как воспроизвести проблему?
Следующий код воспроизводит проблему:
#include <vector>
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Value.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
using namespace llvm;
static LLVMContext mContext;
static IRBuilder<> mBuilder(mContext);
static std::unique_ptr<Module> mModule = make_unique<Module>("example", mContext);
static Module *M = mModule.get();
static Type *dType = Type::getDoubleTy(mContext);
static Type *i32 = IntegerType::get(mContext, 32);
// helper functions
static AllocaInst *entryCreateBlockAllocaType(Function *func, std::string name, Type* type) {
IRBuilder<> tmpBuilder(&func->getEntryBlock(), func->getEntryBlock().begin());
return tmpBuilder.CreateAlloca(type, nullptr, name);
}
static ArrayRef<Value *> PrefixZero (Value *index) {
std::vector<Value *> out;
out.push_back(ConstantInt::get(mContext, APInt(32, 0)));
out.push_back(index);
return ArrayRef<Value *>(out);
}
static AllocaInst *createVariable () {
auto *func = mBuilder.GetInsertBlock()->getParent();
auto *initValue = ConstantInt::get(mContext, APInt(32, 0));
auto *alloca = entryCreateBlockAllocaType(func, "var", initValue->getType());
mBuilder.CreateStore(initValue, alloca);
return alloca;
}
static std::vector<Type *> elementTypes (3, dType);
static AllocaInst *createStruct () {
auto *func = mBuilder.GetInsertBlock()->getParent();
auto *mStructType = StructType::get(mContext, elementTypes);
return entryCreateBlockAllocaType(func, "str", mStructType);
}
int main () {
// create a main function
auto *FT = FunctionType::get(i32, std::vector<Type *>(), false);
auto *f = Function::Create(FT, Function::ExternalLinkage, "main", M);
// set insert point for out below code
auto *bb = BasicBlock::Create(mContext, "entry", f);
mBuilder.SetInsertPoint(bb);
// Create a variable
auto *variable = createVariable();
// create a struct
auto *mStruct = createStruct();
// Create a GEP with the loaded index
auto *loadedVar = mBuilder.CreateLoad(variable, "loaded_index");
// This is where the problem is.
// If `PrefixZero` is changed to `ConstantInt::get(mContext, APInt(32, 0))` this works
auto *elementPtr = mBuilder.CreateGEP(mStruct, PrefixZero(loadedVar));
mBuilder.CreateRet(ConstantInt::get(mContext, APInt(32, 0)));
f->print(errs()); // print out the function
return 1;
}
alloca
- это структура или указатель на структуру? GEP всегда принимает указатель. Если вы еще этого не сделали, попробуйте собрать LLVM с включенными утверждениями. Надеюсь, это даст вам ошибку утверждения с правильным сообщением об ошибке, а не ошибку сегментации. Если это не помогает, опубликуйте MCVE, который я или кто-то другой могу использовать для воспроизведения проблемы. - person sepp2k   schedule 15.06.2018Builder.CreateAlloca
). Я попытаюсь создать llvm с включенными утверждениями и соответствующим образом обновлю свой вопрос. - person zoecarver   schedule 15.06.2018-LLVM_ENABLE_ASSERTIONS=ON
, но ничего не изменилось (AFAIK). Я обновил вопрос, добавив ссылку на созданный мной репозиторий, в котором показано, как воспроизвести проблему. github.com/pudility/GEP_Segmentation_fault - person zoecarver   schedule 15.06.2018