Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ llvm::BasicBlock::孤岛板未按预期运行_C++_Llvm - Fatal编程技术网

C++ llvm::BasicBlock::孤岛板未按预期运行

C++ llvm::BasicBlock::孤岛板未按预期运行,c++,llvm,C++,Llvm,我对LLVM中的BasicBlocks上的isLandingPad有点困惑。我有以下代码,其中我创建了一个空的BasicBlock,然后在上面调用isLandingPad: #包括“llvm/IR/IRBuilder.h” #include)当BasicBlock为空时(因为我们在nullptr上调用isa),这应该会出错。但是,当我运行这个程序时,对isLandingPad的调用成功并返回false。有趣的是,当我内联isLandingPad的函数定义时(如下所示),它会像预期的那样崩溃 我在

我对LLVM中的
BasicBlock
s上的
isLandingPad
有点困惑。我有以下代码,其中我创建了一个空的BasicBlock,然后在上面调用
isLandingPad

#包括“llvm/IR/IRBuilder.h”
#include)当BasicBlock为空时(因为我们在
nullptr
上调用
isa
),这应该会出错。但是,当我运行这个程序时,对
isLandingPad
的调用成功并返回
false
。有趣的是,当我内联
isLandingPad
的函数定义时(如下所示),它会像预期的那样崩溃

我在这里显然做错了什么,但我不明白
BB->isLandingPad()
调用与内联版本有什么不同,也不明白为什么
isLandingPad
不会崩溃,而根据源代码它应该崩溃。

如果代码“应该segfault”,这似乎意味着代码正在调用未定义的行为(UB)在运行时。编译器可能基于错误的假设进行优化,即UB不会出现在您的程序中,并且此错误的假设会导致您观察到的错误结果
isLP==false

您永远不应该调用未定义的行为,也不应该重新构造代码,使其永远不使用可以调用UB的参数调用函数。(例如,在调用
isa
isLandingPad
之前,检查
getFirstNonPHI
的结果

具体来说,您不应该假设UB(例如解引用
nullptr
或其附近的地址)具有定义良好的效果,例如“它将segfault”,因为编译器可能会以消除预期效果的方式重新组织代码(假设UB从未发生)(例如,它将生成不尝试从
nullptr
加载的代码)

内联和优化级别对生成的代码有很大的影响,这就是为什么在不同的情况下会看到不同的结果(无效返回值与segfault)

有关未定义行为的详细信息:

  • (更多参考请参见页面底部的链接)
如果代码“应该segfault”,这似乎意味着代码正在调用未定义的行为(UB)在运行时。编译器可能基于错误的假设进行优化,即UB不会出现在您的程序中,并且此错误的假设会导致您观察到的错误结果
isLP==false

您不应调用未定义的行为,也不应将代码重新构造为从不调用具有可调用UB的参数的函数。(例如,在调用
isa
isLandingPad
之前,请检查
getFirstNonPHI
的结果。)

具体来说,您不应该假设UB(例如解引用
nullptr
或其附近的地址)具有定义良好的效果,例如“它将segfault”,因为编译器可能会以消除预期效果的方式重新组织代码(假设UB从未发生)(例如,它将生成不尝试从
nullptr
加载的代码)

内联和优化级别对生成的代码有很大的影响,这就是为什么在不同的情况下会看到不同的结果(无效返回值与segfault)

有关未定义行为的详细信息:

  • (更多参考请参见页面底部的链接)
    • LLVM本身(至少在我的系统上)是在禁用断言的情况下编译的,因此断言不会触发。当您将其内联到代码中时,您是在启用断言的情况下编译的,因此它会触发

      请注意,由于
      isa
      是一个模板,它将被编译到作为其一部分实例化的编译单元中。在这种情况下,至少有两个:一个在LLVM中,另一个组成您的程序。严格来说,它们应该是相同的(“一个定义规则”)或者你有UB。在这种情况下,实际的结果是从任一编译单元调用
      isa()
      可能最终调用另一个编译单元中实例化的版本。但是,在
      isa()
      的情况下,调用可能是内联的,即,你最终得到的是
      isa()
      特定于实例化它的每个编译单元。

      LLVM本身(至少在我的系统上)是在禁用断言的情况下编译的,因此断言不会触发。当您在代码中内联它时,您是在启用断言的情况下编译的,所以它会触发


      请注意,由于
      isa
      是一个模板,它将被编译到作为其一部分实例化的编译单元中。在这种情况下,至少有两个:一个在LLVM中,另一个组成您的程序。严格来说,它们应该是相同的(“一个定义规则”)或者你有UB。在这种情况下,实际的结果是从任一编译单元调用
      isa()
      可能最终调用另一个编译单元中实例化的版本。但是,在
      isa()
      的情况下,调用可能是内联的,即,你最终得到的是
      isa()
      特定于实例化它的每个编译单元。

      isLandingPad()不要求块的格式正确、完整或其他任何内容。它只是检查:在异常情况下,是否有任何调用指令可以跳转到此块?是或否?仅此而已。如果您的函数已编译一半,并且调用已准备就绪,但异常处理程序尚未启动,则可以使用该指令。哦,
      BB->isLandingPad()
      永远不能保证segfault,尤其是在这种情况下,因为它甚至不尝试访问块本身中的任何指令。isLandingPad()不要求块格式良好或完整或其他任何内容。它只是检查:cas中是否有任何可以跳到此块的调用指令
      isLP = 0
      codegen: /usr/lib/llvm-7/include/llvm/Support/Casting.h:106: static bool llvm::isa_impl_cl<llvm::LandingPadInst, const llvm::Instruction *>::doit(const From *) [To = llvm::LandingPadInst, From = const llvm::Instruction *]: Assertion `Val && "isa<> used on a null pointer"' failed.