C++ 奇怪的叮当声

C++ 奇怪的叮当声,c++,c++11,g++,llvm,clang,C++,C++11,G++,Llvm,Clang,看看这段代码: #include <iostream> #include <string> void foo(int(*f)()) { std::cout << f() << std::endl; } void foo(std::string(*f)()) { std::string s = f(); std::cout << s << std::endl; } int main() {

看看这段代码:

#include <iostream>
#include <string>

void foo(int(*f)()) {
    std::cout << f() << std::endl;
}

void foo(std::string(*f)()) {
    std::string s = f();
    std::cout << s << std::endl;
}

int main() {
    auto bar = [] () -> std::string {
        return std::string("bla");
    };

    foo(bar);

    return 0;
}
导致:

bla
zsh: illegal hardware instruction  ./test
就像它应该做的那样。用

g++ -o test test.cpp -std=c++11
clang++ -o test test.cpp -std=c++11 -stdlib=libc++
clang++ -o test test.cpp -std=c++11 -stdlib=stdlibc++
导致:

bla
zsh: illegal hardware instruction  ./test
并用

g++ -o test test.cpp -std=c++11
clang++ -o test test.cpp -std=c++11 -stdlib=libc++
clang++ -o test test.cpp -std=c++11 -stdlib=stdlibc++
还导致:

zsh: illegal hardware instruction  ./test
Clang/GCC版本:

clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-pc-linux-gnu
Thread model: posix

gcc version 4.7.2 (Gentoo 4.7.2-r1 p1.5, pie-0.5.5) 
有人建议出了什么问题吗


提前谢谢

这很可能是Clang3.2中的一个bug。我无法用叮当的主干重现崩溃。

是的,这是叮当++中的一个错误。我可以在i386pclinuxgnu中用clang3.2复制它

现在进行一些随机分析

我发现错误在于从labmda到函数指针的转换:编译器创建了一种带有调用lambda的适当签名的thunk,但它的指令是
ud2
,而不是
ret

大家可能都知道,ud2指令是一条显式引发“无效操作码”异常的指令。也就是说,故意不定义的指令

看看拆解:这是thunk功能:

main::$_0::__invoke():
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        movl    %ecx, 4(%esp)
        calll   main::$_0::operator()() const ; this calls to the real lambda
        subl    $4, %esp
        ud2   ; <<<-- What the...!!!
奇怪的是,如果返回类型是一个简单的类型,例如
int
,那么这个错误就不会发生。那么生成的thunk是:


我怀疑问题在于返回值的转发。如果它适合一个寄存器,比如
eax
,那么一切都很顺利。但是如果它是一个大的结构,比如
std::string
,它会在堆栈中返回,编译器会感到困惑,并在绝望中发出
ud2

我想说这是ClangFYI中的一个bug,关于肯定的更多信息。行李箱似乎很好用。所以它可能应该在Clang3.3中修复。