clang 中对析构函数的未定义引用

问题描述 投票:0回答:1

编译以下代码给出“对`A::~A()的未定义引用”:

#include <cstdlib>
#include <memory>

template <typename T>
struct A {
        A() {}
        ~A() {}
};

struct Aggregate {
        using key_vector = A<char>;
        using value_vector = A<int>;

        value_vector vals;
        key_vector keys;
};

int
main()
{
        auto x = malloc(sizeof(Aggregate));
        new (x) Aggregate{};

        return 0;
}

该问题存在于 clang 7.0 和 6.0 上(可能还有一些较旧的版本)。请参阅:https://godbolt.org/z/GNPk3V

在较新的 clang 版本和 gcc 上它工作正常。

这是预期的还是 clang 中的某种错误?

c++ linker clang
1个回答
4
投票

这似乎是 Bug 28280,由 https://reviews.llvm.org/D45898:

修复

如果花括号初始化列表中的初始值设定项是具有重要析构函数的 C++ 类,请将析构函数标记为已引用。这修复了 CodeGenFunction::destroyCXXObject 尝试在堆栈展开路径上发出对析构函数的调用但该类的 CXXRecordDecl 没有析构函数的 CXXDestructorDecl 时发生的崩溃。

此示例确实使用了花括号初始化列表,并在调用

_Unwind_Resume
之前发出析构函数调用。析构函数并不简单。将初始化更改为使用
()
而不是
{}
会使错误消失,因为它不再使用花括号初始化列表进行初始化。我的评论中的析构函数调用可能会导致析构函数被标记为引用。也许启用优化会产生相同的效果,使其仅出现在非平凡的析构函数中。

© www.soinside.com 2019 - 2024. All rights reserved.