Hi Rainer, > I noticed you missed one piece of Iain's typeinfo.cc patch, btw.: > > diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc > --- a/gcc/d/typeinfo.cc > +++ b/gcc/d/typeinfo.cc > @@ -886,7 +886,7 @@ public: > if (cd->isCOMinterface ()) > flags |= ClassFlags::isCOMclass; > > - this->layout_field (build_integer_cst (flags)); > + this->layout_field (build_integer_cst (flags, d_uint_type)); > > /* void *deallocator; > OffsetTypeInfo[] m_offTi; (not implemented)
thanks for catching this. I amended the patch and ran the D test suite on S/390 and i386 one more time. For S/390 the number of FAILs is unchanged === libphobos Summary === # of expected passes 380 # of unexpected failures 30 Some of the FAILs are still a little worrying, like tests for "-shared" which I haven't looked at at all so far. Still, it's better than the >200 before. On i386 I see no FAILs with the patch. Regards Robin
diff --git a/gcc/d/dmd/constfold.c b/gcc/d/dmd/constfold.c index ddd356bb966..cb58d4b4f5b 100644 --- a/gcc/d/dmd/constfold.c +++ b/gcc/d/dmd/constfold.c @@ -1752,14 +1752,17 @@ UnionExp Cat(Type *type, Expression *e1, Expression *e2) } else if (e1->op == TOKint64 && e2->op == TOKstring) { - // Concatenate the strings + // [w|d]?char ~ string --> string + // We assume that we only ever prepend one char of the same type + // (wchar,dchar) as the string's characters. + StringExp *es2 = (StringExp *)e2; size_t len = 1 + es2->len; unsigned char sz = es2->sz; dinteger_t v = e1->toInteger(); void *s = mem.xmalloc((len + 1) * sz); - memcpy((char *)s, &v, sz); + Port::valcpy((char *)s, v, sz); memcpy((char *)s + sz, es2->string, es2->len * sz); // Add terminating 0 diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc index dac66acdcd4..865fde2c863 100644 --- a/gcc/d/typeinfo.cc +++ b/gcc/d/typeinfo.cc @@ -830,7 +830,7 @@ public: flags |= ClassFlags::noPointers; Lhaspointers: - this->layout_field (size_int (flags)); + this->layout_field (build_integer_cst (flags, d_uint_type)); /* void *deallocator; */ tree ddtor = (cd->aggDelete) @@ -886,7 +886,7 @@ public: if (cd->isCOMinterface ()) flags |= ClassFlags::isCOMclass; - this->layout_field (size_int (flags)); + this->layout_field (build_integer_cst (flags, d_uint_type)); /* void *deallocator; OffsetTypeInfo[] m_offTi; (not implemented) @@ -1019,7 +1019,7 @@ public: StructFlags::Type m_flags = 0; if (ti->hasPointers ()) m_flags |= StructFlags::hasPointers; - this->layout_field (size_int (m_flags)); + this->layout_field (build_integer_cst (m_flags, d_uint_type)); /* void function(void*) xdtor; */ tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor)) @@ -1033,7 +1033,7 @@ public: this->layout_field (null_pointer_node); /* uint m_align; */ - this->layout_field (size_int (ti->alignsize ())); + this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type)); if (global.params.is64bit) { @@ -1489,8 +1489,8 @@ create_typeinfo (Type *type, Module *mod) array_type_node, array_type_node, ptr_type_node, ptr_type_node, ptr_type_node, ptr_type_node, - size_type_node, ptr_type_node, - ptr_type_node, size_type_node, + d_uint_type, ptr_type_node, + ptr_type_node, d_uint_type, ptr_type_node, argtype, argtype, NULL); } t->vtinfo = TypeInfoStructDeclaration::create (t); diff --git a/gcc/testsuite/gdc.dg/runnable.d b/gcc/testsuite/gdc.dg/runnable.d index e36a2585027..8d9a5868831 100644 --- a/gcc/testsuite/gdc.dg/runnable.d +++ b/gcc/testsuite/gdc.dg/runnable.d @@ -890,12 +890,17 @@ struct S186 } } +static if (size_t.sizeof == 8) + size_t checkval = 0x0200000000000002; +static if (size_t.sizeof == 4) + size_t checkval = 0x02000002; + void check186(in S186 obj, byte fieldB) { assert(obj.fieldA == 2); assert(obj.fieldB == 0); assert(obj.fieldC == 0); - assert(obj._complete == 2); + assert(obj._complete == checkval); assert(fieldB == 0); } @@ -907,7 +912,7 @@ void test186a(size_t val) assert(obj.fieldA == 2); assert(obj.fieldB == 0); assert(obj.fieldC == 0); - assert(obj._complete == 2); + assert(obj._complete == checkval); obj = S186(val); check186(obj, obj.fieldB); @@ -915,12 +920,12 @@ void test186a(size_t val) assert(obj.fieldA == 2); assert(obj.fieldB == 0); assert(obj.fieldC == 0); - assert(obj._complete == 2); + assert(obj._complete == checkval); } void test186() { - test186a(2); + test186a(checkval); } /******************************************/ diff --git a/gcc/testsuite/gdc.dg/simd.d b/gcc/testsuite/gdc.dg/simd.d index 812b36649aa..7d0aa0168c0 100644 --- a/gcc/testsuite/gdc.dg/simd.d +++ b/gcc/testsuite/gdc.dg/simd.d @@ -1576,7 +1576,10 @@ ubyte[16] foounsto() void testOPvecunsto() { auto a = foounsto(); - assert(a == [0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65]); + version(LittleEndian) + assert(a == [0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65, 0, 0, 64, 65]); + version(BigEndian) + assert(a == [65, 64, 0, 0, 65, 64, 0, 0, 65, 64, 0, 0, 65, 64, 0, 0]); } /*****************************************/ diff --git a/gcc/testsuite/gdc.test/runnable/mars1.d b/gcc/testsuite/gdc.test/runnable/mars1.d index 1f4e55d9ac4..91d93dbf81e 100644 --- a/gcc/testsuite/gdc.test/runnable/mars1.d +++ b/gcc/testsuite/gdc.test/runnable/mars1.d @@ -238,13 +238,13 @@ void test13023(ulong n) struct U { int a; union { char c; int d; } long b; } -U f = { b:3, d:2, a:1 }; +U f = { b:3, d:0x22222222, a:1 }; void testU() { assert(f.b == 3); - assert(f.d == 2); - assert(f.c == 2); + assert(f.d == 0x22222222); + assert(f.c == 0x22); assert(f.a == 1); assert(f.sizeof == 16); assert(U.sizeof == 16); diff --git a/gcc/testsuite/gdc.test/runnable/test12.d b/gcc/testsuite/gdc.test/runnable/test12.d index 7656de70af6..db9b45cea61 100644 --- a/gcc/testsuite/gdc.test/runnable/test12.d +++ b/gcc/testsuite/gdc.test/runnable/test12.d @@ -624,7 +624,10 @@ int hoge(S29 s) { char[10] b; printf("%x\n", s); sprintf(b.ptr, "%x", s); - assert(b[0 .. 7] == "4030201"); + version(LittleEndian) + assert(b[0 .. 7] == "4030201"); + version(BigEndian) + assert(b[0 .. 7] == "1020304"); return 0; } diff --git a/gcc/testsuite/gdc.test/runnable/test23.d b/gcc/testsuite/gdc.test/runnable/test23.d index ee17be0b00f..eac2b20b7dd 100644 --- a/gcc/testsuite/gdc.test/runnable/test23.d +++ b/gcc/testsuite/gdc.test/runnable/test23.d @@ -565,7 +565,10 @@ void test25() auto str3 = cast(wchar[3])("defghi"); writefln("str3: ", (cast(char[])str3).length , " : ", (cast(char[])str3)); - assert(cast(char[])str3 == "d\000e\000f\000"c); + version(LittleEndian) + assert(cast(char[])str3 == "d\000e\000f\000"c); + version(BigEndian) + assert(cast(char[])str3 == "\000d\000e\000f"c); } /*******************************************/ diff --git a/gcc/testsuite/gdc.test/runnable/test4.d b/gcc/testsuite/gdc.test/runnable/test4.d index f008da6da72..ff6f6d407ed 100644 --- a/gcc/testsuite/gdc.test/runnable/test4.d +++ b/gcc/testsuite/gdc.test/runnable/test4.d @@ -254,6 +254,16 @@ else version(ARM) assert(TRECT6.BottomRight.offsetof == 16); assert(TRECT6.foo2.offsetof == 24); } +else version(SystemZ) +{ + assert(TRECT6.Left.offsetof == 8); + assert(TRECT6.Top.offsetof == 12); + assert(TRECT6.Right.offsetof == 16); + assert(TRECT6.Bottom.offsetof == 20); + assert(TRECT6.TopLeft.offsetof == 8); + assert(TRECT6.BottomRight.offsetof == 16); + assert(TRECT6.foo2.offsetof == 24); +} else { assert(TRECT6.Left.offsetof == 4); diff --git a/libphobos/configure.tgt b/libphobos/configure.tgt index 0471bfd816b..4ea91c949d7 100644 --- a/libphobos/configure.tgt +++ b/libphobos/configure.tgt @@ -32,6 +32,8 @@ case "${target}" in ;; x86_64-*-netbsd* | i?86-*-netbsd*) ;; + s390*-linux*) + ;; *) UNSUPPORTED=1 ;; diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d index 817790ab7eb..4665f3abcb0 100644 --- a/libphobos/libdruntime/core/sys/posix/fcntl.d +++ b/libphobos/libdruntime/core/sys/posix/fcntl.d @@ -120,6 +120,13 @@ version (CRuntime_Glibc) enum F_SETLK = 6; enum F_SETLKW = 7; } + else version (SystemZ) + { + static assert(off_t.sizeof == 8); + enum F_GETLK = 5; + enum F_SETLK = 6; + enum F_SETLKW = 7; + } else static if ( __USE_FILE_OFFSET64 ) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d index 8c78ba677a4..fbd556a4ac8 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/stat.d +++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d @@ -741,12 +741,12 @@ version (CRuntime_Glibc) alias __ino_t = c_ulong; alias __ino64_t = ulong; alias __mode_t = uint; - alias __nlink_t = uint; + alias __nlink_t = ulong; alias __uid_t = uint; alias __gid_t = uint; alias __off_t = c_long; alias __off64_t = long; - alias __blksize_t = int; + alias __blksize_t = c_long; alias __blkcnt_t = c_long; alias __blkcnt64_t = long; alias __timespec = timespec; diff --git a/libphobos/libdruntime/rt/sections_elf_shared.d b/libphobos/libdruntime/rt/sections_elf_shared.d index d4e1ff07699..5cc7a866fcb 100644 --- a/libphobos/libdruntime/rt/sections_elf_shared.d +++ b/libphobos/libdruntime/rt/sections_elf_shared.d @@ -978,7 +978,10 @@ struct tls_index } } +import gcc.builtins; + extern(C) void* __tls_get_addr(tls_index* ti) nothrow @nogc; +extern(C) void* __tls_get_addr_internal(tls_index* ti) nothrow @nogc; /* The dynamic thread vector (DTV) pointers may point 0x8000 past the start of * each TLS block. This is at least true for PowerPC and Mips platforms. @@ -1012,6 +1015,8 @@ else version (MIPS32) enum TLS_DTV_OFFSET = 0x8000; else version (MIPS64) enum TLS_DTV_OFFSET = 0x8000; +else version (SystemZ) + enum TLS_DTV_OFFSET = 0x0; else static assert( false, "Platform not supported." ); @@ -1022,5 +1027,13 @@ void[] getTLSRange(size_t mod, size_t sz) nothrow @nogc // base offset auto ti = tls_index(mod, 0); - return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; + + version (SystemZ) + { + auto idx = cast(void *)__tls_get_addr_internal(&ti) + + cast(ulong)__builtin_thread_pointer (); + return idx[0 .. sz]; + } + else + return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; } diff --git a/libphobos/src/std/outbuffer.d b/libphobos/src/std/outbuffer.d index 1d594982cc1..e9301181640 100644 --- a/libphobos/src/std/outbuffer.d +++ b/libphobos/src/std/outbuffer.d @@ -408,11 +408,17 @@ class OutBuffer { OutBuffer buf = new OutBuffer(); "hello"w.copy(buf); - assert(buf.toBytes() == "h\x00e\x00l\x00l\x00o\x00"); + version(LittleEndian) + assert(buf.toBytes() == "h\x00e\x00l\x00l\x00o\x00"); + version(BigEndian) + assert(buf.toBytes() == "\x00h\x00e\x00l\x00l\x00o"); } { OutBuffer buf = new OutBuffer(); "hello"d.copy(buf); - assert(buf.toBytes() == "h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00"); + version(LittleEndian) + assert(buf.toBytes() == "h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00"); + version(BigEndian) + assert(buf.toBytes() == "\x00\x00\x00h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o"); } } diff --git a/libphobos/src/std/uni.d b/libphobos/src/std/uni.d index 5f24ad16be5..baee073bfc2 100644 --- a/libphobos/src/std/uni.d +++ b/libphobos/src/std/uni.d @@ -770,6 +770,8 @@ version (X86) enum hasUnalignedReads = true; else version (X86_64) enum hasUnalignedReads = true; +else version (SystemZ) + enum hasUnalignedReads = true; else enum hasUnalignedReads = false; // better be safe then sorry @@ -1245,8 +1247,13 @@ pure nothrow: T opIndex(size_t idx) inout { - return __ctfe ? simpleIndex(idx) : + T ret; + version (LittleEndian) + ret = __ctfe ? simpleIndex(idx) : cast(inout(T))(cast(U*) origin)[idx]; + else + ret = simpleIndex (idx); + return ret; } static if (isBitPacked!T) // lack of user-defined implicit conversion @@ -1259,10 +1266,15 @@ pure nothrow: void opIndexAssign(TypeOfBitPacked!T val, size_t idx) { - if (__ctfe) - simpleWrite(val, idx); - else - (cast(U*) origin)[idx] = cast(U) val; + version (LittleEndian) + { + if (__ctfe) + simpleWrite(val, idx); + else + (cast(U*) origin)[idx] = cast(U) val; + } + else + simpleWrite(val, idx); } } else diff --git a/libphobos/src/std/xml.d b/libphobos/src/std/xml.d index 770c56fdbfb..a0c5349d013 100644 --- a/libphobos/src/std/xml.d +++ b/libphobos/src/std/xml.d @@ -2192,6 +2192,8 @@ private catch (Err e) { fail(e); } } + import core.sys.posix.sys.types : ssize_t; + void checkChars(ref string s) @safe pure // rule 2 { // TO DO - Fix std.utf stride and decode functions, then use those @@ -2201,8 +2203,8 @@ private mixin Check!("Chars"); dchar c; - int n = -1; - foreach (int i,dchar d; s) + ssize_t n = -1; + foreach (size_t i,dchar d; s) { if (!isChar(d)) { @@ -2238,8 +2240,11 @@ private mixin Check!("Name"); if (s.length == 0) fail(); - int n; - foreach (int i,dchar c;s) + ssize_t n; + // i must not be smaller than size_t because size_t is used internally + // in aApply.d and it will be cast e.g. to (int *) which fails on + // big-endian machines. + foreach (size_t i,dchar c;s) { if (c == '_' || c == ':' || isLetter(c)) continue; if (i == 0) fail(); diff --git a/libphobos/testsuite/libphobos.typeinfo/struct-align.d b/libphobos/testsuite/libphobos.typeinfo/struct-align.d new file mode 100644 index 00000000000..72866517481 --- /dev/null +++ b/libphobos/testsuite/libphobos.typeinfo/struct-align.d @@ -0,0 +1,13 @@ +module structalign; + +void main () +{ + struct K { int *a; }; + K k; + auto ti = typeid (k); + + assert (ti.flags () == 1); + + auto ti2 = typeid (k.a); + assert (ti.talign () == ti2.talign ()); +}