Giter Club home page Giter Club logo

automem's People

Contributors

atilaneves avatar boriscarvajal avatar dkorpel avatar drug007 avatar edi33416 avatar geod24 avatar jmh530 avatar n8sh avatar radcapricorn avatar vushu avatar wilzbach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

automem's Issues

RefCounted fails to destroy payload in combination with zip

RefCounted seems to have issues when used together with zip: The refcounted payload is not destroyed. I stumpled upon this when using valgrind to check why my program was not freeing its memory. It works fine with lockstep.
Below is a short reproduction of the error. Runnable version: https://run.dlang.io/is/eVIP3r

/+dub.sdl:
dependency "automem" version="~>0.6.4"
+/
import automem.ref_counted;
import std.range;
import std.stdio;

int created, destroyed;

void main() {
    {
        RefCounted!S s = RefCounted!S(1);
        auto r1 = repeat(s, 2);
        auto r2 = repeat(s, 2);
        foreach(s1, s2; lockstep(r1, r2))
            assert(s1.val == s2.val);
    }
    writeln("after lockstep: created ", created, " vs destroyed ", destroyed);
    assert(created == 1);
    assert(destroyed == 1);
    {
        RefCounted!S s = RefCounted!S(1);
        auto r1 = repeat(s, 2);
        auto r2 = repeat(s, 2);
        foreach(s1, s2; zip(r1, r2))
            assert(s1.val == s2.val);
    }
    writeln("after zip: created ", created, " vs destroyed ", destroyed);
    assert(created == 2);
    assert(destroyed == 2); // fails!
}

struct S {
    @disable this();
    @disable this(this);
    this(int val) {
        this.val = val;
        created++;
    }
    ~this() {
        destroyed++;
    }
    int val;
}

Thanks for looking into this!

Vector.free violates scope

Vector.free is annotated scope on the this parameter. It then passes a member of this to alloc.dispose in @trusted lambda, but does not verify that alloc.dispose has a scope attribute on the argument. This compiles because @trusted turns off escape analysis.

Use after free, caused by iterator(slice) invalidation not prevented by dip1000/dip25

Test case:

/+ dub.sdl:
dependency "automem" version="~>0.5.1"
dflags "-dip1000" "-dip25"
+/

void main() @safe
{
    import std.stdio : writefln;
    import std.experimental.allocator.mallocator: Mallocator;
    import automem.vector;

    auto vec1 = vector(1, 2, 3);
    int[] slice1 = vec1[];
    vec1.reserve(4096);
    int[] slice2 = vec1[];

    "slice1.ptr: %x, slice2.ptr: %x \nslice1: %s, slice2: %s"
        .writefln(&slice1[0], &slice2[0], slice1, slice2);
}

Sample output:

slice1.ptr: 7fc6d4d21000, slice2.ptr: 7fc6d3800000
slice1: [-724430832, 32710, -820732144], slice2: [1, 2, 3]

As far as I understand, languages with support for substructural type systems usually solve this by allowing either a single mutable reference or zero or more const references.

Linking error

Compiling

/+dub.sdl:
dependency "automem" version="~>0.6.1"
+/
import automem;

void main() @nogc
{
    StringM str;
}

by dub test.d --single gives

onlineapp.d:8: error: undefined reference to '_D7automem6vector__T6VectorTyaTS3std12experimental9allocator10mallocator10MallocatorZQCn6__dtorMFNaNbNiNfZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
dmd failed with exit code 1.

@nogc support for classes

Currently, this code snippet below does not compile:

import automem;

class Foo
{
    this() @nogc
    {
    }

    ~this() @nogc
    {
    }
}

void main() @nogc
{
    auto x = Unique!Foo();
}

Error: @nogc function 'D main' cannot call non-@nogc destructor 'automem.unique.Unique!(Foo, IAllocator).Unique.~this'

Would it be possible to have the code above compile? It would be great!

Ali has a nice trick here that shows how to make the compiler assume something is @nogc:
https://forum.dlang.org/post/[email protected]

Can't compile with gdc 9.2.0

I'm interested in trying this library but unfortunately when I add it to my project I can't compile it:

