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

Предел шагов интерпретатора решает, что вообще может быть примером, — и ключа, чтобы его поднять, у check нет

У flang run есть --max-steps, у flang check — нет. Примеры гоняются checkом при каждой проверке и с пределом по умолчанию 1 000 000 шагов; пример, который в него не влезает, отвергается кодом FLANG_EXAMPLE («исчерпала лимит шагов»), и программа не печатается вовсе, потому что emit зовёт те же проверки.

Отсюда правило, которое надо знать ДО того, как писать модуль с тяжёлым вычислением: предел шагов — это верхняя граница на размер входа в примере, и он проектное ограничение, а не мелочь настройки. У SHA-256 он прямо определил форму модуля: один блок стоит 925 195 шагов, значит примером может быть сообщение не длиннее ОДНОГО блока (55 байт с набивкой). Оба коротких официальных вектора FIPS 180-4 — пустое сообщение и abc — влезают и стоят примерами; вектор из миллиона букв «a» не влезает и живёт в flang/test/sha256.test.mjs, где модуль напечатан в JavaScript и предела нет.

Что из этого следует практически. Тяжёлый модуль делится на две части осознанно: то, что проверяется примерами внутри модуля (и значит проверяется всегда, у всех восьми целей печати, и попадает в сетку сверки с интерпретатором), и то, что проверяется снаружи на напечатанном коде. Первая часть — это договор модуля, вторая — улика на корпусе. Складывать всё во вторую заманчиво и неправильно: пример внутри модуля ловит порчу РАНЬШЕ и говорит о ней кодом FLANG_EXAMPLE, а не падением далёкого теста.

Чем подтверждено. Ветка work/bayty. Двоичный поиск по --max-steps: flang run flang/stdlib/sha256.flang --function "Хеш байтов" --args '{"байты": [97, 98, 99]}' отвечает значением начиная с 925 195 шагов и отказывает ниже. При пределе по умолчанию 1 000 000 запас — 7,5 %. Первая редакция модуля стоила 1 394 531 шага, и flang check отвергал ровно четыре примера из тридцати восьми — те, что считали целый блок.

Чем ограничено. Число зависит от учёта шагов в flang/src/interpret.mjs. Если учёт изменится, красным станет flang check flang/stdlib/sha256.flang, а не тест — и это правильное место для такого красного, потому что чинить надо модуль или предел, а не сверку.

Связано: sha256-without-bit-operations-costs-925-thousand-steps-per-block, a-check-that-skips-a-check-is-a-class