<badref> 当使用 CallInst::CreateMalloc 作为结构类型时

<badref> when using CallInst::CreateMalloc for a struct type

本文关键字:CreateMalloc 结构 类型 badref lt gt CallInst      更新时间:2023-10-16

我正在尝试为代码(玩具语言(生成类似于以下C++代码的LLVM IR:

struct test {
int a;
int b;
int c;
};
int main() {
tempVar *a;
a = new test();
}

不幸的是,当我运行verifyModule时,我收到以下错误消息:

Instruction referencing instruction not embedded in a basic block!
%malloccall = tail call i8* @malloc(i64 mul nuw (i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64), i64 3))
<badref> = bitcast i8* %malloccall to %test*

以下 MWE 重现了该问题:

#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <vector>
using namespace llvm;
std::map<std::string, StructType *> allocatedClasses;
std::map<std::string, std::vector<Type *>> classSizes;
static LLVMContext TheContext;
static IRBuilder<> Builder(TheContext);
static std::map<std::string, AllocaInst *> NamedValues;
int main() {
static std::unique_ptr<Module> TheModule;
TheModule = std::make_unique<Module>("inputFile", TheContext);
allocatedClasses["test"] = StructType::create(TheContext, "test");
classSizes["test"] = std::vector<Type *>(3, Type::getInt32Ty(TheContext));
allocatedClasses["test"]->setBody(classSizes["test"]);
FunctionType *mainType = FunctionType::get(Builder.getInt32Ty(), false);
Function *main = Function::Create(mainType, Function::ExternalLinkage, "main",
TheModule.get());
BasicBlock *entry = BasicBlock::Create(TheContext, "entry", main);
Builder.SetInsertPoint(entry);
std::string tV = "tempVar";
NamedValues[tV] = Builder.CreateAlloca(
PointerType::get(allocatedClasses["test"], 0), nullptr, tV);
auto typeSize = ConstantExpr::getSizeOf(allocatedClasses["test"]);
typeSize =
ConstantExpr::getTruncOrBitCast(typeSize, Type::getInt64Ty(TheContext));
CallInst::CreateMalloc(Builder.GetInsertBlock(), Type::getInt64Ty(TheContext),
allocatedClasses["test"], typeSize, nullptr, nullptr,
"");
Builder.CreateRet(ConstantInt::get(TheContext, APInt(32, 0)));
TheModule->print(outs(), nullptr);
Module *test = TheModule.get();
verifyModule(*test, &errs());
}

我编译这个clang++ `llvm-config --cxxflags --ldflags --system-libs --libs all` -g ex.cpp,在x86上使用clang版本10.0.0-4ubuntu1。执行时,程序输出:

; ModuleID = 'inputFile'
source_filename = "inputFile"
%test = type { i32, i32, i32 }
define i32 @main() {
entry:
%tempVar = alloca %test*
%malloccall = tail call i8* @malloc(i64 mul nuw (i64 ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64), i64 3))
ret i32 0
}
declare noalias i8* @malloc(i64)

以及上面的错误消息。

我在这里做错了什么?

您调用的函数的文档显示"注意:此函数不会将位广播添加到基本块,这是调用方的责任。

我不知道为什么不,但来电者是你。