メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: MSC53-CPP

Do not return from a function declared [[noreturn]]

説明

ルール定義

Do not return from a function declared [[noreturn]]1

Polyspace 実装

ルール チェッカーは、"呼び出し元に戻す [[noreturn]] 関数" をチェックします。

すべて展開する

問題

この欠陥は、[[noreturn]] 関数が最終的に実行の流れを呼び出し元関数に戻した場合に発生します。コンパイラは、[[noreturn]] 属性を使用することによって宣言された関数は実行の流れを返さないことを想定します。つまり、[[noreturn]] 関数 f()main() から呼び出された場合、コンパイラは、実行のフローが main() に戻されないことを想定します。このような関数が最終的に実行の流れを戻した場合は、それが未定義の動作につながります。

リスク

[[noreturn]] 関数が最終的に実行の流れを戻した場合は、それが未定義の動作につながり、悪用されてデータ整合性違反を引き起こす可能性があります。

修正方法

関数に return ステートメントが含まれていない場合は、関数の最後の右中かっこが暗黙的な return を意味します。関数内の return ステートメントを除外しても、実行の流れは戻されます。[[noreturn]] 関数は、以下の方法によって、実行の流れを呼び出し元の関数に戻さないようにできます。

  • 無限ループへの進入

  • 例外の発生

  • 別の [[noreturn]] 関数の呼び出し

[[noreturn]] として宣言された関数 noncompliant() を含む次のコードについて考えます。

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

入力 i が 0 の場合は、実行の流れがコードの if-else-if ブロックをスキップして、暗黙的に呼び出し元に戻ります。[[noreturn]] 関数はコード パス内の実行の流れを戻すため、この関数はこのルールに準拠していません。

修正

[[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 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.