MAEC TOOL NEWS:
MAECT-M3T-NC308WA-020501D
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA
ご使用上のお願い
|
Cコンパイラ(アセンブラ・統合化開発環境付き) M3T-NC308WA, M3T-NC30WA, M3T-NC79WAの使用上の注意事項を連絡します。
- if文中のビットフィールドの評価結果に関する注意事項
- 条件式の生成コードに関する注意事項
- if文中のビットフィールドの評価結果に関する注意事項
- 1.1 該当製品
-
- M32C/80, M16C/80, M16C/70シリーズ用Cコンパイラ:
- M3T-NC308WA V.2.00 Release 1 ~ V.3.10 Release 3
- M16C/60, M16C/30, M16C/20, M16C/10シリーズ用Cコンパイラ:
- M3T-NC30WA V.3.20 Release 1 ~ V.5.00 Release 1
- 79xxシリーズ用Cコンパイラ:
- M3T-NC79WA V.3.20 Release 1 ~ V.4.10 Release 1
- 1.2 内容
- if文の条件式に、論理AND演算子 (&&) で連結したビットフィールドの評価式が、複数記述されている場合、不正なコードを生成します。
- 1.3 発生条件
- 以下6点の条件をすべて満たす場合に発生します。
- (1) 最適化オプションに "-OR" を使用し、かつ "-O5" または "-O4" を併用している。
- (2) if文の条件式に、ビットフィールド (1ビット) の評価式が複数記述されている。
- (3) (2)の複数ある評価式が、"==" のみの判定である。
- (4) (2)の複数ある評価式に、即値 "1" と比較する評価式が1つ以上ある。
- (5) (2)の複数ある評価式が、論理AND演算子 (&&) で連結されている。
- (6) 条件成立時の処理が何も行わないもしくは無条件分岐である。
- 1.4 発生例
------------------------------------------------------------------------
struct bitf {
int b0:1;
int b1:1;
int b2:1;
}bit;
int i;
void func1(void){
if((bit.b0 == 1)&&(bit.b2 == 1)){ /* 発生条件(2)、(3)、(4)、(5) */
; /* 発生条件(6) */
}else{
i = 1;
}
}
void func2(void){
if((bit.b0 == 1)&&(bit.b2 == 1)){ /* 発生条件(2)、(3)、(4)、(5) */
goto L1; /* 発生条件(6) */
}
i = 1;
L1:;
}
-------------------------------------------------------------------------
- 1.5 回避策
- オプション "-Ono_logical_or_combine" (-ONLOC) を使用してコンパイルしてください。
- 1.6 恒久対策
- 本内容は、次期バージョンにて改修する予定です。
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA ご使用上のお願い
MAECT-M3T-NC308WA-020501D
- 条件式の生成コードに関する注意事項
- 2.1 該当製品
-
- M16C/60, M16C/30, M16C/20, M16C/10シリーズ用Cコンパイラ:
- M3T-NC30WA V.5.00 Release 1
- 2.2 内容
- 条件式中で、符号なし (unsigned) の変数を使用した引き算と0 (ゼロ) との比較を行なった場合、不正なコードを生成する場合があります。
- 2.3 発生条件
- 以下4点の条件をすべて満たす場合に発生することがあります。
- (1) 条件式中に引き算がある。
- (2) (1)の引き算は、以下a~cのいずれか1つを満たしている。
| 引かれる側 | 引く側 |
| a. | 変数 | 変数 |
| b. | 変数 | 9以上の即値 |
| c. | 即値 | 変数 |
- (3) (2)の変数は、unsigned int型またはunsigned char型である。
- (4) (1)に示す演算結果が、以下のいずれかである。
- 0未満( < 0)
- 0以下( <= 0)
- 2.4 発生例
- 以下の例2では、unsignedの変数から即値を引いた結果、最上位ビットがたった場合も、C言語規則により正の数とみなします。そのため0未満であるかどうかの比較では常に偽となりますが、本現象では真となり成立してしまいます。
-------------------------------------------------------------------------
void func(void)
{
unsigned int i1,i2; /* 発生条件(3)*/
unsigned char c1; /* 発生条件(3)*/
// 例1(if文の真側を実行します。)
i1 = 1;
c1 = 2;
if((i1 - c1) < 0){ /* 発生条件(1)、(2)、(3)、(4)*/
i2 = -1;
}else{
i2 = 1;
}
// 例2(if文の真側を実行します。)
if((i1 - 10) < 0){ /* 発生条件(1)、(2)、(3)、(4)*/
i2 = -1;
}else{
i2 = 1;
}
// 例3(if文の真側を実行します。)
i1 = 10;
if((3 - i1) < 0){ /* 発生条件(1)、(2)、(3)、(4)*/
i2 = -1;
}else{
i2 = 1;
}
}
-------------------------------------------------------------------------
- 2.5 回避策
- 条件式中の引き算に使用する符号なしの変数を、符号付きの型にキャストしてください。
[例]
-------------------------------------------------------------------------
void func(void)
{
unsigned int i1,i2;
unsigned char c1;
// 例1
i1 = 1;
c1 = 2;
if(((int)i1 - c1) <= 0){ /* 符号付きの型にキャスト*/
i2 = -1;
}else{
i2 = 1;
}
// 例2
if(((int)i1 - 10) <= 0){ /* 符号付きの型にキャスト*/
i2 = -1;
}else{
i2 = 1;
}
// 例3
i1 = 10;
if((3 - (int)i1) <= 0){ /* 符号付きの型にキャスト*/
i2 = -1;
}else{
i2 = 1;
}
}
-------------------------------------------------------------------------
- 2.6 恒久対策
- 本内容は、次期バージョンにて改修する予定です。