分段错误 - 访问从LLVM IR代码传递的数组元素

时间:2018-05-25 02:28:45

标签: compiler-construction llvm clang++ llvm-ir

我有一个程序在我使用C ++运行时工作正常但是,当我从我的LLVM IR代码调用它时它不起作用。

功能(library / library.cpp)

extern "C" DLLEXPORT double *DOT(double A[3][3], double B[3][3]) {
  std::cout << A[0][0] << std::endl;
...
}

LLVM IR(out.ll)

declare [3 x double] @DOT([3 x [3 x double]], [3 x [3 x double]])
...
%a1 = load [3 x [3 x double]], [3 x [3 x double]]* %a
%b2 = load [3 x [3 x double]], [3 x [3 x double]]* %b
%calltmp = call [3 x double] @DOT([3 x [3 x double]] %a1, [3 x [3 x double]] %b2)

我没有包含完整的程序以节省空间,但是,如果它有用,只需询问,我会更新问题。

错误(已建立)

[1]    3086 segmentation fault  ./built

我使用以下命令编译代码:

clang++ library/library.cpp out.ll -o built

信息

这有效:

std::cout << A[0] << std::endl; // 0x1

这不是:

std::cout << A[0][0] << std::endl;

1 个答案:

答案 0 :(得分:2)

您使用错误的签名声明了您的函数:

首先,你的函数返回一个指向double的指针,而不是一个双精度数组。这很清楚,因为C ++代码确实将double *称为返回类型。

不太明显的问题是你的参数类型是“指向double数组的指针”,而不是“double to array”。这是因为C和C ++不支持数组类型的函数参数,但是仍然很容易地接受参数列表中的数组类型的语法,但只是将它视为声明指针。因此,double A[3][3]在参数列表中(并且只在那里)只是一种更令人困惑的方式来编写double (*A)[3]

总之,你的声明应该是:

declare double* @DOT([3 x double]*, [3 x double]*)

因此,您还应该更改您的调用代码,使用正确类型的指针调用@DOT