www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - is this an instance of the 16-byte struct bug

reply "Daniel Davidson" <nospam spam.com> writes:
and what is the 16 byte struct bug?

http://forum.dlang.org/post/nqqujtblyvxvtrlsbcpx forum.dlang.org

import std.datetime;
import std.range;
import std.stdio;

struct DateRate {
   Date date;
   double value = 0.0;
}

struct RateCurve {
   private immutable(DateRate)[] _data;
}

struct CFS {
   double initialValue;
   RateCurve growth;
}

void main() {
   auto s = CFS(1.0);
   // auto s = CFS(1.0, RateCurve()); // crashes
   // auto s = CFS(1.0, RateCurve([])); // works
   writeln(s);
}
Nov 02 2013
parent reply "Daniel Davidson" <nospam spam.com> writes:
Ok - pretty sure this is not related to 16-byte structs, since if 
I just remove one of the fields it still crashes. I opened an 
issue - and here is a simplified version:

http://d.puremagic.com/issues/show_bug.cgi?id=11440

import std.stdio;

struct Y {
   private immutable(int)[] _data;
}

struct CFS {
   double x = 5;
   Y growth;
}

void main() {
   auto s = CFS(1.0);      // crash
   //auto s = CFS(1, Y()); // crash
   //auto s = CFS(1, Y([])); // works
   writeln(s);
}
Nov 04 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 4 November 2013 at 19:24:11 UTC, Daniel Davidson wrote:
 Ok - pretty sure this is not related to 16-byte structs, since 
 if I just remove one of the fields it still crashes. I opened 
 an issue - and here is a simplified version:

 http://d.puremagic.com/issues/show_bug.cgi?id=11440

 import std.stdio;

 struct Y {
   private immutable(int)[] _data;
 }

 struct CFS {
   double x = 5;
   Y growth;
 }

 void main() {
   auto s = CFS(1.0);      // crash
   //auto s = CFS(1, Y()); // crash
   //auto s = CFS(1, Y([])); // works
   writeln(s);
 }
What do you mean by crash ?
Nov 04 2013
parent reply "jerro" <a a.com> writes:
 void main() {
  auto s = CFS(1.0);      // crash
  //auto s = CFS(1, Y()); // crash
  //auto s = CFS(1, Y([])); // works
  writeln(s);
 }
What do you mean by crash ?
It's segfaults. It doesn't happen if you change 1.0 literal to some other value, say 2.0. It's a truly bizarre bug. Here's a slightly simplified case: import std.stdio; struct Y { int[] _data; } struct CFS { double x; Y growth; } void main() { auto s = CFS(2.0); writefln("%x", s.growth._data.length); // prints 3ff0000000000000 } It doesn't happen with -O, or when compiled with LDC or GDC.
Nov 04 2013
next sibling parent "jerro" <a a.com> writes:
 It doesn't happen with -O, or when compiled with LDC or GDC.
And it doesn't happen when building with -m32 (I'm on x86_64 linux).
Nov 04 2013
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
OK.

Now usual question to try to understand what is going wrong.

Can you try on 32/64 bits ? Also, what happen with GDC and LDC ?
Nov 04 2013
parent reply "jerro" <a a.com> writes:
On Monday, 4 November 2013 at 22:27:39 UTC, deadalnix wrote:
 OK.

 Now usual question to try to understand what is going wrong.

 Can you try on 32/64 bits ? Also, what happen with GDC and LDC ?
The code I posted above prints 3ff0000000000000 when built with dmd on x86_64 without any flags. It prints 0 if I build with LDC or GDC, or if I build with DMD and add either -O flag or -m32.
Nov 04 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 4 November 2013 at 22:42:35 UTC, jerro wrote:
 On Monday, 4 November 2013 at 22:27:39 UTC, deadalnix wrote:
 OK.

 Now usual question to try to understand what is going wrong.

 Can you try on 32/64 bits ? Also, what happen with GDC and LDC 
 ?
The code I posted above prints 3ff0000000000000 when built with dmd on x86_64 without any flags. It prints 0 if I build with LDC or GDC, or if I build with DMD and add either -O flag or -m32.
Then it look like a dmd backend bug. Can you post the generated assembly ?
Nov 04 2013
parent reply "jerro" <a a.com> writes:
 Then it look like a dmd backend bug. Can you post the generated 
 assembly ?
