flang компилятор доказывает, что программа не зациклится 0.6.2 GitHub

Проверка, переведённая на двоичный, выпадает из прогона молча — потому что CI не собирал двоичный ни разу

CI языка на Linux не собирал bootstrap/ вообще. Собирала его одна работа build-macos.yml, и только на macOS, ради отдельной беды с макросом видимости. Следствие оказалось хуже, чем «двоичный не проверен»: всякая проверка, переведённая с реализации на JavaScript на двоичный, тихо переставала выполняться, а отчёт при этом оставался зелёным.

Механика ровно та же, что у checks-that-stopped-comparing, и это третий её случай. Проба, которой нужен двоичный, написана так:

if (!existsSync(двоичный)) {
  if (process.env.FTS_REQUIRE_BINARY === "1") assert.fail(…)
  t.diagnostic("двоичного нет — соберите «make -C bootstrap»; проба пропущена")
  return null
}

Это правильный уклад — им же пропускаются пробы, которым нужен отсутствующий компилятор Go или Rust. Но переменная FTS_REQUIRE_BINARY не была выставлена нигде: grep по всему дереву находил её ровно в двух местах, и оба — внутри самого файла пробы. То есть предохранитель был заведён и не подключён, а «пропущено» в отчёте читается человеком как «всё хорошо».

Мимо прогона при этом ехали не мелочи: два обходчика, которые целиком написаны на двоичном и сверяют ведомости целиком, — flang/проверки/обход.sh (98 проверок) и flang/проверки/обход-примеров.sh (весь корпус .flang дерева). Из CI они не звались ни разу.

Признак класса, по которому третий случай ищется заранее. Пропуск по отсутствию инструмента обязан иметь парную переменную «требовать», и эта переменная обязана быть выставлена хоть в одной работе CI. Проверяется одним grep: если имя переменной встречается только в файле, который её читает, — предохранитель не подключён. Это дешевле любого разбора логов.

Чем подтверждено. Ветка vypusk/ci-dvoichnyy, коммит 7aa6a229, дерево на fe8e8a37. grep -rn FTS_REQUIRE_BINARY по дереву без node_modules → две строки, обе в flang/test/cli-test-corpus.test.mjs. В .github/workflows/ строк make -C bootstrap было ровно две, обе в build-macos.yml (runs-on: macos-latest).

Подтверждение, найденное в тот же день: ведомость сгнила ровно так

Через несколько часов после того, как эта заметка была записана, нашлось доказательство её же тезиса — и не рассуждением, а прогоном.

flang/проверки/ведомость-примеров.txt записана 20 августа в 01:27 (1c1df904). В 06:19 (8b68b570) отчёт flang test --ledger СМЕНИЛ ФОРМАТ: к трём числам добавилось четвёртое — «своих» примеров у файла. Ведомость после этого никто не перезаписал.

Итог, проверенный прогоном на одном каталоге:

двоичный пишет сейчас   flang/core/evaluate.flang	49 49 0 31
в ведомости лежит       flang/core/evaluate.flang	49 49 0

Расходится НЕ НЕСКОЛЬКО СТРОК, а ВСЕ: ни одна строка старого формата не может совпасть с новым. Плюс к тому в ведомости 774 строки, а файлов .flang в дереве 843, и 38 файлов не попали в неё ещё в момент записи — среди них flang/stdlib/base64.flang, json.flang, sha256.flang, utf8.flang.

То есть обходчик примеров гарантированно красен с 06:19 того же дня, и никто этого не заметил. Заметить было негде: из CI он не звался ни разу — ровно то, о чём заметка.

Это и есть цена неподключённой проверки, выраженная в часах: пять часов от смены формата до обнаружения, и обнаружено не прогоном проверки, а тем, что кто-то полез заводить ей работу в CI.

Чем ограничено. Про то, что двоичный проверяет слабее, здесь не сказано ни слова — это отдельная и уже записанная вещь (bootstrap-circle-is-broken-but-the-binary-cannot-check-itself). Речь только о том, что проверка не выполнялась вовсе.

Связано: checks-that-stopped-comparing, bootstrap-circle-is-broken-but-the-binary-cannot-check-itself, building-the-binary-costs-a-minute-not-an-hour