MAEC TOOL NEWS:
MAECT-CC32R-010816D
M32Rファミリ用クロスツールキットCC32Rの使用上の注意事項を連絡します。
- volatile領域を複数回連続アクセスする場合の最適化に関する注意事項
- 初期化されていないポインタを使用する場合の最適化に関する注意事項
- 該当製品
CC32R V.1.00 Release 1 ~ V.3.00 Release 1
- volatile領域を複数回連続アクセスする場合の注意事項
- 2.1 内容
- volatile領域を同じオフセット演算を使って複数回連続アクセスする場合、-O4を含む最適化を行うとvolatile属性が無効になることがあります。
- 2.2 発生条件
- 以下4点の条件をすべて満たす場合に発生することがあります。
- (1) 最適化オプションとして、-O4を含む最適化を指定している(つまり、-O4, -O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定している)。
- (2) 以下のいずれかの変数が、volatile型で宣言されている (ただし、ビットフィールドは除きます)。
- (a) 構造体、共用体のメンバ
- (b) 配列の要素
- (c) ポインタ+オフセット値で示される場所
- (3) (2)の変数が占める領域を連続して複数回アクセスしている。
- (4) (3)の連続アクセスの間に、関数の呼び出しおよび任意のポインタを使った間接代入を行っていない。
- 2.3 発生例
[ソースファイル例1:sample1.c]
-----------------------------------------------------------------------
extern volatile unsigned short v_array[]; /* 条件2(b) */
void foo(void)
{
while (v_array[7] & 4); /* 条件3 */
/* 条件4 */
while (!(v_array[7] & 4)); /* 条件3 */
}
-----------------------------------------------------------------------
[ソースファイル例2:sample2.c]
-----------------------------------------------------------------------
extern volatile struct { /* 条件2(a) */
int a;
int b;
} v_strarea;
void foo(void)
{
while (v_strarea.a & 4); /* 条件3 */
/* 条件4 */
while (!(v_strarea.a & 4)); /* 条件3 */
}
-----------------------------------------------------------------------
[ソースファイル例3:sample3.c]
-----------------------------------------------------------------------
extern volatile long *v_ptr; /* 条件2(c) */
int foo(void)
{
int answer;
answer = (*(v_ptr + 7) & 4); /* 条件3 */
/* 条件4 */
answer *= (*(v_ptr + 7) & 8); /* 条件3 */
return answer;
}
-----------------------------------------------------------------------
[CC32Rのコマンド操作例(%はプロンプトを表します)]
-----------------------------------------------------------------------
% cc32R -c -O4 sample1.c
% cc32R -c -O4 sample2.c
% cc32R -c -O4 sample3.c
-----------------------------------------------------------------------
- 2.4 回避策
- 次の(1)~(3)のいずれかの方法で回避してください。
- (1) -O4レベルの最適化を抑止する。
- ※-O4を含む最適化は、-O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定しているときに行われます。-Otimeまたは-Ospaceを使用する場合は、同時に-O3,-O2,-O1,-O0のいずれかを指定してください。
- (2) 該当領域をvolatile型のポインタを使ってアクセスする
[ソースファイル例1:sample1.cの回避例]
-------------------------------------------------------------------
extern volatile unsigned short v_array[];
void foo(void)
{
volatile unsigned short *ptr = &v_array[7];
while (*ptr & 4);
while (!(*ptr & 4));
}
-------------------------------------------------------------------
[ソースファイル例2:sample2.cの回避例]
-------------------------------------------------------------------
extern volatile struct s_tag {
int a;
int b;
} v_strarea;
void foo(void)
{
volatile int *ptr = &v_strarea.a;
while (*ptr & 4);
while (!(*ptr & 4));
}
-------------------------------------------------------------------
[ソースファイル例3:sample3.cの回避例]
-------------------------------------------------------------------
extern volatile long *v_ptr;
int foo(void)
{
int answer;
volatile long *ptr = v_ptr + 7;
answer = (*ptr & 4);
answer *= (*ptr & 8);
return answer;
}
-------------------------------------------------------------------
- (3) 該当領域を等価なビットフィールドにする
[ソースファイル例1:sample1.cの回避例]
-------------------------------------------------------------------
extern volatile struct {
unsigned short u16:16;
} v_array[];
void foo(void)
{
while (v_array[7].u16 & 4);
while (!(v_array[7].u16 & 4));
}
-------------------------------------------------------------------
CC32R ご使用上のお願い
MAECT-CC32R-010816D
- 初期化されていないポインタを使用する場合の注意事項
- 3.1 内容
- 初期化されていないポインタを使用するプログラムに対して、-O4を含む最適化を行うと、コンパイラ内部で永久ループに陥り、コンパイルが終了しなくなる場合があります。
- 3.2 発生条件
- 以下6点の条件をすべて満たす場合に発生することがあります。
- (1) 最適化オプションとして、-O4を含む最適化を指定している(-O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定している場合も含みます)。
- (2) auto変数のポインタA, Bが存在する。
- (3) ループ文があり、そのループ文の前に、次のいずれかの文がある。
- (a) if文があり、真の場合はAへの代入がある。偽の場合はAへの代入がない。
- (b) for文またはwhile文があり、そのループ中でAへの代入式がある。
- (4) (3)のループ内にはif~else文があり、else処理の中でポインタAを含む式の値をポインタBに代入している。
- (5) (4)でポインタAを参照するまでに、(3)(a)または(3)(b)以外にポインタAへの代入式がない。
- (6) (4)のポインタBへの代入以外の場所で、ポインタBへの代入式がない。
- 3.3 発生例
[ソースファイル例1:sample1.c]
-----------------------------------------------------------------------
int check1, check2;
void
func(void)
{
int *ptr_A; /* ポインタA */ /* 条件2 */
int *ptr_B; /* ポインタB */ /* 条件2 */
int i;
if (check1) { /* 条件3(a) */
ptr_A = 0; /* 条件3(a) */
} /* 条件3(a) */
for (i = 0; i < 20; i++) {
if (check2) {
} else {
ptr_B = ptr_A; /* 条件4, 5 */
}
}
}
-----------------------------------------------------------------------
[ソースファイル例2:sample2.c]
-----------------------------------------------------------------------
int check1, check2;
void
func(void)
{
int *ptr_A; /* ポインタA */ /* 条件2 */
int **ptr_B; /* ポインタB */ /* 条件2 */
int i;
while (check1) {
ptr_A = 0; /* 条件3(b) */
}
:
for (i = 0; i < 20; i++) {
if (check2) {
:
} else {
ptr_B = (int**)*ptr_A; /* 条件4,5 */
}
}
}
-----------------------------------------------------------------------
[CC32Rのコマンド操作例(%はプロンプトを表します) ]
-----------------------------------------------------------------------
% cc32R -c -O4 sample1.c
% cc32R -c -O4 sample2.c
-----------------------------------------------------------------------
- 3.4 回避策
- 次の(1),(2)のいずれかの方法で回避してください。
- (1) -O4レベルの最適化を抑止する。
- ※-O4を含む最適化は、-O5, -O6, -O7, -Otimeのみ、または-Ospaceのみを指定しているときに行われます。-Otimeまたは-Ospaceを使用する場合は、同時に-O3,-O2,-O1,-O0のいずれかを指定してください。
- (2) ポインタAを初期化する
以下の例に従い、ポインタAが確実に初期化されるようなコードを追加してください。
[sample1.cの回避例]
---------------------------------------------------------------
int *ptr_A;
↓
int *ptr_A = 0;
---------------------------------------------------------------
ソースファイル例2:sample2.cでも同様に初期化してください。