char配列をメンバに持つ共用体型auto変数の初期値に、配列サイズを超える長さの文字列リテラルを{ }なしで指定すると、エラーとならずに文字列全体をコピーするコードが生成され、スタックを破壊してしまう問題点を修正しました。
[例]
void test()
{
union {char c[4];} x = "long string";
/* 配列に収まりきらないがエラーとならない */
}
次の条件を全て満たす時、発生します。
(a) char/unsigned char型配列をメンバに持つ共用体型auto変数が存在する。
(b) (a)の変数の初期値に、配列サイズを超える長さの文字列リテラルを{ }なしで指定している。
構造体の先頭に無名ビットフィールドがあり、その直後のメンバが配列または構造体である構造体に初期値を設定した場合、無名ビットフィールドのギャップ分が出力されない問題を修正しました。
[例]
struct S {
char :1;
char a[3];
} s = {"abc"};
[正しい出力コード]
_s:
.data.l h'00616263
[不正な出力コード]
_s:
.data.l h'61626300 ; 無名ビットフィールドのギャップが出力されない
次の条件を全て満たす時、発生します。
(a) 構造体の先頭メンバに無名ビットフィールドを宣言している。
(b) (a)の直後のメン バが、配列または構造体を宣言している。
(c) 上記構造体変数に初期値を設定している。
H8/300またはノーマルモード時の定数式演算において、定数値をポインタ型へキャスト時、定数値の上位ワードをクリアせず、その後の演算で結果が不正となる場合がある問題点を修正しました。
[例]
long x = (long)(char *)0x12345678;
[出力コード]
.section D,data
_x:
.data.l h'12345678 /* 上位2byteがクリアされない */
次の条件を全て満たす時、発生する場合があります。
(a) cpu=300,300l,300hn,2000nまたは2600nを指定している。
(b) 定数値をポインタ型へキャストしている。
(c) (b)の定数値が2byteを超えている。
switch文を記述した場合、不正に分岐する場合がある問題点を修正しました。
[例]
typedef struct { char a; char* b; char* c; }st;
void func(st x)
{
int i;
switch(x.a)
{
case 0:
func1(x->b); /* 共通式 */
func1(x->c);
:
break;
case 1:
func1(x->b); /* 共通式 */
:
break;
case 2:
func1(x->b); /* 共通式 */
break;
case 3:
func1(x->b); /* 共通式 */
break;
<以下省略>
[出力コード]
switch(x.a)
MOV.W @ER6,R1
CMP.W #-3879,R1
BEQ L1647:16
:
CMP.W #-3884,R1
BEQ L1671:16 <---- (本来 L1673に分岐)
CMP.W #-3883,R1
BEQ L1671:16
:
:
L1671:
:
L1673:
switch文にcase文が複数あり、各case文内の式に共通式が存在する場合、発生することがあります。
1ビットのビットフィールドの値を判定する式があり、かつその前後で0を設定する式が記述された場合、0の設定コードが削除され、オブジェクト不正となる場合がある問題を修正しました。
[例]
unsigned char X,Y;
struct{
unsigned char F1:1;
unsigned char F0:1;
} BIT1,BIT2;
void test(void){
X = 0;
if( BIT1.F0 ){
/* 1ビットのビットフィールドの値を判定します */
if( BIT2.F0 != (Y==0 ? 0 : 1) ){
/* 3項演算子内で0を代入する式が記述されている */
BIT2.F0 = (Y==0 ? 0 : 1);
/* ためオブジェクト不正となる可能性があります */
}
}
}
[出力コード]
BIT2.F0 = (Y==0 ? 0 : 1);
; sub.b r0l,r0lの命令を不正に削除
mov.b r1l,r0h
beq l12:8
mov.b #1,r0l
l12:
bld.b #0,r0l
bst.b #6,@_bit2:32
次の条件を全て満たす時、発生する場合があります。
(a) 1ビットフィールドの判定式が存在する。
(b) (a)の式の前後に0を設定する式が存在する。
unsigned long 型への型変換を実施した変数と、unsigned long型の定数を比較(<、<=、>、>=)した場合、結果が不正となる場合がある問題点を修正しました。
[例]
unsigned int ui1;
int sub()
{
if (((unsigned long)ui1) > 0x80000000L)
return(0);
return(1);
}
[出力コード]
_sub:
sub.w r0,r0 ; 判定式が常に真となり、リターン値が不正となります
rts
次の条件を全て満たす時、発生する場合があります。
(a) (unsigned long)変数と定数の比較(<、<=、>、>=)を行っている。
(b) (a)の変数が unsigned char、unsigned short、unsigned int のいずれかである。
(c) 定数が0x80000000〜0xFFFFFFFFの範囲内のである(-2147483648〜-1)。
(※但し、0xFFFFFFFF(-1)の場合の <=-1、 >-1は除く)
同一データ領域内のビットフィールドへの設定が連続して記述された場合、不正なオブジェクトが生成される場合がある問題点を修正しました。
[例]
struct{
int s1 :1;
int s2 :3;
int s3 :1;
int s4 :3;
}bit;
void func()
{
if (x)
bit.s1=1;
else
bit.s2=2;
}
[出力コード]
<不正コード> <正常コード>
_func: _func:
mov.w r0,r0 mov.w r0,r0
beq l5:8 beq l5:8
mov.l #_bit,er0 bset.b #7,@_bit:32 ; ビットが不正に統合される
mov.w @er0,r1
and.w #-20481,r1
bra l7:8 rts
l5: l5:
mov.l #_bit,er0 mov.b @_bit:32,r0l
mov.w @er0,r1 and.b #-113,r0l
or.w #-24576,r1 or.b #32,r0l
l7:
mov.w r1,@er0 mov.b r0l,@_bit:32
rts rts
同一データ領域内のビットフィールドへの設定を以下の条件の(ア)、(イ)の形で記述した場合、発生する場合があります。
(a) if文 if(---) (ア) else (イ) (b) while文 while((ア)) (イ) (c) カンマ式 ((ア) ? (イ) : EXP) (EXP ? (ア) : (イ))
long型のビットフィールド(ビットオフセット+ビットサイズ<=16またはビットオフセット>16)へ定数値を設定する時、正しく設定できない場合がある問題点を修正しました。
[例]
#include <stdio.h>
struct ST {
char C1;
char C2;
long UL1:6;
long L1 :4;
} st;
void main(){
st.C1 = 10;
st.C2 = 10;
st.L1 = 7;
printf("st.L1 : %ld \n",st.L1);
}
[出力コード]
.cpu 2600a:24
.section p,code,align=2
_main:
push.l er6
:
/* st.L1 = 7; */
/* 不正コード */ /* 正しいコード */
and.b #-4,r0h mov.w @(2:16,er6),e0 ; メンバの参照・設定コードが
and.b #63,r0l and.w #-961,e0 ; 不正に削除されます
or.b #1,r0h or.w #448,e0
or.b #-64,r0l mov.w e0,@(2:16,er6)
:
pop.l er6
rts
次の条件を全て満たす時、発生する場合があります。
(a) long/unsigned long型のビットフィールドへの設定コードで、ビットオフセット+ビットサイズ<=16、またはビットオフセット>16である。
(b) 設定値が定数である。
(c) 最適化有り(-optimize=1、デフォルト)指定している。
(d) 300、300L以外のCPU指定している。
代入先がビットフィールドの乗算の複合代入演算式を記述した場合、生成コードが不正となる場合がある問題点を修正しました。
[例]
struct ST {
unsigned int bit1 :6;
signed int bit2 :3;
} st1,st2,*stp;
sub()
{
//省略
stp->bit1 *= st2.bit2;
//省略
}
[出力コード]
mov.w @_st2:32,r0
mov.w #1539,r1
jsr @$bfsi$3:24 // st2.bit2の値をr0に設定
mov.l @_stp:32,er2
mov.b @er2,r1l
shlr.b #2,r1l
extu.w r1 // stp->bit1の値をr1に設定
mov.w r0,@(2:16,sp) // r0を退避
mov.w r1,r0 // r0を破壊
mulxu.w r0,er0 // 破壊されたr0をst2.bit2として使用
:
次の条件を全て満たす時、発生する場合があります。
(a) 乗算の複合代入演算式が存在している。
(b) (a)の代入先の変数がビットフィールドであり、そのビットフィールドがポインタ参照である。
(c) -regexpansion(デフォルト)を指定している。
(d) 最適化(-optimize=1、デフォルト)を指定している。
(e) レジスタ変数が[E]R3〜[E]R6全て使用されている。
カンマ式の第1子に、その結果を使用しないビットごとの論理演算の(&,^,|)を記述した時、ビット演算の式の中に変数への設定値があった場合でも、その設定値が削除されてしまう問題点を修正しました。
[例]
int i1,i2,i3;
sub()
{
((long)(i2++) & (i3=1)), i1 = 8; /* i2++, i3=1が不正に実行されない */
}
次の条件を全て満たす時、発生する場合があります。
(a) カンマ式の第1子に、その結果を使用しないビットごとの論理演算を記述している。
(b) (a)の第1子、および第2子に変数を更新する式の記述がある(一方が構造体のメンバ記述でも該当)。
(c) (a)の第1子、または第2子に型変換(cast)の記述がある。
無限ループのある関数で、スタック上に割付られた局所変数や引数のデバッグ情報が誤ってしまい、正しくシンボルデバッグができない問題点を修正しました。
[例]
extern int a;
void func()
{
char c[4]; /* cの変数のシンボルデバッグができない */
c[3] = 1;
for(;;){
a++;
}
}
次の条件を全て満たす時、発生します。
(a) debugオプションとoptimizeオプションを指定している。
(b) 関数内に無限ループが存在し、局所変数または引数がスタック上に割りついている。
char/short/int型の変数に対し、型変換後(暗黙の型変換も含む)に単項マイナス演算を行なった場合、演算結果が不正となる不具合を修正しました。
[例1]
char c;
short s;
int i;
long l;
vois sub()
{
s=-c; /* c=-128 の時,s=-128 (正しくはs=128) */
i=-c; /* c=-128 の時,i=-128 (正しくはi=128) */
l=-(long)c; /* c=-128 の時,l=-128 (正しくはl=128) */
l=-(long)s; /* s=-32768 の時,l=-32768 (正しくはl=32768) */
l=-(long)i; /* i=-32768 の時,l=-32768 (正しくはl=32768) */
}
[正しくない出力コード] 不具合例1の s=-c; の場合
MOV.B @_c,R0L
NEG.B R0L
EXTS.W R0
MOV.W R0,@_s
[正しい出力コード] 不具合例1の s=-c; の場合
MOV.B @_c,R0L
EXTS.W R0
NEG.W R0
MOV.W R0,@_s
[例2]
char c;
int i1,i2;
i1 = -c + i2; /* c=-128の時,-cが-128 (正しくは-cは128) */
[例3]
char c;
int func();
int func()
{
return(-c); /* c=-128の時,-cが-128 (正しくは-cは128) */
}
シフト演算後にビットごとAND演算を行なった場合、または連続して複合代入(&=,|=,^=)を行なった場合、コンパイル実行環境によって不正なAND命令が生成されることがある不具合を修正しました。
本件はコンパイラ解放済みメモリ領域の値に依存するため、同一プログラム同一オプションの条件であっても必ず発生するものではありません。
[例1]
unsigned int X;
sub(unsigned int Y)
{
X = (Y >> 14) & 0x2;
}
[正しくない出力コード]
MOV.W @_Y, R0
ROTL.W #H'2, R0
AND.L #H'20002,ER0 <--- 正しくないコード
MOV.W R0, @_X
[正しい出力コード]
MOV.W @_Y, R0
ROTL.W #H'2, R0
AND.W #H'2, R0 <--- 正しいコード
MOV.W R0, @_X
[例2]
int sub(int Y)
{
Y &= 0x3;
Y &= 0x2;
return Y;
}
[正しくない出力コード]
AND.L #H'20002,ER0 <--- 正しくないコード
[正しい出力コード]
AND.W #H'2, R0 <--- 正しいコード
コンパイラの最適化の1つである“ループ内の不変式の括り出し最適化”がコンパイル実行環境によって効かない場合がある現象を修正しました。
比較演算で被比較式の演算結果がオーバーフローする場合、正常に比較分岐できない場合がある不具合を修正しました(ア)。
なお、型変換の記述によりコンパイラの演算最適化(int演算をすべきところchar演算とする)が実施され、その結果オーバーフローになる場合も含まれます(イ)。
[(ア)の例] (i1 - i2)の結果は-32768であり、"OK"にもかかわらず"NG"となってしまう。
int i1 = 1;
int i2 = -32767;
if((i1 - i2) < 0)
printf("OK\n");
else
printf("NG\n");
[(イ)の例] (char)(c1 - c2)の結果は-128であり、"OK"にもかかわらず"NG"となってしまう。
char c1 = 1;
char c2 = -127;
if((char)(c1 - c2) < 0)
printf("OK\n");
else
printf("NG\n");
C++コンパイル時に、abs16オプションを指定してコンパイルした場合、C$INIT,C$VTBLセクションが生成されず、そこに割りつくオブジェクトが$ABS16Cセクションに割り付いていた問題点を修正しました。
C++コンパイル時に、abs8またはabs16オプションを使用すると、#pragma abs8 sectionまたは#pragma abs16 sectionで指定しているセクション名の切り替えが無効になる問題点を修正しました。
構造体のメンバを関数へのポインタでそのポインタを関数のプロトタイプ形式で宣言した場合、デバbグ情報が不正となる問題点を修正しました。
[例]
struct sample {
void (*fp)(int);
};
C++コンパイル時に、メンバ関数と同名の宣言済み関数をメンバ内で再宣言するとコンパイラが不正終了する問題点を修正しました。
[例]
void func();
struct S {
void func() {
extern void func();
}
};
セクションアドレス演算子の結果をデータ以外の目的で絶対アドレスとして使用する場合、オブジェクト不正となる問題点を修正しました。
[例]
void sub(void){
(*((void (*)(void))__sectop("P")))();
}
C++コンパイル時でdebugオプションが指定されたとき、構造体/クラスのメンバにstatic宣言した配列メンバがあり、そのメンバを引数や局所変数として使用した場合、内部エラーが発生する問題点を修正しました。
[例]
class B {
static char EMPTY[];
char *m;
};
class B a;
void func(class B b) {
a=b;
}
オプションで-define=マクロと指定した場合、-define=マクロ=1と同等の動作を行っていた問題点を修正しました。
1ビットのビットフィールドのみの変数同士で、ビットフィールドの型指定子のサイズが互いに異なる時に、ビット演算(&, |, ^, &=, ^=)を実施した場合、不正なコードが出力されることがある問題点を修正しました。
[例]
struct {
char char1 :1;
int int1 :1;
} x1,x2,x3;
void sub(){
x1.int1 |= x2.char1 | x3.char1;
}
[出力コード]
_sub:
BLD.B #7,@_x2:32
BOR.B #7,@_x3:32
BST.B #0,R0L
BLD.B #7,@_x1+2:32 正しいコード
BOR.B #0,R1H ←-- BOR.B #0,R0L
BST.B #7,@_x1+2:32
RTS
Solaris版コンパイラにおいてdebugオプションを指定してコンパイルを行うと、インターナルエラーが発生することがある問題点を修正しました。
構造体サイズが256バイト以上の時、デバッグ情報が不正となっていた問題点を解決しました。
1つのファイルの中のインクルードファイル数が256を超えた時、デバッグ情報が不正になっていた問題点を解決しました。
無限ループを含む関数においてスタック渡し引数が有る場合、当該引数の参照コードが不正となっていた問題点を解決しました。
-stack=smallの指定時に関数の引数として局所変数のアドレスを記述した時、コード不正となる問題点を解決しました。
現ファイル中に存在しないセクションをセクションアドレス演算子で指定する時、セクション名が"$abs16"で始まるセクションのアラインを1から2へ変更しました。
C++プログラムで構造体配列の初期値に定数アドレスを指定した時、静的な初期値とならずに代入式を生成してしまう問題点を解決しました。
C++プログラムで#pragma sectionに"_"を含むセクション名を指定すると、不正に5987エラーを出力する問題点を解決しました。
セクションアドレス演算子で指定されたセクションが当該ファイル中に存在しない場合、コンパイラが自動生成するサイズ0のセクションの属性を"常にDATAとする"から"Pで始まるセクションはCODEとする"に変更しました。
cpu=300かつlongregオプションを指定したとき、[unsigned]long型,または,float型の引数が正しく渡らない。
[例]
int X,Y,Z;
void sub1(long p2)
{
volatile int i1;
for (i1=0;i1<10;i1++)
X++;
Z = (int)p2;
}
[出力コード]
_sub1:
<省略>
MOV.W #_X,R1 <- 外部変数のレジスタ割り付けで引数R1が破壊されている
MOV.W R0,@(2:16,SP)
MOV.W R1,@(4:16,SP) <- 引数p2の下位2byteが不正(#_Xの値が入っている)
SUB.W R0,R0
MOV.W R0,@SP
BRA L9
L8:
<省略>
次の条件を全て満たす時、発生します。
(a) cpu=300または300lを指定。
(b) 最適化あり(optimize=1)を指定。
(c) 引数に[unsigned]long型、またはfloat型を指定。
(d) 上記(c)の引数がオプション-longregによりレジスタ渡しとなる。(R0とR1 または R1とR2)
(e) 関数内で外部変数を使用しており、その変数がレジスタに割りついている。
cpu=300hn,2000n,2600nかつstructregオプションを指定したとき、引数として渡された構造体ポインタを用いて2byteサイズの構造体を引数とする関数を呼び出した場合、構造体引数が正しく渡らない。
[例]
struct ST{
char c1,c2;
};
void sub1(int a, struct ST *p)
{
func1(a, *p); // 構造体へのポインタpを用いて、2byte構造体を引数に指定
}
[出力コード]
_sub2: <- R0(a), E0(p)
MOV.W E0,R1
MOV.B @ER1+,R1H <- R1H = p->c1; ここでR1(p)を破壊
MOV.B @ER1,R1L <- R1L = p->c2;
MOV.W R1,E0
JMP @_func1:16
次の条件を全て満たす時、発生します。
(a) cpu=300hn, 2600n, 2000nを指定。
(b) structregを指定。
(c) 当該関数が2byte構造体へのポインタ引数を持ち、レジスタで渡される。
(d) 当該関数内に2byte構造体引数を持った関数呼び出しがあり、(c)のポインタを用いて構造体引数を設定。
3.1 事例1
1バイトと3バイトで構成されるネストした構造体/共用体を使用し、かつ、その構造体/共用体変数の3バイトの部分の値を代入式で記述した場合、正しく値が設定されない。
[例]
struct A {
char a1;
struct B { char b1,b2,b3; } b;
};
struct A sta;
struct B stb;
void sub()
{
struct A x;
x = sta;
stb = x.b; // x.bの参照不正により代入コードが生成されない。
}
次の条件を全て満たす時、発生します。
(a) 最適化あり(optimize=1)を指定。
(b) 1バイトと3バイトで構成されるネストした構造体/共用体を使用している。
(c) 当該構造体/共用体の3バイトの部分を代入式で参照している。
(d) 当該構造体/共用体はローカル変数で使用され、レジスタに割りついている。
3.2 事例2
ネストした構造体/共用体を使用し、かつその構造体/共用体変数に関数のリターン値を代入した場合、正しく値が設定されない。
[例]
union A{
struct B{ int i1; } b;
struct C{char c1,c2; } c;
};
struct B stb, func();
void sub()
{
union A a;
a.b = func();
stb = a.b;
}
[出力コード]
_sub2:
PUSH.W R6
PUSH.L ER0
JSR @_func:24
ADDS.L #4,SP
MOV.W R6,@_stb:32
POP.W R6
RTS
[正しいコード]
_sub2:
SUB.L #2,SP
MOV.L SP,ER2
PUSH.L ER2
JSR @_func:24
ADDS.L #4,SP
MOV.W @ER2,R3
MOV.W R3,@_stb:32
RTS
次の条件を全て満たす時、発生します。
(a) 最適化あり(optimize=1)を指定。
(b) ネストした構造体/共用体を使用し、構造体メンバに関数のリターン値を代入。
(c) 当該構造体/共用体はローカル変数で使用され、レジスタに割りついている。
div関数を呼び出すとき、structregオプションを指定すると実行結果が不正になる。(-cpu=300,300l以外)
[例]
#include <stdlib.h>
div_t ret;
void sub()
{
ret = div(10,3); // 商と余りが逆に設定される
}
次の条件を全て満たす時、発生します。
(a) cpu=300hn, 2600n, 2000nを指定。
(b) structregを指定。
(c) 標準ライブラリ関数divを使用
シンボルの外部定義より前に外部参照宣言がある時、当該外部変数のシンボリックデバッグができない。
[例]
extern int i;
int i; // デバッガ(HDI)では"out of scope"になる
void func()
{
i++;
}
次の条件を全て満たす時、発生します。
(a) debugオプションを指定。
(b) シンボルの外部定義より前に、当該シンボルの外部参照宣言がある。
非最適化時(optimize=0指定)、次のプログラムにおいてローカル変数がシンボリックデバッグできない。
[例]
int a;
void func()
{
while(1){ // 無限ループ
a=0;
}
a=1;
}
次の条件を全て満たす時、発生します。
(a) 最適化なし(optimize=0)を指定。
(b) debugオプションを指定。
(c) 関数内で無限ループがある。
(d) 無限ループから外へ出るコーディングがない。
1バイトと3バイトで構成される構造体を使用した場合、次のプログラムにおいてインターナルエラー4633が発生する。
[例]
struct A{
char a1;
struct B{
char b1;
char b2;
char b3;
}v;
};
void sub1()
{
struct A x; // xはレジスタに割りついている
x.v.b2 = 10;
func(x.v); // 構造体xの3バイトのメンバvを引数として使用
}
次の条件を全て満たす時、発生します。
(a) 最適化あり(optimize=1)を指定している。
(b) cpu=300以外を指定している。
(c) 1バイトと3バイトで構成されるローカル構造体を使用している。
(d) 上記構造体の3バイトの部分を関数の引数、またはリターン値として使用している。
(e) 上記構造体はレジスタに割りついている。
8.1 事例1
関数コールの後にあるif文の中で、再度同じ関数をコールしている場合に、インターナルエラー4099が発生する。
[例]
void func(int p){ }
void sub(int x)
{
func(1);
if(x==10)
func(1);
}
次の条件を全て満たす時、発生します。
(a) 最適化あり(optimize=1)を指定している。
(b) 関数呼び出しの後、then節しかないif文がある。
(c) if文の直前にある式(複数でも可)と、if文のthen節の最終式が同一。
(d) (c)の同一式の中に関数呼び出しがある。
8.2 事例2
char型の初期値なし変数が512個以上あるファイルをコンパイルした場合に、インターナルエラー4099または4603が発生する。
[例] #pragma abs8 a1; char a1; : char a520;
次の条件を全て満たす時、発生します。
(a) 1ファイルに[unsigned]char型の変数、配列、[unsigned]char型で構成される構造体または共用体定義が512個以上ある。
【注】#pragma section, abs8 section, abs16 section, #pragma abs8, abs16, __abs8,
__abs16使用時は512個より少なくても発生する場合がある。
(b) alignオプション(デフォルト)を指定。
[unsigned]char型の512バイト以上の初期値付き変数、配列、構造体を持つファイルをコンパイルした場合に、インターナルエラー4677が発生する。
[例]
char x[1023] = {
0,0,0,0,0,0,0,0,0,0,
:
:
0,0,0,0,0,0,0,0,0,0
};
char a = 1;
int b = 2;
次の条件を全て満たす時、発生します。
(a) [unsigned]char型の初期値付き変数、配列、構造体のサイズの合計が512バイト以上あり、かつ奇数バイトである。
【注】#pragma section, abs8 section, abs16 section, #pragma abs8, abs16, __abs8,
__abs16使用時は512個より少なくても発生する場合がある。
(b) (a)の変数の後に出現する初期値付きの変数が、1バイトアライン変数、2バイトアライン変数の順である。
(c) alignオプション(デフォルト)を指定。
10.1 事例1
if文で1ビット同士の論理OR(||)演算を記述した場合、インターナルエラー4774(または4954)が発生する。
[例]
struct BIT{
char b1:1;
char b2:1;
}B1,B2;
int x;
void sub1()
{
if(B1.b1){
if(B1.b1 || B2.b2) // 1bit同士の論理OR演算
x++; // B1.b1の値はレジスタに割りついている
}
}
次の条件を全て満たす時、発生します。
(a) 最適化あり(optimize=1)を指定している。
(b) if文で1ビット同士の論理OR(||)演算を記述している。
(c) (a)の1ビット変数の一方または両方がレジスタに割りついている。
10.2 事例2
[unsigned] char型変数と2バイト構造体をメンバにもつ構造体を使用した場合、インターナルエラー4774が発生する。
[例]
struct A{
char d;
struct B { char b1; char b2; }s1;
};
struct C{
struct B s1,s2;
}
struct A sta;
struct C stc;
void sub()
{
struct A a; // En(上位byte):a.d,En(下位byte):a.s1.b1,RnH:a.s1.b2
struct C c; // Em:c.s1,Rm:c.s2
a.s1 = c.s1;
sta = a;
}
次の条件を全て満たす時、発生します。
(a) [unsigned] char型変数と2バイト構造体(構造体B)をメンバにもつ構造体(構造体A)を使用している。
(b) 構造体Aの構造体メンバ(構造体B)に単純代入式(=)による代入を記述。
(c) 構造体Aはローカル変数で、かつレジスタに割りついている。
(d) 代入元の構造体もレジスタEn側に割りついている。
(e) 最適化あり(optimize=1)を指定。
(f) cpu=300, 300l以外を指定。
割り込み関数指定時に、割り込み関数終了指定としてsy=$<シンボル名>を指定した場合、リンク時に次のインターナルエラーが発生する。
** L4000 (-) Internal error : (8001) "File:in_cainf.cpp Line:2169 / IOP Reference Symbol Name Not Found:_<シンボル名>" / "<ファイル名>"
[例]
#pragma interrupt func(sy=$sub)
void func()
{
}
goptimize指定なし時、実行時ルーチンを呼び出す場合にスタック使用量が不正になる。
[例]
long LL;
volatile long a,b;
void func()
{
LL=a/b; // 実行時ルーチン$DIVL$3が呼び出される
g();
}
g(){}
次の条件を全て満たす時、発生します。
(a) goptimizeオプションを指定しない。
(b) ファイル内に外部参照シンボルが存在しない。
(c) 実行時ルーチン呼び出しのコードが生成される。
code=asmcode指定時、割り込み関数やエントリ関数などでベクタテーブル出力を指定した場合、ベクタテーブルが不正にcode属性で出力される。
[例]
#pragma entry func(vect=2)
void func(){}
次の条件を全て満たす時、発生します。
(a) code=asmcodeオプションを指定。
(b) #pragma, キーワードによりベクタテーブル出力を指定。
__STDC__マクロが未定義となる。
[例]
#ifdef __STDC__
#define CONST const
#else
#define CONST
#endif
CONST int a=0; // V3ではCセクションに割りついていたが、
// V4ではDセクションに割りついてしまう。
head=stdio指定で生成したライブラリをリンクしたときに、次のメッセージが発生する。
** L2310 (W) Undefined external symbol "_modf" referenced in "_log10"
次のいずれかの条件を満たす時、発生します。
(a) head=stdioを指定時にhead=mathまたはmathfを指定していない。
(b) head=ios指定時にhead=stdio, stdlib, ctypeまたはstringを指定していない。
(c) head=complex指定時にhead=mathまたはmathfを指定していない。
(d) head=cppstring指定時にhead=stringを指定していない(Windows版)。
(e) head=cppstring指定時にhead=stringまたはnewを指定していない(UNIX版)。