[Issue 5780] New: handles[patch] std.traits.hasIndirections incorrectly handels static arrays

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Mar 23 22:09:00 PDT 2011


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

           Summary: handles[patch] std.traits.hasIndirections incorrectly
                    handels static arrays
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: patch
          Severity: critical
          Priority: P1
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: sandford at jhu.edu


--- Comment #0 from Rob Jacques <sandford at jhu.edu> 2011-03-23 22:05:38 PDT ---
Problem: 
std.traits.hasIndirections currently does not return true for static arrays of
types with indirections. More fundamentally, it's unit tests do not verify it's
output for all template instances. I've set the priority of this bug based on
the fact that manual memory allocation routines are apt to utilize
hasIndirections to determine whether or not to apply the no scan GC attribute
and getting this wrong results in memory stomping/corruption. 

Solution:
I've added detection and handling of static arrays to hasIndirectionsImpl.
Also, to prevent future unforeseen corner cases, I've added a private template,
hasIndirectionsUnittest, which allows each instance of hasIndirections!T to
generate a unit test which verifies the value of hasIndirections!T against T's
runtime GC flags. Also, a specific unit test for static arrays was added.

Patch: (Based on DMD 2.052)

/**
Returns $(D true) if and only if $(D T)'s representation includes at
least one of the following: $(OL $(LI a raw pointer $(D U*);) $(LI an
array $(D U[]);) $(LI a reference to a class type $(D C).)
$(LI an associative array.) $(LI a delegate.))
 */

template hasIndirections(T)
{
    enum hasIndirections = hasIndirectionsUnittest!T.implementation;
}

// Tests hasIndirections against the GC's runtime info for every T
private template hasIndirectionsUnittest(T)
{
    enum implementation = hasIndirectionsImpl!(RepresentationTypeTuple!T);

    unittest {
        assert( hasIndirections!T == (typeid(T[]).next.flags & 1) );
    }
}

template hasIndirectionsImpl(T...)
{
    static if (!T.length)
    {
        enum hasIndirectionsImpl = false;
    }
    else static if(isFunctionPointer!(T[0]))
    {
        enum hasIndirectionsImpl = hasIndirectionsImpl!(T[1 .. $]);
    }
    else static if(isStaticArray!(T[0]))
    {
        enum hasIndirectionsImpl = hasIndirectionsImpl!(T[1 .. $]) ||
        hasIndirectionsImpl!(RepresentationTypeTuple!(typeof(T[0].init[0])));
    }
    else
    {
        enum hasIndirectionsImpl = isPointer!(T[0]) || isDynamicArray!(T[0]) ||
            is (T[0] : const(Object)) || isAssociativeArray!(T[0]) ||
            isDelegate!(T[0]) || is(T[0] == interface)
            || hasIndirectionsImpl!(T[1 .. $]);
    }
}

unittest
{
    struct S1 { int a; Object b; }
    static assert(hasIndirections!(S1));
    struct S2 { string a; }
    static assert(hasIndirections!(S2));
    struct S3 { int a; immutable Object b; }
    static assert(hasIndirections!(S3));
    static assert(hasIndirections!(int[string]));
    static assert(hasIndirections!(void delegate()));

    interface I;
    static assert(hasIndirections!I);
    static assert(!hasIndirections!(void function()));
    static assert(hasIndirections!(void*[1]));
    static assert(!hasIndirections!(byte[1]));
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list