diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-02-28 15:47:52 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-02-28 17:49:01 +0100 |
commit | 1027dc459204894f4503f713a3d73826e4bbab15 (patch) | |
tree | 606564b15e0978c77c76d0e618c00c25a78aaf38 /gcc | |
parent | 430c89274d7f82810724126637ffdc5507d442f0 (diff) | |
download | gcc-1027dc459204894f4503f713a3d73826e4bbab15.zip gcc-1027dc459204894f4503f713a3d73826e4bbab15.tar.gz gcc-1027dc459204894f4503f713a3d73826e4bbab15.tar.bz2 |
d: Merge upstream dmd cf63dd8e5, druntime caf14b0f, phobos 41aaf8c26.
D front-end changes:
- Import dmd v2.099.0-rc.1.
- The `main' can now return type `noreturn' and supports return
inference.
D Runtime changes:
- Import druntime v2.099.0-rc.1.
- C bindings for stat_t on powerpc-linux has been fixed.
Phobos changes:
- Import phobos v2.099.0-rc.1.
gcc/d/ChangeLog:
* d-target.cc (Target::_init): Initialize C type size fields.
* dmd/MERGE: Merge upstream dmd cf63dd8e5.
* dmd/VERSION: Update version to v2.099.0-rc.1.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime caf14b0f.
* src/MERGE: Merge upstream phobos 41aaf8c26.
gcc/testsuite/ChangeLog:
* gdc.dg/torture/simd7413a.d: Update.
* gdc.dg/ubsan/pr88957.d: Update.
* gdc.dg/simd18489.d: New test.
* gdc.dg/torture/simd21727.d: New test.
Diffstat (limited to 'gcc')
42 files changed, 725 insertions, 581 deletions
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 02f7b74..610be74 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -158,9 +158,14 @@ Target::_init (const Param &) Type::thash_t = Type::tsize_t; /* Set-up target C ABI. */ - this->c.longsize = int_size_in_bytes (long_integer_type_node); - this->c.long_doublesize = int_size_in_bytes (long_double_type_node); + this->c.boolsize = (BOOL_TYPE_SIZE / BITS_PER_UNIT); + this->c.shortsize = (SHORT_TYPE_SIZE / BITS_PER_UNIT); + this->c.intsize = (INT_TYPE_SIZE / BITS_PER_UNIT); + this->c.longsize = (LONG_TYPE_SIZE / BITS_PER_UNIT); + this->c.long_longsize = (LONG_LONG_TYPE_SIZE / BITS_PER_UNIT); + this->c.long_doublesize = (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT); this->c.wchar_tsize = (WCHAR_TYPE_SIZE / BITS_PER_UNIT); + this->c.bitFieldStyle = targetm.ms_bitfield_layout_p (unknown_type_node) ? TargetC::BitFieldStyle::MS : TargetC::BitFieldStyle::Gcc_Clang; diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index b92f376..f08d53a 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -cb49e99f80e8111c71035b88fe47fe7d855c300f +cf63dd8e5a77ecb68cf5e7c43bf7b6c4c1154bbe The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 12042ff..4bb69df 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.099.0-beta.1 +v2.099.0-rc.1 diff --git a/gcc/d/dmd/common/outbuffer.d b/gcc/d/dmd/common/outbuffer.d index e5cc43b..fafe90e 100644 --- a/gcc/d/dmd/common/outbuffer.d +++ b/gcc/d/dmd/common/outbuffer.d @@ -82,18 +82,17 @@ struct OutBuffer /** Frees resources associated. */ - extern (C++) void dtor() nothrow @trusted + extern (C++) void dtor() pure nothrow @trusted { if (fileMapping) { if (fileMapping.active) fileMapping.close(); - fileMapping = null; } else { debug (stomp) memset(data.ptr, 0xFF, data.length); - free(data.ptr); + pureFree(data.ptr); } } @@ -102,17 +101,7 @@ struct OutBuffer */ extern (C++) ~this() pure nothrow @trusted { - if (fileMapping) - { - if (fileMapping.active) - fileMapping.close(); - fileMapping = null; - } - else - { - debug (stomp) memset(data.ptr, 0xFF, data.length); - pureFree(data.ptr); - } + dtor(); } /// For porting with ease from dmd.backend.outbuf.Outbuffer @@ -150,17 +139,10 @@ struct OutBuffer */ extern (C++) void destroy() pure nothrow @trusted { - if (fileMapping && fileMapping.active) - { - fileMapping.close(); - data = null; - offset = 0; - } - else - { - debug (stomp) memset(data.ptr, 0xFF, data.length); - pureFree(extractData()); - } + dtor(); + fileMapping = null; + data = null; + offset = 0; } /** diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 0fe6459..3ded10a 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -48,8 +48,12 @@ final class CParser(AST) : Parser!AST linkage = LINK.c; Ccompile = true; - // Configure sizes for C `long`, `long double`, `wchar_t` + // Configure sizes for C `long`, `long double`, `wchar_t`, ... + this.boolsize = target.boolsize; + this.shortsize = target.shortsize; + this.intsize = target.intsize; this.longsize = target.longsize; + this.long_longsize = target.long_longsize; this.long_doublesize = target.long_doublesize; this.wchar_tsize = target.wchar_tsize; @@ -2271,36 +2275,36 @@ final class CParser(AST) : Parser!AST case TKW.xshort: case TKW.xsigned | TKW.xshort: case TKW.xsigned | TKW.xshort | TKW.xint: - case TKW.xshort | TKW.xint: t = AST.Type.tint16; break; + case TKW.xshort | TKW.xint: t = integerTypeForSize(shortsize); break; case TKW.xunsigned | TKW.xshort | TKW.xint: - case TKW.xunsigned | TKW.xshort: t = AST.Type.tuns16; break; + case TKW.xunsigned | TKW.xshort: t = unsignedTypeForSize(shortsize); break; case TKW.xint: case TKW.xsigned: - case TKW.xsigned | TKW.xint: t = AST.Type.tint32; break; + case TKW.xsigned | TKW.xint: t = integerTypeForSize(intsize); break; case TKW.xunsigned: - case TKW.xunsigned | TKW.xint: t = AST.Type.tuns32; break; + case TKW.xunsigned | TKW.xint: t = unsignedTypeForSize(intsize); break; case TKW.xlong: case TKW.xsigned | TKW.xlong: case TKW.xsigned | TKW.xlong | TKW.xint: - case TKW.xlong | TKW.xint: t = longsize == 4 ? AST.Type.tint32 : AST.Type.tint64; break; + case TKW.xlong | TKW.xint: t = integerTypeForSize(longsize); break; case TKW.xunsigned | TKW.xlong | TKW.xint: - case TKW.xunsigned | TKW.xlong: t = longsize == 4 ? AST.Type.tuns32 : AST.Type.tuns64; break; + case TKW.xunsigned | TKW.xlong: t = unsignedTypeForSize(longsize); break; case TKW.xllong: case TKW.xsigned | TKW.xllong: case TKW.xsigned | TKW.xllong | TKW.xint: - case TKW.xllong | TKW.xint: t = AST.Type.tint64; break; + case TKW.xllong | TKW.xint: t = integerTypeForSize(long_longsize); break; case TKW.xunsigned | TKW.xllong | TKW.xint: - case TKW.xunsigned | TKW.xllong: t = AST.Type.tuns64; break; + case TKW.xunsigned | TKW.xllong: t = unsignedTypeForSize(long_longsize); break; case TKW.xvoid: t = AST.Type.tvoid; break; - case TKW.xbool: t = AST.Type.tbool; break; + case TKW.xbool: t = boolsize == 1 ? AST.Type.tbool : integerTypeForSize(boolsize); break; case TKW.xfloat: t = AST.Type.tfloat32; break; case TKW.xdouble: t = AST.Type.tfloat64; break; @@ -4379,6 +4383,48 @@ final class CParser(AST) : Parser!AST } /*********************** + * Return suitable signed integer type for the given size + * Params: + * size = size of type + * Returns: + * corresponding signed D integer type + */ + private AST.Type integerTypeForSize(ubyte size) + { + if (size <= 1) + return AST.Type.tint8; + if (size <= 2) + return AST.Type.tint16; + if (size <= 4) + return AST.Type.tint32; + if (size <= 8) + return AST.Type.tint64; + error("unsupported integer type"); + return AST.Type.terror; + } + + /*********************** + * Return suitable unsigned integer type for the given size + * Params: + * size = size of type + * Returns: + * corresponding unsigned D integer type + */ + private AST.Type unsignedTypeForSize(ubyte size) + { + if (size <= 1) + return AST.Type.tuns8; + if (size <= 2) + return AST.Type.tuns16; + if (size <= 4) + return AST.Type.tuns32; + if (size <= 8) + return AST.Type.tuns64; + error("unsupported integer type"); + return AST.Type.terror; + } + + /*********************** * Return suitable D float type for C `long double` * Params: * flags = kind of float to return (real, imaginary, complex). diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index 986b53f..9564b03 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -1713,6 +1713,38 @@ extern(C++): * Ds char16_t * u <source-name> # vendor extended type */ + if (t.isimaginary() || t.iscomplex()) + { + // https://issues.dlang.org/show_bug.cgi?id=22806 + // Complex and imaginary types are represented in the same way as + // arrays or vectors in C++. First substitute the outer type, then + // write out the mangle string of the underlying type. + if (substitute(t)) + return; + append(t); + CV_qualifiers(t); + + if (t.isimaginary()) + buf.writeByte('G'); // 'G' means imaginary + else + buf.writeByte('C'); // 'C' means complex + + switch (t.ty) + { + case Timaginary32: + case Tcomplex32: + return Type.tfloat32.accept(this); + case Timaginary64: + case Tcomplex64: + return Type.tfloat64.accept(this); + case Timaginary80: + case Tcomplex80: + return Type.tfloat80.accept(this); + default: + assert(0); + } + } + char c; char p = 0; switch (t.ty) @@ -1739,12 +1771,6 @@ extern(C++): case Tchar: c = 'c'; break; case Twchar: p = 'D'; c = 's'; break; // since C++11 case Tdchar: p = 'D'; c = 'i'; break; // since C++11 - case Timaginary32: p = 'G'; c = 'f'; break; // 'G' means imaginary - case Timaginary64: p = 'G'; c = 'd'; break; - case Timaginary80: p = 'G'; c = 'e'; break; - case Tcomplex32: p = 'C'; c = 'f'; break; // 'C' means complex - case Tcomplex64: p = 'C'; c = 'd'; break; - case Tcomplex80: p = 'C'; c = 'e'; break; default: return error(t); @@ -1889,11 +1915,11 @@ extern(C++): else if (id == Id.__c_ulonglong) return writeBasicType(t, 0, 'y'); else if (id == Id.__c_complex_float) - return writeBasicType(t, 'C', 'f'); + return Type.tcomplex32.accept(this); else if (id == Id.__c_complex_double) - return writeBasicType(t, 'C', 'd'); + return Type.tcomplex64.accept(this); else if (id == Id.__c_complex_real) - return writeBasicType(t, 'C', 'e'); + return Type.tcomplex80.accept(this); doSymbol(t); } diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d index ad305f9..1e6799f 100644 --- a/gcc/d/dmd/dmangle.d +++ b/gcc/d/dmd/dmangle.d @@ -231,168 +231,19 @@ unittest } } -/*********************** - * Mangle basic type ty to buf. - */ - -private void tyToDecoBuffer(OutBuffer* buf, int ty) -{ - const c = mangleChar[ty]; - buf.writeByte(c); - if (c == 'z') - buf.writeByte(ty == Tint128 ? 'i' : 'k'); -} - -/********************************* - * Mangling for mod. - */ -private void MODtoDecoBuffer(OutBuffer* buf, MOD mod) -{ - switch (mod) - { - case 0: - break; - case MODFlags.const_: - buf.writeByte('x'); - break; - case MODFlags.immutable_: - buf.writeByte('y'); - break; - case MODFlags.shared_: - buf.writeByte('O'); - break; - case MODFlags.shared_ | MODFlags.const_: - buf.writestring("Ox"); - break; - case MODFlags.wild: - buf.writestring("Ng"); - break; - case MODFlags.wildconst: - buf.writestring("Ngx"); - break; - case MODFlags.shared_ | MODFlags.wild: - buf.writestring("ONg"); - break; - case MODFlags.shared_ | MODFlags.wildconst: - buf.writestring("ONgx"); - break; - default: - assert(0); - } -} - private extern (C++) final class Mangler : Visitor { alias visit = Visitor.visit; public: static assert(Key.sizeof == size_t.sizeof); - AssocArray!(Type, size_t) types; // Type => (offset+1) in buf - AssocArray!(Identifier, size_t) idents; // Identifier => (offset+1) in buf + OutBuffer* buf; - Type rootType; + Backref backref; extern (D) this(OutBuffer* buf, Type rootType = null) { this.buf = buf; - this.rootType = rootType; - } - - /** - * writes a back reference with the relative position encoded with base 26 - * using upper case letters for all digits but the last digit which uses - * a lower case letter. - * The decoder has to look up the referenced position to determine - * whether the back reference is an identifier (starts with a digit) - * or a type (starts with a letter). - * - * Params: - * pos = relative position to encode - */ - void writeBackRef(size_t pos) - { - buf.writeByte('Q'); - enum base = 26; - size_t mul = 1; - while (pos >= mul * base) - mul *= base; - while (mul >= base) - { - auto dig = cast(ubyte)(pos / mul); - buf.writeByte('A' + dig); - pos -= dig * mul; - mul /= base; - } - buf.writeByte('a' + cast(ubyte)pos); - } - - /** - * Back references a non-basic type - * - * The encoded mangling is - * 'Q' <relative position of first occurrence of type> - * - * Params: - * t = the type to encode via back referencing - * - * Returns: - * true if the type was found. A back reference has been encoded. - * false if the type was not found. The current position is saved for later back references. - */ - bool backrefType(Type t) - { - if (t.isTypeBasic()) - return false; - - /** - * https://issues.dlang.org/show_bug.cgi?id=21591 - * - * Special case for unmerged TypeFunctions: use the generic merged - * function type as backref cache key to avoid missed backrefs. - * - * Merging is based on mangling, so we need to avoid an infinite - * recursion by excluding the case where `t` is the root type passed to - * `mangleToBuffer()`. - */ - if (t != rootType) - { - if (t.isFunction_Delegate_PtrToFunction()) - { - t = t.merge2(); - } - } - - return backrefImpl(types, t); - } - - /** - * Back references a single identifier - * - * The encoded mangling is - * 'Q' <relative position of first occurrence of type> - * - * Params: - * id = the identifier to encode via back referencing - * - * Returns: - * true if the identifier was found. A back reference has been encoded. - * false if the identifier was not found. The current position is saved for later back references. - */ - bool backrefIdentifier(Identifier id) - { - return backrefImpl(idents, id); - } - - private extern(D) bool backrefImpl(T)(ref AssocArray!(T, size_t) aa, T key) - { - auto p = aa.getLvalue(key); - if (*p) - { - const offset = *p - 1; - writeBackRef(buf.length - offset); - return true; - } - *p = buf.length + 1; - return false; + this.backref = Backref(rootType); } void mangleSymbol(Dsymbol s) @@ -402,14 +253,14 @@ public: void mangleType(Type t) { - if (!backrefType(t)) + if (!backref.addRefToType(buf, t)) t.accept(this); } void mangleIdentifier(Identifier id, Dsymbol s) { - if (!backrefIdentifier(id)) - toBuffer(id.toString(), s); + if (!backref.addRefToIdentifier(buf, id)) + toBuffer(buf, id.toString(), s); } //////////////////////////////////////////////////////////////////////////// @@ -541,7 +392,7 @@ public: // Write argument types foreach (idx, param; t.parameterList) - param.accept(this); + mangleParameter(param); //if (buf.data[buf.length - 1] == '@') assert(0); buf.writeByte('Z' - t.parameterList.varargs); // mark end of arg list if (tret !is null) @@ -582,7 +433,7 @@ public: //printf("TypeTuple.toDecoBuffer() t = %p, %s\n", t, t.toChars()); visit(cast(Type)t); Parameter._foreach(t.arguments, (idx, param) { - param.accept(this); + mangleParameter(param); return 0; }); buf.writeByte('Z'); @@ -643,24 +494,8 @@ public: else buf.writeByte('0'); - /* There can be multiple different declarations in the same - * function that have the same mangled name. - * This results in localNum having a non-zero number, which - * is used to add a fake parent of the form `__Sddd` to make - * the mangled names unique. - * https://issues.dlang.org/show_bug.cgi?id=20565 - */ if (localNum) - { - uint ndigits = 1; - auto n = localNum; - while (n >= 10) - { - n /= 10; - ++ndigits; - } - buf.printf("%u__S%u", ndigits + 3, localNum); - } + writeLocalParent(buf, localNum); } } @@ -692,67 +527,6 @@ public: } } - /************************************************************ - * Write length prefixed string to buf. - */ - extern (D) void toBuffer(const(char)[] id, Dsymbol s) - { - const len = id.length; - if (buf.length + len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone - s.error("excessive length %llu for symbol, possible recursive expansion?", cast(ulong)(buf.length + len)); - else - { - buf.print(len); - buf.writestring(id); - } - } - - /************************************************************ - * Try to obtain an externally mangled identifier from a declaration. - * If the declaration is at global scope or mixed in at global scope, - * the user might want to call it externally, so an externally mangled - * name is returned. Member functions or nested functions can't be called - * externally in C, so in that case null is returned. C++ does support - * namespaces, so extern(C++) always gives a C++ mangled name. - * - * See also: https://issues.dlang.org/show_bug.cgi?id=20012 - * - * Params: - * d = declaration to mangle - * - * Returns: - * an externally mangled name or null if the declaration cannot be called externally - */ - extern (D) static const(char)[] externallyMangledIdentifier(Declaration d) - { - const par = d.toParent(); //toParent() skips over mixin templates - if (!par || par.isModule() || d.linkage == LINK.cpp || - (d.linkage == LINK.c && d.isCsymbol() && d.isFuncDeclaration())) - { - if (d.linkage != LINK.d && d.localNum) - d.error("the same declaration cannot be in multiple scopes with non-D linkage"); - final switch (d.linkage) - { - case LINK.d: - break; - case LINK.c: - case LINK.windows: - case LINK.objc: - return d.ident.toString(); - case LINK.cpp: - { - const p = target.cpp.toMangle(d); - return p.toDString(); - } - case LINK.default_: - case LINK.system: - d.error("forward declaration"); - return d.ident.toString(); - } - } - return null; - } - override void visit(Declaration d) { //printf("Declaration.mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", @@ -1009,13 +783,13 @@ public: if (d.mangleOverride) { buf.writeByte('X'); - toBuffer(d.mangleOverride, d); + toBuffer(buf, d.mangleOverride, d); continue; } if (const id = externallyMangledIdentifier(d)) { buf.writeByte('X'); - toBuffer(id, d); + toBuffer(buf, id, d); continue; } if (!d.type || !d.type.deco) @@ -1052,7 +826,7 @@ public: if (s.ident) mangleIdentifier(s.ident, s); else - toBuffer(s.toString(), s); + toBuffer(buf, s.toString(), s); //printf("Dsymbol.mangle() %s = %s\n", s.toChars(), id); } @@ -1080,68 +854,15 @@ public: override void visit(RealExp e) { buf.writeByte('e'); - realToMangleBuffer(e.value); - } - - void realToMangleBuffer(real_t value) - { - /* Rely on %A to get portable mangling. - * Must munge result to get only identifier characters. - * - * Possible values from %A => mangled result - * NAN => NAN - * -INF => NINF - * INF => INF - * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79 - * 0X1.9P+2 => 19P2 - */ - if (CTFloat.isNaN(value)) - { - buf.writestring("NAN"); // no -NAN bugs - return; - } - - if (value < CTFloat.zero) - { - buf.writeByte('N'); - value = -value; - } - - if (CTFloat.isInfinity(value)) - { - buf.writestring("INF"); - return; - } - - char[36] buffer = void; - // 'A' format yields [-]0xh.hhhhp+-d - const n = CTFloat.sprint(buffer.ptr, 'A', value); - assert(n < buffer.length); - foreach (const c; buffer[2 .. n]) - { - switch (c) - { - case '-': - buf.writeByte('N'); - break; - - case '+': - case '.': - break; - - default: - buf.writeByte(c); - break; - } - } + realToMangleBuffer(buf, e.value); } override void visit(ComplexExp e) { buf.writeByte('c'); - realToMangleBuffer(e.toReal()); + realToMangleBuffer(buf, e.toReal()); buf.writeByte('c'); // separate the two - realToMangleBuffer(e.toImaginary()); + realToMangleBuffer(buf, e.toImaginary()); } override void visit(NullExp e) @@ -1258,7 +979,7 @@ public: //////////////////////////////////////////////////////////////////////////// - override void visit(Parameter p) + void mangleParameter(Parameter p) { // https://dlang.org/spec/abi.html#Parameter @@ -1331,3 +1052,318 @@ public: visitWithMask(p.type, (stc & STC.in_) ? MODFlags.const_ : 0); } } + +/*************************************** + * Manage back reference mangling + */ +private struct Backref +{ + /** + * Back references a non-basic type + * + * The encoded mangling is + * 'Q' <relative position of first occurrence of type> + * + * Params: + * t = the type to encode via back referencing + * + * Returns: + * true if the type was found. A back reference has been encoded. + * false if the type was not found. The current position is saved for later back references. + */ + bool addRefToType(OutBuffer* buf, Type t) + { + if (t.isTypeBasic()) + return false; + + /** + * https://issues.dlang.org/show_bug.cgi?id=21591 + * + * Special case for unmerged TypeFunctions: use the generic merged + * function type as backref cache key to avoid missed backrefs. + * + * Merging is based on mangling, so we need to avoid an infinite + * recursion by excluding the case where `t` is the root type passed to + * `mangleToBuffer()`. + */ + if (t != rootType) + { + if (t.isFunction_Delegate_PtrToFunction()) + { + t = t.merge2(); + } + } + + return backrefImpl(buf, types, t); + } + + /** + * Back references a single identifier + * + * The encoded mangling is + * 'Q' <relative position of first occurrence of type> + * + * Params: + * id = the identifier to encode via back referencing + * + * Returns: + * true if the identifier was found. A back reference has been encoded. + * false if the identifier was not found. The current position is saved for later back references. + */ + bool addRefToIdentifier(OutBuffer* buf, Identifier id) + { + return backrefImpl(buf, idents, id); + } + + private: + + extern(D) bool backrefImpl(T)(OutBuffer* buf, ref AssocArray!(T, size_t) aa, T key) + { + auto p = aa.getLvalue(key); + if (*p) + { + const offset = *p - 1; + writeBackRef(buf, buf.length - offset); + return true; + } + *p = buf.length + 1; + return false; + } + + Type rootType; /// avoid infinite recursion + AssocArray!(Type, size_t) types; /// Type => (offset+1) in buf + AssocArray!(Identifier, size_t) idents; /// Identifier => (offset+1) in buf +} + + +/*********************** + * Mangle basic type ty to buf. + */ + +private void tyToDecoBuffer(OutBuffer* buf, int ty) +{ + const c = mangleChar[ty]; + buf.writeByte(c); + if (c == 'z') + buf.writeByte(ty == Tint128 ? 'i' : 'k'); +} + +/********************************* + * Mangling for mod. + */ +private void MODtoDecoBuffer(OutBuffer* buf, MOD mod) +{ + switch (mod) + { + case 0: + break; + case MODFlags.const_: + buf.writeByte('x'); + break; + case MODFlags.immutable_: + buf.writeByte('y'); + break; + case MODFlags.shared_: + buf.writeByte('O'); + break; + case MODFlags.shared_ | MODFlags.const_: + buf.writestring("Ox"); + break; + case MODFlags.wild: + buf.writestring("Ng"); + break; + case MODFlags.wildconst: + buf.writestring("Ngx"); + break; + case MODFlags.shared_ | MODFlags.wild: + buf.writestring("ONg"); + break; + case MODFlags.shared_ | MODFlags.wildconst: + buf.writestring("ONgx"); + break; + default: + assert(0); + } +} + + +/** + * writes a back reference with the relative position encoded with base 26 + * using upper case letters for all digits but the last digit which uses + * a lower case letter. + * The decoder has to look up the referenced position to determine + * whether the back reference is an identifier (starts with a digit) + * or a type (starts with a letter). + * + * Params: + * buf = buffer to write to + * pos = relative position to encode + */ +private +void writeBackRef(OutBuffer* buf, size_t pos) +{ + buf.writeByte('Q'); + enum base = 26; + size_t mul = 1; + while (pos >= mul * base) + mul *= base; + while (mul >= base) + { + auto dig = cast(ubyte)(pos / mul); + buf.writeByte('A' + dig); + pos -= dig * mul; + mul /= base; + } + buf.writeByte('a' + cast(ubyte)pos); +} + + +/************************************************************ + * Write length prefixed string to buf. + */ +private +extern (D) void toBuffer(OutBuffer* buf, const(char)[] id, Dsymbol s) +{ + const len = id.length; + if (buf.length + len >= 8 * 1024 * 1024) // 8 megs ought be enough for anyone + s.error("excessive length %llu for symbol, possible recursive expansion?", cast(ulong)(buf.length + len)); + else + { + buf.print(len); + buf.writestring(id); + } +} + + +/***** + * There can be multiple different declarations in the same + * function that have the same mangled name. + * This results in localNum having a non-zero number, which + * is used to add a fake parent of the form `__Sddd` to make + * the mangled names unique. + * https://issues.dlang.org/show_bug.cgi?id=20565 + * Params: + * buf = buffer to write to + * localNum = local symbol number + */ +private +void writeLocalParent(OutBuffer* buf, uint localNum) +{ + uint ndigits = 1; + auto n = localNum; + while (n >= 10) + { + n /= 10; + ++ndigits; + } + buf.printf("%u__S%u", ndigits + 3, localNum); +} + +/************************* + * Write real to buffer. + * Params: + * buf = buffer to write to + * value = real to write + */ +private +void realToMangleBuffer(OutBuffer* buf, real_t value) +{ + /* Rely on %A to get portable mangling. + * Must munge result to get only identifier characters. + * + * Possible values from %A => mangled result + * NAN => NAN + * -INF => NINF + * INF => INF + * -0X1.1BC18BA997B95P+79 => N11BC18BA997B95P79 + * 0X1.9P+2 => 19P2 + */ + if (CTFloat.isNaN(value)) + { + buf.writestring("NAN"); // no -NAN bugs + return; + } + + if (value < CTFloat.zero) + { + buf.writeByte('N'); + value = -value; + } + + if (CTFloat.isInfinity(value)) + { + buf.writestring("INF"); + return; + } + + char[36] buffer = void; + // 'A' format yields [-]0xh.hhhhp+-d + const n = CTFloat.sprint(buffer.ptr, 'A', value); + assert(n < buffer.length); + foreach (const c; buffer[2 .. n]) + { + switch (c) + { + case '-': + buf.writeByte('N'); + break; + + case '+': + case '.': + break; + + default: + buf.writeByte(c); + break; + } + } +} + +/************************************************************ + * Try to obtain an externally mangled identifier from a declaration. + * If the declaration is at global scope or mixed in at global scope, + * the user might want to call it externally, so an externally mangled + * name is returned. Member functions or nested functions can't be called + * externally in C, so in that case null is returned. C++ does support + * namespaces, so extern(C++) always gives a C++ mangled name. + * + * See also: https://issues.dlang.org/show_bug.cgi?id=20012 + * + * Params: + * d = declaration to mangle + * + * Returns: + * an externally mangled name or null if the declaration cannot be called externally + */ +private +extern (D) const(char)[] externallyMangledIdentifier(Declaration d) +{ + const par = d.toParent(); //toParent() skips over mixin templates + if (!par || par.isModule() || d.linkage == LINK.cpp || + (d.linkage == LINK.c && d.isCsymbol() && d.isFuncDeclaration())) + { + if (d.linkage != LINK.d && d.localNum) + d.error("the same declaration cannot be in multiple scopes with non-D linkage"); + final switch (d.linkage) + { + case LINK.d: + break; + case LINK.c: + case LINK.windows: + case LINK.objc: + return d.ident.toString(); + case LINK.cpp: + { + const p = target.cpp.toMangle(d); + return p.toDString(); + } + case LINK.default_: + case LINK.system: + d.error("forward declaration"); + return d.ident.toString(); + } + } + return null; +} + + diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 84e29fe..6568442 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -615,6 +615,14 @@ extern (C++) final class Module : Package const dmdConfFile = global.inifilename.length ? FileName.canonicalName(global.inifilename) : "not found"; errorSupplemental(loc, "config file: %.*s", cast(int)dmdConfFile.length, dmdConfFile.ptr); } + else if (FileName.ext(this.arg) || !loc.isValid()) + { + // Modules whose original argument name has an extension, or do not + // have a valid location come from the command-line. + // Error that their file cannot be found and return early. + .error(loc, "cannot find input file `%s`", srcfile.toChars()); + return false; + } else { // if module is not named 'package' but we're trying to read 'package.d', we're looking for a package module diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 8ad0178..ef25717 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -464,8 +464,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor //printf("sc.stc = %x\n", sc.stc); //printf("storage_class = x%x\n", storage_class); - if (global.params.vcomplex) - dsym.type.checkComplexTransition(dsym.loc, sc); + dsym.type.checkComplexTransition(dsym.loc, sc); // Calculate type size + safety checks if (sc.func && !sc.intypeof) diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 0320f66..6692fb9 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -3285,8 +3285,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else assert(0); - if (global.params.vcomplex) - exp.type.checkComplexTransition(exp.loc, sc); + exp.type.checkComplexTransition(exp.loc, sc); result = e; } @@ -5375,8 +5374,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } - if (global.params.vcomplex) - ta.checkComplexTransition(exp.loc, sc); + ta.checkComplexTransition(exp.loc, sc); Expression e; auto tb = ta.toBasetype(); diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d index 0ca756e..7e0f404 100644 --- a/gcc/d/dmd/file_manager.d +++ b/gcc/d/dmd/file_manager.d @@ -185,11 +185,7 @@ nothrow: if (res == 1) return readToFileBuffer(name); - const fullName = lookForSourceFile(name, global.path ? (*global.path)[] : null); - if (!fullName) - return null; - - return readToFileBuffer(fullName); + return null; } extern(C++) FileBuffer* lookup(const(char)* filename) diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index 39cb845..afc0ebb 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -549,9 +549,22 @@ extern (C++) class FuncDeclaration : Declaration if (thandle.ty == Tstruct) { vthis.storage_class |= STC.ref_; - // if member function is marked 'inout', then 'this' is 'return ref' - if (type.ty == Tfunction && (cast(TypeFunction)type).isInOutQual()) - vthis.storage_class |= STC.return_; + + /* if member function is marked 'inout', then 'this' is 'return ref' + * The same thing is done for `ref inout` parameters in TypeFunction's semantic routine. + */ + if (auto tf = type.isTypeFunction()) + { + /* This feature was a mistake, but existing code relies on it. + * So only disable it in @safe code and DIP1000 code + */ + if (!(global.params.useDIP1000 == FeatureState.enabled && + tf.trust == TRUST.safe)) + { + if (tf.isInOutQual()) + vthis.storage_class |= STC.return_; + } + } } } diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 7c8b504..6377e9c 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -60,7 +60,11 @@ class Lexer bool Ccompile; /// true if compiling ImportC // The following are valid only if (Ccompile == true) + ubyte boolsize; /// size of a C _Bool, default 1 + ubyte shortsize; /// size of a C short, default 2 + ubyte intsize; /// size of a C int, default 4 ubyte longsize; /// size of C long, 4 or 8 + ubyte long_longsize; /// size of a C long long, default 8 ubyte long_doublesize; /// size of C long double, 8 or D real.sizeof ubyte wchar_tsize; /// size of C wchar_t, 2 or 4 @@ -2312,7 +2316,7 @@ class Lexer case FLAGS.decimal | FLAGS.long_: /* First that fits: long, long long */ - if (longsize == 4) + if (longsize == 4 || long_longsize == 4) { if (n & 0xFFFFFFFF_80000000L) result = TOK.int64Literal; @@ -2329,7 +2333,7 @@ class Lexer /* First that fits: long, unsigned long, long long, * unsigned long long */ - if (longsize == 4) + if (longsize == 4 || long_longsize == 4) { if (n & 0x8000000000000000L) result = TOK.uns64Literal; @@ -2353,7 +2357,7 @@ class Lexer case FLAGS.decimal | FLAGS.unsigned | FLAGS.long_: /* First that fits: unsigned long, unsigned long long */ - if (longsize == 4) + if (longsize == 4 || long_longsize == 4) { if (n & 0xFFFFFFFF00000000L) result = TOK.uns64Literal; @@ -2710,6 +2714,8 @@ class Lexer case '2': case '3': case '4': + if (!linemarker) + goto Lerr; flags = true; // linemarker flags seen ++p; if ('0' <= *p && *p <= '9') diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 2897877..9297ad9 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -648,7 +648,15 @@ extern (C++) abstract class Type : ASTNode goto Lcovariant; } else if (t1n.ty == t2n.ty && t1n.implicitConvTo(t2n)) + { + if (t1.isref && t2.isref) + { + // Treat like pointers to t1n and t2n + if (t1n.constConv(t2n) < MATCH.constant) + goto Lnotcovariant; + } goto Lcovariant; + } else if (t1n.ty == Tnull) { // NULL is covariant with any pointer type, but not with any diff --git a/gcc/d/dmd/root/file.d b/gcc/d/dmd/root/file.d index 6331a62..1f33c18 100644 --- a/gcc/d/dmd/root/file.d +++ b/gcc/d/dmd/root/file.d @@ -97,13 +97,13 @@ nothrow: int fd = name.toCStringThen!(slice => open(slice.ptr, O_RDONLY)); if (fd == -1) { - //printf("\topen error, errno = %d\n",errno); + //perror("\topen error"); return result; } //printf("\tfile opened\n"); if (fstat(fd, &buf)) { - perror("\tfstat error"); + //perror("\tfstat error"); close(fd); return result; } @@ -112,12 +112,12 @@ nothrow: numread = .read(fd, buffer, size); if (numread != size) { - perror("\tread error"); + //perror("\tread error"); goto err2; } if (close(fd) == -1) { - perror("\tclose error"); + //perror("\tclose error"); goto err; } // Always store a wchar ^Z past end of buffer so scanner has a @@ -289,3 +289,35 @@ nothrow: } } +private +{ + version (linux) version (PPC) + { + // https://issues.dlang.org/show_bug.cgi?id=22823 + // Define our own version of stat_t, as older versions of the compiler + // had the st_size field at the wrong offset on PPC. + alias stat_t_imported = core.sys.posix.sys.stat.stat_t; + static if (stat_t_imported.st_size.offsetof != 48) + { + extern (C) nothrow @nogc: + struct stat_t + { + ulong[6] __pad1; + ulong st_size; + ulong[6] __pad2; + } + version (CRuntime_Glibc) + { + int fstat64(int, stat_t*) @trusted; + alias fstat = fstat64; + int stat64(const scope char*, stat_t*) @system; + alias stat = stat64; + } + else + { + int fstat(int, stat_t*) @trusted; + int stat(const scope char*, stat_t*) @system; + } + } + } +} diff --git a/gcc/d/dmd/root/speller.d b/gcc/d/dmd/root/speller.d index b3e59f5..9b9460d 100644 --- a/gcc/d/dmd/root/speller.d +++ b/gcc/d/dmd/root/speller.d @@ -42,6 +42,7 @@ private: import core.stdc.stdlib; import core.stdc.string; +import dmd.common.string : SmallBuffer; enum isSearchFunction(alias fun) = is(searchFunctionType!fun); alias searchFunctionType(alias fun) = typeof(() {int x; return fun("", x);}()); @@ -63,15 +64,8 @@ auto spellerX(alias dg)(const(char)[] seed, bool flag) /* Need buffer to store trial strings in */ char[30] tmp = void; - char[] buf; - if (seed.length <= tmp.sizeof - 1) - buf = tmp; - else - { - buf = (cast(char*)alloca(seed.length + 1))[0 .. seed.length + 1]; // leave space for extra char - if (!buf.ptr) - return null; // no matches - } + auto sb = SmallBuffer!char(seed.length + 1, tmp[]); + char[] buf = sb[]; int cost = int.max; searchFunctionType!dg p = null; @@ -164,15 +158,8 @@ auto spellerY(alias dg)(const(char)[] seed, size_t index, out int cost) * space for an extra char for insertions */ char[30] tmp = void; // stack allocations are fastest - char[] buf; - if (seed.length <= tmp.sizeof - 1) - buf = tmp; - else - { - buf = (cast(char*)alloca(seed.length + 1))[0 .. seed.length + 1]; // leave space for extra char - if (!buf.ptr) - return null; // no matches - } + auto sb = SmallBuffer!char(seed.length + 1, tmp[]); + char[] buf = sb[]; buf[0 .. index] = seed[0 .. index]; cost = int.max; // start with worst possible match diff --git a/gcc/d/dmd/root/string.d b/gcc/d/dmd/root/string.d index 0c7cad0..ec62292 100644 --- a/gcc/d/dmd/root/string.d +++ b/gcc/d/dmd/root/string.d @@ -69,17 +69,12 @@ The return value of `T` auto toCStringThen(alias dg)(const(char)[] src) nothrow { import dmd.root.rmem : mem; + import dmd.common.string : SmallBuffer; const len = src.length + 1; char[512] small = void; - scope ptr = (src.length < (small.length - 1)) - ? small[0 .. len] - : (cast(char*)mem.xmalloc(len))[0 .. len]; - scope (exit) - { - if (&ptr[0] != &small[0]) - mem.xfree(&ptr[0]); - } + auto sb = SmallBuffer!char(len, small[]); + scope ptr = sb[]; ptr[0 .. src.length] = src[]; ptr[src.length] = '\0'; return dg(ptr); diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index 3f01966..b706777 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -468,7 +468,7 @@ private extern(C++) final class Semantic3Visitor : Visitor { stc |= STC.variadic; auto vtypeb = vtype.toBasetype(); - if (vtypeb.ty == Tarray) + if (vtypeb.ty == Tarray || vtypeb.ty == Tclass) { /* Since it'll be pointing into the stack for the array * contents, it needs to be `scope` @@ -620,7 +620,7 @@ private extern(C++) final class Semantic3Visitor : Visitor funcdecl.checkDmain(); // Check main() parameters and return type } - if (global.params.vcomplex && f.next !is null) + if (f.next !is null) f.next.checkComplexTransition(funcdecl.loc, sc); if (funcdecl.returns && !funcdecl.fbody.isErrorStatement()) @@ -1292,17 +1292,13 @@ private extern(C++) final class Semantic3Visitor : Visitor // Eliminate maybescope's { // Create and fill array[] with maybe candidates from the `this` and the parameters - VarDeclaration[] array = void; - VarDeclaration[10] tmp = void; size_t dim = (funcdecl.vthis !is null) + (funcdecl.parameters ? funcdecl.parameters.dim : 0); - if (dim <= tmp.length) - array = tmp[0 .. dim]; - else - { - auto ptr = cast(VarDeclaration*)mem.xmalloc(dim * VarDeclaration.sizeof); - array = ptr[0 .. dim]; - } + + import dmd.common.string : SmallBuffer; + auto sb = SmallBuffer!VarDeclaration(dim, tmp[]); + VarDeclaration[] array = sb[]; + size_t n = 0; if (funcdecl.vthis) array[n++] = funcdecl.vthis; @@ -1313,11 +1309,7 @@ private extern(C++) final class Semantic3Visitor : Visitor array[n++] = v; } } - eliminateMaybeScopes(array[0 .. n]); - - if (dim > tmp.length) - mem.xfree(array.ptr); } // Infer STC.scope_ diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d index e954625..7b9c454 100644 --- a/gcc/d/dmd/target.d +++ b/gcc/d/dmd/target.d @@ -331,7 +331,11 @@ struct TargetC Gcc_Clang, /// gcc and clang } bool crtDestructorsSupported = true; /// Not all platforms support crt_destructor + ubyte boolsize; /// size of a C `_Bool` type + ubyte shortsize; /// size of a C `short` or `unsigned short` type + ubyte intsize; /// size of a C `int` or `unsigned int` type ubyte longsize; /// size of a C `long` or `unsigned long` type + ubyte long_longsize; /// size of a C `long long` or `unsigned long long` type ubyte long_doublesize; /// size of a C `long double` ubyte wchar_tsize; /// size of a C `wchar_t` type Runtime runtime; /// vendor of the C runtime to link against diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index fdae14c..f3d3859 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -70,7 +70,11 @@ struct TargetC }; uint8_t crtDestructorsSupported; // Not all platforms support crt_destructor + uint8_t boolsize; // size of a C '_Bool' type + uint8_t shortsize; // size of a C 'short' or 'unsigned short' type + uint8_t intsize; // size of a C 'int' or 'unsigned int' type uint8_t longsize; // size of a C 'long' or 'unsigned long' type + uint8_t long_longsize; // size of a C 'long long' or 'unsigned long long' type uint8_t long_doublesize; // size of a C 'long double' uint8_t wchar_tsize; // size of a C 'wchar_t' type Runtime runtime; diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index a9f5028..c23e0fb 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -67,7 +67,7 @@ enum class TOK : unsigned char comment, // Operators - lessThan, // 54 + lessThan, greaterThan, lessOrEqual, greaterOrEqual, @@ -77,7 +77,7 @@ enum class TOK : unsigned char notIdentity, is_, - leftShift, // 64 + leftShift, rightShift, leftShiftAssign, rightShiftAssign, @@ -112,7 +112,7 @@ enum class TOK : unsigned char orOr, // Numeric literals - int32Literal, // 104, + int32Literal, uns32Literal, int64Literal, uns64Literal, @@ -126,12 +126,12 @@ enum class TOK : unsigned char imaginary80Literal, // Char constants - charLiteral, // 116, + charLiteral, wcharLiteral, dcharLiteral, // Leaf operators - identifier, // 119, + identifier, string_, hexadecimalString, this_, @@ -139,7 +139,7 @@ enum class TOK : unsigned char error, // Basic types - void_, // 127 + void_, int8, uns8, int16, @@ -165,7 +165,7 @@ enum class TOK : unsigned char bool_, // Aggregates - struct_, // 151 + struct_, class_, interface_, union_, @@ -197,7 +197,7 @@ enum class TOK : unsigned char immutable_, // Statements - if_, // 181 + if_, else_, while_, for_, @@ -223,7 +223,7 @@ enum class TOK : unsigned char onScopeSuccess, // Contracts - invariant_, // 205 + invariant_, // Testing unittest_, @@ -233,7 +233,7 @@ enum class TOK : unsigned char ref_, macro_, - parameters, // 210 + parameters, traits, pure_, nothrow_, diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index ec86bc5..6160251 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -568,11 +568,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } if (e.ident == Id.isDeprecated) { - if (global.params.vcomplex) - { - if (isTypeX(t => t.iscomplex() || t.isimaginary()).toBool().hasValue(true)) - return True(); - } + if (isTypeX(t => t.iscomplex() || t.isimaginary()).toBool().hasValue(true)) + return True(); return isDsymX(t => t.isDeprecated()); } if (e.ident == Id.isFuture) diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index 637b32e..1f03836 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -1151,7 +1151,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) return mtype; } //printf("TypeFunction::semantic() this = %p\n", this); - //printf("TypeFunction::semantic() %s, sc.stc = %llx, fargs = %p\n", toChars(), sc.stc, fargs); + //printf("TypeFunction::semantic() %s, sc.stc = %llx\n", mtype.toChars(), sc.stc); bool errors = false; @@ -1458,6 +1458,17 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc) fparam.storageClass &= ~STC.return_; // https://issues.dlang.org/show_bug.cgi?id=18963 } } + + if (i + 1 == dim && tf.parameterList.varargs == VarArg.typesafe && + (t.isTypeDArray() || t.isTypeClass())) + { + /* This is because they can be constructed on the stack + * https://dlang.org/spec/function.html#typesafe_variadic_functions + */ + .error(loc, "typesafe variadic function parameter `%s` of type `%s` cannot be marked `return`", + fparam.ident ? fparam.ident.toChars() : "", t.toChars()); + errors = true; + } } if (fparam.storageClass & STC.out_) diff --git a/gcc/testsuite/gdc.dg/simd18489.d b/gcc/testsuite/gdc.dg/simd18489.d new file mode 100644 index 0000000..4591f68 --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd18489.d @@ -0,0 +1,8 @@ +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +double dot (double2 a) { + return a.ptr[0] * a.ptr[1]; +} diff --git a/gcc/testsuite/gdc.test/runnable/ice21727.d b/gcc/testsuite/gdc.dg/torture/simd21727.d index 5b5745f..d277f53 100644 --- a/gcc/testsuite/gdc.test/runnable/ice21727.d +++ b/gcc/testsuite/gdc.dg/torture/simd21727.d @@ -1,7 +1,7 @@ -// REQUIRED_ARGS: -m64 -O -inline -// DISABLED: win32 linux32 freebsd32 osx32 netbsd32 dragonflybsd32 // https://issues.dlang.org/show_bug.cgi?id=21727 - +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } import core.simd; @nogc nothrow pure @safe: @@ -25,10 +25,7 @@ pragma(inline, false) Float4 identity(Float4 a) pragma(inline, true) Float4 twoTimes(const ref Float4 a) { - version (D_SIMD) - return Float4(cast(float4) __simd(XMM.ADDPS, a.mVector, a.mVector)); - else // Allow non-DMD compilers to compile this test. - return Float4(a.mVector + a.mVector); + return Float4(a.mVector + a.mVector); } pragma(inline, false) Float4 fourTimes(const Float4 a) diff --git a/gcc/testsuite/gdc.dg/torture/simd7413a.d b/gcc/testsuite/gdc.dg/torture/simd7413a.d index 13bd69a..38c9924 100644 --- a/gcc/testsuite/gdc.dg/torture/simd7413a.d +++ b/gcc/testsuite/gdc.dg/torture/simd7413a.d @@ -2,7 +2,6 @@ // { dg-additional-options "-mavx" { target avx_runtime } } // { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } // { dg-skip-if "needs gcc/config.d" { ! d_runtime } } -// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } import core.simd; void main() diff --git a/gcc/testsuite/gdc.dg/ubsan/pr88957.d b/gcc/testsuite/gdc.dg/ubsan/pr88957.d index e6366d4..23433d5 100644 --- a/gcc/testsuite/gdc.dg/ubsan/pr88957.d +++ b/gcc/testsuite/gdc.dg/ubsan/pr88957.d @@ -1,5 +1,6 @@ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88957 -// { dg-do compile } +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } // { dg-additional-options "-fsanitize=undefined" } alias int4 = __vector(int[4]); diff --git a/gcc/testsuite/gdc.test/compilable/b18489.d b/gcc/testsuite/gdc.test/compilable/b18489.d deleted file mode 100644 index 2cc386f..0000000 --- a/gcc/testsuite/gdc.test/compilable/b18489.d +++ /dev/null @@ -1,8 +0,0 @@ -// REQUIRED_ARGS: -O -m64 -import core.simd; - -double dot (double2 a) { - return a.ptr[0] * a.ptr[1]; -} - -void main () { } diff --git a/gcc/testsuite/gdc.test/compilable/issue21390.d b/gcc/testsuite/gdc.test/compilable/issue21390.d new file mode 100644 index 0000000..a553632 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/issue21390.d @@ -0,0 +1,3 @@ +struct S { @disable this(); } +// Does not compile: "default construction is disabled for type `S`" +extern __gshared S gVariable1; diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17927.d b/gcc/testsuite/gdc.test/fail_compilation/fail17927.d index 348d473..5f371da 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail17927.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail17927.d @@ -2,11 +2,11 @@ * TEST_OUTPUT: --- fail_compilation/fail17927.d(13): Error: scope variable `this` may not be returned +fail_compilation/fail17927.d(15): Error: scope variable `this` may not be returned fail_compilation/fail17927.d(21): Error: scope variable `ptr` may not be returned fail_compilation/fail17927.d(23): Error: scope variable `ptr` may not be returned --- */ - // https://issues.dlang.org/show_bug.cgi?id=17927 struct String { diff --git a/gcc/testsuite/gdc.test/fail_compilation/fix17751.d b/gcc/testsuite/gdc.test/fail_compilation/fix17751.d deleted file mode 100644 index 11b9c54..0000000 --- a/gcc/testsuite/gdc.test/fail_compilation/fix17751.d +++ /dev/null @@ -1,22 +0,0 @@ -/* REQUIRED_ARGS: -m64 - * TEST_OUTPUT: ---- -fail_compilation/fix17751.d(15): Error: last parameter to `__simd()` must be a constant ---- - */ - -// https://issues.dlang.org/show_bug.cgi?id=17751 - -import core.simd; - -pure @safe V1 simd(XMM opcode, V1, V2)(V1 op1, V2 op2, ubyte imm8) - if (is(V1 == __vector) && is(V2 == __vector)) -{ - return cast(V1)__simd(opcode, op1, op2, imm8); -} - -void main() -{ - float4 a, b; - a = simd!(XMM.CMPPD)(a, b, 0x7A); -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue22826.d b/gcc/testsuite/gdc.test/fail_compilation/issue22826.d new file mode 100644 index 0000000..ee1802a --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/issue22826.d @@ -0,0 +1,7 @@ +/* TEST_OUTPUT: +--- +fail_compilation/issue22826.d(7): Error: #line integer ["filespec"]\n expected +fail_compilation/issue22826.d(7): Error: declaration expected, not `3` +--- +*/ +#line 12 "issue22826.d" 3 diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21546.d b/gcc/testsuite/gdc.test/fail_compilation/test21546.d new file mode 100644 index 0000000..22565e4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test21546.d @@ -0,0 +1,59 @@ +/* TEST_OUTPUT: +--- +fail_compilation/test21546.d(113): Error: cannot implicitly convert expression `pc` of type `const(int)* delegate() return` to `int* delegate() return` +fail_compilation/test21546.d(114): Error: cannot implicitly convert expression `pc` of type `const(int)* delegate() return` to `immutable(int)* delegate() return` +fail_compilation/test21546.d(115): Error: cannot implicitly convert expression `pi` of type `immutable(int)* delegate() return` to `int* delegate() return` +fail_compilation/test21546.d(213): Error: cannot implicitly convert expression `dc` of type `const(int) delegate() ref return` to `int delegate() ref return` +fail_compilation/test21546.d(214): Error: cannot implicitly convert expression `dc` of type `const(int) delegate() ref return` to `immutable(int) delegate() ref return` +fail_compilation/test21546.d(215): Error: cannot implicitly convert expression `di` of type `immutable(int) delegate() ref return` to `int delegate() ref return` +fail_compilation/test21546.d(305): Error: cannot implicitly convert expression `[dgi]` of type `immutable(int) delegate() ref return[]` to `int delegate() ref return[]` +--- + */ +// https://issues.dlang.org/show_bug.cgi?id=21546 + +#line 100 + +alias Pm = int* delegate() return; +alias Pc = const(int)* delegate() return; +alias Pi = immutable(int)* delegate() return; + +void f() +{ + Pm pm; + Pc pc; + Pi pi; + pc = pm; + pc = pi; + + pm = pc; + pi = pc; + pm = pi; +} + +#line 200 + +alias DGm = ref int delegate() return; +alias DGc = ref const(int) delegate() return; +alias DGi = ref immutable(int) delegate() return; + +void g() +{ + DGm dm; + DGc dc; + DGi di; + dc = dm; + dc = di; + + dm = dc; + di = dc; + dm = di; +} + +#line 300 + +void h() +{ + immutable int i = 0; + DGi dgi = ref() => i; + DGm[] dgms = [ dgi ]; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22023.d b/gcc/testsuite/gdc.test/fail_compilation/test22023.d new file mode 100644 index 0000000..a0f553b --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test22023.d @@ -0,0 +1,26 @@ +/* TEST_OUTPUT: +--- +fail_compilation/test22023.d(102): Error: typesafe variadic function parameter `a` of type `int[]` cannot be marked `return` +fail_compilation/test22023.d(107): Error: typesafe variadic function parameter `c` of type `test22023.C` cannot be marked `return` +--- +*/ + +// issues.dlang.org/show_bug.cgi?id=22023 + +#line 100 + +@safe: +ref int f(return int[] a ...) +{ + return a[2]; +} + +ref int g(return C c ...) +{ + return c.x; +} + +class C +{ + int x; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22818.d b/gcc/testsuite/gdc.test/fail_compilation/test22818.d new file mode 100644 index 0000000..ae96b3b --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test22818.d @@ -0,0 +1,21 @@ +/* REQUIRED_ARGS: -preview=dip1000 + * TEST_OUTPUT: +--- +fail_compilation/test22818.d(104): Error: scope variable `c` may not be returned +--- +*/ + +// issues.dlang.org/show_bug.cgi?id=22818 + +#line 100 + +@safe: +ref int g(C c ...) +{ + return c.x; +} + +class C +{ + int x; +} diff --git a/gcc/testsuite/gdc.test/runnable/nan.d b/gcc/testsuite/gdc.test/runnable/nan.d index d4e4ae4..9b97699 100644 --- a/gcc/testsuite/gdc.test/runnable/nan.d +++ b/gcc/testsuite/gdc.test/runnable/nan.d @@ -45,15 +45,26 @@ void test2(T)() assert(a is c); static if (T.mant_dig == 64 && T.max_exp == 16384) + { enum size = 10; // x87, exclude padding + enum mant_dig = T.mant_dig; + } + else static if (T.mant_dig == 106) + { + enum size = 8; // IBM, only look at first index + enum mant_dig = 53; + } else + { enum size = T.sizeof; + enum mant_dig = T.mant_dig; + } const pa = (cast(ubyte*) &a)[0 .. size]; // the highest 2 bits of the mantissa should be set, everything else zero - assert(bittst(pa, T.mant_dig - 1)); - assert(bittst(pa, T.mant_dig - 2)); - foreach(p; 0..T.mant_dig - 2) + assert(bittst(pa, mant_dig - 1)); + assert(bittst(pa, mant_dig - 2)); + foreach(p; 0..mant_dig - 2) assert(!bittst(pa, p)); } diff --git a/gcc/testsuite/gdc.test/runnable/previewin.d b/gcc/testsuite/gdc.test/runnable/previewin.d index 12a0551..117070df 100644 --- a/gcc/testsuite/gdc.test/runnable/previewin.d +++ b/gcc/testsuite/gdc.test/runnable/previewin.d @@ -157,10 +157,10 @@ struct WithDtor void testin1(in uint p) { static assert(!__traits(isRef, p)); } // By ref because of size void testin2(in ulong[64] p) { static assert(__traits(isRef, p)); } -// By value or ref depending on size -void testin3(in ValueT p) { static assert(!__traits(isRef, p)); } +// By value or ref depending on size (or structs always passed by reference) +void testin3(in ValueT p) { static assert(!__traits(isRef, p) || true); } void testin3(in RefT p) { static assert(__traits(isRef, p)); } -// By ref because of size +// By ref because of size (or arrays always passed by reference) void testin4(in ValueT[64] p) { static assert(__traits(isRef, p)); } void testin4(in RefT[4] p) { static assert(__traits(isRef, p)); } diff --git a/gcc/testsuite/gdc.test/runnable/sroa13220.d b/gcc/testsuite/gdc.test/runnable/sroa13220.d deleted file mode 100644 index 2cec666..0000000 --- a/gcc/testsuite/gdc.test/runnable/sroa13220.d +++ /dev/null @@ -1,103 +0,0 @@ -/* REQUIRED_ARGS: -O -inline -noboundscheck - */ -// https://github.com/dlang/pull/13220 - -version (D_SIMD) -{ - -mixin template VectorOps(VectorType, ArrayType: BaseType[N], BaseType, size_t N) -{ - enum Count = N; - alias Base = BaseType; - - BaseType* ptr() return pure nothrow @nogc - { - return array.ptr; - } - - // Unary operators - VectorType opUnary(string op)() pure nothrow @safe @nogc - { - VectorType res = void; - mixin("res.array[] = " ~ op ~ "array[];"); - return res; - } - - // Binary operators - VectorType opBinary(string op)(VectorType other) pure const nothrow @safe @nogc - { - VectorType res = void; - mixin("res.array[] = array[] " ~ op ~ " other.array[];"); - return res; - } - - // Assigning a BaseType value - void opAssign(BaseType e) pure nothrow @safe @nogc - { - array[] = e; - } - - // Assigning a static array - void opAssign(ArrayType v) pure nothrow @safe @nogc - { - array[] = v[]; - } - - void opOpAssign(string op)(VectorType other) pure nothrow @safe @nogc - { - mixin("array[] " ~ op ~ "= other.array[];"); - } - - // Assigning a dyn array - this(ArrayType v) pure nothrow @safe @nogc - { - array[] = v[]; - } - - // Broadcast constructor - this(BaseType x) pure nothrow @safe @nogc - { - array[] = x; - } - - ref inout(BaseType) opIndex(size_t i) inout pure nothrow @safe @nogc - { - return array[i]; - } -} - -// Note: can't be @safe with this signature -Vec loadUnaligned(Vec)(const(BaseType!Vec)* pvec) @trusted -{ - // Since this vector is emulated, it doesn't have alignement constraints - // and as such we can just cast it. - return *cast(Vec*)(pvec); -} - -private template BaseType(V) -{ - alias typeof( ( { V v; return v; }()).array[0]) BaseType; -} - -struct int4 -{ - int[4] array; - mixin VectorOps!(int4, int[4]); -} - -alias __m128i = int4; -} - -int main() -{ - version (D_SIMD) - { - int4 A = [1, 2, 3, 4]; - int4 ia = A; - ia.ptr[2] = 5; - int4 C = ia; - int[4] result = [1, 2, 5, 4]; - assert(C.array == result); - } - return 0; -} diff --git a/gcc/testsuite/gdc.test/runnable/test15.d b/gcc/testsuite/gdc.test/runnable/test15.d index 70e3a82..b4acc23 100644 --- a/gcc/testsuite/gdc.test/runnable/test15.d +++ b/gcc/testsuite/gdc.test/runnable/test15.d @@ -1425,7 +1425,7 @@ void test19758() int[2] array = [16, 678]; union U { int i; bool b; } U u; - u.i = 0xDEADBEEF; + u.i = 0xBFBFBFBF; assert(array[u.b] == 678); } diff --git a/gcc/testsuite/gdc.test/runnable/testconst.d b/gcc/testsuite/gdc.test/runnable/testconst.d index 502dca0..191ddad 100644 --- a/gcc/testsuite/gdc.test/runnable/testconst.d +++ b/gcc/testsuite/gdc.test/runnable/testconst.d @@ -1623,7 +1623,7 @@ struct S3748 const int z = 6; C3748 c; - inout(int)* getX() inout + inout(int)* getX() inout return { static assert(!__traits(compiles, { x = 4; @@ -3348,9 +3348,9 @@ struct S10758 { int x; inout(int) screwUpVal(ref inout(int) _) inout { return x; } - ref inout(int) screwUpRef(ref inout(int) _) inout { return x; } - inout(int)* screwUpPtr(ref inout(int) _) inout { return &x; } - inout(int)[] screwUpArr(ref inout(int) _) inout { return (&x)[0 .. 1]; } + ref inout(int) screwUpRef(ref inout(int) _) inout return { return x; } + inout(int)* screwUpPtr(ref inout(int) _) inout return { return &x; } + inout(int)[] screwUpArr(ref inout(int) _) inout return { return (&x)[0 .. 1]; } } void test10758(ref inout(int) wx, inout(int)* wp, inout(int)[] wa, inout(S10758) ws) @@ -3497,14 +3497,14 @@ inout(int)* delegate(inout(int)*) nest10761(inout(int)* x) struct S10761 { int x; - inout(int)* screwUp() inout { return &x; } + inout(int)* screwUp() inout return { return &x; } } -inout(int)* delegate() inout memfn10761(inout(int)* x) +inout(int)* delegate() inout return memfn10761(inout(int)* x) { auto s = new inout S10761(1); auto dg = &s.screwUp; - static assert(is(typeof(dg) == inout(int)* delegate() inout)); + static assert(is(typeof(dg) == inout(int)* delegate() inout return)); return dg; } @@ -3542,7 +3542,7 @@ void test10761() auto dg_m = memfn10761(&mx); auto dg_c = memfn10761(&cx); auto dg_i = memfn10761(&ix); - alias DG = const(int)* delegate() const; + alias DG = const(int)* delegate() return const; static assert(is(typeof(dg_m) == DG)); static assert(is(typeof(dg_c) == DG)); static assert(is(typeof(dg_i) == DG)); diff --git a/gcc/testsuite/gdc.test/runnable/testscope2.d b/gcc/testsuite/gdc.test/runnable/testscope2.d index 1b8cf29..4de1eba 100644 --- a/gcc/testsuite/gdc.test/runnable/testscope2.d +++ b/gcc/testsuite/gdc.test/runnable/testscope2.d @@ -178,7 +178,7 @@ struct S10 { int x; - ref inout(int) foo() inout + ref inout(int) foo() inout return { return x; } diff --git a/gcc/testsuite/gdc.test/runnable/traits_getPointerBitmap.d b/gcc/testsuite/gdc.test/runnable/traits_getPointerBitmap.d index 3c5a4bd..8996c9e 100644 --- a/gcc/testsuite/gdc.test/runnable/traits_getPointerBitmap.d +++ b/gcc/testsuite/gdc.test/runnable/traits_getPointerBitmap.d @@ -213,7 +213,7 @@ void testRTInfo() testType!(fn) ([ 0b0 ]); testType!(S!fn) ([ 0b100 ]); testType!(NullType) ([ 0b0 ]); - version(D_LP64) + static if (__traits(compiles, __vector(float[4]))) testType!(__vector(float[4])) ([ 0b00 ]); testType!(Object[int]) ([ 0b1 ]); |