Bug 11888 – Incorrect behaviour taking slice from return value
Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-01-09T22:46:00Z
Last change time
2015-02-18T03:37:43Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
turkeyman
Comments
Comment #0 by turkeyman — 2014-01-09T22:46:54Z
So given a C-style function like this, that returns a pointer and length via pointer argument:
ubyte* test(size_t* len)
{
*len = 100;
return cast(ubyte*)1234;
}
Call it, but immediately use the size argument to slice a range:
size_t size;
ubyte[] t = test(&size)[0..size];
t is null.
If I break it into separate statements, it works:
size_t size;
ubyte* pt = test(&size);
ubyte[] t = pt[0..size];
t.ptr = 1234, t.length = 100;
Comment #1 by turkeyman — 2014-01-09T22:52:40Z
I think invalid codegen deserves a higher priority...
Comment #2 by monarchdodra — 2014-01-09T23:12:49Z
(In reply to comment #0)
> So given a C-style function like this, that returns a pointer and length via
> pointer argument:
> ubyte* test(size_t* len)
> {
> *len = 100;
> return cast(ubyte*)1234;
> }
>
> Call it, but immediately use the size argument to slice a range:
> size_t size;
> ubyte[] t = test(&size)[0..size];
>
> t is null.
>
> If I break it into separate statements, it works:
> size_t size;
> ubyte* pt = test(&size);
> ubyte[] t = pt[0..size];
>
> t.ptr = 1234, t.length = 100;
Isn't this an issue mutating and using a parameter in a same "function"?
I don't know how the compiler rewrites slicing a pointer, but if you interpret it as a "3-argument function, you get":
slice(ptr, low, high);
eg:
slice(test(&size), 0, size);
Here, "size" is read as parameter 3, but also mutated as parameter 1.
Comment #3 by monarchdodra — 2014-01-09T23:15:27Z
(In reply to comment #2)
> Isn't this an issue mutating and using a parameter in a same "function"?
Ah. I just stumbled on the thread. I see Andrei commented that: "Evaluation should proceed as if it were strictly left to right."
Comment #4 by turkeyman — 2014-01-10T04:40:32Z
(In reply to comment #2)
> (In reply to comment #0)
> > So given a C-style function like this, that returns a pointer and length via
> > pointer argument:
> > ubyte* test(size_t* len)
> > {
> > *len = 100;
> > return cast(ubyte*)1234;
> > }
> >
> > Call it, but immediately use the size argument to slice a range:
> > size_t size;
> > ubyte[] t = test(&size)[0..size];
> >
> > t is null.
> >
> > If I break it into separate statements, it works:
> > size_t size;
> > ubyte* pt = test(&size);
> > ubyte[] t = pt[0..size];
> >
> > t.ptr = 1234, t.length = 100;
>
> Isn't this an issue mutating and using a parameter in a same "function"?
>
> I don't know how the compiler rewrites slicing a pointer, but if you interpret
> it as a "3-argument function, you get":
>
> slice(ptr, low, high);
> eg:
> slice(test(&size), 0, size);
>
> Here, "size" is read as parameter 3, but also mutated as parameter 1.
If it's not to be fixed, it must at least be an error. This sort of undefined and unexpected behaviour isn't really acceptable.