メインコンテンツ

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

CERT C++: EXP36-C

Do not cast pointers into more strictly aligned pointer types

説明

ルール定義

ポインターをアライメントがより厳密なポインター型にキャストしないようにします。1

Polyspace 実装

ルール チェッカーは、"格納先バッファーと正しくアライメントされていないソース バッファー" をチェックします。

すべて展開する

問題

"格納先バッファーと正しくアライメントされていないソース バッファー" の問題は、ポインター間変換内のソース ポインターと変換先ポインターがアライメントされていない場合に発生します。正しくないアライメントは次のような理由で発生します。

  • ソース ポインターが、変換先ポインターが指しているものより小さいバッファーを指している。

  • ソース ポインターが、変換先ポインターが指しているものより大きいバッファーを指しているが、バッファー サイズが格納先バッファー サイズの倍数になっていない。

Polyspace® は、以下の場合に、このルールの違反を報告しません。

  • 正しくアライメントされていないポインター間の変換を許可する環境を使用している。たとえば、32 ビットと 64 ビットの x86 環境では、char*uint16_t* に変換しても、プログラムは異常終了しません。

  • 変換先のタイプに正しくアライメントされたソース ポインターを使用している。次に例を示します。

    • alignas 指定子を使用して、ソース ポインターのアライメントと変換先ポインターのアライメントを一致させている。

    • aligned_alloc()malloc()realloc() などの関数から返されるポインターを使用している。これらのポインターは、変換先ポインターのアライメントと一致します。

リスク

ポインターのアライメントがポインター間変換で変化した場合は、変換後のポインターをデリファレンスしたときに、プログラムが異常終了します。

修正方法

ポインター間変換でのポインターのアライメントの変更は避けてください。

例 — 変換中にポインター アライメントを変更
#include <string.h>
struct record {
  int len;
  /* ... */
};

int copyBuffer (char *data, int offset)
{
  struct record *tmp;
  struct record dest;
  tmp = (struct record *) (data + offset);   //Noncompliant
  memcpy (&dest, tmp, sizeof (dest));
  /* ... */

  return dest.len;
}

この例では、関数 copyBufferchar* ポインターを struct record* ポインターに変換してから、memcpy 操作が行われます。memcpy 操作は、tmpstruct record* アライメントを前提としているため、未定義動作につながります。ルール チェッカーは、このルールの違反を報告します。

この問題を回避するには、中間の struct record* ポインターを使用する代わりに、data + offsetmemcpy 操作のソース引数として使用します。

例 — alignas 指定子を使用してアライメントの不一致を回避する

この例は、alignas 指定子を使用することによって、char ポインター char_pint としてアライメントします。char_pint としてアライメントされるため、これを int* に変換してもこのルールに違反しません。

#include <stdalign.h>
#include <assert.h>
  
void foo(void) {
  /* Align char_p to the alignment of an int */
  alignas(int) char char_p = 'a';
  int *int_p = (int *)&char_p; //Compliant
  char *char_new = (char *)int_p;
  /* Both char_new and &char_p point to equally aligned objects */
  
}

チェック情報

グループ: 02.式 (EXP)

バージョン履歴

R2019a で導入

すべて展開する


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.