Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 20, 2013 Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
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. |
April 20, 2013 Re: Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
Posted in reply to deed | Made available on dpaste: http://dpaste.dzfl.pl/7b5c36f8 On dpaste, the struct with an int didn't compile. (Same error message) It turns out that Template!(2, Sint).statArr()[0].writeln(); compiles with $ dmd test.d -m64 but not with $ dmd test.d |
April 20, 2013 Re: Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
Posted in reply to deed | 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.
|
April 20, 2013 Re: Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
Sorry should specify this was on linux x64
|
April 20, 2013 Re: Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
Posted in reply to deed | 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.
btw: all the imaginary/complex builtin types will likely be deprecated at some point in the future. std.complex is the intended replacement
|
April 20, 2013 Re: Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 |
April 21, 2013 Re: Bug: Accessing return value of type static array with length 1 or 2 by index. | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | > bug submitted:
> http://d.puremagic.com/issues/show_bug.cgi?id=9969
Thanks for reporting.
By the way, I was compiling for Windows and had only compile time errors.
|
Copyright © 1999-2021 by the D Language Foundation