执行失败 Value::getName 和 Value::HasName (LLVM)

Execution fail with Value::getName and Value::HasName (LLVM)

我正在做一个程序来列出 .ll 文件的所有函数调用。

这是我的代码:

void foo (const Module *M) {
    for (const Function &F : *M) {
        for (const BasicBlock &BB : F) {
            for (const Instruction &I : BB) {
                // CallInst: represents a function call
                if (dyn_cast<CallInst>(&I)) {
                    StringRef name = dyn_cast<CallInst>(&I)->getCalledFunction()->getName();
                    std::cout << name.str() << "\n";
                ...
                ...

问题在第 7 行。 在这个文件中:https://pastebin.com/vYhVf4qS

当我的程序用我所有的测试文件时,没有问题,但是当我用这个测试时,出现这个错误:

#0 0x0000000000427d10 llvm::sys::PrintStackTrace(llvm::raw_ostream&) /ubuntu/llvm/llvm-3.9.0.src/lib/Support/Unix/Signals.inc:402:0
#1 0x00000000004280af PrintStackTraceSignalHandler(void*) /ubuntu/llvm/llvm-3.9.0.src/lib/Support/Unix/Signals.inc:470:0
#2 0x0000000000426157 llvm::sys::RunSignalHandlers() /ubuntu/llvm/llvm-3.9.0.src/lib/Support/Signals.cpp:44:0
#3 0x0000000000427557 SignalHandler(int) /ubuntu/llvm/llvm-3.9.0.src/lib/Support/Unix/Signals.inc:256:0
#4 0x00007fbde269c390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
#5 0x000000000040b402 llvm::Value::hasName() const /ubuntu/llvm/llvm-3.9.0.src/include/llvm/IR/Value.h:233:0
#6 0x000000000040afa7 buildFunctionsCallMap[abi:cxx11](llvm::Module const*) /foo/PrintCallingFunctions.cpp:50:0
#7 0x000000000040b168 printCallingFuntions(llvm::Module const*) /foo/PrintCallingFunctions.cpp:75:0
#8 0x00000000004070bf main ...../main.cpp:76:0
#9 0x00007fbde15f3830 __libc_start_main /build/glibc-9tT8Do/glibc-2.23/csu/../csu/libc-start.c:325:0
#10 0x0000000000406bb9 _start (../../../build/bin/foo+0x406bb9)
Stack dump:
0.  Program arguments: ../../../build/bin/foo QLA_D3_c1_veq_V_dot_V.ll

问题好像是我调用getName()函数的时候调用了hasName(),最后一个报错了,但是我不明白为什么,也不知道怎么解决

如果调用是通过函数指针的间接调用,getCalledFunction() return 可能为 null。我查看了您的 IR 文件,调用如下所示:

%14 = call i32 (i32, { double, double }*, ...) bitcast (i32 (...)* @__alignx to i32 (i32, { double, double }*, ...)*)(i32 16, { double, double }* %13)

调用目标是位播常量表达式,所以这很可能是问题所在。您可以改用 getCalledValue()——在这种情况下,它会 return 一个 ConstantExpr 表示位播,您可以尝试使用 stripPointerCasts() 来获取函数本身。