digitalmars.D - DMD optimization bug?
- Jacob Carlborg (29/29) Mar 21 2013 The code below works fine without optimizations. But with optimizations
- Iain Buclaw (7/37) Mar 21 2013 As I see it, that code should *always* cause a segmentation fault.
- Jacob Carlborg (5/37) Mar 22 2013 Crap, that example was incorrect, it should look like this:
- Dmitry Olshansky (8/58) Mar 22 2013 OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5
- Jacob Carlborg (33/38) Mar 22 2013 I'm showing here a reduced minimal test case, that's why it looks
- Dmitry Olshansky (10/19) Mar 22 2013 It doesn't change the fact that pointer to slice is not going to work.
- Jacob Carlborg (5/6) Mar 22 2013 I want to know both if it exists and get back the value. I could use an
- Dmitry Olshansky (8/12) Mar 22 2013 Yes, that or ref parameter.
- Jacob Carlborg (5/10) Mar 22 2013 Yeah, that would probably also work. Thanks for the help.
- Dmitry Olshansky (6/18) Mar 22 2013 Pure and hellish kind of luck.
- Jacob Carlborg (4/7) Mar 22 2013 Hehe :)
- Iain Buclaw (9/55) Mar 21 2013 Just to be clear, the program should stop at the point of:
The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit. DMD 2.062 64bit: Segfault DMD 2.062 32bit: Prints a huge array then segfault DMD 2.061 64bit: Segfault DMD 2.061 32bit: Prints a fairly small array (10 elements) with random numbers DMD head (7dcc72a997) 32bit: Bus error: 10 I'm using Mac OS X 10.8.2. import std.stdio; int[]* getDeserializedSlice () { void[] a = [1, 2, 3, 4, 5].dup; auto b = &a; if (auto c = b) auto d = &(cast(int[]) *c)[1 .. 1 + 2]; return null; } void main () { writeln(*getDeserializedSlice()); } Is the above code supposed to work? The test case might look a bit strange, the full source code is here: https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672 -- /Jacob Carlborg
Mar 21 2013
On 21 March 2013 20:29, Jacob Carlborg <doob me.com> wrote:The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit. DMD 2.062 64bit: Segfault DMD 2.062 32bit: Prints a huge array then segfault DMD 2.061 64bit: Segfault DMD 2.061 32bit: Prints a fairly small array (10 elements) with random numbers DMD head (7dcc72a997) 32bit: Bus error: 10 I'm using Mac OS X 10.8.2. import std.stdio; int[]* getDeserializedSlice () { void[] a = [1, 2, 3, 4, 5].dup; auto b = &a; if (auto c = b) auto d = &(cast(int[]) *c)[1 .. 1 + 2]; return null; } void main () { writeln(*getDeserializedSlice(**)); } Is the above code supposed to work? The test case might look a bit strange, the full source code is here: https://github.com/jacob-**carlborg/orange/blob/master/** orange/serialization/**Serializer.d#L1672<https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672> -- /Jacob CarlborgAs I see it, that code should *always* cause a segmentation fault. You are returning 'null', and then dereferencing it... Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Mar 21 2013
On 2013-03-21 22:46, Iain Buclaw wrote:On 21 March 2013 20:29, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit. DMD 2.062 64bit: Segfault DMD 2.062 32bit: Prints a huge array then segfault DMD 2.061 64bit: Segfault DMD 2.061 32bit: Prints a fairly small array (10 elements) with random numbers DMD head (7dcc72a997) 32bit: Bus error: 10 I'm using Mac OS X 10.8.2. import std.stdio; int[]* getDeserializedSlice () { void[] a = [1, 2, 3, 4, 5].dup; auto b = &a; if (auto c = b) auto d = &(cast(int[]) *c)[1 .. 1 + 2]; return null; } void main () { writeln(*getDeserializedSlice(__)); } Is the above code supposed to work? The test case might look a bit strange, the full source code is here: https://github.com/jacob-__carlborg/orange/blob/master/__orange/serialization/__Serializer.d#L1672 <https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672> -- /Jacob CarlborgCrap, that example was incorrect, it should look like this: return &(cast(int[]) *c)[1 .. 1 + 2]; -- /Jacob Carlborg
Mar 22 2013
22-Mar-2013 11:26, Jacob Carlborg пишет:On 2013-03-21 22:46, Iain Buclaw wrote:OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5 ints) slice. *c is that slice, (cast(int[])*c)[1..3] is pieces of that slice an r-value. Mmm so you are returning a pointer to r-value (a local temporary)? What's the point of the code? -- Dmitry OlshanskyOn 21 March 2013 20:29, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit. DMD 2.062 64bit: Segfault DMD 2.062 32bit: Prints a huge array then segfault DMD 2.061 64bit: Segfault DMD 2.061 32bit: Prints a fairly small array (10 elements) with random numbers DMD head (7dcc72a997) 32bit: Bus error: 10 I'm using Mac OS X 10.8.2. import std.stdio; int[]* getDeserializedSlice () { void[] a = [1, 2, 3, 4, 5].dup; auto b = &a; if (auto c = b) auto d = &(cast(int[]) *c)[1 .. 1 + 2]; return null; } void main () { writeln(*getDeserializedSlice(__)); } Is the above code supposed to work? The test case might look a bit strange, the full source code is here: https://github.com/jacob-__carlborg/orange/blob/master/__orange/serialization/__Serializer.d#L1672 <https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672> -- /Jacob CarlborgCrap, that example was incorrect, it should look like this: return &(cast(int[]) *c)[1 .. 1 + 2];
Mar 22 2013
On 2013-03-22 09:14, Dmitry Olshansky wrote:OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5 ints) slice. *c is that slice, (cast(int[])*c)[1..3] is pieces of that slice an r-value. Mmm so you are returning a pointer to r-value (a local temporary)? What's the point of the code?I'm showing here a reduced minimal test case, that's why it looks strange. The full source code is here: https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672 private T* getDeserializedSlice (T) (Slice slice) { if (auto array = slice.id in deserializedSlices) return &(cast(T) *array)[slice.offset .. slice.offset + slice.length]; return null; } In my serializer I'm storing already deserialized arrays in a associative array, looking like this: void[][size_t] deserializedSlices; The "size_t" is a unique identification. What I'm doing here is returning a slice from an already deserialized array. "Slice" is a struct as follows: struct Slice { size_t id; // id of the array the slice originates to size_t offset; // start position of the slice in the array size_t length; // length of the slice } What I'm doing in "getDeserializedSlice" is checking if the slice id is available in the associative array. If it is I deference the array (since I'm getting a pointer from the "in" expression), then casting it to the correct array type. After that I'm slicing the array and returns a pointer to it. I figured that was safe since it's always stored in the associative array, but that might not be the case. I guess I could return the slice by an out parameter instead and return a bool from the function. -- /Jacob Carlborg
Mar 22 2013
22-Mar-2013 13:01, Jacob Carlborg пишет:On 2013-03-22 09:14, Dmitry Olshansky wrote:It doesn't change the fact that pointer to slice is not going to work. Esp pointer to stack-allocated slice. You'll get garbage and sometimes segfaults. What's wrong with returning slice by value ?OK so c points to [1, 2, 3, 4, 5] (and who knows if it's 5 bytes or 5 ints) slice. *c is that slice, (cast(int[])*c)[1..3] is pieces of that slice an r-value. Mmm so you are returning a pointer to r-value (a local temporary)? What's the point of the code?I'm showing here a reduced minimal test case, that's why it looks strange. The full source code is here:https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672Exactly what you describe there is not going to work at all. Taking address of temporary slice (a[x..y] is a temporary value) is welcoming a segfault. -- Dmitry Olshansky
Mar 22 2013
On 2013-03-22 10:07, Dmitry Olshansky wrote:What's wrong with returning slice by value ?I want to know both if it exists and get back the value. I could use an out parameter for that though. -- /Jacob Carlborg
Mar 22 2013
22-Mar-2013 15:56, Jacob Carlborg пишет:On 2013-03-22 10:07, Dmitry Olshansky wrote:Yes, that or ref parameter. Another option is: return null - doesn't exists (both ptr and .length are zeros) return a slice that has zero length and non-zero ptr - exists but empty Dunno if it's suitable to what your doing with it later on. -- Dmitry OlshanskyWhat's wrong with returning slice by value ?I want to know both if it exists and get back the value. I could use an out parameter for that though.
Mar 22 2013
On 2013-03-22 13:00, Dmitry Olshansky wrote:Yes, that or ref parameter. Another option is: return null - doesn't exists (both ptr and .length are zeros) return a slice that has zero length and non-zero ptr - exists but empty Dunno if it's suitable to what your doing with it later on.Yeah, that would probably also work. Thanks for the help. BTW, was it only luck that it worked with out optimizations? -- /Jacob Carlborg
Mar 22 2013
22-Mar-2013 16:25, Jacob Carlborg пишет:On 2013-03-22 13:00, Dmitry Olshansky wrote:Pure and hellish kind of luck. Well there is a lot of folklore that prescribes that luck is more of demonic then celestial nature :) -- Dmitry OlshanskyYes, that or ref parameter. Another option is: return null - doesn't exists (both ptr and .length are zeros) return a slice that has zero length and non-zero ptr - exists but empty Dunno if it's suitable to what your doing with it later on.Yeah, that would probably also work. Thanks for the help. BTW, was it only luck that it worked with out optimizations?
Mar 22 2013
On 2013-03-22 13:28, Dmitry Olshansky wrote:Pure and hellish kind of luck. Well there is a lot of folklore that prescribes that luck is more of demonic then celestial nature :)Hehe :) -- /Jacob Carlborg
Mar 22 2013
On 21 March 2013 21:46, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 21 March 2013 20:29, Jacob Carlborg <doob me.com> wrote:Just to be clear, the program should stop at the point of: writeln(*getDeserializedSlice()) Where getSerializedSlice() has returned 'null' and then null gets dereferenced. All other behaviours where the program tries to print *(null) are wrong code. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';The code below works fine without optimizations. But with optimizations (the -O flag) turned on it segfaults. The behavior with optimizations turned on is a bit different depending on which version of DMD I try and if I compile for 32 or 64bit. DMD 2.062 64bit: Segfault DMD 2.062 32bit: Prints a huge array then segfault DMD 2.061 64bit: Segfault DMD 2.061 32bit: Prints a fairly small array (10 elements) with random numbers DMD head (7dcc72a997) 32bit: Bus error: 10 I'm using Mac OS X 10.8.2. import std.stdio; int[]* getDeserializedSlice () { void[] a = [1, 2, 3, 4, 5].dup; auto b = &a; if (auto c = b) auto d = &(cast(int[]) *c)[1 .. 1 + 2]; return null; } void main () { writeln(*getDeserializedSlice()); }As I see it, that code should *always* cause a segmentation fault. You are returning 'null', and then dereferencing it...Is the above code supposed to work? The test case might look a bit strange, the full source code is here: https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1672 -- /Jacob Carlborg
Mar 21 2013