dotnet/roslyn

Int64 indices are silently truncated when used to access MD array elements

オープン

#30,648 opened on 2018/10/22

 (1 件のコメント) (0 件のリアクション) (0 人の担当者)C# (4,257 件のフォーク)batch import
Area-CompilersBughelp wanted

Repository metrics

Stars
 (20,414 個のスター)
PR merge metrics
 (平均マージ 6d 17h) (30d で 256 merged PRs)

説明

The following code should produce an exception (IndexOutOfRangeException but OverflowException would do too I guess) but it does not:

        static void Main() => Test(new int[42, 42], 41, 41);
        [MethodImpl(MethodImplOptions.NoInlining)]
        static void Test(int[,] a, long x, long y) => a[x | (0x12345678L << 32), y] = 42;

The generated IL code is:

    ldarg.0
    ldarg.1
    ldc.i8     0x1234567800000000
    or
    conv.ovf.i
    ldarg.2
    conv.ovf.i
    ldc.i4.s   42
    call instance void int32[0..., 0...]::Set(int32,int32,int32)

The spec appears to be silent about this case. From the generated code it looks like the intention was to handle this case by using a checked cast, the same is done with SZ arrays.

There must have been some confusion with ldelem. That one accepts both int32 and native int but MD array accessors support only int32 indices and passing a native int argument in this case would result in silent truncation. That conv.ovf.i should really be conv.ovf.i4.

Reproduced with VS 15.8.7 but I'd guess that the problem is much older.

コントリビューターガイド