000000000043050c <_Dmain>: 43050c: push %rbp 43050d: mov %rsp,%rbp 430510: sub $0x40,%rsp 430514: movabs $0x3ff0000000000000,%rax 43051b: 43051e: mov %rax,-0x40(%rbp) 430522: movsd -0x40(%rbp),%xmm0 430527: rex.W movsd %xmm0,-0x30(%rbp) 43052d: xor %edx,%edx 43052f: mov %rax,-0x10(%rbp) 430533: mov %rdx,-0x8(%rbp) 430537: mov %rax,-0x28(%rbp) 43053b: mov %rdx,-0x20(%rbp) 43053f: mov 0x28022(%rip),%rdx 430546: mov 0x28013(%rip),%rsi 43054d: mov -0x28(%rbp),%rdi 430551: callq 430874 <void std.stdio.writefln!(immutable(char)[], ulong).writefln(immutable(char)[], ulong)> 430556: xor %eax,%eax 430558: leaveq 430559: retq
Nov 04 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 4 November 2013 at 22:56:48 UTC, jerro wrote:
 Then it look like a dmd backend bug. Can you post the 
 generated assembly ?
000000000043050c <_Dmain>: 43050c: push %rbp 43050d: mov %rsp,%rbp 430510: sub $0x40,%rsp 430514: movabs $0x3ff0000000000000,%rax 43051b: 43051e: mov %rax,-0x40(%rbp) 430522: movsd -0x40(%rbp),%xmm0 430527: rex.W movsd %xmm0,-0x30(%rbp) 43052d: xor %edx,%edx 43052f: mov %rax,-0x10(%rbp) 430533: mov %rdx,-0x8(%rbp) 430537: mov %rax,-0x28(%rbp) 43053b: mov %rdx,-0x20(%rbp)
    43053f:       mov    0x28022(%rip),%rdx
    430546:       mov    0x28013(%rip),%rsi
What are these ? What are they referering to ?
    43054d:       mov    -0x28(%rbp),%rdi
    430551:       callq  430874 <void
 std.stdio.writefln!(immutable(char)[],
 ulong).writefln(immutable(char)[], ulong)>
    430556:       xor    %eax,%eax
    430558:       leaveq
    430559:       retq
This calls writefln, this is not what your code does just above. Are you sure you are posting the right assembly ? Do you use the inline flag ?
Nov 04 2013
parent reply "jerro" <a a.com> writes:
On Monday, 4 November 2013 at 23:07:27 UTC, deadalnix wrote:
 On Monday, 4 November 2013 at 22:56:48 UTC, jerro wrote:
 Then it look like a dmd backend bug. Can you post the 
 generated assembly ?
000000000043050c <_Dmain>: 43050c: push %rbp 43050d: mov %rsp,%rbp 430510: sub $0x40,%rsp 430514: movabs $0x3ff0000000000000,%rax 43051b: 43051e: mov %rax,-0x40(%rbp) 430522: movsd -0x40(%rbp),%xmm0 430527: rex.W movsd %xmm0,-0x30(%rbp) 43052d: xor %edx,%edx 43052f: mov %rax,-0x10(%rbp) 430533: mov %rdx,-0x8(%rbp) 430537: mov %rax,-0x28(%rbp) 43053b: mov %rdx,-0x20(%rbp)
   43053f:       mov    0x28022(%rip),%rdx
   430546:       mov    0x28013(%rip),%rsi
What are these ? What are they referering to
My guess is they are refering to length and ptr for "%x" string literal, which is passed to writefln.
   43054d:       mov    -0x28(%rbp),%rdi
   430551:       callq  430874 <void
 std.stdio.writefln!(immutable(char)[],
 ulong).writefln(immutable(char)[], ulong)>
   430556:       xor    %eax,%eax
   430558:       leaveq
   430559:       retq
