Llvm18 ffat-lto-objects неопределенные виртуальные таблицыC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Llvm18 ffat-lto-objects неопределенные виртуальные таблицы

Сообщение Anonymous »

Привет!
Я переношу проект из старой версии C++ на новую, используя недавно вышедший пакет llvm 18.
Для этого я хотел бы включить оптимизацию LTO, однако по практическим соображениям я пытаюсь использовать жирный lto (вновь добавленный в llvm начиная с версии 18).
проект, который я портирую, имеет огромное количество зависимостей, поэтому мне приходится проверять компиляцию.
Однако, когда я компилирую с параметрами оптимизации (-flto -ffat-lto-objects), Я получаю неопределенные ошибки vtable. (неопределенный символ: vtable для [имя класса])
Он является систематическим и обрабатывается почти для каждого отдельного класса, который наследует виртуальные функции и имеет их. (весь список был бы слишком большим, чтобы разместить его здесь, плюс поскольку это код под соглашением о неразглашении, я даже не смог разместить его там)
Что странно (по крайней мере, для меня) заключается в том, что когда я удаляю поддержку жирных объектов, у меня не возникает проблем с виртуальными таблицами.
Итак, если я скомпилирую и свяжу без опции код компилируется и связывается нормально.
если я компилирую только с -flto, код компилируется и связывается нормально. (то же самое касается -flto=thin и -funified-lto)
Если я добавлю --ffat-lto-objects, lld внезапно выдаст массу ошибок (всегда vtable).< /p>
использование унифицированного конвейера lto вообще не решает проблему
Этого не происходит в связке C< /strong> (я имею в виду, что в C нет vtable) и ни из общей библиотеки, которая является автономной.
Это похоже на то, что lld просто игнорирует vtable, содержащуюся в deps моей программы (поскольку deps является общей или статической библиотекой, проблема та же, она не связана с окончательным двоичным файлом).
черт возьми, в контексте общей библиотеки он даже показывает мне ошибки, исходящие из стандартной библиотеки. (если я связываю другие библиотеки как общие библиотеки, а не как статические)
из того, что я вижу в коде, ни одна функция не является неопределенной (каждая виртуальная функция имеет определение , либо в заголовочном файле, либо в исходном файле).
Возможно ли, что опция fat lto еще не достаточно развита, чтобы ее можно было использовать в проекте? или я что-то упускаю (возможно, флаг или особенность fat lto)?
вот примерный пример определения проекта:
< pre class="lang-cpp Prettyprint-override">// lib header

class A {
public:
A() { /* does stuff */ };
virtual ~A();
};

// lib source

A::~A() {
// implementation
}

// bin source

int main()
{
// whatever
A variable; // link error pointing to A's constructor


Изменить:
попробовав несколько вещей, выяснилось, что именно комбинация толстого lto и унифицированного lto приводит к ошибкам. имея только толстый lto (с тонким/полным lto), строго ничего не делайте и не применяйте никаких оптимизаций, а только компилируйте.
Второе редактирование:
Вот минимальный код для воспроизведения ошибка:
file1.hpp
class base {
public:
virtual ~base();
virtual void fun1();
};

file1.cpp
#include "file1.hpp"

base::~base() {}
void base::fun1() {}

file2.hpp
#include "file1.hpp"

class child : public base {
public:
~child() = default;

void fun1() override {}
};

main.cpp
#include "file2.hpp"
int main()
{
child c;
return 1;
}

Скомпилируйте с помощью следующей команды:
clang++-18 main.cpp file1.cpp -o prog -flto -ffat-lto-objects -funified-lto -fuse-ld=lld-18
(замените clang++-18 и lld-18 на имена вашей clang + lld версии 18, как и в предыдущих версиях, она компилируется. Однако, поскольку добавлен жирный lto в llvm18 этот флаг, вероятно, просто игнорируется)
и у вас должна быть именно такая ошибка ссылки:
ld.lld-18: error: undefined symbol: vtable for child
>>> referenced by main.cpp
>>> /tmp/main-0d4e8c.o:(child::child())
>>> the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)

ld.lld-18: error: undefined symbol: vtable for base
>>> referenced by main.cpp
>>> /tmp/main-0d4e8c.o:(base::base())
>>> did you mean: typeinfo for base
>>> defined in: /tmp/file1-07950c.o
>>> the vtable symbol may be undefined because the class is missing its key function (see https://lld.llvm.org/missingkeyfunction)
clang++-18: error: linker command failed with exit code 1 (use -v to see invocation)


Подробнее здесь: https://stackoverflow.com/questions/784 ... ed-vtables
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»