コンパイラ作成(96) 型変換のバグ修正
バグ修正
プログラム眺めてたらバグを見っけたよ。
// double型 double dadd(double a, double b) { printf("dadd: %f %f\n", a, b); return a + b; } int main() { double x = 12.3, y = -2.8; printf("%f %f %f\n", x, y, dadd(5.4, 3.2)); printf("%d %d %f\n", 12, 7, dadd(5.4, 3.2)); }
この前、int型→double型の変換処理を入れたけど、変換が要らないときにもcvtsi2sdしてたよ。
関数コール
functionの引数の処理部。
# 引数を順番に評価する (0...operand.size-2).each do |i| savegpr, savexmm = @numuseregs, @numusexmms @numuseregs, @numusexmms = i-xmm, xmm type = codegen_el operand[i+2] @numuseregs, @numusexmms = savegpr, savexmm if f != nil then if f[1][i] == "size_t" && type == "int" then codegen " movsx rax, eax" type = f[1][i] elsif f[1][i] == "void*" && is_pointer_type?(type) then type = f[1][i] elsif f[1][i] == "double" && type == "int" then codegen " cvtsi2sd xmm8, eax" type = f[1][i] end if type != f[1][i] then perror "incompatible type parameter" end end if type == "int" || type == "char" then codegen " mov #{@regs32[i-xmm]}, eax" elsif type == "size_t" codegen " mov #{@regs64[i-xmm]}, rax" elsif is_pointer_type?(type) then codegen " mov #{@regs64[i-xmm]}, rax" elsif type == "double" then codegen " movsd xmm#{xmm}, xmm8" xmm += 1 else perror end end
if文の条件が間違ってたよ。size_tの場合も拙かったんで併せて修正。
動作テスト
~/myc$ myc p25.myc ~/myc$ ./p25 dadd: 5.400000 3.200000 12.300000 -2.800000 8.600000 dadd: 5.400000 3.200000 12 7 8.600000 ~/myc$
修正完了。修正箇所のプログラムをよく見て一人レビューするの大事だな。それで怪しいとこ見つけたら即テスト。次回は今回やるはずだったreturn文での型変換をやるつもりだよ。