После шести месяцев разработки представлен релиз проекта LLVM 18.1.0 – GCC-совместимого инструментария (компиляторы, оптимизаторы и генераторы кода), компилирующего программы в промежуточный биткод RISC-подобных виртуальных инструкций (низкоуровневая виртуальная машина с многоуровневой системой оптимизаций). Сгенерированный псевдокод может быть преобразован при помощи JIT-компилятора в машинные инструкции непосредственно в момент выполнения программы.
Начиная с ветки 18.x проект перешёл на новую схему формирования номеров версий. По аналогии с проектами GCC и GDB, нулевой выпуск (“N.0”) теперь используется в процессе разработки, а первая стабильная версия снабжается номером “N.1”. Изменение позволяет отделить сборки на основе находящейся в разработке ветки (mainline) от сборок ветки с финальными релизами. Например, при подготовке нынешнего выпуска разработка велась с использованием нестабильной ветки LLVM 18.0, а первый стабильный релиз вышел под номером 18.1.0. В дальнейшем при необходимости каждые две недели могут формироваться корректирующие выпуски под номерами 18.1.1, 18.1.2 и т.п. В случае внесения в текущую ветку изменений, нарушающих ABI, обновление будет сформировано с изменением второй цифры версии (т.е. 18.2.0).
Основные улучшения в Clang 18:
- Изменения, связанные с языком Си:
- Структуры, объединения и массивы с признаком “const” по аналогии с GCC теперь могут использоваться как константные выражения.
- Перечисления (enum) теперь отражаются в метаданных TBAA (Type Based Alias Analysis) в своём исходном целочисленном типе, вместо обработки как типа “char”.
- Добавлена поддержка атрибута “counted_by”, через которое можно указать поле в структуре с гибким массивом, определяющим число элементов в гибком массиве. Атрибут может использоваться в clang для повышения эффективности проверок выхода за границу буфера.
- Возможности, определённые в будущем Си-стандарте C23:
- Добавлена поддержка флагов “-std=c23” и “-std=gnu23”, а также значения “202311L” для макроса “__STDC_VERSION__”, определяющих стандарт C23 и расширения GNU C23.
- Добавлена поддержка выражения “requires c23” для привязки модулей к поддержке стандарта C23.
- Реализована поддержка вывода типа при определении объектов, что позволяет использовать вместо типа признак “auto” для определения типа переменных на основе типа выражения для их инициализации. Например: “auto y = cos(x);”.
- Добавлена поддержка заголовочного файла с макросами для проверки целочисленных вычислений.
- Разрешено размещение меток в любых местах внутри составных выражений.
- При компиляции в режиме C23 прекращена поддержка в коде триграфов,
последовательностей из трёх ASCII-символов, обрабатываемых как один символ, например, последовательность “??=” можно было использовать вместо “#”. После появления Unicode поддержка триграфов потеряла смысл.
- Добавлена возможность использования сразу нескольких переменных-заполнителей с именем “_” в одной области видимости, например, теперь являются корректными конструкции: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // ранее выводилось предупреждение в режиме -Wunused }
- Предоставлена возможность использования строковых литералов в контесте, в котором они не используются для инициализации массива символов и не попадают в результирующий код, а применяются только во время компиляции для диагностических сообщений и препроцессинга, например, в качестве параметров директив и атрибутов _Pragma, asm, extern, static_assert, [[deprecated]] и [[nodiscard]].
- Переведена в разряд устаревших выполнение неявных преобразований перечисляемых значений в арифметических вычислениях. int main() { enum E1 { e }; enum E2 { f }; bool b = e
- Реализована спецификация, определяющая возможности, связанные с инициализацией параметров шаблонов.
Основные новшества LLVM 18.0:
- В бэкенд для архитектуры X86 добавлена поддержка расширений архитектуры набора команд (ISA): USER_MSR, VX10.1-256 и AVX10.1-512.
Тип i128 унифицирован с типом __int128 из GCC и clang, что позволило усилить бинарную совместимость с внешними проектами, такими как Rust. - В бэкенде для архитектуры RISC-V стабилизирована поддержка расширений Zicond, Zfa, Zihintntl, Zvbb, Zvbc, Zvkb, Zvkg, Zvkn, Zvknc, Zvkned, Zvkng, Zvknha, Zvknhb, Zvks, Zvksc, Zvksed, Zvksg, Zvksh и Zvkt. Добавлены встроенные функции для расширений Zk*, Zbb и Zbc. Добавлена эксперимнтальная поддержка генерации кода для архитектур RV32E, RV64E, ilp32e и lp64e. Реализована поддержка расширений Ziccif, Ziccrse, Ziccamoa, Zicclsm, Za64rs, Za128rs, Zic64b и Smepmp.
- В бэкенд для архитектуры LoongArch добавлены встроенные функций (Intrinsics) для расширений LSX (128-bits SIMD) и LASX (256-bits SIMD). Добавлена поддержка новых инструкций, появившихся в спецификации LoongArch Reference Manual 1.10. Добавлена начальная поддержка автоматической векторизации. Улучшена генерация кода.
- В бэкенд для архитектуры AArch64 добавлена поддержка процессоров
Cortex-A520, Cortex-A720 и Cortex-X4. Реализована поддержка ассемблера и дизассемблера для расширений архитектуры, предложенных в 2023 году.
Добавлена поддержка механизма защиты Stack Clash Protection, позволяющего выявлять факты переполнения стека и блокировать методы атак на основе пересечения стека и кучи. - В бэкенд для архитектуры ARM добавлена поддержка процессора Cortex-M52 и обеспечена возможность работы в режиме только исполнения (execute-only) для архитектуры Armv6-M.
- Улучшены бэкенды для архитектур WebAssembly, MIPS, PowerPC, AMDGPU.
- Расширены возможности компоновщика LLD. Добавлена поддержка объектов
FatLTO. Улучшена поддержка архитектур RISC-V и AArch64. - В библиотеке Libc++ продолжена реализация возможностей стандартов C++20, C++23 и C++26.
- В отладчике LLDB добавлена поддержка автоматического извлечения символов и бинарных данных с внешних серверов, поддерживающих протокол DEBUFINFOD.
Расширена поддержка архитектуры AArch64 и добавлена возможность отладки расширений SME и SME2 (Scalable Matrix Extension). - Удалены обвязки для языка Python.