exponenta event banner

CERT C++: ERR55-CPP

Технические требования к исключению чести

Описание

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

Характеристики исключения чести [1 ]

Внедрение Polyspace

Эта проверка проверяет наличие выходящих функций Noexcept с исключением.

Примеры

развернуть все

Проблема

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

Когда noexcept объект вызывает другие вызываемые объекты, Polyspace ® делает определенные предположения, чтобы вычислить, могут ли быть необработанные исключения.

  • Функция: Когда noexcept функция вызывает другую функцию, Polyspace проверяет, может ли вызываемая функция вызвать исключение, только если она указана как noexcept(<false>). Если вызываемая функция указана как noexcept, Polyspace предполагает, что он не вызывает исключения. Некоторые стандартные библиотечные функции, такие как конструктор std::string, используйте указатели на функции для выделения памяти, что может вызвать исключения. Поскольку эти функции не указаны как noexcept(<false>), Polyspace не помечает функцию, которая вызывает эти стандартные библиотечные функции.

  • Внешняя функция: При noexcept функция вызывает внешнюю функцию, Polyspace помечает объявление функции, если внешняя функция указана как noexcept(<false>).

  • Виртуальная функция: Когда функция вызывает виртуальную функцию, Polyspace помечает объявление функции, если виртуальная функция указана как noexcept(<false>) в производном классе. Например, если noexcept функция вызывает виртуальную функцию, которая объявлена как noexcept(<true>) в базовом классе, и noexcept(<false>) в последующем производном классе Polyspace помечает объявление noexcept функция.

  • Указатели на функцию: Когда noexcept функция вызывает указатель на функцию, Polyspace предполагает, что указатель на функцию не вызывает исключений.

При анализе того, вызывает ли функция необработанные исключения, Polyspace игнорирует:

  • Исключения, возникшие в деструкторах

  • Исключения, возникшие в atexit() операции

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

Риск

Если noexcept функция выходит за исключением, компилятор вызывает std::terminate() неявно. Функция std::terminate() завершает выполнение программы способом, определенным реализацией. То есть точный процесс завершения программы зависит от конкретного набора используемого программного и аппаратного обеспечения. Например, std:terminate() может вызвать std::abort() аварийно прервать выполнение без размотки стека, что приведет к утечке ресурсов и уязвимостям безопасности.

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

Укажите функцию как noexcept или noexcept(true) только если известно, что функция не выходит за исключением. Если вы не уверены, укажите его с помощью noexcept(false)

Пример

Рассмотрим этот код, в котором две функции указаны как noexcept. Polyspace статически анализирует эти функции и функции, которые они вызывают.

#include <stdexcept>
#include <typeinfo>
bool f(bool flag){
	if(flag==true)
	throw flag;
	return flag;
	
}
void LibraryFunc_noexcept_false() noexcept(false);  
void SpecFalseCT() noexcept  // Noncompliant
{
	try {
		LibraryFunc_noexcept_false();
	} catch (int &e) {
		LibraryFunc_noexcept_false();  
	} catch (std::exception &e) {
	} catch (...) {
	}
}
bool flag = false;
void Caller() noexcept {          //Noncompliant
	try {
		if(f(flag)){
			//...
		}
	} catch (int i) {
		//...
	} 
}

  • Polyspace помечает noexcept функция SpecFaleCT() потому что эта функция вызывает noexcept(false) внешняя функция LibraryFunc_noexcept_false() без каких-либо исключений, которые могут быть из него вызваны. Эти исключения могут привести к noexcept для выхода с исключением.

  • Polyspace помечает noexcept функция Caller потому что эта функция вызывает noexcept(false) функция f(), который содержит явное throw заявление. Даже несмотря на throw инструкция не выполняется, когда flag является false, Polyspace игнорирует динамический контекст и флаги Caller.

Исправление

При определении функций укажите их как noexcept только в том случае, если в функции обрабатываются все возможные исключения. В противном случае укажите их как noexcept(false). В случаях, когда исключение не возникает в динамическом контексте, необходимо обосновать этот дефект с помощью комментариев.

#include <stdexcept>
#include <typeinfo>
bool f(bool flag){
	if(flag==true)
	throw flag;
	return flag;
	
}
void LibraryFunc_noexcept_false() noexcept(false);  
void SpecFalseCT() noexcept(false)// Compliant
{
	try {
		LibraryFunc_noexcept_false();
	} catch (int &e) {
		LibraryFunc_noexcept_false();  
	} catch (std::exception &e) {
	} catch (...) {
	}
}
bool flag = false;
void Caller() noexcept{//Noncompliant // polyspace CERT-CPP:ERR55-CPP 
//[Justified:Unset] "Exception is not thrown when flag is false"
	try {
		if(f(flag)){
			//...
		}
	} catch (int i) {
		//...
	} 
}

  • Функция SpecFalseCT теперь указан как noexcept(false) потому что она вызывает внешнюю функцию, которая может вызвать исключения. Эта функция соответствует этому правилу.

  • Функция f() не вызывает исключение, когда flag является false. Функция Caller соответствует его спецификации исключения, но Polyspace помечает его, поскольку Polyspace игнорирует динамический контекст. Этот дефект обоснован с помощью комментария.

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

Группа: 08. Особые ситуации и обработка ошибок (ERR)
Представлен в R2020b

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

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

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