[1/8] Compiling D object 'subprojects/automem/83545ae@@automem@sha/automem_source_automem_array.d.o'.
FAILED: subprojects/automem/83545ae@@automem@sha/automem_source_automem_array.d.o 
gdc -Isubprojects/automem/83545ae@@automem@sha -Isubprojects/automem -I../../../code/d/snake/subprojects/automem -I../../../code/d/snake/subprojects/automem/automem/source -fdiagnostics-color=always -Wall -Wdeprecated -g -fdebug -fPIC -MD -MQ 'subprojects/automem/83545ae@@automem@sha/automem_source_automem_array.d.o' -MF 'subprojects/automem/83545ae@@automem@sha/automem_source_automem_array.d.o.deps' -o 'subprojects/automem/83545ae@@automem@sha/automem_source_automem_array.d.o' -c ../../../code/d/snake/subprojects/automem/automem/source/automem/array.d
/home/michele/dev/code/d/snake/subprojects/automem/automem/source/automem/vector.d:308:11: error: statement expected to be { }, not (
  308 |         in(start >= 0)
      |           ^
/home/michele/dev/code/d/snake/subprojects/automem/automem/source/automem/vector.d:310:9: error: found 'do' when expecting ';' following statement
  310 |         do
      |         ^
/home/michele/dev/code/d/snake/subprojects/automem/automem/source/automem/vector.d:311:5: error: missing body { ... } after in or out
  311 |     {
      |     ^
ninja: build stopped: subcommand failed.

I'm quite new to D and I'm not sure what that syntax means but it looks like gdc doesn't understand it either.

After dmd 2.076.0, RefCounted can't be used with shared types

source/automem/utils.d(8,6): Error: shared method automem.ref_counted.TestUtils!().SharedStruct.~this is not callable using a non-shared object
source/automem/utils.d(12,6): Error: shared method automem.ref_counted.TestUtils!().SharedStruct.~this is not callable using a non-shared object
source/automem/ref_counted.d(370,20): Error: template instance automem.ref_counted.RefCounted!(shared(SharedStruct), IAllocator) error instantiating
source/automem/utils.d(8,6): Error: shared method automem.ref_counted.TestUtils!().SharedStruct.~this is not callable using a non-shared object
source/automem/utils.d(12,6): Error: shared method automem.ref_counted.TestUtils!().SharedStruct.~this is not callable using a non-shared object
source/automem/ref_counted.d(461,20): Error: template instance automem.ref_counted.RefCounted!(shared(SharedStruct), TestAllocator*) error instantiating
source/automem/ref_counted.d(513,5): Error: static assert  __traits(compiles, sendRefCounted(Allocator, Args...)(Args args)(7)) is false

Can't compile unittest target with automem in dependencies

After adding automem 0.0.9 to dub dependencies my -unittest build failed with error message:

../../.dub/packages/automem-0.0.9/automem/source/automem/ref_counted.d(9,12): Error: module test_allocator is in file 'test_allocator.d' which cannot be read
import path[0] = source/
import path[1] = ../../.dub/packages/automem-0.0.9/automem/source/
import path[2] = ../diet-ng/source/
import path[3] = ../../.dub/packages/mysql-native-1.1.0/mysql-native/source/
....

Invariant violation in debug mode

/+dub.sdl:
dependency "automem" version="~>0.6.1"
+/
import automem;

StringM str;

void main() @nogc
{
	str ~= "a";
	str.popBack;
	str ~= "a"; // generates the error "Assigning to non default initialised non mutable member" in vector.d:297

	assert(str.length == 1);
	assert(str[0] == 'a');
}

due to the fact that after popBack call and adding new element again the last element of the storage has already been initialized so the check fails.

Vector.opIndex violates return

/// Access the ith element. Can throw RangeError.
ref inout(E) opIndex(long i) scope return inout {
if(i < 0 || i >= length)
mixin(throwBoundsException);
return _elements[i.toSizeT];
}

struct Vector(E, Allocator = typeof(theAllocator)) if(isAllocator!Allocator) {
...
    E[] _elements;
...
    /// Access the ith element. Can throw RangeError.
    ref inout(E) opIndex(long i) scope return inout {
        if(i < 0 || i >= length)
            mixin(throwBoundsException);
        return _elements[i.toSizeT];
    }
...

The signature is incorrect. Because this is passed by ref and the function returns by ref, the function is return-ref so it may return the address of this (this._elements), but not the value (this._elements[i]).

Blocking dlang/dmd#12665 (comment)

Wrongly trusted return statement in automem.vector.range() allows obtaining a reference to expired stack frame

This @trusted block of code:

// FIXME - why isn't &this @safe?
return Range(() @trusted { return &this; }(),
start,
end);

allows a pointer to the vector to escape:

/+ dub.sdl:
dependency "automem" version="==0.6.0"
dflags "-preview=dip1000" "-preview=dip25"
+/

import automem.vector;

@safe:

typeof(vector(1).range()) global;

void main()
{
    auto vec1 = vector(1, 2, 3);
    global = vec1.range; // compiles, but it shouldn't
}

Stack corruption PoC:

/+ dub.sdl:
dependency "automem" version="==0.6.0"
dflags "-preview=dip1000" "-preview=dip25"
+/

import std.stdio : writeln;
import automem.vector;

@safe:

typeof(vector(1).range()) global;

void main()
{
    escape;
    global.length.writeln; // 0
    stackSmash;
    global.length.writeln; // 42
}

void escape()
{
    auto vec1 = vector(1, 2, 3);
    global = vec1.range;
}

void stackSmash()
{
    long[4096] arr = 42;
}
$DC --version
DMD64 D Compiler v2.085.0
Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved written by Walter Bright

dub automem_test.d
0
42

Cannot foreach over Unique or RefCounted ranges

Example:

/+ dub.sdl:
       dependency "automem" version="~>0.6.1"
 +/
import automem;

void main()
{
    auto r = S();
    auto rc = RefCounted!S();
    auto un = Unique!S();
    foreach(i; r) {} //works
    foreach(i; rc) {}
    foreach(i; un) {}
}

struct S
{
    @property int front() {return 0;}
    void popFront(){}
    @property bool empty(){return false;}
}
dub test.d                                                                                             :(
test.d(13,5): Error: invalid foreach aggregate rc, define opApply(), range primitives, or use .tupleof
test.d(14,5): Error: invalid foreach aggregate un, define opApply(), range primitives, or use .tupleof

Same thing happens if front is a data member. For unique it's probably not possible to fix this, because of this DMD problem: https://issues.dlang.org/show_bug.cgi?id=15413
But I don't know why it doesn't work for RefCounted.

Crash with RefCounted

Probably a user error, but shouldn't this code be correct?

/+ dub.sdl:
       dependency "automem" version="~>0.6.1"
 +/

import automem;

void main()
{
    auto rc = RefCounted!S();
    for (auto r2 = rc; !r2.empty; r2.popFront)
    {
    }
}

struct S
{
    int front = 0;
    void popFront(){front++;}
    @property bool empty(){return front > 100;}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.