Clang 将`[<;长度>;x i8]*`转换为`i8*`

Clang 将`[<;长度>;x i8]*`转换为`i8*`,clang,llvm,llvm-ir,Clang,Llvm,Llvm Ir,我正在尝试将参数替换为现有函数调用。初始参数是一个全局字符串,我试图用一个本地字符串替换它 无论我尝试什么,我都会得到一个调用参数类型与函数签名不匹配运行时错误 具体来说,我想将参数替换为printf函数-declare dso_local i32@printf(i8*,…)#1。代码中对它的调用如下所示: @message = dso_local global [12 x i8] c"Hello World\00", align 1 ... %call = call i32

我正在尝试将参数替换为现有函数调用。初始参数是一个全局字符串,我试图用一个本地字符串替换它

无论我尝试什么,我都会得到一个
调用参数类型与函数签名不匹配运行时错误

具体来说,我想将参数替换为
printf
函数-
declare dso_local i32@printf(i8*,…)#1
。代码中对它的调用如下所示:

@message = dso_local global [12 x i8] c"Hello World\00", align 1
...
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @message, i64 0, i64 0))
我分配并GEP本地替换字符串,如下所示:

%0 = alloca [12 x i8], align 1
%1 = getelementptr inbounds [12 x i8], [12 x i8]* %0, i64 0
但是,当我在
%call
上使用
setOperand()
将参数替换为
%1
时,会出现上述错误。我猜
[12 x i8]*
i8*
不同,但我找不到一种方法来铸造它

我已尝试使用
CreatePointerCast()
强制转换,它创建了以下内容:

%2 = addrspacecast [12 x i8]* %1 to i8 addrspace(8)*
但是得到了相同的错误(我想,
%2
的类型是
i8 addrspace(8)*
,这与
i8*
不同)

创建GEP时,还尝试显式指定
i8*
类型:

Builder->CreateInBoundsGEP(llvm::Type::getInt8PtrTy(Ctx, 8), ...)

没用。

我认为您错误地使用了
GEP
指令

还记得您提供的
[12 x i8]*
类型指针上的第一个索引步骤吗?第二个索引指定帮助计算字符串第一个字符的起始地址,这可能是您遗漏的