コンパイラ作成(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文での型変換をやるつもりだよ。