Showing with 78 additions and 18 deletions.
  1. +11 −2 src/core/stdc/stdarg.d
  2. +6 −6 src/core/sys/posix/sys/stat.d
  3. +2 −2 src/core/sys/posix/sys/statvfs.d
  4. +1 −1 src/core/sys/windows/stat.d
  5. +2 −2 src/core/time.d
  6. +32 −3 src/object.di
  7. +7 −1 src/object_.d
  8. +17 −1 src/rt/lifetime.d
13 changes: 11 additions & 2 deletions src/core/stdc/stdarg.d
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,19 @@ else version (X86_64)
{
}

import core.stdc.stdlib : alloca;

///
void va_copy(out va_list dest, va_list src)
void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof))
{
dest = src;
// Instead of copying the pointers, and aliasing the source va_list,
// the default argument alloca will allocate storage in the caller's
// stack frame. This is still not correct (it should be allocated in
// the place where the va_list variable is declared) but most of the
// time the caller's stack frame _is_ the place where the va_list is
// allocated, so in most cases this will now work.
dest = cast(va_list)storage;
*dest = *src;
}
}
else
Expand Down
12 changes: 6 additions & 6 deletions src/core/sys/posix/sys/stat.d
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ version( linux )
{
static if( __USE_LARGEFILE64 )
{
int fstat64(int, stat_t*);
int fstat64(int, stat_t*) @trusted;
alias fstat64 fstat;

int lstat64(in char*, stat_t*);
Expand All @@ -967,7 +967,7 @@ version( linux )
}
else
{
int fstat(int, stat_t*);
int fstat(int, stat_t*) @trusted;
int lstat(in char*, stat_t*);
int stat(in char*, stat_t*);
}
Expand All @@ -976,7 +976,7 @@ else version (Solaris)
{
version (D_LP64)
{
int fstat(int, stat_t*);
int fstat(int, stat_t*) @trusted;
int lstat(in char*, stat_t*);
int stat(in char*, stat_t*);

Expand All @@ -991,7 +991,7 @@ else version (Solaris)
{
static if (__USE_LARGEFILE64)
{
int fstat64(int, stat_t*);
int fstat64(int, stat_t*) @trusted;
alias fstat64 fstat;

int lstat64(in char*, stat_t*);
Expand All @@ -1002,15 +1002,15 @@ else version (Solaris)
}
else
{
int fstat(int, stat_t*);
int fstat(int, stat_t*) @trusted;
int lstat(in char*, stat_t*);
int stat(in char*, stat_t*);
}
}
}
else version( Posix )
{
int fstat(int, stat_t*);
int fstat(int, stat_t*) @trusted;
int lstat(in char*, stat_t*);
int stat(in char*, stat_t*);
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/sys/posix/sys/statvfs.d
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ version(linux) {
int statvfs64 (const char * file, statvfs_t* buf);
alias statvfs64 statvfs;

int fstatvfs64 (int fildes, statvfs_t *buf);
int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
alias fstatvfs64 fstatvfs;
}
else
Expand Down Expand Up @@ -108,5 +108,5 @@ else
}

int statvfs (const char * file, statvfs_t* buf);
int fstatvfs (int fildes, statvfs_t *buf);
int fstatvfs (int fildes, statvfs_t *buf) @trusted;
}
2 changes: 1 addition & 1 deletion src/core/sys/windows/stat.d
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ struct struct_stat
}

int stat(char *, struct_stat *);
int fstat(int, struct_stat *);
int fstat(int, struct_stat *) @trusted;
int _wstat(wchar *, struct_stat *);
4 changes: 2 additions & 2 deletions src/core/time.d
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,9 @@ public:
foreach(T; _TypeTuple!(TickDuration, const TickDuration, immutable TickDuration))
{
auto t = TickDuration.from!units(1);
assert(cast(T)cast(D)dur!units(1) == t, units);
assertApprox(cast(T)cast(D)dur!units(1), t - TickDuration(1), t + TickDuration(1), units);
t = TickDuration.from!units(2);
assert(cast(T)cast(D)dur!units(2) == t, units);
assertApprox(cast(T)cast(D)dur!units(2), t - TickDuration(1), t + TickDuration(1), units);
}
}
else
Expand Down
35 changes: 32 additions & 3 deletions src/object.di
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ class Object
string toString();
size_t toHash() @trusted nothrow;
int opCmp(Object o);
bool opEquals(Object o);

bool opEquals(Object o)
{
return this is o;
}

interface Monitor
{
Expand All @@ -45,8 +49,33 @@ class Object
static Object factory(string classname);
}

bool opEquals(const Object lhs, const Object rhs);
bool opEquals(Object lhs, Object rhs);
bool opEquals(const Object lhs, const Object rhs)
{
// A hack for the moment.
return opEquals(cast()lhs, cast()rhs);
}

bool opEquals(Object lhs, Object rhs)
{
// If aliased to the same object or both null => equal
if (lhs is rhs) return true;

// If either is null => non-equal
if (lhs is null || rhs is null) return false;

// If same exact type => one call to method opEquals
if (typeid(lhs) is typeid(rhs) ||
!__ctfe && typeid(lhs).opEquals(typeid(rhs)))
/* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't
(issue 7147). But CTFE also guarantees that equal TypeInfos are
always identical. So, no opEquals needed during CTFE. */
{
return lhs.opEquals(rhs);
}

// General case => symmetric calls to method opEquals
return lhs.opEquals(rhs) && rhs.opEquals(lhs);
}

void setSameMutex(shared Object ownee, shared Object owner);

Expand Down
8 changes: 7 additions & 1 deletion src/object_.d
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,14 @@ bool opEquals(Object lhs, Object rhs)
if (lhs is null || rhs is null) return false;

// If same exact type => one call to method opEquals
if (typeid(lhs) is typeid(rhs) || typeid(lhs).opEquals(typeid(rhs)))
if (typeid(lhs) is typeid(rhs) ||
!__ctfe && typeid(lhs).opEquals(typeid(rhs)))
/* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't
(issue 7147). But CTFE also guarantees that equal TypeInfos are
always identical. So, no opEquals needed during CTFE. */
{
return lhs.opEquals(rhs);
}

// General case => symmetric calls to method opEquals
return lhs.opEquals(rhs) && rhs.opEquals(lhs);
Expand Down
18 changes: 17 additions & 1 deletion src/rt/lifetime.d
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,7 @@ void finalize_array2(void* p, size_t size) nothrow
{
si = *cast(TypeInfo_Struct*)(p + size_t.sizeof);
size = *cast(size_t*)p;
p += LARGEPAD;
p += LARGEPREFIX;
}

try
Expand Down Expand Up @@ -2670,3 +2670,19 @@ unittest
import core.exception : InvalidMemoryOperationError;
assert(!test!InvalidMemoryOperationError);
}

// test bug 14126
unittest
{
static struct S
{
S* thisptr;
~this() { assert(&this == thisptr); thisptr = null;}
}

S[] test14126 = new S[2048]; // make sure we allocate at least a PAGE
foreach(ref s; test14126)
{
s.thisptr = &s;
}
}