CERT C++: MSC53-CPP

Не возвращайтесь из функции, объявленной [[noreturn]]

Описание

Определение правила

Не возвращайтесь из функции, объявленной [[noreturn]][1]

Реализация Polyspace

Эта проверка проверяет на [[noreturn]] функции, возвращающиеся к вызывающему абоненту.

Примеры

расширить все

Проблема

Этот дефект возникает, когда [[noreturn]] функция в конечном счете возвращает поток выполнения функции вызывающего абонента. Компилятор ожидает, что функция, объявленная при помощи [[noreturn]] атрибут не возвращает поток выполнения. То есть, если [[noreturn]] функциональные f() вызывается из main(), тогда компилятор ожидает, что поток выполнения не возвращается к main(). Если такая функция в конечном счете возвращает поток выполнения, это приводит к неопределенному поведению.

Риск

Если a [[noreturn]] функция в конечном счете возвращает поток выполнения, это приводит к неопределенному поведению, которое может использоваться, чтобы вызвать нарушения целостности данных.

Зафиксировать

Если функция не имеет return оператор, затем конечная закрывающая скобка функции подразумевает неявное return. Опускание return оператор в функции не препятствует возвращению потока выполнения. A [[noreturn]] функция может запретить возврат потока выполнения в вызывающую функцию путем:

  • Вход в бесконечный цикл

  • Выдвижение исключения

  • Вызов другого [[noreturn]] функция

Пример

Рассмотрим следующий код, содержащий функцию noncompliant(), который объявляется как [[noreturn]].

#include <cstdlib>
[[noreturn]] void bad_f(int i)
{
	if (i > 0)
	throw "Received positive input";
	else if (i < 0)
	std::exit(0);
} //Noncompliant

Когда вход i равен нулю, поток выполнения пропускает if-else-if блок кода и неявно возвращается к вызывающему абоненту. Потому что [[noreturn]] функция возвращает поток выполнения в код пути, эта функция не совместима с этим правилом.

Коррекция

A [[noreturn]] функция не должна возвращать поток выполнения в код пути. Можно предотвратить возврат несколькими способами. Рассмотрите следующий код, где [[noreturn]] функция не возвращает поток выполнения в код пути.

#include <cstdlib>
[[noreturn]] void compliant(int i)
{
	if (i > 0)
	throw "Received positive input";
	else if (i < 0)
	std::exit(0);
	else if(i==0)
	while(true){
		//...
	}
}//Compliant

Эта функция соответствует этому правилу, потому что:

  • Когда i > 0функция вызывает исключение.

  • Когда i < 0, функция вызывает [[noreturn]] функциональные std::exit().

  • Когда i==0, функция входит в бесконечный цикл.

Потому что [[noreturn]] функция не возвращает поток выполнения в пути вызова, она соответствует этому правилу.

Проверяйте информацию

Группа: 49. Разное (MSC)
Введенный в R2020b

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.