• Тестирование LLVM

    • Перевод
    Продолжение. Начало здесь.

    Введение


    Когда программа достигает определённого размера, можно гарантировать, что она слабо специфицирована и не может быть полностью понята одним человеком. Это подтверждается по много раз в день людьми, которые слабо осведомлены о работе друг друга. Программа имеет множество зависимостей, включая компилятор, операционную систему, библиотеки, каждая из которых содержит свои собственные баги, и всё это обновляется время от времени. Более того, ПО обычно должно работать на нескольких разных платформах, каждая из которых имеет свои особенности. Принимая во внимание большое количество возможностей для неверного поведения, почему вообще мы можем ожидать, что наша большая программа будет работать так, как ожидается? Одна из самых главных вещей, это тестирование. Таким образом, мы можем убедиться, что ПО работает так, как нужно в любой важной для нас конфигурации и платформе, и когда оно не работает, найдутся умные люди, которые смогут отследить и устранить проблему.
    Читать дальше →
  • Путеводитель по исходникам LLVM

    • Перевод
    В моём углубленном курсе компиляторов прошлой осенью мы провели некоторое время, изучая дерево исходников LLVM. Миллион строк кода на C++ выглядят пугающе, но я нахожу это интересным упражнением, и, по крайней мере, некоторые студенты с этим согласны, и я подумал, что я попытаюсь написать что-то подобное. Мы будем использовать LLVM 3.9, но предыдущие (и, возможно, будущие) релизы не сильно отличаются.

    Читать дальше →
  • Мой первый компилятор на LLVM

    • Перевод
    • Tutorial
    Это руководство посвящено написанию простейшего компилятора на LLVM. Никакой предварительной подготовки не требуется.



    Входным языком нашего компилятора будет BF. Это классический «игрушечный» язык для компиляторов, и даже есть компилятор BF в примерах к LLVM! В этом посте я приведу процесс написания компилятора с пояснениями.
    Читать дальше →
    • +33
    • 8,8k
    • 9
  • UB-2017. Часть 1

    • Перевод
    От переводчика:
    Переводы статьи про неопределённое поведение в языке C от Криса Латтнера, одного из ведущих разработчиков проекта LLVM, вызвали большой интерес, и даже некоторое непонимание со стороны тех, кто не встречался с описываемыми явлениями на практике. В своей статье Крис даёт ссылку на блог Джона Реджера, и на его статью от 2010 года, посвящённую UB в C и C++. Но в блоге Реджера есть и гораздо более новые статьи на эту тему (что не отменяет ценность старых, однако).

    Я хочу предложить вашему вниманию свежую статью «Undefined Behavior in 2017». Статья в оригинале имеет очень большой объём, и я разбил её на части.

    В первой части речь пойдёт о разных инструментах поиска UB: ASan, UBSan, TSan и т.д.
    ASan — Address Sanitizer от компании Google, разработанный на основе LLVM.
    UBSan — Undefined Behavior Sanitizer, предназначен для обнаружения различных UB в программах на C и C++, доступен для Clang и GCC.
    TSan — Thread Sanitizer, предназначен для обнаружения UB в многопоточных программах.
    Если вам эта тема покажется далёкой от практики, я рекомендую дождаться продолжения, потому что в конце вас ждёт поистине огромный список UB языка С++ (их должно быть около 200!)
    И я рекомендую прочитать также старые статьи Реджера, они не утратили актуальности.
    Об авторе: Джон Реджер является профессором Computer Science в университете штата Юта в США.


    Мы часто слышим, что некоторые люди утверждают, что проблемы, вытекающие из неопределённого поведения (UB) в C и C++ в основном решены путём широкого распространения инструментов динамической проверки, таких, как ASan, UBSan, MSan и TSan. Мы здесь покажем очевидное: несмотря на то, что в последние годы произошло множество прекрасных улучшений в этих инструментах, проблемы UB далеки от разрешения, и рассмотрим ситуацию в деталях.


    Читать дальше →
  • Что каждый программист на C должен знать об Undefined Behavior. Часть 3/3

    • Перевод
    Часть 1
    Часть 2
    Часть 3

    В первой части цикла мы рассмотрели неопределённое поведение в С и показали некоторые случаи, которые позволяют сделать С более быстрым, чем «безопасные» языки. В части 2 мы рассмотрели некоторые неожиданные баги, которые могут противоречить представлениям многих программистов об языке С. В этой части, мы рассмотрим проблемы, которые компилятор Clang решает, чтобы достичь высокого быстродействия, и устранить некоторые сюрпризы.
    image
    Читать дальше →
    • +19
    • 6,3k
    • 7
  • Что каждый программист на C должен знать об Undefined Behavior. Часть 2/3

    • Перевод
    Часть 1
    Часть 2
    Часть 3

    В первой части нашего цикла мы обсудили, что такое неопределённое поведение, и как оно позволяет компиляторам C и C++ генерировать более высокопроизводительные приложения, чем «безопасные» языки. В этом посте мы обсудим, чем на самом деле является «небезопасный» C, объяснив некоторые совершенно неожиданные эффекты, вызываемые неопределённым поведением. В третьей части, мы обсудим, как «дружественные» компиляторы могут смягчить некоторые из таких эффектов, даже если они не обязаны это делать.

    Мне нравится называть это «Почему неопределённое поведение часто пугает и ужасает программистов на C».

    image
    Читать дальше →
  • Что каждый программист на C должен знать об Undefined Behavior. Часть 1/3

    • Перевод
    Часть 1
    Часть 2
    Часть 3

    Люди иногда спрашивают, почему код, скомпиливанный в LLVM иногда генерирует сигналы SIGTRAP, когда оптимизация была включена. Покопавшись, они обнаруживают, что Clang сгенерировал инструкцию «ud2» (подразумевается код X86) — то же, что генерируется __builtin_trap(). В этой статье рассматривается несколько вопросов, касающихся неопределённого поведения кода на C и того, как LLVM его обрабатывает.

    image

    В этой статье (первой из трёх) мы попытаемся объяснить некоторые из этих вопросов, чтобы вы могли лучше понять связанные с ними компромиссы и сложности, и возможно, изучить немного больше тёмные стороны С. Мы выясним, что C не является «высокоуровневым ассемблером», как многие опытные программисты на C (особенно те, кто сфокусирован на низком уровне) предпочитают думать, и что C++ и Objective-C напрямую унаследовали множество таких проблем.
    Читать дальше →
  • Почему LLVM может вызвать никогда не вызываемую функцию?

      Что бы ни сказал тебе твой дракон, он солгал. Драконы лживы. Ты не знаешь, что ждет тебя на другой стороне.
      Майкл Суэнвик. «Дочь железного дракона»

      Не так давно на Хабре был опубликован пост под названием "Как может вызваться никогда не вызываемая функция?". Выводы из статьи простые: в случае undefined behaviour компилятор вправе предпринимать любые действия, даже если они будут совершенно неожиданными. Однако меня заинтересовал сам механизм этой оптимизации. Результатом своего небольшого исследования я хочу поделиться с уважаемым сообществом хабра.


      Читать дальше →
    • Игрушечный фронтенд для LLVM, написанный на Rust: Руководство для начинающих

      • Перевод
      • Tutorial
      Примечание переводчика
      Приведённый в статье код скомпилирован с достаточно старыми версиями крейтов peg и peg_syntax_ext. Для текущих версий в исходники нужно внести минимальные изменения. Я вставил изменённые участки в спойлеры по тексту статьи. Для сборки кода установите компилятор nightly Rust.
      Полный исходник с моими правками можно скачать здесь: https://github.com/arktur04/rust-llvm-toy-frontend


      В настоящее время я работаю над компилятором, который написан на Rust, и порождает LLVM IR. LLVM API выглядит немного пугающе для новичков, и по нему не так много руководств (и все они на C++, поэтому не вполне очевидно, как сделать то же самое на Rust). Я бы хотел, чтобы кто-то протянул мне руку помощи, когда я начинал всё это, и эта статья является тем, что я хотел бы показать самому себе в то время.



      В Rust наилучшая возможность взаимодействия с LLVM — через крейт llvm-sys. Один добрый человек разместил документацию к нему здесь. Конечно, вам следует также изучить руководство по LLVM, так как оно поможет вам понять, как LLVM “думает”. Этот пост, в основном, является переводом на Rust подмножества из этого руководства.

      Полный исходный код для этого руководства находится здесь.
      Читать дальше →
    • Создание языка программирования с использованием LLVM. Часть 10: Заключение и другие вкусности LLVM

      • Перевод
      • Tutorial
      Оглавление:
      Часть 1: Введение и лексический анализ
      Часть 2: Реализация парсера и AST
      Часть 3: Генерация кода LLVM IR
      Часть 4: Добавление JIT и поддержки оптимизатора
      Часть 5: Расширение языка: Поток управления
      Часть 6: Расширение языка: Операторы, определяемые пользователем
      Часть 7: Расширение языка: Изменяемые переменные
      Часть 8: Компиляция в объектный код
      Часть 9: Добавляем отладочную информацию
      Часть 10: Заключение и другие вкусности LLVM



      9.1. Заключение


      Добро пожаловать в заключительную часть руководства “Создание языка программирования с использованием LLVM”. На протяжении этого руководства, мы вырастили наш маленький язык Калейдоскоп с бесполезной игрушки до довольно интересной (хотя, возможно, по-прежнему бесполезной) игрушки.
      Читать дальше →
      • +15
      • 4,3k
      • 4