www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3150] New: cast from dynamic array to ulong is allowed

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150

           Summary: cast from dynamic array to ulong is allowed
           Product: D
           Version: 1.045
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Keywords: spec
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: kamm-removethis incasoftware.de


This compiles and seems to set u to foo.length.

void main() {
    void[] foo = "abc";
    ulong u = cast(ulong)foo;
}

The cast is an error for any other numeric type. I think it ought to be an
error - if it is desired, it should at least be documented.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 07 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|spec                        |accepts-invalid, patch
                 CC|                            |clugdbug yahoo.com.au


--- Comment #1 from Don <clugdbug yahoo.com.au> 2010-05-07 22:57:16 PDT ---
Although types other than ulong currently generate error messages, they should 
all be caught at the front end.

PATCH:
CastExp::semantic() in expression.c around line 7960 (DMD 2.045)

            if (tobn->isTypeBasic() && tobn->size() < t1bn->size())
                // Allow things like casting a long* to an int*
                ;
            else if (tobn->ty != Tvoid)
                // Cast to a pointer other than void*
                goto Lunsafe;
        }
        // BUG: Check for casting array types, such as void[] to int*[]
    }
+    if (fromtype->ty == Tarray && totype->ty != Tarray && totype->ty !=Tvoid)
+    {
+        error("Cannot cast %s of type %s to %s", e1->toChars(),
e1->type->toChars(), to->toChars());
+        return new ErrorExp();
+    }
    e = e1->castTo(sc, to);
    return e;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 07 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150



--- Comment #2 from Don <clugdbug yahoo.com.au> 2010-05-10 02:00:27 PDT ---
druntime currently relies on this behaviour in one place, and it's pretty nasty
code. For example, it assumes pointers are 32 bits long.

rt/lifetime.d
_d_newarraymT()
_d_newarraymiT()
These both cast a void[] to a ulong.

Instead of:
        result = cast(ulong)foo(ti, pdim, ndims);
should be: 
        static assert((void[]).sizeof == ulong.sizeof);       
        void[] r = foo(ti, pdim, ndims);
        result = *cast(ulong *)&r;

In fact, this is a very ugly bit of code. It only seems to be used in e2ir.c,
NewExp::toElem(), where there's another hack to get the .ptr out of the ulong.
I don't see any reason why extern(D) couldn't be used instead, so that it could
just return an array.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150


Steven Schveighoffer <schveiguy yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy yahoo.com


--- Comment #3 from Steven Schveighoffer <schveiguy yahoo.com> 2010-05-10
04:08:33 PDT ---
Actually, you need a type besides a D array because you do not want to trigger
runtime calls when setting the length.

Because those functions are extern(C) functions, you can return whatever type
you want (as long as it's the same size as an array struct).  But the portion
which sets the length must not use an actual array.

What we can do is change the return types (there are other functions which
return ulong) from ulong to the Array struct defined somewhere in that file.

There might be opitmizations that the compiler makes when forming a ulong vs.
some arbitrary type, I'll have to investigate that.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150



--- Comment #4 from Don <clugdbug yahoo.com.au> 2010-05-10 04:20:38 PDT ---
(In reply to comment #3)
 Actually, you need a type besides a D array because you do not want to trigger
 runtime calls when setting the length.

I don't understand this comment. A D array is used internally in the function. The function calculates a void[], and then casts this to ulong to return it. Then, in the compiler, it grabs the ulong back into a pointer. This all happens in the glue layer -- it's too late for any runtime calls to be added. Have I missed something?
 There might be opitmizations that the compiler makes when forming a ulong vs.
 some arbitrary type, I'll have to investigate that.

Could be, but as far as I can tell, the dynamic array ABI is identical to ulong (result in EDX:EAX). So the compiler could probably cast it to ulong internally in e2ir.c, if there were any problems. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150



--- Comment #5 from Steven Schveighoffer <schveiguy yahoo.com> 2010-05-10
04:28:16 PDT ---
Look at this part of the code, which actually writes the void[]:

auto r = _d_newarrayT(ti, dim); // r is of type ulong
p = *cast(void[]*)(&r);

This is inside the foo inner function (comment added by me).

Care must be taken not to set the individual parts of the array because you can
trigger runtime calls.

I'm not saying that this means casting to/from ulong is the best solution, I'm
just trying to explain why an actual D array may not be the most suitable type
to use internally.

I'm unsure why the foo function uses arrays internally, it clearly takes great
pains not to trigger any runtime calls by using casting and the ptr member.  I
don't see why it can't do this with the Array struct type instead.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 10 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3150



--- Comment #6 from Don <clugdbug yahoo.com.au> 2010-05-10 07:14:57 PDT ---
(In reply to comment #5)
 Look at this part of the code, which actually writes the void[]:
 
 auto r = _d_newarrayT(ti, dim); // r is of type ulong
 p = *cast(void[]*)(&r);
 
 This is inside the foo inner function (comment added by me).
 
 Care must be taken not to set the individual parts of the array because you can
 trigger runtime calls.

I still don't see a problem. The only thing that code is doing, is casting from ulong back to void[]. That code should just be: p = _d_newarrayT(ti, dim);
 I'm not saying that this means casting to/from ulong is the best solution, I'm
 just trying to explain why an actual D array may not be the most suitable type
 to use internally.
 
 I'm unsure why the foo function uses arrays internally, it clearly takes great
 pains not to trigger any runtime calls by using casting and the ptr member.  I
 don't see why it can't do this with the Array struct type instead.

No, that's not the reason for the gymnastics in the code. The code is so old that when it was originally written, .ptr didn't exist for arrays (.ptr was added in DMD 0.107). The hack of casting to ulong is recent though (it doesn't exist in D1), and I think it's a bug. Although at first the code looks clever and magical, I think it's actually just an arcane legacy of a time when the language was very primitive and required lots of hacks. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 10 2010