Bug: Accessing return value of type static array with length 1 or 2 by index.

John Colvin john.loughran.colvin at gmail.com
Sat Apr 20 08:24:04 PDT 2013


On Saturday, 20 April 2013 at 13:37:55 UTC, John Colvin wrote:
> On Saturday, 20 April 2013 at 12:23:20 UTC, deed wrote:
>> import std.stdio : writeln;
>>
>> template Template (uint n, T)
>> {
>>    T[n] statArr()
>>    {
>>        T[n] arr;
>>        return arr;
>>    }
>>
>>    T[] dynArr()
>>    {
>>        T[] dynArr = new T[n];
>>        return dynArr;
>>    }
>> }
>>
>> void main()
>> {
>>    alias statArr9 = Template!(9, int).statArr;
>>    alias statArr3 = Template!(3, int).statArr;
>>    alias statArr2 = Template!(2, int).statArr;
>>    alias statArr1 = Template!(1, int).statArr;
>>    alias statArr0 = Template!(0, int).statArr;
>>
>>    // Fine
>>    statArr9().writeln();       // Writes [0, 0, 0, 0, 0, 0, 0, 
>> 0, 0]
>>    statArr3().writeln();       // Writes [0, 0, 0]
>>    statArr2().writeln();       // Writes [0, 0]
>>    statArr1().writeln();       // Writes [0]
>>    statArr0().writeln();       // Writes []
>>
>>    // 2 bugs
>>    statArr9()[0].writeln();    // OK : Writes 0
>>    statArr3()[0].writeln();    // OK : Writes 0
>>    //statArr2()[0].writeln();  // BUG: Internal error: 
>> ..\ztc\cgcs.c 344
>>    //statArr1()[0].writeln();  // BUG: Internal error: 
>> ..\ztc\cgcs.c 344
>>    //statArr0()[0].writeln();  // OK : Error: array index 0 is 
>> out of bounds
>>                                //      getArr0()[0 .. 0]
>>
>>
>>    alias dynArr9 = Template!(9, int).dynArr;
>>    alias dynArr3 = Template!(3, int).dynArr;
>>    alias dynArr2 = Template!(2, int).dynArr;
>>    alias dynArr1 = Template!(1, int).dynArr;
>>    alias dynArr0 = Template!(0, int).dynArr;
>>
>>    dynArr9()[0].writeln();     // OK: Writes 0
>>    dynArr3()[0].writeln();     // OK: Writes 0
>>    dynArr2()[0].writeln();     // OK: Writes 0
>>    dynArr1()[0].writeln();     // OK: Writes 0
>>    //dynArr0()[0].writeln();   // OK: 
>> core.exception.RangeError:
>>                                //     Range violation
>>
>>    // Other types
>>    //Template!(2, bool).statArr()[0].writeln();    // BUG
>>    //Template!(2, byte).statArr()[0].writeln();    // BUG
>>    //Template!(2, ubyte).statArr()[0].writeln();   // BUG
>>    //Template!(2, short).statArr()[0].writeln();   // BUG
>>    //Template!(2, ushort).statArr()[0].writeln();  // BUG
>>    //Template!(2, int).statArr()[0].writeln();     // BUG
>>    //Template!(2, uint).statArr()[0].writeln();    // BUG
>>    //Template!(2, long).statArr()[0].writeln();    // BUG
>>    //Template!(2, ulong).statArr()[0].writeln();   // BUG
>>    //Template!(2, float).statArr()[0].writeln();   // BUG
>>    //Template!(2, double).statArr()[0].writeln();  // BUG
>>    Template!(2, real).statArr()[0].writeln();      // OK : 
>> Writes nan
>>    //Template!(2, ifloat).statArr()[0].writeln();  // BUG
>>    //Template!(2, idouble).statArr()[0].writeln(); // BUG
>>    Template!(2, ireal).statArr()[0].writeln();     // OK : 
>> Writes inan
>>    //Template!(2, cfloat).statArr()[0].writeln();  // BUG
>>    Template!(2, cdouble).statArr()[0].writeln();   // OK : 
>> Writes nan+nani
>>    Template!(2, creal).statArr()[0].writeln();     // OK : 
>> Writes nan+nani
>>    //Template!(2, char).statArr()[0].writeln();    // BUG
>>    //Template!(2, wchar).statArr()[0].writeln();   // BUG
>>    //Template!(2, dchar).statArr()[0].writeln();   // BUG
>>
>>    struct Sint     { int  a; }
>>    struct Sreal    { real a; }
>>    Template!(2, Sint).statArr()[0].writeln();      // OK : 
>> Writes Sint(0)
>>    Template!(2, Sreal).statArr()[0].writeln();     // OK : 
>> Writes Sreal(nan)
>> }
>>
>>
>> Found in both dmd 2.061 and 2.062 for 32- and 64-bit. Other 
>> types only tested with dmd 2.062.
>
> I can only replicate one of these bugs in dmd git master x64, 
> the cfloat one. It segfaults during the initialisation of the 
> array.
>
> dmd calls _memset64 to do the initialisation. It seems to 
> (partially) forget that we're in x64 and tries to pass the 
> value to set to (float.nan) on the stack.
>
> The result: A complete mess. Not enough arguments, in the wrong 
> places.
>
> _memset64 gets the right destination pointer but gets the 
> length of the array (2) as the value to write and then tries to 
> initialise RDX number of values. But RDX was never set. 
> Segfault.

bug submitted:
http://d.puremagic.com/issues/show_bug.cgi?id=9969


More information about the Digitalmars-d-learn mailing list