メインコンテンツ

AUTOSAR C++14 Rule M15-3-3

Handlers of a function-try-block implementation of a class constructor or destructor shall not reference non-static members from this class or its bases.

説明

ルール定義

Handlers of a function-try-block implementation of a class constructor or destructor shall not reference non-static members from this class or its bases.

根拠

関数 try ブロックのハンドラー catch ブロックは、関数本体および初期化子リストから発生した例外を処理します。これらの catch ブロックは、クラスのコンストラクターおよびデストラクターで使用されている場合、クラスの非静的メンバーの作成中または破棄中に発生した例外を処理する可能性があります。つまり、クラスの非静的メンバーの有効期間が始まる前、または終わった後に、catch ブロックが実行される可能性があります。このような catch ブロックでクラスの非静的メンバーにアクセスする場合、コンパイラはまだ作成されていないオブジェクトまたは削除済みのオブジェクトにアクセスしようとする可能性があります。これは未定義の動作です。次に例を示します。

class C{
	
	private:
	int* inptr_x;
	public:
	C() try: inptr_x(new int){}
	catch(...){
		intptr_x = nullptr;
		//...
	}
};
この例では、C のコンストラクターを実装するために、関数 try ブロックを使用して、初期化子リストでのメモリ割り当て操作で発生した例外を処理します。この function-try-block の catch ブロックで、クラス メンバー C.intptr_x にアクセスします。catch ブロックは、intptr_x のメモリ割り当てが失敗すると実行されます。つまり、catch ブロックは、メンバーの有効期間が始まる前にこのメンバーへのアクセスを試行します。これは未定義の動作です。

未定義の動作を回避するには、コンストラクターおよびデストラクターの function-try-block 実装の catch ブロックで、オブジェクトの非静的データ メンバーや基底クラスを使用しないようにします。

Polyspace 実装

コンストラクターまたはデストラクター function-try ブロックの catch ブロックに含まれるステートメントが次のいずれかにアクセスする場合、Polyspace® はそのステートメントにフラグを設定します。

  • オブジェクトの非静的メンバー

  • オブジェクトの基底クラス

  • 基底クラスの非静的メンバー

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include<cstdint>
class B
{
public:
	B ( ) try: x(0){/*...*/}
	catch ( ... )
	{
		if ( 0 == x ){/*...*/}  //Noncompliant
		//...
	}
	~B ( ) try{/*...*/}
	catch ( ... )
	{
		if ( 0 == x ){/*...*/} //Noncompliant
		//...
		else if (sb == 1){/*...*/} //Compliant
		//....	
	}
public:
	static int32_t sb;
protected:
	int32_t x;
};

class D : public B
{
public:
	D ( ) try: B(),y{0}{/*...*/}
	catch ( ... )
	{
		if ( 0 == x ){/*...*/}  //Noncompliant
		//...
		else if (y == 1){/*...*/}   //Noncompliant
		//...
	}
	~D ( )try {/*...*/}
	catch ( ... )
	{
		if ( 0 == x ) {/*...*/} //Noncompliant
		//...
	}
protected:
	int32_t y;
};

この例では、BD のコンストラクターおよびデストラクターは、function-try-block を使用して実装されています。これらの function-try ブロックの catch ブロックは、クラスとその基底クラスの非静的メンバーにアクセスします。Polyspace は、catch ブロック内のこれらの非静的メンバーへのアクセスにフラグを設定します。static メンバーの有効期間はオブジェクト自体の有効期間よりも長いため、Polyspace は、これらの catch ブロック内での static オブジェクトへのアクセスにフラグを設定しません。

チェック情報

グループ: Exception Handling
カテゴリ: Required、Automated

バージョン履歴

R2019a で導入