aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-02-28 15:47:52 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2022-02-28 17:49:01 +0100
commit1027dc459204894f4503f713a3d73826e4bbab15 (patch)
tree606564b15e0978c77c76d0e618c00c25a78aaf38 /gcc
parent430c89274d7f82810724126637ffdc5507d442f0 (diff)
downloadgcc-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')
-rw-r--r--gcc/d/d-target.cc9
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/common/outbuffer.d32
-rw-r--r--gcc/d/dmd/cparse.d66
-rw-r--r--gcc/d/dmd/cppmangle.d44
-rw-r--r--gcc/d/dmd/dmangle.d626
-rw-r--r--gcc/d/dmd/dmodule.d8
-rw-r--r--gcc/d/dmd/dsymbolsem.d3
-rw-r--r--gcc/d/dmd/expressionsem.d6
-rw-r--r--gcc/d/dmd/file_manager.d6
-rw-r--r--gcc/d/dmd/func.d19
-rw-r--r--gcc/d/dmd/lexer.d12
-rw-r--r--gcc/d/dmd/mtype.d8
-rw-r--r--gcc/d/dmd/root/file.d40
-rw-r--r--gcc/d/dmd/root/speller.d23
-rw-r--r--gcc/d/dmd/root/string.d11
-rw-r--r--gcc/d/dmd/semantic3.d22
-rw-r--r--gcc/d/dmd/target.d4
-rw-r--r--gcc/d/dmd/target.h4
-rw-r--r--gcc/d/dmd/tokens.h20
-rw-r--r--gcc/d/dmd/traits.d7
-rw-r--r--gcc/d/dmd/typesem.d13
-rw-r--r--gcc/testsuite/gdc.dg/simd18489.d8
-rw-r--r--gcc/testsuite/gdc.dg/torture/simd21727.d (renamed from gcc/testsuite/gdc.test/runnable/ice21727.d)11
-rw-r--r--gcc/testsuite/gdc.dg/torture/simd7413a.d1
-rw-r--r--gcc/testsuite/gdc.dg/ubsan/pr88957.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/b18489.d8
-rw-r--r--gcc/testsuite/gdc.test/compilable/issue21390.d3
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail17927.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fix17751.d22
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/issue22826.d7
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test21546.d59
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22023.d26
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test22818.d21
-rw-r--r--gcc/testsuite/gdc.test/runnable/nan.d17
-rw-r--r--gcc/testsuite/gdc.test/runnable/previewin.d6
-rw-r--r--gcc/testsuite/gdc.test/runnable/sroa13220.d103
-rw-r--r--gcc/testsuite/gdc.test/runnable/test15.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/testconst.d16
-rw-r--r--gcc/testsuite/gdc.test/runnable/testscope2.d2
-rw-r--r--gcc/testsuite/gdc.test/runnable/traits_getPointerBitmap.d2
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 ]);