Spec-Zone.ru › C

Анализируемость

Это необязательное расширение языка C, ограничивающее потенциальные результаты выполнения некоторых форм неопределенного поведения, что повышает эффективность статического анализа таких программ. Анализируемость гарантируется только при включении предопределенной макроконстанты макроконстанты __STDC_ANALYZABLE__(C11) в компиляторе.

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

Критическое неопределенное поведение

Критическое неопределенное поведение — это неопределенное поведение, которое может выполнить запись в память или чтение из памяти с модификатором volatile за пределами границ любого объекта. Программа, имеющая критическое неопределенное поведение, может быть уязвимой для эксплойтов.

Только следующие неопределенные поведения являются критическими:

  • доступ к объекту за пределами его жизни (например, через висячий указатель)
  • запись в объект, объявление которого не совместимо
  • вызов функции через указатель на функцию, тип которого не совместим с типом функции, на которую он указывает
  • вычисление выражения типа lvalue, но оно не обозначает объект
  • попытка модификации строковой константы
  • разыменование некорректного (нулевой, неопределенный и т. д.) или выходящего за пределы указателя
  • модификация константного объекта через неконстантный указатель
  • вызов стандартной библиотечной функции или макроса с некорректным аргументом
  • вызов вариадической функции стандартной библиотеки с неожиданным типом аргумента (например, вызов printf с аргументом типа, который не соответствует его спецификатору преобразования)
  • longjmp при отсутствии setjmp в вызывающей области, между потоками или из области типа виртуальной машины.
  • любое использование указателя, который был освобожден free или realloc
  • любой доступ к массиву за пределами границ в функции библиотеки строк или широких строк

Ограниченное неопределенное поведение

Ограниченное неопределенное поведение — это неопределенное поведение, которое не может выполнить незаконную запись в память, хотя может вызвать ловушку и может произвести или сохранить неопределенные значения.

  • Все неопределенные поведения, не перечисленные как критические, являются ограниченными, включая
    • гонки данных в многопоточных программах
    • использование неопределенных значений с автоматическим сроком жизни
    • нарушения строгого алиасинга
    • доступ к невыровненному объекту
    • переполнение знакового целого
    • неупорядоченные побочные эффекты, изменяющие один и тот же скаляр или изменяющие и читающие один и тот же скаляр
    • переполнение при преобразовании из плавающей точки в целое или из указателя в целое преобразования
    • побитовое сдвиг на отрицательное или слишком большое количество бит
    • деление на ноль
    • использование выражения void
    • непосредственное присваивание или memcpy неточно перекрывающихся объектов
    • нарушения restrict
    • и т.д. ВСЕ неопределенные поведения, отсутствующие в критически списке.

Примечания

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

Расширение анализируемости позволяет, как форму реализации, определённого поведения, для обработчика ограничений времени выполнения вызываться при возникновении ловушки.

Ссылки

  • Стандарт C11 (ISO/IEC 9899:2011):
    • 6.10.8.3/1 Условные макросы (с. 177)
    • Приложение L Анализируемость (с. 652-653)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/analyzability

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API