c++ - LLVM ParseIR 段错误

标签 c++ segmentation-fault llvm llvm-ir

我正在尝试将一个函数(“fun”)编译为 LLVM IR,并使用 ParseIR 函数创建一个模块。程序在调用 ParseIR 时出现段错误。我正在使用 LLVM 3.5,代码如下。

#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>

#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_os_ostream.h"

using std::cout;
using std::endl;
using std::ostringstream;
using std::string;

using llvm::getGlobalContext;
using llvm::LLVMContext;
using llvm::MemoryBuffer;
using llvm::Module;
using llvm::ParseIR;
using llvm::SMDiagnostic;
using llvm::StringRef;

int main() {
    string fun = "int fun(int x) {return x;}\n";

    string cmd = "echo '" + fun + "' |"
               + " clang++ -cc1 -xc++ -O0 -std=c++1y -fno-use-cxa-atexit"
               + " -I/usr/local/lib/clang/3.5.0/include/"
               + " -I/usr/include/c++/4.9/"
               + " -I/usr/include/x86_64-linux-gnu/c++/4.9/bits/"
               + " -I/usr/include/x86_64-linux-gnu -I/usr/include/"
               + " -I/usr/include/x86_64-linux-gnu/c++/4.9/"
               + " -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include/"
               + " -I/usr/include/c++/4.9/backward/"
               + " -I/usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed/"
               + " -stdlib=libstdc++ -S -emit-llvm"
               + " -o /dev/stdout 2> /dev/stdout";

    FILE *file = popen(cmd.c_str(), "r");
    ostringstream llvm;
    char line[1024];
    while (fgets(line, 1024, file))
        llvm << line;
    pclose(file);

    LLVMInitializeNativeTarget();
    LLVMInitializeNativeAsmPrinter();
    LLVMContext &ctx = getGlobalContext();
    SMDiagnostic *err;
    StringRef ref = StringRef(llvm.str().c_str());
    MemoryBuffer *buff = MemoryBuffer::getMemBuffer(ref);

    cout << "***** C++ *****\n" << fun << "\n"
         << "***** LLVM *****\n" << llvm.str() << endl;

    //segfault
    Module *mod = ParseIR(buff, *err, ctx);

    return 0;
}

我使用以下命令编译并运行了上面的代码:

g++ -std=c++14 fun.cpp -o fun `llvm-config --cxxflags --ldflags --libs --system-libs`
./fun
***** C++ *****
int fun(int x) {return x;}

***** LLVM *****
; ModuleID = '-'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind
define i32 @_Z3funi(i32 %x) #0 {
  %1 = alloca i32, align 4
  store i32 %x, i32* %1, align 4
  %2 = load i32* %1, align 4
  ret i32 %2
}

attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.ident = !{!0}

!0 = metadata !{metadata !"clang version 3.5.1 (branches/release_35 225591)"}

Segmentation fault (core dumped)

最佳答案

您没有初始化您的 SMDiagnostic*,而是在调用 ParseIR 时取消引用它。这就是您的程序出现段错误的原因。请参阅代码中的注释以进行修复。

LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMContext &ctx = getGlobalContext();
SMDiagnostic err; // create an SMDiagnostic instance
MemoryBuffer* buff = MemoryBuffer::getMemBuffer(llvm.str());
cout << "***** C++ *****\n" << fun << "\n"
     << "***** LLVM *****\n" << llvm.str() << endl;

Module *mod = ParseIR(buff, err, ctx); // use err directly

关于c++ - LLVM ParseIR 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29761024/

相关文章:

C++ + 运算符的这种用法叫什么?目的是什么?

c++ - 工作线程中的同步 ioctl 与异步 ioctl

c - 在执行期间出现段错误

c - strcpy 周围的段错误?

c - ptr*** 不工作

clang - 完整且独立的 LLVM/musl 工具链

c++ - 在 R 脚本中使用 C++ 程序的返回值

linux - 在 Windows 10 上运行 LLVM passes 在终端中没有输出?

c++ - 在LLVM中获取全局字符串值

c++ - 模板参数中的T&和T&&有什么区别?