[Bug 283] New: Wrong code with -O, possible cleanup_point_expr bug

gdc-bugzilla at gdcproject.org gdc-bugzilla at gdcproject.org
Thu Jan 25 01:05:52 UTC 2018


https://bugzilla.gdcproject.org/show_bug.cgi?id=283

            Bug ID: 283
           Summary: Wrong code with -O, possible cleanup_point_expr bug
           Product: GDC
           Version: development
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: Normal
         Component: gdc
          Assignee: ibuclaw at gdcproject.org
          Reporter: ibuclaw at gdcproject.org

Can't reduce the program down much further.  Something in our code-gen is not
quite right, and the optimizer is making false assumptions as a result of it.

During the reduction of it, making a change to `front()` makes the problem go
away.  The different between the two is that the "bad" version generates a
CLEANUP_POINT_EXPR for the temporary, making it a possible regression.

See: https://github.com/D-Programming-GDC/GDC/pull/585

---
  version = SIGILL;     // Comment out to get segfault instead.
//version = SUCCESS;    // Uncomment to get a successful program.

struct Impl
{
    size_t _count;
}

struct RefCountedStore
{
    Impl* _store;

    void initialize()
    {
        import core.stdc.stdlib : malloc;
        _store = cast(Impl*) malloc(Impl.sizeof);
        _store._count = 1;
    }

    bool isInitialized()
    {
        return _store !is null;
    }

    void ensureInitialized()
    {
        if (!isInitialized)
            initialize();
    }
}

struct RefCounted14443
{
    RefCountedStore _refCounted;

    this(int)
    {
        _refCounted.initialize();
    }

    this(this)
    {
        version (SIGILL)
        {
            if (!_refCounted.isInitialized)
                assert(0);
        }
        ++_refCounted._store._count;
    }

    ~this()
    {
        version (SIGILL)
        {
            if (!_refCounted.isInitialized)
                assert(0);
            if (_refCounted._store._count <= 0)
                assert(0);
        }
        if (--_refCounted._store._count)
            return;

        import core.stdc.stdlib : free;
        free(_refCounted._store);
        _refCounted._store = null;
    }

    int refCountedPayload()
    {
        _refCounted.ensureInitialized();
        return 1;
    }
}

struct PathRange14443
{
    RefCounted14443 path;

    @property PathElement14443 front()
    {
        version (SUCCESS)
        {
            auto tmp = path.refCountedPayload();
            return PathElement14443(this);
        }
        else
            return PathElement14443(this, path.refCountedPayload());
    }
}

struct PathElement14443
{
    PathRange14443 range;

    version (SUCCESS)
    {
        this(PathRange14443 range)
        {
            this.range = range;
        }
    }
    else
    {
        this(PathRange14443 range, int)
        {
            this.range = range;
        }
    }
}

void main()
{
    auto path = RefCounted14443(12);
    if (path._refCounted._store._count != 1)
        assert(0);
    {
        auto _r = PathRange14443(path);
        if (path._refCounted._store._count != 2)
            assert(0);
        {
            auto element = _r.front;
            if (path._refCounted._store._count != 3)
                assert(0);
        }
        if (path._refCounted._store._count != 2)
            assert(0);
    }
    if (path._refCounted._store._count != 1)
        assert(0);
}

-- 
You are receiving this mail because:
You are watching all bug changes.


More information about the D.gnu mailing list