This calls writefln, this is not what your code does just above. Are you sure you are posting the right assembly ? Do you use the inline flag ?
I think you are confusing my post with some other post (I am not OP). My code sample was: import std.stdio; struct Y { int[] _data; } struct CFS { double x; Y growth; } void main() { auto s = CFS(1.0); writefln("%x", s.growth._data.length); // prints 3ff0000000000000 } The constructor's argument was 2.0 in my previous sample, but it should have been 1.0.
Nov 04 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 4 November 2013 at 23:14:08 UTC, jerro wrote:
 On Monday, 4 November 2013 at 23:07:27 UTC, deadalnix wrote:
 On Monday, 4 November 2013 at 22:56:48 UTC, jerro wrote:
 Then it look like a dmd backend bug. Can you post the 
 generated assembly ?
000000000043050c <_Dmain>: 43050c: push %rbp 43050d: mov %rsp,%rbp 430510: sub $0x40,%rsp 430514: movabs $0x3ff0000000000000,%rax 43051b: 43051e: mov %rax,-0x40(%rbp) 430522: movsd -0x40(%rbp),%xmm0 430527: rex.W movsd %xmm0,-0x30(%rbp) 43052d: xor %edx,%edx 43052f: mov %rax,-0x10(%rbp) 430533: mov %rdx,-0x8(%rbp) 430537: mov %rax,-0x28(%rbp) 43053b: mov %rdx,-0x20(%rbp)
  43053f:       mov    0x28022(%rip),%rdx
  430546:       mov    0x28013(%rip),%rsi
What are these ? What are they referering to
My guess is they are refering to length and ptr for "%x" string literal, which is passed to writefln.
  43054d:       mov    -0x28(%rbp),%rdi
  430551:       callq  430874 <void
 std.stdio.writefln!(immutable(char)[],
 ulong).writefln(immutable(char)[], ulong)>
  430556:       xor    %eax,%eax
  430558:       leaveq
  430559:       retq
This calls writefln, this is not what your code does just above. Are you sure you are posting the right assembly ? Do you use the inline flag ?
I think you are confusing my post with some other post (I am not OP).
OK, my mistake.
 My code sample was:

 import std.stdio;

 struct Y {
       int[] _data;
 }

 struct CFS {
       double x;
       Y growth;
 }

 void main() {
       auto s = CFS(1.0);
       writefln("%x", s.growth._data.length); // prints
 3ff0000000000000
 }

 The constructor's argument was 2.0 in my previous sample, but it
 should have been 1.0.
I'm not sure what DMD is trying to do, but the function call to writefln is clearly wrong.
Nov 04 2013
next sibling parent "Daniel Davidson" <nospam spam.com> writes:
On Tuesday, 5 November 2013 at 00:16:11 UTC, deadalnix wrote:
 I'm not sure what DMD is trying to do, but the function call to 
 writefln is clearly wrong.
Strange bug. FWIW adding a constructor `this(immutable(int)[] data) { _data = data; }` seems to be a workaround. Thanks Dan
Nov 05 2013
prev sibling parent "Daniel Davidson" <nospam spam.com> writes:
On Tuesday, 5 November 2013 at 00:16:11 UTC, deadalnix wrote:
 I'm not sure what DMD is trying to do, but the function call to 
 writefln is clearly wrong.
Strange bug. FWIW adding a constructor `this(immutable(int)[] data) { _data = data; }` seems to be a workaround. Thanks Dan
Nov 05 2013
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 4 November 2013 at 22:09:45 UTC, jerro wrote:
 void main() {
 auto s = CFS(1.0);      // crash
 //auto s = CFS(1, Y()); // crash
 //auto s = CFS(1, Y([])); // works
 writeln(s);
 }
What do you mean by crash ?
It's segfaults. It doesn't happen if you change 1.0 literal to some other value, say 2.0. It's a truly bizarre bug. Here's a slightly simplified case: import std.stdio; struct Y { int[] _data; } struct CFS { double x; Y growth; } void main() { auto s = CFS(2.0); writefln("%x", s.growth._data.length); // prints 3ff0000000000000 } It doesn't happen with -O, or when compiled with LDC or GDC.
Can't reproduce on Git master x86_64 linux. Prints 0 no matter what flags are used.
Nov 05 2013
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 5 November 2013 at 09:34:47 UTC, John Colvin wrote:
 On Monday, 4 November 2013 at 22:09:45 UTC, jerro wrote:
 void main() {
 auto s = CFS(1.0);      // crash
 //auto s = CFS(1, Y()); // crash
 //auto s = CFS(1, Y([])); // works
 writeln(s);
 }
What do you mean by crash ?
It's segfaults. It doesn't happen if you change 1.0 literal to some other value, say 2.0. It's a truly bizarre bug. Here's a slightly simplified case: import std.stdio; struct Y { int[] _data; } struct CFS { double x; Y growth; } void main() { auto s = CFS(2.0); writefln("%x", s.growth._data.length); // prints 3ff0000000000000 } It doesn't happen with -O, or when compiled with LDC or GDC.
Can't reproduce on Git master x86_64 linux. Prints 0 no matter what flags are used.
Oh wait no, sorry. It does print 3ff0000000000000 if I use 1.0 instead of 2.0
Nov 05 2013
prev sibling parent "Daniel Davidson" <nospam spam.com> writes:
On Tuesday, 5 November 2013 at 09:34:47 UTC, John Colvin wrote:
 Can't reproduce on Git master x86_64 linux. Prints 0 no matter 
 what flags are used.
Mac - OS X 10.9 (13A603) dmd -v DMD64 D Compiler v2.064 Copyright (c) 1999-2013 by Digital Mars written by Walter Bright bash-3.2$ rdmd --chatty --force /Users/user /tmp/init.d stat /tmp/.rdmd-502 stat /tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD 'dmd' '-v' '-o-' '/Users/user/tmp/init.d' '-I/Users/user/tmp' read /tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD/rdmd.deps which dmd stat /Users/user/bin/dmd 'dmd' '-of/tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD/init' '-od/tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD/objs' '-I/Users/user/tmp' '/Users/user/tmp/init.d' stat /tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD/objs rmdirRecurse /tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD/objs '/tmp/.rdmd-502/rdmd-init.d-7C1A09D7F9F238EF000AE7814A586BCD/init' Segmentation fault: 11
Nov 05 2013