public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4644] d: Merge upstream dmd, druntime f9efc98fd7, phobos a3f22129d.
@ 2023-10-15 11:12 Iain Buclaw
0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2023-10-15 11:12 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:ac908237bd551fb55f2f82736cb37038e9b91459
commit r14-4644-gac908237bd551fb55f2f82736cb37038e9b91459
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sun Oct 15 12:05:10 2023 +0200
d: Merge upstream dmd, druntime f9efc98fd7, phobos a3f22129d.
D front-end changes:
- Import dmd v2.105.2.
- A function with enum storage class is now deprecated.
- Global variables can now be initialized with Associative
Arrays.
- Improvements for the C++ header generation of static variables
used in a default argument context.
D runtime changes:
- Import druntime v2.105.2.
- The `core.memory.GC' functions `GC.enable', `GC.disable',
`GC.collect', and `GC.minimize' `have been marked `@safe'.
Phobos changes:
- Import phobos v2.105.2.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd f9efc98fd7.
* dmd/VERSION: Bump version to v2.105.2.
* d-builtins.cc (build_frontend_type): Update for new front-end
interface.
* d-diagnostic.cc (verrorReport): Don't emit tips when error gagging
is turned on.
* d-lang.cc (d_handle_option): Remove obsolete parameter.
(d_post_options): Likewise.
(d_read_ddoc_files): New function.
(d_generate_ddoc_file): New function.
(d_parse_file): Update for new front-end interface.
* expr.cc (ExprVisitor::visit (AssocArrayLiteralExp *)): Check for new
front-end lowering of static associative arrays.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime f9efc98fd7.
* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add
core/internal/newaa.d.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos a3f22129d.
* testsuite/libphobos.hash/test_hash.d: Update test.
* testsuite/libphobos.phobos/phobos.exp: Add compiler flags
-Wno-deprecated.
* testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise.
gcc/testsuite/ChangeLog:
* lib/gdc-utils.exp (gdc-convert-args): Handle new compiler options.
Diff:
---
gcc/d/d-builtins.cc | 3 +-
gcc/d/d-diagnostic.cc | 5 +-
gcc/d/d-lang.cc | 78 ++++-
gcc/d/dmd/MERGE | 2 +-
gcc/d/dmd/VERSION | 2 +-
gcc/d/dmd/attrib.d | 2 +-
gcc/d/dmd/blockexit.d | 107 +++---
gcc/d/dmd/canthrow.d | 2 +-
gcc/d/dmd/chkformat.d | 32 +-
gcc/d/dmd/clone.d | 20 +-
gcc/d/dmd/cond.d | 2 +-
gcc/d/dmd/cparse.d | 11 +-
gcc/d/dmd/cppmangle.d | 2 -
gcc/d/dmd/ctfeexpr.d | 6 +-
gcc/d/dmd/dcast.d | 13 +-
gcc/d/dmd/dclass.d | 6 +-
gcc/d/dmd/declaration.d | 7 +-
gcc/d/dmd/delegatize.d | 1 -
gcc/d/dmd/denum.d | 2 -
gcc/d/dmd/dinterpret.d | 14 +-
gcc/d/dmd/dmacro.d | 56 ++-
gcc/d/dmd/dmodule.d | 4 +-
gcc/d/dmd/doc.d | 353 +++++++++----------
gcc/d/dmd/doc.h | 3 +-
gcc/d/dmd/dscope.d | 1 +
gcc/d/dmd/dstruct.d | 1 +
gcc/d/dmd/dsymbol.d | 1 +
gcc/d/dmd/dsymbolsem.d | 58 +++-
gcc/d/dmd/dtemplate.d | 24 +-
gcc/d/dmd/dtoh.d | 10 +-
gcc/d/dmd/errors.h | 3 +-
gcc/d/dmd/errorsink.d | 1 +
gcc/d/dmd/escape.d | 40 ++-
gcc/d/dmd/expression.d | 47 +--
gcc/d/dmd/expression.h | 3 +-
gcc/d/dmd/expressionsem.d | 109 +++---
gcc/d/dmd/func.d | 21 +-
gcc/d/dmd/globals.d | 33 +-
gcc/d/dmd/globals.h | 35 +-
gcc/d/dmd/hdrgen.d | 375 +++++++++++----------
gcc/d/dmd/hdrgen.h | 4 +-
gcc/d/dmd/iasmgcc.d | 2 +-
gcc/d/dmd/id.d | 2 +
gcc/d/dmd/init.d | 2 +-
gcc/d/dmd/initsem.d | 31 +-
gcc/d/dmd/json.d | 23 +-
gcc/d/dmd/json.h | 2 +-
gcc/d/dmd/lexer.d | 88 ++++-
gcc/d/dmd/location.d | 20 +-
gcc/d/dmd/module.h | 2 +-
gcc/d/dmd/mtype.d | 55 ++-
gcc/d/dmd/mtype.h | 5 +-
gcc/d/dmd/opover.d | 8 +-
gcc/d/dmd/optimize.d | 28 +-
gcc/d/dmd/parse.d | 110 ++++--
gcc/d/dmd/printast.d | 2 +-
gcc/d/dmd/safe.d | 23 +-
gcc/d/dmd/semantic2.d | 53 +++
gcc/d/dmd/semantic3.d | 14 +-
gcc/d/dmd/statement.d | 117 +------
gcc/d/dmd/statement.h | 3 +-
gcc/d/dmd/statementsem.d | 293 ++++++++--------
gcc/d/dmd/tokens.d | 22 +-
gcc/d/dmd/tokens.h | 1 +
gcc/d/dmd/traits.d | 2 +-
gcc/d/dmd/typesem.d | 19 +-
gcc/d/dmd/utils.d | 24 +-
gcc/d/expr.cc | 9 +
.../gdc.test/compilable/dtoh_StructDeclaration.d | 15 +
gcc/testsuite/gdc.test/compilable/dtoh_functions.d | 4 +-
gcc/testsuite/gdc.test/compilable/issue22682.d | 8 +
gcc/testsuite/gdc.test/compilable/obsolete_body.d | 5 +
.../gdc.test/compilable/shortened_methods.d | 5 +
gcc/testsuite/gdc.test/compilable/test23145.d | 13 +-
gcc/testsuite/gdc.test/compilable/test24066.d | 11 +
gcc/testsuite/gdc.test/compilable/test24107.d | 17 +
gcc/testsuite/gdc.test/compilable/test24109.d | 17 +
gcc/testsuite/gdc.test/compilable/test24118.d | 15 +
gcc/testsuite/gdc.test/fail_compilation/aa_init.d | 16 +
gcc/testsuite/gdc.test/fail_compilation/body.d | 11 -
.../gdc.test/fail_compilation/chkformat.d | 2 +
.../gdc.test/fail_compilation/dephexstrings.d | 9 -
.../gdc.test/fail_compilation/diag10169.d | 3 +-
.../gdc.test/fail_compilation/diag10783.d | 5 +-
.../gdc.test/fail_compilation/diag12063.d | 42 ++-
.../gdc.test/fail_compilation/diag12829.d | 13 +-
.../gdc.test/fail_compilation/diag13609a.d | 7 +-
.../gdc.test/fail_compilation/diag14145.d | 9 +-
.../gdc.test/fail_compilation/diag15713.d | 9 +-
gcc/testsuite/gdc.test/fail_compilation/diag3913.d | 6 +-
gcc/testsuite/gdc.test/fail_compilation/diag5385.d | 24 +-
gcc/testsuite/gdc.test/fail_compilation/diag7477.d | 4 +-
gcc/testsuite/gdc.test/fail_compilation/diag8697.d | 3 +-
gcc/testsuite/gdc.test/fail_compilation/diag8894.d | 12 +-
.../fail_compilation/dip1000_deprecation.d | 19 +-
gcc/testsuite/gdc.test/fail_compilation/dip22a.d | 12 +-
.../gdc.test/fail_compilation/enum_function.d | 9 +-
.../gdc.test/fail_compilation/fail10528.d | 20 +-
.../gdc.test/fail_compilation/fail10534.d | 32 +-
gcc/testsuite/gdc.test/fail_compilation/fail109.d | 2 +-
gcc/testsuite/gdc.test/fail_compilation/fail121.d | 5 +-
gcc/testsuite/gdc.test/fail_compilation/fail136.d | 2 +-
.../gdc.test/fail_compilation/fail17570.d | 7 +-
.../gdc.test/fail_compilation/fail17969.d | 3 +-
.../gdc.test/fail_compilation/fail18219.d | 9 +-
.../gdc.test/fail_compilation/fail18892.d | 6 +-
.../gdc.test/fail_compilation/fail18970.d | 10 +-
.../gdc.test/fail_compilation/fail18979.d | 3 +-
gcc/testsuite/gdc.test/fail_compilation/fail1900.d | 6 +-
.../gdc.test/fail_compilation/fail19076.d | 5 +-
.../gdc.test/fail_compilation/fail19103.d | 8 +-
gcc/testsuite/gdc.test/fail_compilation/fail196.d | 49 +--
.../gdc.test/fail_compilation/fail20637.d | 3 +-
.../gdc.test/fail_compilation/fail22054.d | 10 +-
.../gdc.test/fail_compilation/fail22529.d | 2 +-
.../gdc.test/fail_compilation/fail23109.d | 2 +
gcc/testsuite/gdc.test/fail_compilation/fail61.d | 11 +-
gcc/testsuite/gdc.test/fail_compilation/fail7861.d | 3 +-
gcc/testsuite/gdc.test/fail_compilation/fail9.d | 3 +-
.../gdc.test/fail_compilation/fail_scope.d | 30 +-
.../gdc.test/fail_compilation/faildottypeinfo.d | 5 +-
.../gdc.test/fail_compilation/fnconstraint.d | 11 +-
.../gdc.test/fail_compilation/goto_skip.d | 57 ++++
gcc/testsuite/gdc.test/fail_compilation/ice10713.d | 3 +-
gcc/testsuite/gdc.test/fail_compilation/ice10938.d | 5 +-
gcc/testsuite/gdc.test/fail_compilation/ice11518.d | 6 +-
gcc/testsuite/gdc.test/fail_compilation/ice11982.d | 20 +-
gcc/testsuite/gdc.test/fail_compilation/ice8100.d | 7 +-
.../gdc.test/fail_compilation/issue12652.d | 24 --
.../gdc.test/fail_compilation/issue22682.d | 18 +
gcc/testsuite/gdc.test/fail_compilation/lexer1.d | 4 +-
gcc/testsuite/gdc.test/fail_compilation/lexer2.d | 8 +-
gcc/testsuite/gdc.test/fail_compilation/main.d | 9 +
.../gdc.test/fail_compilation/match_func_ptr.d | 17 +
.../fail_compilation/misc_parser_err_cov1.d | 3 +-
gcc/testsuite/gdc.test/fail_compilation/nogc3.d | 18 +-
.../gdc.test/fail_compilation/noreturn_expr.d | 16 +
.../gdc.test/fail_compilation/noreturn_expr2.d | 14 +
.../gdc.test/fail_compilation/operator_undefined.d | 20 ++
gcc/testsuite/gdc.test/fail_compilation/parseStc.d | 6 +-
gcc/testsuite/gdc.test/fail_compilation/retscope.d | 2 +-
gcc/testsuite/gdc.test/fail_compilation/skip.d | 6 +-
.../gdc.test/fail_compilation/switch_skip.d | 48 +++
gcc/testsuite/gdc.test/fail_compilation/switches.d | 68 +---
.../gdc.test/fail_compilation/test13536.d | 7 +-
.../gdc.test/fail_compilation/test15785.d | 5 +-
.../gdc.test/fail_compilation/test15897.d | 3 +-
.../gdc.test/fail_compilation/test16188.d | 1 +
.../gdc.test/fail_compilation/test16193.d | 5 +-
.../gdc.test/fail_compilation/test16365.d | 9 +-
.../gdc.test/fail_compilation/test17380spec.d | 7 +-
.../gdc.test/fail_compilation/test20655.d | 32 ++
.../gdc.test/fail_compilation/test21353.d | 13 +-
.../gdc.test/fail_compilation/test21912.d | 20 +-
.../gdc.test/fail_compilation/test22329.d | 3 +-
.../gdc.test/fail_compilation/test23112.d | 3 +-
.../gdc.test/fail_compilation/test24015.d | 20 ++
.../gdc.test/fail_compilation/test24036.d | 21 ++
.../gdc.test/fail_compilation/test24065.d | 18 +
.../gdc.test/fail_compilation/test24084.d | 28 ++
.../gdc.test/fail_compilation/test24110.d | 12 +
.../gdc.test/fail_compilation/testOpApply.d | 16 +-
gcc/testsuite/gdc.test/fail_compilation/testsemi.d | 3 +-
gcc/testsuite/gdc.test/runnable/staticaa.d | 126 +++++++
gcc/testsuite/gdc.test/runnable/test24078.d | 6 +
gcc/testsuite/gdc.test/runnable/test24139.d | 25 ++
gcc/testsuite/lib/gdc-utils.exp | 3 +
libphobos/libdruntime/MERGE | 2 +-
libphobos/libdruntime/Makefile.am | 6 +-
libphobos/libdruntime/Makefile.in | 37 +-
libphobos/libdruntime/core/internal/newaa.d | 144 ++++++++
libphobos/libdruntime/core/stdc/math.d | 13 +-
libphobos/libdruntime/core/stdcpp/string.d | 6 +-
libphobos/libdruntime/core/sys/posix/fcntl.d | 21 ++
libphobos/libdruntime/core/sys/posix/signal.d | 22 +-
.../libdruntime/core/sys/posix/sys/resource.d | 35 +-
libphobos/libdruntime/core/sys/windows/sql.d | 4 +
libphobos/libdruntime/core/sys/windows/sqlext.d | 4 +
libphobos/libdruntime/core/sys/windows/sqltypes.d | 4 +
libphobos/libdruntime/core/sys/windows/sqlucode.d | 4 +
libphobos/libdruntime/core/sys/windows/winnt.d | 2 +-
libphobos/libdruntime/object.d | 8 +
libphobos/libdruntime/rt/aaA.d | 19 ++
libphobos/libdruntime/rt/minfo.d | 14 +-
libphobos/src/MERGE | 2 +-
libphobos/src/std/int128.d | 46 ++-
libphobos/src/std/string.d | 1 +
libphobos/testsuite/libphobos.hash/test_hash.d | 4 +-
libphobos/testsuite/libphobos.phobos/phobos.exp | 2 +-
.../libphobos.phobos_shared/phobos_shared.exp | 2 +-
190 files changed, 2771 insertions(+), 1427 deletions(-)
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 60f76fc694c..cf998d22721 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -322,7 +322,8 @@ build_frontend_type (tree type)
return NULL;
}
- args->push (Parameter::create (sc, targ, NULL, NULL, NULL));
+ args->push (Parameter::create (Loc (), sc, targ,
+ NULL, NULL, NULL));
}
/* GCC generic and placeholder built-ins are marked as variadic, yet
diff --git a/gcc/d/d-diagnostic.cc b/gcc/d/d-diagnostic.cc
index be779d93297..b698d4e49b8 100644
--- a/gcc/d/d-diagnostic.cc
+++ b/gcc/d/d-diagnostic.cc
@@ -220,7 +220,7 @@ d_diagnostic_report_diagnostic (const Loc &loc, int opt, const char *format,
void D_ATTRIBUTE_FORMAT(2,0) ATTRIBUTE_GCC_DIAG(2,0)
verrorReport (const Loc& loc, const char *format, va_list ap, ErrorKind kind,
- const char *prefix1 = NULL, const char *prefix2 = NULL)
+ const char *prefix1, const char *prefix2)
{
diagnostic_t diag_kind = DK_UNSPECIFIED;
int opt = 0;
@@ -277,6 +277,9 @@ verrorReport (const Loc& loc, const char *format, va_list ap, ErrorKind kind,
}
else if (kind == ErrorKind::tip)
{
+ if (global.gag)
+ return;
+
diag_kind = DK_DEBUG;
verbatim = true;
}
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index f290acf494b..6509d766708 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -779,7 +779,6 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
case OPT_Wall:
if (value)
global.params.warnings = DIAGNOSTICinform;
- global.params.obsolete = value;
break;
case OPT_Wdeprecated:
@@ -941,7 +940,6 @@ d_post_options (const char ** fn)
global.compileEnv.previewIn = global.params.previewIn;
global.compileEnv.ddocOutput = global.params.ddoc.doOutput;
global.compileEnv.shortenedMethods = global.params.shortenedMethods;
- global.compileEnv.obsolete = global.params.obsolete;
/* Add in versions given on the command line. */
if (global.params.versionids)
@@ -1002,6 +1000,66 @@ d_write_file (const char *filename, const char *data)
error ("writing output file %s: %m", filename);
}
+/* Read ddoc macro files named by the DDOCFILES, then write the concatenated
+ the contents into DDOCBUF. */
+
+static void
+d_read_ddoc_files (Strings &ddocfiles, OutBuffer &ddocbuf)
+{
+ if (ddocbuf.length ())
+ return;
+
+ for (size_t i = 0; i < ddocfiles.length; i++)
+ {
+ int fd = open (ddocfiles[i], O_RDONLY);
+ bool ok = false;
+ struct stat buf;
+
+ if (fd == -1 || fstat (fd, &buf))
+ {
+ error ("unable to open %s for reading: %m", ddocfiles[i]);
+ continue;
+ }
+
+ /* Check we've not been given a directory, or a file bigger than 4GB. */
+ if (S_ISDIR (buf.st_mode))
+ errno = ENOENT;
+ else if (buf.st_size != unsigned (buf.st_size))
+ errno = EMFILE;
+ else
+ {
+ unsigned size = unsigned (buf.st_size);
+ char *buffer = (char *) xmalloc (size);
+
+ if (read (fd, buffer, size) == ssize_t (size))
+ {
+ ddocbuf.write (buffer, size);
+ ok = true;
+ }
+
+ free (buffer);
+ }
+
+ close (fd);
+ if (!ok)
+ fatal_error (input_location, "reading ddoc file %s: %m", ddocfiles[i]);
+ }
+}
+
+static void
+d_generate_ddoc_file (Module *m, OutBuffer &ddocbuf)
+{
+ input_location = make_location_t (m->loc);
+
+ d_read_ddoc_files (global.params.ddoc.files, ddocbuf);
+
+ OutBuffer ddocbuf_out;
+ gendocfile (m, ddocbuf.peekChars (), ddocbuf.length (), global.datetime,
+ global.errorSink, ddocbuf_out);
+
+ d_write_file (m->docfile.toChars (), ddocbuf_out.peekChars ());
+}
+
/* Implements the lang_hooks.parse_file routine for language D. */
static void
@@ -1038,6 +1096,9 @@ d_parse_file (void)
Modules modules;
modules.reserve (num_in_fnames);
+ /* Buffer for contents of .ddoc files. */
+ OutBuffer ddocbuf;
+
/* In this mode, the first file name is supposed to be a duplicate
of one of the input files. */
if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
@@ -1125,7 +1186,8 @@ d_parse_file (void)
if (m->filetype == FileType::ddoc)
{
- gendocfile (m, global.errorSink);
+ d_generate_ddoc_file (m, ddocbuf);
+
/* Remove M from list of modules. */
modules.remove (i);
i--;
@@ -1168,7 +1230,9 @@ d_parse_file (void)
if (global.params.verbose)
message ("import %s", m->toChars ());
- genhdrfile (m);
+ OutBuffer buf;
+ genhdrfile (m, buf);
+ d_write_file (m->hdrfile.toChars (), buf.peekChars ());
}
dump_headers = true;
@@ -1308,7 +1372,7 @@ d_parse_file (void)
if (global.params.json.doOutput)
{
OutBuffer buf;
- json_generate (&buf, &modules);
+ json_generate (modules, buf);
d_write_file (global.params.json.name.ptr, buf.peekChars ());
}
@@ -1318,7 +1382,7 @@ d_parse_file (void)
for (size_t i = 0; i < modules.length; i++)
{
Module *m = modules[i];
- gendocfile (m, global.errorSink);
+ d_generate_ddoc_file (m, ddocbuf);
}
}
@@ -1331,7 +1395,7 @@ d_parse_file (void)
OutBuffer buf;
buf.doindent = 1;
- moduleToBuffer (&buf, m);
+ moduleToBuffer (buf, m);
message ("%s", buf.peekChars ());
}
}
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index dc267787cab..d5dfe0d0edd 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-4574d1728d1f7e52ff40e6733b8c39889d128349
+f9efc98fd7954741333f72c6a50af273f3863a1a
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 8012337e422..fd05dcf2136 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.105.0
+v2.105.2
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index baabe930c68..5a91bc74229 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -679,7 +679,7 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration
{
assert(visibility.kind > Visibility.Kind.undefined);
OutBuffer buf;
- visibilityToBuffer(&buf, visibility);
+ visibilityToBuffer(buf, visibility);
return buf.extractChars();
}
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index bdc81f246cd..a0da77a2898 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -18,6 +18,7 @@ import dmd.astenums;
import dmd.canthrow;
import dmd.dclass;
import dmd.declaration;
+import dmd.errorsink;
import dmd.expression;
import dmd.func;
import dmd.globals;
@@ -56,11 +57,11 @@ enum BE : int
* Params:
* s = statement to check for block exit status
* func = function that statement s is in
- * mustNotThrow = generate an error if it throws
+ * eSink = generate an error if it throws
* Returns:
* BE.xxxx
*/
-int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
+int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink)
{
int result = BE.none;
@@ -97,7 +98,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
if (s.exp.type && s.exp.type.toBasetype().isTypeNoreturn())
result = BE.halt;
- result |= canThrow(s.exp, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
}
}
@@ -143,23 +144,23 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
// Deprecated in 2.100
// Make an error in 2.110
if (sl && sl.isCaseStatement())
- s.deprecation("switch case fallthrough - use 'goto %s;' if intended", gototype);
+ global.errorSink.deprecation(s.loc, "switch case fallthrough - use 'goto %s;' if intended", gototype);
else
- s.error("switch case fallthrough - use 'goto %s;' if intended", gototype);
+ global.errorSink.error(s.loc, "switch case fallthrough - use 'goto %s;' if intended", gototype);
}
}
}
if (!(result & BE.fallthru) && !s.comeFrom())
{
- if (blockExit(s, func, mustNotThrow) != BE.halt && s.hasCode() &&
+ if (blockExit(s, func, eSink) != BE.halt && s.hasCode() &&
s.loc != Loc.initial) // don't emit warning for generated code
- s.warning("statement is not reachable");
+ global.errorSink.warning(s.loc, "statement is not reachable");
}
else
{
result &= ~BE.fallthru;
- result |= blockExit(s, func, mustNotThrow);
+ result |= blockExit(s, func, eSink);
}
slast = s;
}
@@ -173,7 +174,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
if (s)
{
- int r = blockExit(s, func, mustNotThrow);
+ int r = blockExit(s, func, eSink);
result |= r & ~(BE.break_ | BE.continue_ | BE.fallthru);
if ((r & (BE.fallthru | BE.continue_ | BE.break_)) == 0)
result &= ~BE.fallthru;
@@ -184,7 +185,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
void visitScope(ScopeStatement s)
{
//printf("ScopeStatement::blockExit(%p)\n", s.statement);
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
}
void visitWhile(WhileStatement s)
@@ -197,7 +198,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
if (s._body)
{
- result = blockExit(s._body, func, mustNotThrow);
+ result = blockExit(s._body, func, eSink);
if (result == BE.break_)
{
result = BE.fallthru;
@@ -210,7 +211,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
result = BE.fallthru;
if (result & BE.fallthru)
{
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
if (!(result & BE.break_) && s.condition.toBool().hasValue(true))
result &= ~BE.fallthru;
@@ -223,13 +224,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
result = BE.fallthru;
if (s._init)
{
- result = blockExit(s._init, func, mustNotThrow);
+ result = blockExit(s._init, func, eSink);
if (!(result & BE.fallthru))
return;
}
if (s.condition)
{
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
const opt = s.condition.toBool();
if (opt.hasValue(true))
@@ -241,22 +242,22 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
result &= ~BE.fallthru; // the body must do the exiting
if (s._body)
{
- int r = blockExit(s._body, func, mustNotThrow);
+ int r = blockExit(s._body, func, eSink);
if (r & (BE.break_ | BE.goto_))
result |= BE.fallthru;
result |= r & ~(BE.fallthru | BE.break_ | BE.continue_);
}
if (s.increment)
- result |= canThrow(s.increment, func, mustNotThrow);
+ result |= canThrow(s.increment, func, eSink !is null);
}
void visitForeach(ForeachStatement s)
{
result = BE.fallthru;
- result |= canThrow(s.aggr, func, mustNotThrow);
+ result |= canThrow(s.aggr, func, eSink !is null);
if (s._body)
- result |= blockExit(s._body, func, mustNotThrow) & ~(BE.break_ | BE.continue_);
+ result |= blockExit(s._body, func, eSink) & ~(BE.break_ | BE.continue_);
}
void visitForeachRange(ForeachRangeStatement s)
@@ -269,30 +270,30 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
//printf("IfStatement::blockExit(%p)\n", s);
result = BE.none;
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
const opt = s.condition.toBool();
if (opt.hasValue(true))
{
- result |= blockExit(s.ifbody, func, mustNotThrow);
+ result |= blockExit(s.ifbody, func, eSink);
}
else if (opt.hasValue(false))
{
- result |= blockExit(s.elsebody, func, mustNotThrow);
+ result |= blockExit(s.elsebody, func, eSink);
}
else
{
- result |= blockExit(s.ifbody, func, mustNotThrow);
- result |= blockExit(s.elsebody, func, mustNotThrow);
+ result |= blockExit(s.ifbody, func, eSink);
+ result |= blockExit(s.elsebody, func, eSink);
}
//printf("IfStatement::blockExit(%p) = x%x\n", s, result);
}
void visitConditional(ConditionalStatement s)
{
- result = blockExit(s.ifbody, func, mustNotThrow);
+ result = blockExit(s.ifbody, func, eSink);
if (s.elsebody)
- result |= blockExit(s.elsebody, func, mustNotThrow);
+ result |= blockExit(s.elsebody, func, eSink);
}
void visitPragma(PragmaStatement s)
@@ -308,11 +309,11 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
void visitSwitch(SwitchStatement s)
{
result = BE.none;
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
if (s._body)
{
- result |= blockExit(s._body, func, mustNotThrow);
+ result |= blockExit(s._body, func, eSink);
if (result & BE.break_)
{
result |= BE.fallthru;
@@ -325,12 +326,12 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
void visitCase(CaseStatement s)
{
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
}
void visitDefault(DefaultStatement s)
{
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
}
void visitGotoDefault(GotoDefaultStatement s)
@@ -353,7 +354,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
result = BE.return_;
if (s.exp)
- result |= canThrow(s.exp, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
}
void visitBreak(BreakStatement s)
@@ -369,20 +370,20 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
void visitSynchronized(SynchronizedStatement s)
{
- result = blockExit(s._body, func, mustNotThrow);
+ result = blockExit(s._body, func, eSink);
}
void visitWith(WithStatement s)
{
result = BE.none;
- result |= canThrow(s.exp, func, mustNotThrow);
- result |= blockExit(s._body, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
+ result |= blockExit(s._body, func, eSink);
}
void visitTryCatch(TryCatchStatement s)
{
assert(s._body);
- result = blockExit(s._body, func, false);
+ result = blockExit(s._body, func, null);
int catchresult = 0;
foreach (c; *s.catches)
@@ -390,7 +391,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
if (c.type == Type.terror)
continue;
- int cresult = blockExit(c.handler, func, mustNotThrow);
+ int cresult = blockExit(c.handler, func, eSink);
/* If we're catching Object, then there is no throwing
*/
@@ -411,10 +412,10 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
}
catchresult |= cresult;
}
- if (mustNotThrow && (result & BE.throw_))
+ if (eSink && (result & BE.throw_))
{
// now explain why this is nothrow
- blockExit(s._body, func, mustNotThrow);
+ blockExit(s._body, func, eSink);
}
result |= catchresult;
}
@@ -423,12 +424,12 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
result = BE.fallthru;
if (s._body)
- result = blockExit(s._body, func, false);
+ result = blockExit(s._body, func, null);
// check finally body as well, it may throw (bug #4082)
int finalresult = BE.fallthru;
if (s.finalbody)
- finalresult = blockExit(s.finalbody, func, false);
+ finalresult = blockExit(s.finalbody, func, null);
// If either body or finalbody halts
if (result == BE.halt)
@@ -436,13 +437,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
if (finalresult == BE.halt)
result = BE.none;
- if (mustNotThrow)
+ if (eSink)
{
// now explain why this is nothrow
if (s._body && (result & BE.throw_))
- blockExit(s._body, func, mustNotThrow);
+ blockExit(s._body, func, eSink);
if (s.finalbody && (finalresult & BE.throw_))
- blockExit(s.finalbody, func, mustNotThrow);
+ blockExit(s.finalbody, func, eSink);
}
version (none)
@@ -452,7 +453,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
// destructor call, exit of synchronized statement, etc.
if (result == BE.halt && finalresult != BE.halt && s.finalbody && s.finalbody.hasCode())
{
- s.finalbody.warning("statement is not reachable");
+ eSink.warning(s.finalbody.loc, "statement is not reachable");
}
}
@@ -472,12 +473,12 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
if (s.internalThrow)
{
// https://issues.dlang.org/show_bug.cgi?id=8675
- // Allow throwing 'Throwable' object even if mustNotThrow.
+ // Allow throwing 'Throwable' object even if eSink.
result = BE.fallthru;
return;
}
- result = checkThrow(s.loc, s.exp, mustNotThrow, func);
+ result = checkThrow(s.loc, s.exp, func, eSink);
}
void visitGoto(GotoStatement s)
@@ -489,7 +490,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
void visitLabel(LabelStatement s)
{
//printf("LabelStatement::blockExit(%p)\n", s);
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
if (s.breaks)
result |= BE.fallthru;
}
@@ -502,8 +503,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
if(func)
func.setThrow(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not");
- if (mustNotThrow)
- s.error("`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); // TODO
+ if (eSink)
+ eSink.error(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); // TODO
else
result |= BE.throw_;
}
@@ -528,15 +529,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
+ Params:
+ loc = location of the `throw`
+ exp = expression yielding the throwable
- + mustNotThrow = inside of a `nothrow` scope?
+ + eSink = if !null then inside of a `nothrow` scope
+ func = function containing the `throw`
+
+ Returns: `BE.[err]throw` depending on the type of `exp`
+/
-BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow, FuncDeclaration func)
+BE checkThrow(ref const Loc loc, Expression exp, FuncDeclaration func, ErrorSink eSink)
{
- import dmd.errors : error;
-
Type t = exp.type.toBasetype();
ClassDeclaration cd = t.isClassHandle();
assert(cd);
@@ -545,8 +544,8 @@ BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow, FuncDe
{
return BE.errthrow;
}
- if (mustNotThrow)
- loc.error("`%s` is thrown but not caught", exp.type.toChars());
+ if (eSink)
+ eSink.error(loc, "`%s` is thrown but not caught", exp.type.toChars());
else if (func)
func.setThrow(loc, "`%s` is thrown but not caught", exp.type);
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index ba13eb084bd..4cead300f40 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -202,7 +202,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
override void visit(ThrowExp te)
{
- const res = checkThrow(te.loc, te.e1, mustNotThrow, func);
+ const res = checkThrow(te.loc, te.e1, func, mustNotThrow ? global.errorSink : null);
assert((res & ~(CT.exception | CT.error)) == 0);
result |= res;
}
diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d
index feaa3c7ee6b..8cfad5916c7 100644
--- a/gcc/d/dmd/chkformat.d
+++ b/gcc/d/dmd/chkformat.d
@@ -15,7 +15,7 @@ import core.stdc.ctype : isdigit;
import dmd.astenums;
import dmd.cond;
-import dmd.errors;
+import dmd.errorsink;
import dmd.expression;
import dmd.globals;
import dmd.identifier;
@@ -53,6 +53,7 @@ import dmd.target;
* format = format string
* args = arguments to match with format string
* isVa_list = if a "v" function (format check only)
+ * eSink = where the error messages go
*
* Returns:
* `true` if errors occurred
@@ -60,7 +61,8 @@ import dmd.target;
* C99 7.19.6.1
* https://www.cplusplus.com/reference/cstdio/printf/
*/
-bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list)
+public
+bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list, ErrorSink eSink)
{
//printf("checkPrintFormat('%.*s')\n", cast(int)format.length, format.ptr);
size_t n; // index in args
@@ -87,7 +89,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
{
// format check only
if (fmt == Format.error)
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
continue;
}
@@ -96,7 +98,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
if (n == args.length)
{
if (args.length < (n + 1))
- deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
+ eSink.deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
else
skip = true;
return null;
@@ -106,7 +108,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
void errorMsg(const char* prefix, Expression arg, const char* texpect, Type tactual)
{
- deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
+ eSink.deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
prefix ? prefix : "", arg.toChars(), cast(int)slice.length, slice.ptr, texpect, tactual.toChars());
}
@@ -178,7 +180,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
else
errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t);
if (t.isintegral() && t.size() != c_longsize)
- errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
+ eSink.errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
}
break;
@@ -226,7 +228,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
break;
case Format.n: // pointer to int
- if (!(t.ty == Tpointer && tnext.ty == Tint32))
+ if (!(t.ty == Tpointer && tnext.ty == Tint32 && tnext.isMutable()))
errorMsg(null, e, "int*", t);
break;
@@ -286,7 +288,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
break;
case Format.error:
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
break;
case Format.GNU_m:
@@ -327,6 +329,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
* format = format string
* args = arguments to match with format string
* isVa_list = if a "v" function (format check only)
+ * eSink = where the error messages go
*
* Returns:
* `true` if errors occurred
@@ -334,7 +337,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
* C99 7.19.6.2
* https://www.cplusplus.com/reference/cstdio/scanf/
*/
-bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list)
+public
+bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list, ErrorSink eSink)
{
size_t n = 0;
for (size_t i = 0; i < format.length;)
@@ -357,7 +361,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
{
// format check only
if (fmt == Format.error)
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
continue;
}
@@ -366,7 +370,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
if (n == args.length)
{
if (!asterisk)
- deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
+ eSink.deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
return null;
}
return args[n++];
@@ -374,7 +378,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
void errorMsg(const char* prefix, Expression arg, const char* texpect, Type tactual)
{
- deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
+ eSink.deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
prefix ? prefix : "", arg.toChars(), cast(int)slice.length, slice.ptr, texpect, tactual.toChars());
}
@@ -512,7 +516,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
break;
case Format.error:
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
break;
case Format.GNU_m:
@@ -523,6 +527,8 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
return false;
}
+/*****************************************************************************************************/
+
private:
/**************************************
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 4cff1ecf49c..181268ec26c 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -297,7 +297,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc)
}
auto fparams = new Parameters();
- fparams.push(new Parameter(STC.nodtor, sd.type, Id.p, null, null));
+ fparams.push(new Parameter(loc, STC.nodtor, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(fparams), sd.handleType(), LINK.d, stc | STC.ref_);
auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.assign, stc, tf);
fop.storage_class |= STC.inference;
@@ -546,10 +546,11 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
TypeFunction tfeqptr;
{
Scope scx;
+ scx.eSink = sc.eSink;
/* const bool opEquals(ref const S s);
*/
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));
+ parameters.push(new Parameter(Loc.initial, STC.ref_ | STC.const_, sd.type, null, null, null));
tfeqptr = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d);
tfeqptr.mod = MODFlags.const_;
tfeqptr = cast(TypeFunction)tfeqptr.typeSemantic(Loc.initial, &scx);
@@ -577,7 +578,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
Loc declLoc; // loc is unnecessary so __xopEquals is never called directly
Loc loc; // loc is unnecessary so errors are gagged
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
+ parameters.push(new Parameter(loc, STC.ref_ | STC.const_, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d, STC.const_);
tf = tf.addSTC(STC.const_).toTypeFunction();
Identifier id = Id.xopEquals;
@@ -620,10 +621,11 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
TypeFunction tfcmpptr;
{
Scope scx;
+ scx.eSink = sc.eSink;
/* const int opCmp(ref const S s);
*/
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));
+ parameters.push(new Parameter(Loc.initial, STC.ref_ | STC.const_, sd.type, null, null, null));
tfcmpptr = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d);
tfcmpptr.mod = MODFlags.const_;
tfcmpptr = cast(TypeFunction)tfcmpptr.typeSemantic(Loc.initial, &scx);
@@ -701,7 +703,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
Loc declLoc; // loc is unnecessary so __xopCmp is never called directly
Loc loc; // loc is unnecessary so errors are gagged
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
+ parameters.push(new Parameter(loc, STC.ref_ | STC.const_, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d, STC.const_);
tf = tf.addSTC(STC.const_).toTypeFunction();
Identifier id = Id.xopCmp;
@@ -820,7 +822,7 @@ FuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc)
Loc declLoc; // loc is unnecessary so __xtoHash is never called directly
Loc loc; // internal code should have no loc to prevent coverage
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
+ parameters.push(new Parameter(loc, STC.ref_ | STC.const_, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(parameters), Type.thash_t, LINK.d, STC.nothrow_ | STC.trusted);
Identifier id = Id.xtoHash;
auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf);
@@ -1074,7 +1076,7 @@ private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclara
// // TODO: if (del) delete (char*)this;
// return (void*) this;
// }
- Parameter delparam = new Parameter(STC.undefined_, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null);
+ Parameter delparam = new Parameter(Loc.initial, STC.undefined_, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null);
Parameters* params = new Parameters;
params.push(delparam);
const stc = dtor.storage_class & ~STC.scope_; // because we add the `return this;` later
@@ -1126,7 +1128,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
return null;
// Generate shim only when ABI incompatible on target platform
- if (ad.classKind != ClassKind.cpp || !target.cpp.wrapDtorInExternD)
+ if (dtor._linkage != LINK.cpp || !target.cpp.wrapDtorInExternD)
return dtor;
// generate member function that adjusts calling convention
@@ -1514,7 +1516,7 @@ private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const
{
auto fparams = new Parameters();
auto structType = sd.type;
- fparams.push(new Parameter(paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
+ fparams.push(new Parameter(Loc.initial, paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
ParameterList pList = ParameterList(fparams);
auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_);
auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true);
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index 360acf590bb..76cef77d8ed 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -322,7 +322,7 @@ extern (C++) final class StaticForeach : RootObject
foreach (params; pparams)
{
auto p = aggrfe ? (*aggrfe.parameters)[i] : rangefe.prm;
- params.push(new Parameter(p.storageClass, p.type, p.ident, null, null));
+ params.push(new Parameter(aloc, p.storageClass, p.type, p.ident, null, null));
}
}
Expression[2] res;
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 03383d13fd5..b05d81d3b14 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -626,7 +626,7 @@ final class CParser(AST) : Parser!AST
default:
// ImportC extensions: parse as a D asm block.
- s = parseAsm();
+ s = parseAsm(compileEnv.masm);
break;
}
break;
@@ -3114,12 +3114,13 @@ final class CParser(AST) : Parser!AST
}
Identifier id;
+ const paramLoc = token.loc;
auto t = cparseDeclarator(DTR.xparameter, tspec, id, specifier);
if (token.value == TOK.__attribute__)
cparseGnuAttributes(specifier);
if (specifier.mod & MOD.xconst)
t = toConst(t);
- auto param = new AST.Parameter(specifiersToSTC(LVL.parameter, specifier),
+ auto param = new AST.Parameter(paramLoc, specifiersToSTC(LVL.parameter, specifier),
t, id, null, null);
parameters.push(param);
if (token.value == TOK.rightParenthesis || token.value == TOK.endOfFile)
@@ -3297,8 +3298,10 @@ final class CParser(AST) : Parser!AST
nextToken();
else
{
- error("extended-decl-modifier expected");
- break;
+ error("extended-decl-modifier expected after `__declspec(`, saw `%s` instead", token.toChars());
+ nextToken();
+ if (token.value != TOK.rightParenthesis)
+ break;
}
}
}
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 5d74ec4c91a..0c32fad7803 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -23,7 +23,6 @@
module dmd.cppmangle;
-import core.stdc.string;
import core.stdc.stdio;
import dmd.arraytypes;
@@ -46,7 +45,6 @@ import dmd.common.outbuffer;
import dmd.root.rootobject;
import dmd.root.string;
import dmd.target;
-import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index d355538e97c..c0a2ca6a2a5 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -12,7 +12,6 @@
module dmd.ctfeexpr;
import core.stdc.stdio;
-import core.stdc.stdlib;
import core.stdc.string;
import dmd.arraytypes;
import dmd.astenums;
@@ -306,9 +305,10 @@ UnionExp copyLiteral(Expression e)
}
if (auto aae = e.isAssocArrayLiteralExp())
{
- emplaceExp!(AssocArrayLiteralExp)(&ue, e.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values));
+ emplaceExp!(AssocArrayLiteralExp)(&ue, aae.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values));
AssocArrayLiteralExp r = ue.exp().isAssocArrayLiteralExp();
- r.type = e.type;
+ r.type = aae.type;
+ r.lowering = aae.lowering;
r.ownedByCtfe = OwnedBy.ctfe;
return ue;
}
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index b2aa6433baf..d7cb2b1f970 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -23,7 +23,6 @@ import dmd.declaration;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
-import dmd.errors;
import dmd.escape;
import dmd.expression;
import dmd.expressionsem;
@@ -32,7 +31,6 @@ import dmd.globals;
import dmd.hdrgen;
import dmd.location;
import dmd.impcnvtab;
-import dmd.id;
import dmd.importc;
import dmd.init;
import dmd.intrange;
@@ -44,7 +42,6 @@ import dmd.root.rmem;
import dmd.root.utf;
import dmd.tokens;
import dmd.typesem;
-import dmd.visitor;
enum LOG = false;
@@ -73,7 +70,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
{
// no need for an extra cast when matching is exact
- if (match == MATCH.convert && e.type.isTypeNoreturn())
+ if (match == MATCH.convert && e.type.isTypeNoreturn() && e.op != EXP.type)
{
return specialNoreturnCast(e, t);
}
@@ -174,7 +171,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
{
//printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", e.type, e.type ? e.type.toChars() : NULL, t.toChars());
FuncExp fe;
- if (e.matchType(t, sc, &fe) > MATCH.nomatch)
+ if (e.matchType(t, sc, &fe, global.errorSink) > MATCH.nomatch)
{
return fe;
}
@@ -1075,7 +1072,7 @@ MATCH implicitConvTo(Expression e, Type t)
MATCH visitFunc(FuncExp e)
{
//printf("FuncExp::implicitConvTo type = %p %s, t = %s\n", e.type, e.type ? e.type.toChars() : NULL, t.toChars());
- MATCH m = e.matchType(t, null, null, 1);
+ MATCH m = e.matchType(t, null, null, global.errorSinkNull);
if (m > MATCH.nomatch)
{
return m;
@@ -1537,7 +1534,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
{
return e;
}
- if (e.type.isTypeNoreturn())
+ if (e.type.isTypeNoreturn() && e.op != EXP.type)
{
return specialNoreturnCast(e, t);
}
@@ -2489,7 +2486,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
{
//printf("FuncExp::castTo type = %s, t = %s\n", e.type.toChars(), t.toChars());
FuncExp fe;
- if (e.matchType(t, sc, &fe, 1) > MATCH.nomatch)
+ if (e.matchType(t, sc, &fe, global.errorSinkNull) > MATCH.nomatch)
{
return fe;
}
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index 20cb82e1a36..b446e77b879 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -19,14 +19,12 @@ import core.stdc.string;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
-import dmd.attrib;
import dmd.gluelayer;
import dmd.declaration;
import dmd.dscope;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.func;
-import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.location;
@@ -879,6 +877,10 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
return 0;
}
+ // opaque class is not abstract if it is not declared abstract
+ if (!members)
+ return no();
+
for (size_t i = 0; i < members.length; i++)
{
auto s = (*members)[i];
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 8a91a802dae..b21678ce508 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -16,7 +16,6 @@ import core.stdc.stdio;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
-import dmd.attrib;
import dmd.ctorflow;
import dmd.dclass;
import dmd.delegatize;
@@ -647,11 +646,11 @@ extern (C++) final class TupleDeclaration : Declaration
{
buf.printf("_%s_%d", ident.toChars(), i);
auto id = Identifier.idPool(buf.extractSlice());
- auto arg = new Parameter(STC.in_, t, id, null);
+ auto arg = new Parameter(Loc.initial, STC.in_, t, id, null);
}
else
{
- auto arg = new Parameter(0, t, null, null, null);
+ auto arg = new Parameter(Loc.initial, 0, t, null, null, null);
}
(*args)[i] = arg;
if (!t.deco)
@@ -1602,6 +1601,8 @@ extern (C++) class VarDeclaration : Declaration
{
inuse++;
_init = _init.initializerSemantic(_scope, type, INITinterpret);
+ import dmd.semantic2 : lowerStaticAAs;
+ lowerStaticAAs(this, _scope);
_scope = null;
inuse--;
}
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index 559f103908d..490ef56646f 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -21,7 +21,6 @@ import dmd.dsymbol;
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
-import dmd.globals;
import dmd.init;
import dmd.initsem;
import dmd.location;
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index 87b40b854b9..955a17dc6e8 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -24,13 +24,11 @@ import dmd.dscope;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.expression;
-import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.init;
import dmd.location;
import dmd.mtype;
-import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 59483511f6d..7cdafda050c 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -40,7 +40,6 @@ import dmd.init;
import dmd.initsem;
import dmd.location;
import dmd.mtype;
-import dmd.printast;
import dmd.root.rmem;
import dmd.root.array;
import dmd.root.ctfloat;
@@ -635,8 +634,6 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
{
if (ctfeGlobals.callDepth > CTFE_RECURSION_LIMIT)
{
- // This is a compiler error. It must not be suppressed.
- global.gag = 0;
fd.error("CTFE recursion limit exceeded");
e = CTFEExp.cantexp;
break;
@@ -790,7 +787,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
istate.start = null;
}
- s.error("statement `%s` cannot be interpreted at compile time", s.toChars());
+ error(s.loc, "statement `%s` cannot be interpreted at compile time", s.toChars());
result = CTFEExp.cantexp;
}
@@ -976,7 +973,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
{
// To support this, we need to copy all the closure vars
// into the delegate literal.
- s.error("closures are not yet supported in CTFE");
+ error(s.loc, "closures are not yet supported in CTFE");
result = CTFEExp.cantexp;
return;
}
@@ -1259,7 +1256,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
if (!scase)
{
if (s.hasNoDefault)
- s.error("no `default` or `case` for `%s` in `switch` statement", econdition.toChars());
+ error(s.loc, "no `default` or `case` for `%s` in `switch` statement", econdition.toChars());
scase = s.sdefault;
}
@@ -1599,7 +1596,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
return;
istate.start = null;
}
- s.error("`asm` statements cannot be interpreted at compile time");
+ error(s.loc, "`asm` statements cannot be interpreted at compile time");
result = CTFEExp.cantexp;
}
@@ -6105,7 +6102,8 @@ public:
result = interpret(&ue, e.msg, istate);
if (exceptionOrCant(result))
return;
- if (StringExp se = result.isStringExp())
+ result = scrubReturnValue(e.loc, result);
+ if (StringExp se = result.toStringExp())
e.error("%s", se.toStringz().ptr);
else
e.error("%s", result.toChars());
diff --git a/gcc/d/dmd/dmacro.d b/gcc/d/dmd/dmacro.d
index 6fc23e99e86..6e6c4b17e99 100644
--- a/gcc/d/dmd/dmacro.d
+++ b/gcc/d/dmd/dmacro.d
@@ -13,11 +13,12 @@ module dmd.dmacro;
import core.stdc.ctype;
import core.stdc.string;
-import dmd.doc;
import dmd.common.outbuffer;
import dmd.root.rmem;
-extern (C++) struct MacroTable
+@trusted:
+
+struct MacroTable
{
/**********************************
* Define name=text macro.
@@ -26,7 +27,7 @@ extern (C++) struct MacroTable
* name = name of macro
* text = text of macro
*/
- extern (D) void define(const(char)[] name, const(char)[] text) nothrow pure @safe
+ void define(const(char)[] name, const(char)[] text) nothrow pure @safe
{
//printf("MacroTable::define('%.*s' = '%.*s')\n", cast(int)name.length, name.ptr, text.length, text.ptr);
if (auto table = name in mactab)
@@ -37,13 +38,16 @@ extern (C++) struct MacroTable
mactab[name] = new Macro(name, text);
}
+ alias fp_t = bool function(const(char)* p) @nogc nothrow pure;
+
/*****************************************************
* Look for macros in buf and expand them in place.
* Only look at the text in buf from start to pend.
*
* Returns: `true` on success, `false` when the recursion limit was reached
*/
- extern (D) bool expand(ref OutBuffer buf, size_t start, ref size_t pend, const(char)[] arg, int recursionLimit) nothrow pure
+ bool expand(ref OutBuffer buf, size_t start, ref size_t pend, const(char)[] arg, int recursionLimit,
+ fp_t isIdStart, fp_t isIdTail) nothrow pure
{
version (none)
{
@@ -101,7 +105,7 @@ extern (C++) struct MacroTable
end += marg.length - 2;
// Scan replaced text for further expansion
size_t mend = u + marg.length;
- const success = expand(buf, u, mend, null, recursionLimit);
+ const success = expand(buf, u, mend, null, recursionLimit, isIdStart, isIdTail);
if (!success)
return false;
end += mend - (u + marg.length);
@@ -119,7 +123,7 @@ extern (C++) struct MacroTable
end += -2 + 2 + marg.length + 2;
// Scan replaced text for further expansion
size_t mend = u + 2 + marg.length;
- const success = expand(buf, u + 2, mend, null, recursionLimit);
+ const success = expand(buf, u + 2, mend, null, recursionLimit, isIdStart, isIdTail);
if (!success)
return false;
end += mend - (u + 2 + marg.length);
@@ -149,7 +153,7 @@ extern (C++) struct MacroTable
/* Scan forward to find end of macro name and
* beginning of macro argument (marg).
*/
- for (v = u + 2; v < end; v += utfStride(p + v))
+ for (v = u + 2; v < end; v += utfStride(p[v]))
{
if (!isIdTail(p + v))
{
@@ -228,7 +232,7 @@ extern (C++) struct MacroTable
// Scan replaced text for further expansion
m.inuse++;
size_t mend = v + 1 + 2 + m.text.length + 2;
- const success = expand(buf, v + 1, mend, marg, recursionLimit);
+ const success = expand(buf, v + 1, mend, marg, recursionLimit, isIdStart, isIdTail);
if (!success)
return false;
end += mend - (v + 1 + 2 + m.text.length + 2);
@@ -260,7 +264,7 @@ extern (C++) struct MacroTable
private:
- extern (D) Macro* search(const(char)[] name) @nogc nothrow pure @safe
+ Macro* search(const(char)[] name) @nogc nothrow pure @safe
{
//printf("Macro::search(%.*s)\n", cast(int)name.length, name.ptr);
if (auto table = name in mactab)
@@ -299,7 +303,7 @@ struct Macro
* copy allocated with mem.xmalloc()
*/
-char[] memdup(const(char)[] p) nothrow pure @trusted
+char[] memdup(const(char)[] p) nothrow pure
{
size_t len = p.length;
return (cast(char*)memcpy(mem.xmalloc(len), p.ptr, len))[0 .. len];
@@ -424,3 +428,35 @@ Largstart:
//printf("extractArg%d('%.*s') = '%.*s'\n", n, cast(int)end, p, cast(int)marg.length, marg.ptr);
return v;
}
+
+/*****************************************
+ * Get number of UTF-8 code units in code point that starts with `c`
+ * Params:
+ * c = starting code unit
+ * Returns: number of UTF-8 code units (i.e. bytes), else 1 on invalid UTF start
+ */
+@safe
+int utfStride(char c) @nogc nothrow pure
+{
+ return
+ c < 0x80 ? 1 :
+ c < 0xC0 ? 1 : // invalid UTF start
+ c < 0xE0 ? 2 :
+ c < 0xF0 ? 3 :
+ c < 0xF8 ? 4 :
+ c < 0xFC ? 5 :
+ c < 0xFE ? 6 :
+ 1; // invalid UTF start
+}
+
+unittest
+{
+ assert(utfStride(0) == 1);
+ assert(utfStride(0x80) == 1);
+ assert(utfStride(0xC0) == 2);
+ assert(utfStride(0xE0) == 3);
+ assert(utfStride(0xF0) == 4);
+ assert(utfStride(0xF8) == 5);
+ assert(utfStride(0xFC) == 6);
+ assert(utfStride(0xFE) == 1);
+}
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 4a2e15c981b..eb68b31edeb 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -780,7 +780,9 @@ extern (C++) final class Module : Package
{
filetype = FileType.c;
+ global.compileEnv.masm = target.os == Target.OS.Windows && !target.omfobj; // Microsoft inline assembler format
scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv);
+ global.compileEnv.masm = false;
p.nextToken();
checkCompiledImport();
members = p.parseModule();
@@ -1253,7 +1255,7 @@ extern (C++) final class Module : Package
// Back end
int doppelganger; // sub-module
Symbol* cov; // private uint[] __coverage;
- uint* covb; // bit array of valid code line numbers
+ uint[] covb; // bit array of valid code line numbers
Symbol* sictor; // module order independent constructor
Symbol* sctor; // module constructor
Symbol* sdtor; // module destructor
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index 887fd6c696c..5488d5a0008 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -52,9 +52,11 @@ import dmd.root.rmem;
import dmd.root.string;
import dmd.root.utf;
import dmd.tokens;
-import dmd.utils;
import dmd.visitor;
+private:
+
+public
struct Escape
{
const(char)[][char.max] strings;
@@ -94,7 +96,7 @@ struct Escape
/***********************************************************
*/
-private class Section
+class Section
{
const(char)[] name;
const(char)[] body_;
@@ -105,7 +107,7 @@ private class Section
assert(0);
}
- void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
+ void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
if (name.length)
@@ -151,16 +153,16 @@ private class Section
size_t o = buf.length;
buf.write(body_);
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
buf.writestring(")");
}
}
/***********************************************************
*/
-private final class ParamSection : Section
+final class ParamSection : Section
{
- override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
+ override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
Dsymbol s = (*a)[0]; // test
@@ -241,7 +243,7 @@ private final class ParamSection : Section
}
else if (fparam && fparam.type && fparam.ident)
{
- .toCBuffer(fparam.type, buf, fparam.ident, &hgs);
+ toCBuffer(fparam.type, buf, fparam.ident, hgs);
}
else
{
@@ -257,7 +259,7 @@ private final class ParamSection : Section
buf.write(namestart[0 .. namelen]);
}
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightCode(sc, a, *buf, o);
+ highlightCode(sc, a, buf, o);
}
buf.writestring(")");
buf.writestring("$(DDOC_PARAM_DESC ");
@@ -265,7 +267,7 @@ private final class ParamSection : Section
size_t o = buf.length;
buf.write(textstart[0 .. textlen]);
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
}
buf.writestring(")");
}
@@ -317,19 +319,19 @@ private final class ParamSection : Section
/***********************************************************
*/
-private final class MacroSection : Section
+final class MacroSection : Section
{
- override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
+ override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
//printf("MacroSection::write()\n");
DocComment.parseMacros(dc.escapetable, *dc.pmacrotable, body_);
}
}
-private alias Sections = Array!(Section);
+alias Sections = Array!(Section);
// Workaround for missing Parameter instance for variadic params. (it's unnecessary to instantiate one).
-private bool isCVariadicParameter(Dsymbols* a, const(char)[] p) @safe
+bool isCVariadicParameter(Dsymbols* a, const(char)[] p) @safe
{
foreach (member; *a)
{
@@ -340,7 +342,7 @@ private bool isCVariadicParameter(Dsymbols* a, const(char)[] p) @safe
return false;
}
-private Dsymbol getEponymousMember(TemplateDeclaration td) @safe
+Dsymbol getEponymousMember(TemplateDeclaration td) @safe
{
if (!td.onemember)
return null;
@@ -355,7 +357,7 @@ private Dsymbol getEponymousMember(TemplateDeclaration td) @safe
return null;
}
-private TemplateDeclaration getEponymousParent(Dsymbol s) @safe
+TemplateDeclaration getEponymousParent(Dsymbol s) @safe
{
if (!s.parent)
return null;
@@ -363,40 +365,46 @@ private TemplateDeclaration getEponymousParent(Dsymbol s) @safe
return (td && getEponymousMember(td)) ? td : null;
}
-private immutable ddoc_default = import("default_ddoc_theme." ~ ddoc_ext);
-private immutable ddoc_decl_s = "$(DDOC_DECL ";
-private immutable ddoc_decl_e = ")\n";
-private immutable ddoc_decl_dd_s = "$(DDOC_DECL_DD ";
-private immutable ddoc_decl_dd_e = ")\n";
+immutable ddoc_default = import("default_ddoc_theme." ~ ddoc_ext);
+immutable ddoc_decl_s = "$(DDOC_DECL ";
+immutable ddoc_decl_e = ")\n";
+immutable ddoc_decl_dd_s = "$(DDOC_DECL_DD ";
+immutable ddoc_decl_dd_e = ")\n";
/****************************************************
+ * Generate Ddoc file for Module m.
+ * Params:
+ * m = Module
+ * ddoctext_ptr = combined text of .ddoc files for macro definitions
+ * ddoctext_length = extant of ddoctext_ptr
+ * datetime = charz returned by ctime()
+ * eSink = send error messages to eSink
+ * outbuf = append the Ddoc text to this
*/
-extern(C++) void gendocfile(Module m, ErrorSink eSink)
+public
+extern(C++) void gendocfile(Module m, const char* ddoctext_ptr, size_t ddoctext_length, const char* datetime, ErrorSink eSink, ref OutBuffer outbuf)
{
- __gshared OutBuffer mbuf;
- __gshared int mbuf_done;
- OutBuffer buf;
- //printf("Module::gendocfile()\n");
- if (!mbuf_done) // if not already read the ddoc files
- {
- mbuf_done = 1;
- // Use our internal default
- mbuf.writestring(ddoc_default);
- // Override with DDOCFILE specified in the sc.ini file
- char* p = getenv("DDOCFILE");
- if (p)
- global.params.ddoc.files.shift(p);
- // Override with the ddoc macro files from the command line
- for (size_t i = 0; i < global.params.ddoc.files.length; i++)
- {
- auto buffer = readFile(m.loc, global.params.ddoc.files[i]);
- // BUG: convert file contents to UTF-8 before use
- const data = buffer.data;
- //printf("file: '%.*s'\n", cast(int)data.length, data.ptr);
- mbuf.write(data);
- }
- }
- DocComment.parseMacros(m.escapetable, m.macrotable, mbuf[]);
+ gendocfile(m, ddoctext_ptr[0 .. ddoctext_length], datetime, eSink, outbuf);
+}
+
+/****************************************************
+ * Generate Ddoc text for Module `m` and append it to `outbuf`.
+ * Params:
+ * m = Module
+ * ddoctext = combined text of .ddoc files for macro definitions
+ * datetime = charz returned by ctime()
+ * eSink = send error messages to eSink
+ * outbuf = append the Ddoc text to this
+ */
+public
+void gendocfile(Module m, const char[] ddoctext, const char* datetime, ErrorSink eSink, ref OutBuffer outbuf)
+{
+ // Load internal default macros first
+ DocComment.parseMacros(m.escapetable, m.macrotable, ddoc_default[]);
+
+ // Ddoc files override default macros
+ DocComment.parseMacros(m.escapetable, m.macrotable, ddoctext);
+
Scope* sc = Scope.createGlobal(m, eSink); // create root scope
DocComment* dc = DocComment.parse(m, m.comment);
dc.pmacrotable = &m.macrotable;
@@ -409,14 +417,9 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
m.macrotable.define("TITLE", p);
}
// Set time macros
- {
- time_t t;
- time(&t);
- char* p = ctime(&t);
- p = mem.xstrdup(p);
- m.macrotable.define("DATETIME", p.toDString());
- m.macrotable.define("YEAR", p[20 .. 20 + 4]);
- }
+ m.macrotable.define("DATETIME", datetime[0 .. 26]);
+ m.macrotable.define("YEAR", datetime[20 .. 20 + 4]);
+
const srcfilename = m.srcfile.toString();
m.macrotable.define("SRCFILENAME", srcfilename);
const docfilename = m.docfile.toString();
@@ -426,6 +429,8 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
dc.copyright.nooutput = 1;
m.macrotable.define("COPYRIGHT", dc.copyright.body_);
}
+
+ OutBuffer buf;
if (m.filetype == FileType.ddoc)
{
const ploc = m.md ? &m.md.loc : &m.loc;
@@ -433,14 +438,14 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
if (!loc.filename)
loc.filename = srcfilename.ptr;
- size_t commentlen = strlen(cast(char*)m.comment);
+ size_t commentlen = m.comment ? strlen(cast(char*)m.comment) : 0;
Dsymbols a;
// https://issues.dlang.org/show_bug.cgi?id=9764
// Don't push m in a, to prevent emphasize ddoc file name.
if (dc.macros)
{
commentlen = dc.macros.name.ptr - m.comment;
- dc.macros.write(loc, dc, sc, &a, &buf);
+ dc.macros.write(loc, dc, sc, &a, buf);
}
buf.write(m.comment[0 .. commentlen]);
highlightText(sc, &a, loc, buf, 0);
@@ -449,73 +454,47 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
{
Dsymbols a;
a.push(m);
- dc.writeSections(sc, &a, &buf);
+ dc.writeSections(sc, &a, buf);
emitMemberComments(m, buf, sc);
}
//printf("BODY= '%.*s'\n", cast(int)buf.length, buf.data);
m.macrotable.define("BODY", buf[]);
+
OutBuffer buf2;
buf2.writestring("$(DDOC)");
size_t end = buf2.length;
- const success = m.macrotable.expand(buf2, 0, end, null, global.recursionLimit);
+ // Expand buf in place with macro expansions
+ const success = m.macrotable.expand(buf2, 0, end, null, global.recursionLimit, &isIdStart, &isIdTail);
if (!success)
eSink.error(Loc.initial, "DDoc macro expansion limit exceeded; more than %d expansions.", global.recursionLimit);
- version (all)
+ /* Remove all the escape sequences from buf,
+ * and make CR-LF the newline.
+ */
+ const slice = buf2[];
+ outbuf.reserve(slice.length);
+ auto p = slice.ptr;
+ for (size_t j = 0; j < slice.length; j++)
{
- /* Remove all the escape sequences from buf2,
- * and make CR-LF the newline.
- */
+ char c = p[j];
+ if (c == 0xFF && j + 1 < slice.length)
{
- const slice = buf2[];
- buf.setsize(0);
- buf.reserve(slice.length);
- auto p = slice.ptr;
- for (size_t j = 0; j < slice.length; j++)
- {
- char c = p[j];
- if (c == 0xFF && j + 1 < slice.length)
- {
- j++;
- continue;
- }
- if (c == '\n')
- buf.writeByte('\r');
- else if (c == '\r')
- {
- buf.writestring("\r\n");
- if (j + 1 < slice.length && p[j + 1] == '\n')
- {
- j++;
- }
- continue;
- }
- buf.writeByte(c);
- }
+ j++;
+ continue;
}
- writeFile(m.loc, m.docfile.toString(), buf[]);
- }
- else
- {
- /* Remove all the escape sequences from buf2
- */
+ if (c == '\n')
+ outbuf.writeByte('\r');
+ else if (c == '\r')
{
- size_t i = 0;
- char* p = buf2.data;
- for (size_t j = 0; j < buf2.length; j++)
+ outbuf.writestring("\r\n");
+ if (j + 1 < slice.length && p[j + 1] == '\n')
{
- if (p[j] == 0xFF && j + 1 < buf2.length)
- {
- j++;
- continue;
- }
- p[i] = p[j];
- i++;
+ j++;
}
- buf2.setsize(i);
+ continue;
}
- writeFile(m.loc, m.docfile.toString(), buf2[]);
+ outbuf.writeByte(c);
}
}
@@ -526,11 +505,12 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
* to preserve text literally. This also means macros in the
* text won't be expanded.
*/
-void escapeDdocString(OutBuffer* buf, size_t start)
+public
+void escapeDdocString(ref OutBuffer buf, size_t start)
{
for (size_t u = start; u < buf.length; u++)
{
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case '$':
@@ -568,14 +548,14 @@ void escapeDdocString(OutBuffer* buf, size_t start)
* directly preceeded by a backslash with $(LPAREN) or $(RPAREN) instead of
* counting them as stray parentheses
*/
-private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool respectBackslashEscapes, ErrorSink eSink)
+private void escapeStrayParenthesis(Loc loc, ref OutBuffer buf, size_t start, bool respectBackslashEscapes, ErrorSink eSink)
{
uint par_open = 0;
char inCode = 0;
bool atLineStart = true;
for (size_t u = start; u < buf.length; u++)
{
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case '(':
@@ -619,7 +599,7 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
// Issue 15465: don't try to escape unbalanced parens inside code
// blocks.
int numdash = 1;
- for (++u; u < buf.length && (*buf)[u] == c; ++u)
+ for (++u; u < buf.length && buf[u] == c; ++u)
++numdash;
--u;
if (c == '`' || (atLineStart && numdash >= 3))
@@ -635,14 +615,14 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
// replace backslash-escaped parens with their macros
if (!inCode && respectBackslashEscapes && u+1 < buf.length)
{
- if ((*buf)[u+1] == '(' || (*buf)[u+1] == ')')
+ if (buf[u+1] == '(' || buf[u+1] == ')')
{
- const paren = (*buf)[u+1] == '(' ? "$(LPAREN)" : "$(RPAREN)";
+ const paren = buf[u+1] == '(' ? "$(LPAREN)" : "$(RPAREN)";
buf.remove(u, 2); //remove the \)
buf.insert(u, paren); //insert this instead
u += 8; //skip over newly inserted macro
}
- else if ((*buf)[u+1] == '\\')
+ else if (buf[u+1] == '\\')
++u;
}
break;
@@ -657,7 +637,7 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
for (size_t u = buf.length; u > start;)
{
u--;
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case ')':
@@ -683,14 +663,14 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
// Basically, this is to skip over things like private{} blocks in a struct or
// class definition that don't add any components to the qualified name.
-private Scope* skipNonQualScopes(Scope* sc) @safe
+Scope* skipNonQualScopes(Scope* sc) @safe
{
while (sc && !sc.scopesym)
sc = sc.enclosing;
return sc;
}
-private bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includeParent)
+bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includeParent)
{
if (!s || s.isPackage() || s.isModule())
return false;
@@ -721,7 +701,7 @@ private bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includ
return true;
}
-private void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader = false)
+void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader = false)
{
Identifier ident;
{
@@ -846,7 +826,7 @@ private void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader
/******************************* emitComment **********************************/
/** Get leading indentation from 'src' which represents lines of code. */
-private size_t getCodeIndent(const(char)* src)
+size_t getCodeIndent(const(char)* src)
{
while (src && (*src == '\r' || *src == '\n'))
++src; // skip until we find the first non-empty line
@@ -860,7 +840,7 @@ private size_t getCodeIndent(const(char)* src)
}
/** Recursively expand template mixin member docs into the scope. */
-private void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Scope* sc)
+void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Scope* sc)
{
if (!tm.semanticRun)
tm.dsymbolSemantic(sc);
@@ -879,7 +859,7 @@ private void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Sc
}
}
-private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
+void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
{
if (!sds.members)
return;
@@ -920,14 +900,14 @@ private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
buf.writestring(")");
}
-private void emitVisibility(ref OutBuffer buf, Import i)
+void emitVisibility(ref OutBuffer buf, Import i)
{
// imports are private by default, which is different from other declarations
// so they should explicitly show their visibility
emitVisibility(buf, i.visibility);
}
-private void emitVisibility(ref OutBuffer buf, Declaration d)
+void emitVisibility(ref OutBuffer buf, Declaration d)
{
auto vis = d.visibility;
if (vis.kind != Visibility.Kind.undefined && vis.kind != Visibility.Kind.public_)
@@ -936,13 +916,13 @@ private void emitVisibility(ref OutBuffer buf, Declaration d)
}
}
-private void emitVisibility(ref OutBuffer buf, Visibility vis)
+void emitVisibility(ref OutBuffer buf, Visibility vis)
{
- visibilityToBuffer(&buf, vis);
+ visibilityToBuffer(buf, vis);
buf.writeByte(' ');
}
-private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
+void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
extern (C++) final class EmitComment : Visitor
{
@@ -1037,7 +1017,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
// Put the ddoc comment as the document 'description'
buf.writestring(ddoc_decl_dd_s);
{
- dc.writeSections(sc, &dc.a, buf);
+ dc.writeSections(sc, &dc.a, *buf);
if (ScopeDsymbol sds = dc.a[0].isScopeDsymbol())
emitMemberComments(sds, *buf, sc);
}
@@ -1226,7 +1206,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
s.accept(v);
}
-private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
+void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
extern (C++) final class ToDocBuffer : Visitor
{
@@ -1246,7 +1226,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
//printf("Dsymbol::toDocbuffer() %s\n", s.toChars());
HdrGenState hgs;
hgs.ddoc = true;
- .toCBuffer(s, buf, &hgs);
+ toCBuffer(s, *buf, hgs);
}
void prefix(Dsymbol s)
@@ -1296,7 +1276,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
HdrGenState hgs;
hgs.ddoc = true;
emitVisibility(*buf, i);
- .toCBuffer(i, buf, &hgs);
+ toCBuffer(i, *buf, hgs);
}
override void visit(Declaration d)
@@ -1315,10 +1295,10 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
Type origType = d.originalType ? d.originalType : d.type;
if (origType.ty == Tfunction)
{
- functionToBufferFull(cast(TypeFunction)origType, buf, d.ident, &hgs, td);
+ functionToBufferFull(cast(TypeFunction)origType, *buf, d.ident, &hgs, td);
}
else
- .toCBuffer(origType, buf, d.ident, &hgs);
+ toCBuffer(origType, *buf, d.ident, hgs);
}
else
buf.writestring(d.ident.toString());
@@ -1331,7 +1311,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
if (i)
buf.writestring(", ");
- toCBuffer((*td.origParameters)[i], buf, &hgs);
+ toCBuffer((*td.origParameters)[i], *buf, hgs);
}
}
buf.writeByte(')');
@@ -1345,7 +1325,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
buf.writestring("$(DDOC_CONSTRAINT ");
}
- .toCBuffer(td.constraint, buf, &hgs);
+ toCBuffer(td.constraint, *buf, hgs);
if (noFuncDecl)
{
@@ -1505,7 +1485,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
else
{
HdrGenState hgs;
- .toCBuffer(bc.type, buf, null, &hgs);
+ toCBuffer(bc.type, *buf, null, hgs);
}
}
buf.writestring(";\n");
@@ -1520,7 +1500,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
buf.writestring(": $(DDOC_ENUM_BASETYPE ");
HdrGenState hgs;
- .toCBuffer(ed.memtype, buf, null, &hgs);
+ toCBuffer(ed.memtype, *buf, null, hgs);
buf.writestring(")");
}
buf.writestring(";\n");
@@ -1540,6 +1520,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
/***********************************************************
*/
+public
struct DocComment
{
Sections sections; // Section*[]
@@ -1872,7 +1853,7 @@ struct DocComment
}
}
- void writeSections(Scope* sc, Dsymbols* a, OutBuffer* buf)
+ void writeSections(Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
//printf("DocComment::writeSections()\n");
@@ -1897,7 +1878,7 @@ struct DocComment
size_t o = buf.length;
buf.write(sec.body_);
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
buf.writestring(")");
}
else
@@ -1928,7 +1909,7 @@ struct DocComment
buf.writestring("----\n");
buf.writestring(codedoc);
buf.writestring("----\n");
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
}
buf.writestring(")");
}
@@ -1948,7 +1929,7 @@ struct DocComment
/*****************************************
* Return true if comment consists entirely of "ditto".
*/
-private bool isDitto(const(char)* comment)
+bool isDitto(const(char)* comment)
{
if (comment)
{
@@ -1962,13 +1943,13 @@ private bool isDitto(const(char)* comment)
/**********************************************
* Skip white space.
*/
-private const(char)* skipwhitespace(const(char)* p)
+const(char)* skipwhitespace(const(char)* p)
{
return skipwhitespace(p.toDString).ptr;
}
/// Ditto
-private const(char)[] skipwhitespace(const(char)[] p) @safe
+const(char)[] skipwhitespace(const(char)[] p) @safe
{
foreach (idx, char c; p)
{
@@ -1993,7 +1974,7 @@ private const(char)[] skipwhitespace(const(char)[] p) @safe
* chars = the characters to skip; order is unimportant
* Returns: the index after skipping characters.
*/
-private size_t skipChars(ref OutBuffer buf, size_t i, string chars) @safe
+size_t skipChars(ref OutBuffer buf, size_t i, string chars) @safe
{
Outer:
foreach (j, c; buf[][i..$])
@@ -2028,7 +2009,7 @@ unittest {
* r = the string to replace `c` with
* Returns: `s` with `c` replaced with `r`
*/
-private inout(char)[] replaceChar(inout(char)[] s, char c, string r) pure @safe
+inout(char)[] replaceChar(inout(char)[] s, char c, string r) pure @safe
{
int count = 0;
foreach (char sc; s)
@@ -2070,7 +2051,7 @@ unittest
* s = the string to lowercase
* Returns: the lowercase version of the string or the original if already lowercase
*/
-private string toLowercase(string s) pure @safe
+string toLowercase(string s) pure @safe
{
string lower;
foreach (size_t i; 0..s.length)
@@ -2112,7 +2093,7 @@ unittest
* to = the index within `buf` to stop counting at, exclusive
* Returns: the indent
*/
-private int getMarkdownIndent(ref OutBuffer buf, size_t from, size_t to) @safe
+int getMarkdownIndent(ref OutBuffer buf, size_t from, size_t to) @safe
{
const slice = buf[];
if (to > slice.length)
@@ -2158,7 +2139,7 @@ size_t skiptoident(ref OutBuffer buf, size_t i) @safe
/************************************************
* Scan forward past end of identifier.
*/
-private size_t skippastident(ref OutBuffer buf, size_t i) @safe
+size_t skippastident(ref OutBuffer buf, size_t i) @safe
{
const slice = buf[];
while (i < slice.length)
@@ -2188,7 +2169,7 @@ private size_t skippastident(ref OutBuffer buf, size_t i) @safe
* Scan forward past end of an identifier that might
* contain dots (e.g. `abc.def`)
*/
-private size_t skipPastIdentWithDots(ref OutBuffer buf, size_t i) @safe
+size_t skipPastIdentWithDots(ref OutBuffer buf, size_t i) @safe
{
const slice = buf[];
bool lastCharWasDot;
@@ -2250,7 +2231,7 @@ private size_t skipPastIdentWithDots(ref OutBuffer buf, size_t i) @safe
* i if not a URL
* index just past it if it is a URL
*/
-private size_t skippastURL(ref OutBuffer buf, size_t i)
+size_t skippastURL(ref OutBuffer buf, size_t i)
{
const slice = buf[][i .. $];
size_t j;
@@ -2295,7 +2276,7 @@ Lno:
* i = an index within `buf`. If `i` is after `iAt` then it gets
* reduced by the length of the removed macro.
*/
-private void removeBlankLineMacro(ref OutBuffer buf, ref size_t iAt, ref size_t i)
+void removeBlankLineMacro(ref OutBuffer buf, ref size_t iAt, ref size_t i)
{
if (!iAt)
return;
@@ -2320,7 +2301,7 @@ private void removeBlankLineMacro(ref OutBuffer buf, ref size_t iAt, ref size_t
* loc = the current location within the file
* Returns: whether a thematic break was replaced
*/
-private bool replaceMarkdownThematicBreak(ref OutBuffer buf, ref size_t i, size_t iLineStart, const ref Loc loc)
+bool replaceMarkdownThematicBreak(ref OutBuffer buf, ref size_t i, size_t iLineStart, const ref Loc loc)
{
const slice = buf[];
@@ -2356,7 +2337,7 @@ private bool replaceMarkdownThematicBreak(ref OutBuffer buf, ref size_t i, size_
* the detected heading level from 1 to 6, or
* 0 if not at an ATX heading
*/
-private int detectAtxHeadingLevel(ref OutBuffer buf, const size_t i) @safe
+int detectAtxHeadingLevel(ref OutBuffer buf, const size_t i) @safe
{
const iHeadingStart = i;
const iAfterHashes = skipChars(buf, i, "#");
@@ -2380,7 +2361,7 @@ private int detectAtxHeadingLevel(ref OutBuffer buf, const size_t i) @safe
* buf = an OutBuffer containing the DDoc
* i = the index within `buf` to start looking for a suffix at
*/
-private void removeAnyAtxHeadingSuffix(ref OutBuffer buf, size_t i)
+void removeAnyAtxHeadingSuffix(ref OutBuffer buf, size_t i)
{
size_t j = i;
size_t iSuffixStart = 0;
@@ -2425,7 +2406,7 @@ private void removeAnyAtxHeadingSuffix(ref OutBuffer buf, size_t i)
* headingLevel = the level (1-6) of heading to end. Is set to `0` when this
* function ends.
*/
-private void endMarkdownHeading(ref OutBuffer buf, size_t iStart, ref size_t iEnd, const ref Loc loc, ref int headingLevel)
+void endMarkdownHeading(ref OutBuffer buf, size_t iStart, ref size_t iEnd, const ref Loc loc, ref int headingLevel)
{
char[5] heading = "$(H0 ";
heading[3] = cast(char) ('0' + headingLevel);
@@ -2446,7 +2427,7 @@ private void endMarkdownHeading(ref OutBuffer buf, size_t iStart, ref size_t iEn
* quoteLevel = the current quote level. Is set to `0` when this function ends.
* Returns: the amount that `i` was moved
*/
-private size_t endAllMarkdownQuotes(ref OutBuffer buf, size_t i, ref int quoteLevel)
+size_t endAllMarkdownQuotes(ref OutBuffer buf, size_t i, ref int quoteLevel)
{
const length = quoteLevel;
for (; quoteLevel > 0; --quoteLevel)
@@ -2468,7 +2449,7 @@ private size_t endAllMarkdownQuotes(ref OutBuffer buf, size_t i, ref int quoteLe
* `0` when this function ends.
* Returns: the amount that `i` was moved
*/
-private size_t endAllListsAndQuotes(ref OutBuffer buf, ref size_t i, ref MarkdownList[] nestedLists, ref int quoteLevel, out int quoteMacroLevel)
+size_t endAllListsAndQuotes(ref OutBuffer buf, ref size_t i, ref MarkdownList[] nestedLists, ref int quoteLevel, out int quoteMacroLevel)
{
quoteMacroLevel = 0;
const i0 = i;
@@ -2487,7 +2468,7 @@ private size_t endAllListsAndQuotes(ref OutBuffer buf, ref size_t i, ref Markdow
* downToLevel = the length within `inlineDelimiters`` to reduce emphasis to
* Returns: the number of characters added to the buffer by the replacements
*/
-private size_t replaceMarkdownEmphasis(ref OutBuffer buf, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, int downToLevel = 0)
+size_t replaceMarkdownEmphasis(ref OutBuffer buf, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, int downToLevel = 0)
{
size_t replaceEmphasisPair(ref MarkdownDelimiter start, ref MarkdownDelimiter end)
{
@@ -2566,7 +2547,7 @@ private size_t replaceMarkdownEmphasis(ref OutBuffer buf, const ref Loc loc, ref
/****************************************************
*/
-private bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
+bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
{
foreach (member; *a)
{
@@ -2608,7 +2589,7 @@ private bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
/****************************************************
*/
-private bool isKeyword(const(char)[] str) @safe
+bool isKeyword(const(char)[] str) @safe
{
immutable string[3] table = ["true", "false", "null"];
foreach (s; table)
@@ -2621,7 +2602,7 @@ private bool isKeyword(const(char)[] str) @safe
/****************************************************
*/
-private TypeFunction isTypeFunction(Dsymbol s) @safe
+TypeFunction isTypeFunction(Dsymbol s) @safe
{
FuncDeclaration f = s.isFuncDeclaration();
/* f.type may be NULL for template members.
@@ -2637,7 +2618,7 @@ private TypeFunction isTypeFunction(Dsymbol s) @safe
/****************************************************
*/
-private Parameter isFunctionParameter(Dsymbol s, const(char)[] str) @safe
+Parameter isFunctionParameter(Dsymbol s, const(char)[] str) @safe
{
TypeFunction tf = isTypeFunction(s);
if (tf && tf.parameterList.parameters)
@@ -2655,7 +2636,7 @@ private Parameter isFunctionParameter(Dsymbol s, const(char)[] str) @safe
/****************************************************
*/
-private Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
+Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
{
foreach (Dsymbol sym; *a)
{
@@ -2670,7 +2651,7 @@ private Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
/****************************************************
*/
-private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
+Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
{
foreach (Dsymbol dsym; *a)
{
@@ -2718,7 +2699,7 @@ private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @sa
/****************************************************
*/
-private TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)
+TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)
{
for (size_t i = 0; i < a.length; i++)
{
@@ -2744,7 +2725,7 @@ private TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_
* Return true if str is a reserved symbol name
* that starts with a double underscore.
*/
-private bool isReservedName(const(char)[] str) @safe
+bool isReservedName(const(char)[] str) @safe
{
immutable string[] table =
[
@@ -2791,7 +2772,7 @@ private bool isReservedName(const(char)[] str) @safe
/****************************************************
* A delimiter for Markdown inline content like emphasis and links.
*/
-private struct MarkdownDelimiter
+struct MarkdownDelimiter
{
size_t iStart; /// the index where this delimiter starts
int count; /// the length of this delimeter's start sequence
@@ -2811,7 +2792,7 @@ private struct MarkdownDelimiter
/****************************************************
* Info about a Markdown list.
*/
-private struct MarkdownList
+struct MarkdownList
{
string orderedStart; /// an optional start number--if present then the list starts at this number
size_t iStart; /// the index where the list item starts
@@ -3028,7 +3009,7 @@ private struct MarkdownList
/****************************************************
* A Markdown link.
*/
-private struct MarkdownLink
+struct MarkdownLink
{
string href; /// the link destination
string title; /// an optional title for the link
@@ -3607,7 +3588,7 @@ private struct MarkdownLink
/**************************************************
* A set of Markdown link references.
*/
-private struct MarkdownLinkReferences
+struct MarkdownLinkReferences
{
MarkdownLink[string] references; // link references keyed by normalized label
MarkdownLink[string] symbols; // link symbols keyed by name
@@ -3872,7 +3853,7 @@ private struct MarkdownLinkReferences
}
}
-private enum TableColumnAlignment
+enum TableColumnAlignment
{
none,
left,
@@ -3893,7 +3874,7 @@ private enum TableColumnAlignment
* columnAlignments = alignments to populate for each column
* Returns: the index of the end of the parsed delimiter, or `0` if not found
*/
-private size_t parseTableDelimiterRow(ref OutBuffer buf, const size_t iStart, bool inQuote, ref TableColumnAlignment[] columnAlignments) @safe
+size_t parseTableDelimiterRow(ref OutBuffer buf, const size_t iStart, bool inQuote, ref TableColumnAlignment[] columnAlignments) @safe
{
size_t i = skipChars(buf, iStart, inQuote ? ">| \t" : "| \t");
while (i < buf.length && buf[i] != '\r' && buf[i] != '\n')
@@ -3945,7 +3926,7 @@ private size_t parseTableDelimiterRow(ref OutBuffer buf, const size_t iStart, bo
* columnAlignments = the parsed alignments for each column
* Returns: the number of characters added by starting the table, or `0` if unchanged
*/
-private size_t startTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, bool inQuote, ref MarkdownDelimiter[] inlineDelimiters, out TableColumnAlignment[] columnAlignments)
+size_t startTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, bool inQuote, ref MarkdownDelimiter[] inlineDelimiters, out TableColumnAlignment[] columnAlignments)
{
const iDelimiterRowEnd = parseTableDelimiterRow(buf, iEnd + 1, inQuote, columnAlignments);
if (iDelimiterRowEnd)
@@ -3981,7 +3962,7 @@ private size_t startTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const r
* delta = the number of characters added by replacing the row, or `0` if unchanged
* Returns: `true` if a table row was found and replaced
*/
-private bool replaceTableRow(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, TableColumnAlignment[] columnAlignments, bool headerRow, out size_t delta)
+bool replaceTableRow(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, TableColumnAlignment[] columnAlignments, bool headerRow, out size_t delta)
{
delta = 0;
@@ -4108,7 +4089,7 @@ private bool replaceTableRow(ref OutBuffer buf, size_t iStart, size_t iEnd, cons
* columnAlignments = alignments for each column; upon return is set to length `0`
* Returns: the number of characters added by ending the table, or `0` if unchanged
*/
-private size_t endTable(ref OutBuffer buf, size_t i, ref TableColumnAlignment[] columnAlignments)
+size_t endTable(ref OutBuffer buf, size_t i, ref TableColumnAlignment[] columnAlignments)
{
if (!columnAlignments.length)
return 0;
@@ -4130,7 +4111,7 @@ private size_t endTable(ref OutBuffer buf, size_t i, ref TableColumnAlignment[]
* columnAlignments = alignments for each column; upon return is set to length `0`
* Returns: the number of characters added by replacing the row, or `0` if unchanged
*/
-private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, ref TableColumnAlignment[] columnAlignments)
+size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, ref TableColumnAlignment[] columnAlignments)
{
size_t delta;
replaceTableRow(buf, iStart, iEnd, loc, inlineDelimiters, columnAlignments, false, delta);
@@ -4148,7 +4129,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con
* buf = an OutBuffer containing the DDoc
* offset = the index within buf to start highlighting
*/
-private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
+void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
{
const incrementLoc = loc.linnum == 0 ? 1 : 0;
loc.linnum = loc.linnum + incrementLoc;
@@ -4417,7 +4398,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
codebuf.write(buf[iCodeStart + count .. i]);
// escape the contents, but do not perform highlighting except for DDOC_PSYMBOL
highlightCode(sc, a, codebuf, 0);
- escapeStrayParenthesis(loc, &codebuf, 0, false, sc.eSink);
+ escapeStrayParenthesis(loc, codebuf, 0, false, sc.eSink);
buf.remove(iCodeStart, i - iCodeStart + count); // also trimming off the current `
immutable pre = "$(DDOC_BACKQUOTED ";
i = buf.insert(iCodeStart, pre);
@@ -4626,7 +4607,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
highlightCode2(sc, a, codebuf, 0);
else
codebuf.remove(codebuf.length-1, 1); // remove the trailing 0 byte
- escapeStrayParenthesis(loc, &codebuf, 0, false, sc.eSink);
+ escapeStrayParenthesis(loc, codebuf, 0, false, sc.eSink);
buf.remove(iCodeStart, i - iCodeStart);
i = buf.insert(iCodeStart, codebuf[]);
i = buf.insert(i, ")\n");
@@ -5002,7 +4983,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
/**************************************************
* Highlight code for DDOC section.
*/
-private void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offset)
+void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offset)
{
auto imp = s.isImport();
if (imp && imp.aliases.length > 0)
@@ -5037,7 +5018,7 @@ private void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offse
/****************************************************
*/
-private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
+void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
{
//printf("highlightCode(a = '%s')\n", a.toChars());
bool resolvedTemplateParameters = false;
@@ -5119,7 +5100,7 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
size_t lastOffset = parametersBuf.length;
- .toCBuffer(tp, ¶metersBuf, &hgs);
+ toCBuffer(tp, parametersBuf, hgs);
paramLens[parami] = parametersBuf.length - lastOffset;
}
@@ -5163,7 +5144,7 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
/****************************************
*/
-private void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const(char)* pend)
+void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const(char)* pend)
{
for (; p < pend; p++)
{
@@ -5178,7 +5159,7 @@ private void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const(
/**************************************************
* Highlight code for CODE section.
*/
-private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
+void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
{
scope eSinkNull = new ErrorSinkNull();
@@ -5236,7 +5217,7 @@ private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of
* https://issues.dlang.org/show_bug.cgi?id=7715
* https://issues.dlang.org/show_bug.cgi?id=10519
*/
- escapeDdocString(&res, o);
+ escapeDdocString(res, o);
res.writeByte(')');
}
else
@@ -5252,7 +5233,7 @@ private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of
/****************************************
* Determine if p points to the start of a "..." parameter identifier.
*/
-private bool isCVariadicArg(const(char)[] p) @nogc nothrow pure @safe
+bool isCVariadicArg(const(char)[] p) @nogc nothrow pure @safe
{
return p.length >= 3 && p[0 .. 3] == "...";
}
@@ -5260,6 +5241,7 @@ private bool isCVariadicArg(const(char)[] p) @nogc nothrow pure @safe
/****************************************
* Determine if p points to the start of an identifier.
*/
+@trusted
bool isIdStart(const(char)* p) @nogc nothrow pure
{
dchar c = *p;
@@ -5279,6 +5261,7 @@ bool isIdStart(const(char)* p) @nogc nothrow pure
/****************************************
* Determine if p points to the rest of an identifier.
*/
+@trusted
bool isIdTail(const(char)* p) @nogc nothrow pure
{
dchar c = *p;
@@ -5298,7 +5281,7 @@ bool isIdTail(const(char)* p) @nogc nothrow pure
/****************************************
* Determine if p points to the indentation space.
*/
-private bool isIndentWS(const(char)* p) @nogc nothrow pure @safe
+bool isIndentWS(const(char)* p) @nogc nothrow pure @safe
{
return (*p == ' ') || (*p == '\t');
}
@@ -5316,7 +5299,7 @@ int utfStride(const(char)* p) @nogc nothrow pure
return cast(int)i;
}
-private inout(char)* stripLeadingNewlines(inout(char)* s) @nogc nothrow pure
+inout(char)* stripLeadingNewlines(inout(char)* s) @nogc nothrow pure
{
while (s && *s == '\n' || *s == '\r')
s++;
diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h
index 669e308dcf6..562427f1a4d 100644
--- a/gcc/d/dmd/doc.h
+++ b/gcc/d/dmd/doc.h
@@ -13,4 +13,5 @@
class Module;
class ErrorSink;
-void gendocfile(Module *m, ErrorSink *eSink);
+void gendocfile(Module *m, const char *ddoctext_ptr, size_t ddoctext_length,
+ const char *datetime, ErrorSink *eSink, OutBuffer &outbuf);
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index c2c0628f5ed..981e093934c 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -169,6 +169,7 @@ extern (C++) struct Scope
sc.scopesym = new ScopeDsymbol();
sc.scopesym.symtab = new DsymbolTable();
sc.eSink = eSink;
+ assert(eSink);
// Add top level package as member of this global scope
Dsymbol m = _module;
while (m.parent)
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index 49b98411ad3..a131a8a721c 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -105,6 +105,7 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
if (!sc) // inline may request TypeInfo.
{
Scope scx;
+ scx.eSink = global.errorSink;
scx._module = sd.getModule();
getTypeInfoType(sd.loc, t, &scx);
sd.requestTypeInfo = true;
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 0fa4dbcfa5c..c9a2c92194b 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -1801,6 +1801,7 @@ public:
if (!tfgetmembers)
{
Scope sc;
+ sc.eSink = global.errorSink;
auto parameters = new Parameters();
Parameters* p = new Parameter(STC.in_, Type.tchar.constOf().arrayOf(), null, null);
parameters.push(p);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 378d3e6dd64..ebdd3a8566d 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -83,7 +83,7 @@ else version = MARS;
enum LOG = false;
-private uint setMangleOverride(Dsymbol s, const(char)[] sym)
+package uint setMangleOverride(Dsymbol s, const(char)[] sym)
{
if (s.isFuncDeclaration() || s.isVarDeclaration())
{
@@ -766,7 +766,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else
{
OutBuffer buf;
- stcToBuffer(&buf, stc);
+ stcToBuffer(buf, stc);
dsym.error("cannot be `%s`", buf.peekChars());
}
dsym.storage_class &= ~stc; // strip off
@@ -783,7 +783,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (stc)
{
OutBuffer buf;
- stcToBuffer(&buf, stc);
+ stcToBuffer(buf, stc);
dsym.error("cannot be `scope` and `%s`", buf.peekChars());
}
else if (dsym.isMember())
@@ -1121,11 +1121,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (ne.member && !(ne.member.storage_class & STC.scope_))
{
import dmd.escape : setUnsafeDIP1000;
- const inSafeFunc = sc.func && sc.func.isSafeBypassingInference();
+ const inSafeFunc = sc.func && sc.func.isSafeBypassingInference(); // isSafeBypassingInference may call setUnsafe().
if (sc.setUnsafeDIP1000(false, dsym.loc, "`scope` allocation of `%s` requires that constructor be annotated with `scope`", dsym))
errorSupplemental(ne.member.loc, "is the location of the constructor");
- else if (global.params.obsolete && inSafeFunc)
- warningSupplemental(ne.member.loc, "is the location of the constructor");
}
ne.onstack = 1;
dsym.onstack = true;
@@ -1512,11 +1510,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
ob.writestring(") : ");
// use visibility instead of sc.visibility because it couldn't be
// resolved yet, see the comment above
- visibilityToBuffer(ob, imp.visibility);
+ visibilityToBuffer(*ob, imp.visibility);
ob.writeByte(' ');
if (imp.isstatic)
{
- stcToBuffer(ob, STC.static_);
+ stcToBuffer(*ob, STC.static_);
ob.writeByte(' ');
}
ob.writestring(": ");
@@ -2528,9 +2526,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (!em.ed.isAnonymous())
em.ed.memtype = t;
}
+ const errors = global.startGagging();
Expression e = new IntegerExp(em.loc, 0, t);
e = e.ctfeInterpret();
-
+ if (global.endGagging(errors))
+ {
+ error(em.loc, "cannot generate 0 value of type `%s` for `%s`",
+ t.toChars(), em.toChars());
+ }
// save origValue for better json output
em.origValue = e;
@@ -2564,7 +2567,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (emprev.errors)
return errorReturn();
+ auto errors = global.startGagging();
Expression eprev = emprev.value;
+ assert(eprev);
// .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
? em.ed.memtype
@@ -2578,12 +2583,23 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
emax = emax.expressionSemantic(sc);
emax = emax.ctfeInterpret();
- // Set value to (eprev + 1).
- // But first check that (eprev != emax)
- assert(eprev);
+ // check that (eprev != emax)
Expression e = new EqualExp(EXP.equal, em.loc, eprev, emax);
e = e.expressionSemantic(sc);
e = e.ctfeInterpret();
+ if (global.endGagging(errors))
+ {
+ // display an introductory error before showing what actually failed
+ error(em.loc, "cannot check `%s` value for overflow", em.toPrettyChars());
+ // rerun to show errors
+ Expression e2 = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
+ e2 = e2.expressionSemantic(sc);
+ e2 = e2.ctfeInterpret();
+ e2 = new EqualExp(EXP.equal, em.loc, eprev, e2);
+ e2 = e2.expressionSemantic(sc);
+ e2 = e2.ctfeInterpret();
+ }
+ // now any errors are for generating a value
if (e.toInteger())
{
auto mt = em.ed.memtype;
@@ -2593,13 +2609,21 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
emprev.ed.toChars(), emprev.toChars(), mt.toChars());
return errorReturn();
}
-
+ errors = global.startGagging();
// Now set e to (eprev + 1)
e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
e = e.expressionSemantic(sc);
e = e.castTo(sc, eprev.type);
e = e.ctfeInterpret();
-
+ if (global.endGagging(errors))
+ {
+ error(em.loc, "cannot generate value for `%s`", em.toPrettyChars());
+ // rerun to show errors
+ Expression e2 = new AddExp(em.loc, eprev, IntegerExp.literal!1);
+ e2 = e2.expressionSemantic(sc);
+ e2 = e2.castTo(sc, eprev.type);
+ e2 = e2.ctfeInterpret();
+ }
// save origValue (without cast) for better json output
if (e.op != EXP.error) // avoid duplicate diagnostics
{
@@ -3351,7 +3375,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
{
OutBuffer buf;
- MODtoBuffer(&buf, tf.mod);
+ MODtoBuffer(buf, tf.mod);
funcdecl.error("without `this` cannot be `%s`", buf.peekChars());
tf.mod = 0; // remove qualifiers
}
@@ -3889,7 +3913,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
OutBuffer buf;
auto fd = s.isFuncDeclaration();
- functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,
+ functionToBufferFull(cast(TypeFunction)(funcdecl.type), buf,
new Identifier(funcdecl.toPrettyChars()), &hgs, null);
const(char)* funcdeclToChars = buf.peekChars();
@@ -3912,7 +3936,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
else
{
- functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,
+ functionToBufferFull(cast(TypeFunction)(fd.type), buf1,
new Identifier(fd.toPrettyChars()), &hgs, null);
error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index e492c7e7aef..67ca2ef66a4 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -750,7 +750,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
if (i)
buf.writestring(", ");
- .toCBuffer(tp, &buf, &hgs);
+ toCBuffer(tp, buf, hgs);
}
buf.writeByte(')');
@@ -768,7 +768,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
constraint)
{
buf.writestring(" if (");
- .toCBuffer(constraint, &buf, &hgs);
+ toCBuffer(constraint, buf, hgs);
buf.writeByte(')');
}
@@ -865,7 +865,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
if (!fparam.ident)
continue;
// don't add it, if it has no name
- auto v = new VarDeclaration(loc, fparam.type, fparam.ident, null);
+ auto v = new VarDeclaration(fparam.loc, fparam.type, fparam.ident, null);
fparam.storageClass |= STC.parameter;
v.storage_class = fparam.storageClass;
v.dsymbolSemantic(scx);
@@ -6024,14 +6024,14 @@ extern (C++) class TemplateInstance : ScopeDsymbol
override const(char)* toChars() const
{
OutBuffer buf;
- toCBufferInstance(this, &buf);
+ toCBufferInstance(this, buf);
return buf.extractChars();
}
override final const(char)* toPrettyCharsHelper()
{
OutBuffer buf;
- toCBufferInstance(this, &buf, true);
+ toCBufferInstance(this, buf, true);
return buf.extractChars();
}
@@ -6058,11 +6058,9 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
case Classification.error:
return &errorSupplemental;
- case Classification.warning:
- return &warningSupplemental;
case Classification.deprecation:
return &deprecationSupplemental;
- case Classification.gagged, Classification.tip:
+ case Classification.gagged, Classification.tip, Classification.warning:
assert(0);
}
}();
@@ -7056,10 +7054,10 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (td_ambig)
{
- .error(loc, "%s `%s.%s` matches more than one template declaration:\n%s: `%s`\nand\n%s: `%s`",
- td_best.kind(), td_best.parent.toPrettyChars(), td_best.ident.toChars(),
- td_best.loc.toChars(), td_best.toChars(),
- td_ambig.loc.toChars(), td_ambig.toChars());
+ .error(loc, "%s `%s.%s` matches more than one template declaration:",
+ td_best.kind(), td_best.parent.toPrettyChars(), td_best.ident.toChars());
+ .errorSupplemental(td_best.loc, "`%s`\nand:", td_best.toChars());
+ .errorSupplemental(td_ambig.loc, "`%s`", td_ambig.toChars());
return false;
}
if (td_best)
@@ -7825,7 +7823,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
override const(char)* toChars() const
{
OutBuffer buf;
- toCBufferInstance(this, &buf);
+ toCBufferInstance(this, buf);
return buf.extractChars();
}
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 6a7442ad702..d5f658a8a42 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -199,7 +199,8 @@ struct _d_dynamicArray final
else
{
const(char)[] name = FileName.combine(global.params.cxxhdr.dir, global.params.cxxhdr.name);
- writeFile(Loc.initial, name, buf[]);
+ if (!writeFile(Loc.initial, name, buf[]))
+ return fatal();
}
}
@@ -2327,7 +2328,12 @@ public:
{
//printf("%s %d\n", p.defaultArg.toChars, p.defaultArg.op);
buf.writestring(" = ");
+ // Always emit the FDN of a symbol for the default argument,
+ // to avoid generating an ambiguous assignment.
+ auto save = adparent;
+ adparent = null;
printExpressionFor(p.type, p.defaultArg);
+ adparent = save;
}
}
@@ -2636,7 +2642,7 @@ public:
import dmd.hdrgen;
// Hex floating point literals were introduced in C++ 17
const allowHex = global.params.cplusplus >= CppStdRevision.cpp17;
- floatToBuffer(e.type, e.value, buf, allowHex);
+ floatToBuffer(e.type, e.value, *buf, allowHex);
}
}
diff --git a/gcc/d/dmd/errors.h b/gcc/d/dmd/errors.h
index c6b5975113a..759ad277fda 100644
--- a/gcc/d/dmd/errors.h
+++ b/gcc/d/dmd/errors.h
@@ -14,6 +14,7 @@
struct Loc;
+// Constants used to discriminate kinds of error messages.
enum class ErrorKind
{
warning = 0,
@@ -43,7 +44,7 @@ D_ATTRIBUTE_FORMAT(1, 2) void message(const char *format, ...);
D_ATTRIBUTE_FORMAT(2, 3) void message(const Loc& loc, const char *format, ...);
D_ATTRIBUTE_FORMAT(1, 2) void tip(const char *format, ...);
-D_ATTRIBUTE_FORMAT(2, 0) void verrorReport(const Loc& loc, const char *format, va_list ap, const char *p1 = NULL, const char *p2 = NULL);
+D_ATTRIBUTE_FORMAT(2, 0) void verrorReport(const Loc& loc, const char *format, va_list ap, ErrorKind kind, const char *p1 = NULL, const char *p2 = NULL);
D_ATTRIBUTE_FORMAT(2, 0) void verrorReportSupplemental(const Loc& loc, const char* format, va_list ap, ErrorKind kind);
#if defined(__GNUC__) || defined(__clang__)
diff --git a/gcc/d/dmd/errorsink.d b/gcc/d/dmd/errorsink.d
index e14829ecfdb..ce2351738d6 100644
--- a/gcc/d/dmd/errorsink.d
+++ b/gcc/d/dmd/errorsink.d
@@ -62,6 +62,7 @@ class ErrorSinkNull : ErrorSink
/*****************************************
* Simplest implementation, just sends messages to stderr.
+ * See also: ErrorSinkCompiler.
*/
class ErrorSinkStderr : ErrorSink
{
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index f817a4ee42f..8562e2eabd6 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -37,6 +37,8 @@ import dmd.tokens;
import dmd.visitor;
import dmd.arraytypes;
+private:
+
/// Groups global state for escape checking together
package(dmd) struct EscapeState
{
@@ -69,6 +71,7 @@ package(dmd) struct EscapeState
* Returns:
* `true` if error
*/
+public
bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
Expression ethis, Expressions* arguments, bool gag)
{
@@ -179,7 +182,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
const(char)* msg = eb.isMutable && eb2.isMutable
? "more than one mutable reference %s `%s` in arguments to `%s()`"
: "mutable and const references %s `%s` in arguments to `%s()`";
- error((*arguments)[i].loc, msg,
+ sc.eSink.error((*arguments)[i].loc, msg,
referenceVerb,
v.toChars(),
fd ? fd.toPrettyChars() : "indirectly");
@@ -226,6 +229,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
* Returns:
* `true` if any elements escaped
*/
+public
bool checkArrayLiteralEscape(Scope *sc, ArrayLiteralExp ae, bool gag)
{
bool errors;
@@ -249,6 +253,7 @@ bool checkArrayLiteralEscape(Scope *sc, ArrayLiteralExp ae, bool gag)
* Returns:
* `true` if any elements escaped
*/
+public
bool checkAssocArrayLiteralEscape(Scope *sc, AssocArrayLiteralExp ae, bool gag)
{
bool errors;
@@ -274,6 +279,7 @@ bool checkAssocArrayLiteralEscape(Scope *sc, AssocArrayLiteralExp ae, bool gag)
* v = parameter that was not inferred
* recursionLimit = recursion limit for printing the reason
*/
+private
void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
{
recursionLimit--;
@@ -316,12 +322,13 @@ void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
* Returns:
* `true` if pointers to the stack can escape via assignment
*/
+public
bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag)
{
enum log = false;
- if (log) printf("checkParamArgumentEscape(arg: %s par: %s)\n",
+ if (log) printf("checkParamArgumentEscape(arg: %s par: %s parSTC: %llx)\n",
arg ? arg.toChars() : "null",
- parId ? parId.toChars() : "null");
+ parId ? parId.toChars() : "null", parStc);
//printf("type = %s, %d\n", arg.type.toChars(), arg.type.hasPointers());
if (!arg.type.hasPointers())
@@ -334,7 +341,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
if (parStc & STC.scope_)
{
// These errors only apply to non-scope parameters
- // When the paraneter is `scope`, only `checkScopeVarAddr` on `er.byref` is needed
+ // When the parameter is `scope`, only `checkScopeVarAddr` on `er.byref` is needed
er.byfunc.setDim(0);
er.byvalue.setDim(0);
er.byexp.setDim(0);
@@ -467,6 +474,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
* Returns:
* `true` if assignment to `firstArg` would cause an error
*/
+public
bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Parameter param, bool gag)
{
enum log = false;
@@ -502,6 +510,7 @@ bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Pa
* Returns:
* `true` if construction would cause an escaping reference error
*/
+public
bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
{
enum log = false;
@@ -543,6 +552,7 @@ bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
}
/// How a `return` parameter escapes its pointer value
+public
enum ReturnParamDest
{
returnVal, /// through return statement: `return x`
@@ -564,6 +574,7 @@ enum ReturnParamDest
* tthis = type of `this` parameter, or `null` if none
* Returns: What a `return` parameter should transfer the lifetime of the argument to
*/
+public
ReturnParamDest returnParamDest(TypeFunction tf, Type tthis)
{
assert(tf);
@@ -596,6 +607,7 @@ ReturnParamDest returnParamDest(TypeFunction tf, Type tthis)
* Returns:
* `true` if pointers to the stack can escape via assignment
*/
+public
bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
{
enum log = false;
@@ -912,7 +924,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
!(va && va.storage_class & STC.temp))
{
if (!gag)
- deprecation(ee.loc, "slice of static array temporary returned by `%s` assigned to longer lived variable `%s`",
+ sc.eSink.deprecation(ee.loc, "slice of static array temporary returned by `%s` assigned to longer lived variable `%s`",
ee.toChars(), e1.toChars());
//result = true;
continue;
@@ -959,6 +971,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkThrowEscape(Scope* sc, Expression e, bool gag)
{
//printf("[%s] checkThrowEscape, e = %s\n", e.loc.toChars(), e.toChars());
@@ -1002,6 +1015,7 @@ bool checkThrowEscape(Scope* sc, Expression e, bool gag)
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
import dmd.globals: FeatureState;
@@ -1124,7 +1138,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
if (log) printf("byexp %s\n", ee.toChars());
if (!gag)
- error(ee.loc, "storing reference to stack allocated value returned by `%s` into allocated memory causes it to escape",
+ sc.eSink.error(ee.loc, "storing reference to stack allocated value returned by `%s` into allocated memory causes it to escape",
ee.toChars());
result = true;
}
@@ -1144,6 +1158,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkReturnEscape(Scope* sc, Expression e, bool gag)
{
//printf("[%s] checkReturnEscape, e: %s\n", e.loc.toChars(), e.toChars());
@@ -1161,6 +1176,7 @@ bool checkReturnEscape(Scope* sc, Expression e, bool gag)
* Returns:
* `true` if references to the stack can escape
*/
+public
bool checkReturnEscapeRef(Scope* sc, Expression e, bool gag)
{
version (none)
@@ -1266,7 +1282,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
else if (v.isTypesafeVariadicArray && p == sc.func)
{
if (!gag)
- error(e.loc, "returning `%s` escapes a reference to variadic parameter `%s`", e.toChars(), v.toChars());
+ sc.eSink.error(e.loc, "returning `%s` escapes a reference to variadic parameter `%s`", e.toChars(), v.toChars());
result = false;
}
else
@@ -1420,7 +1436,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
else
{
if (!gag)
- error(ee.loc, "escaping reference to stack allocated value returned by `%s`", ee.toChars());
+ sc.eSink.error(ee.loc, "escaping reference to stack allocated value returned by `%s`", ee.toChars());
result = true;
}
}
@@ -1434,6 +1450,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
* va = variable to infer scope for
* Returns: `true` if succesful or already `scope`
*/
+private
bool inferScope(VarDeclaration va)
{
if (!va)
@@ -1526,6 +1543,7 @@ private bool inferReturn(FuncDeclaration fd, VarDeclaration v, bool returnScope)
* live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`.
* retRefTransition = if `e` is returned through a `return ref scope` function call
*/
+public
void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false)
{
//printf("[%s] escapeByValue, e: %s\n", e.loc.toChars(), e.toChars());
@@ -1924,6 +1942,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
* live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`.
* retRefTransition = if `e` is returned through a `return ref scope` function call
*/
+private
void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false)
{
//printf("[%s] escapeByRef, e: %s, retRefTransition: %d\n", e.loc.toChars(), e.toChars(), retRefTransition);
@@ -2158,6 +2177,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
/************************************
* Aggregate the data collected by the escapeBy??() functions.
*/
+public
struct EscapeByResults
{
VarDeclarations byref; // array into which variables being returned by ref are inserted
@@ -2295,6 +2315,7 @@ private void doNotInferScope(VarDeclaration v, RootObject o)
* f = final function type. `funcdecl.type` started as the 'premature type' before attribute
* inference, then its inferred attributes are copied over to final type `f`
*/
+public
void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
{
@@ -2427,6 +2448,7 @@ private void eliminateMaybeScopes(VarDeclaration[] array)
* Returns:
* true if it's a pointer (or reference) to mutable data
*/
+private
bool isReferenceToMutable(Type t)
{
t = t.baseElemOf();
@@ -2486,6 +2508,7 @@ bool isReferenceToMutable(Type t)
* Returns:
* true if it's a pointer (or reference) to mutable data
*/
+private
bool isReferenceToMutable(Parameter p, Type t)
{
if (p.isReference())
@@ -2561,6 +2584,7 @@ private void addMaybe(VarDeclaration va, VarDeclaration v)
}
// `setUnsafePreview` partially evaluated for dip1000
+public
bool setUnsafeDIP1000(Scope* sc, bool gag, Loc loc, const(char)* msg,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 07cc8d4b7e8..99f65879046 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -40,6 +40,7 @@ import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.escape;
import dmd.expressionsem;
import dmd.func;
@@ -813,7 +814,7 @@ extern (C++) abstract class Expression : ASTNode
{
OutBuffer buf;
HdrGenState hgs;
- toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
return buf.extractChars();
}
@@ -1186,7 +1187,7 @@ extern (C++) abstract class Expression : ASTNode
return checkValue();
}
- extern (D) final bool checkArithmetic()
+ extern (D) final bool checkArithmetic(EXP op)
{
if (op == EXP.error)
return true;
@@ -1194,7 +1195,11 @@ extern (C++) abstract class Expression : ASTNode
return true;
if (!type.isintegral() && !type.isfloating())
{
- error("`%s` is not of arithmetic type, it is a `%s`", toChars(), type.toChars());
+ // unary aggregate ops error here
+ const char* msg = type.isAggregate() ?
+ "operator `%s` is not defined for `%s` of type `%s`" :
+ "illegal operator `%s` for `%s` of type `%s`";
+ error(msg, EXPtoString(op).ptr, toChars(), type.toChars());
return true;
}
return checkValue();
@@ -3250,6 +3255,8 @@ extern (C++) final class AssocArrayLiteralExp : Expression
Expressions* keys;
Expressions* values;
+ /// Lower to core.internal.newaa for static initializaton
+ Expression lowering;
extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values) @safe
{
@@ -4036,13 +4043,11 @@ extern (C++) final class FuncExp : Expression
return new FuncExp(loc, fd);
}
- extern (D) MATCH matchType(Type to, Scope* sc, FuncExp* presult, int flag = 0)
+ extern (D) MATCH matchType(Type to, Scope* sc, FuncExp* presult, ErrorSink eSink)
{
-
- static MATCH cannotInfer(Expression e, Type to, int flag)
+ MATCH cannotInfer()
{
- if (!flag)
- e.error("cannot infer parameter types from `%s`", to.toChars());
+ eSink.error(loc, "cannot infer parameter types from `%s`", to.toChars());
return MATCH.nomatch;
}
@@ -4055,8 +4060,7 @@ extern (C++) final class FuncExp : Expression
{
if (tok == TOK.function_)
{
- if (!flag)
- error("cannot match function literal to delegate type `%s`", to.toChars());
+ eSink.error(loc, "cannot match function literal to delegate type `%s`", to.toChars());
return MATCH.nomatch;
}
tof = cast(TypeFunction)to.nextOf();
@@ -4065,8 +4069,7 @@ extern (C++) final class FuncExp : Expression
{
if (tok == TOK.delegate_)
{
- if (!flag)
- error("cannot match delegate literal to function pointer type `%s`", to.toChars());
+ eSink.error(loc, "cannot match delegate literal to function pointer type `%s`", to.toChars());
return MATCH.nomatch;
}
}
@@ -4075,7 +4078,7 @@ extern (C++) final class FuncExp : Expression
{
if (!tof)
{
- return cannotInfer(this, to, flag);
+ return cannotInfer();
}
// Parameter types inference from 'tof'
@@ -4086,7 +4089,7 @@ extern (C++) final class FuncExp : Expression
const dim = tf.parameterList.length;
if (tof.parameterList.length != dim || tof.parameterList.varargs != tf.parameterList.varargs)
- return cannotInfer(this, to, flag);
+ return cannotInfer();
auto tiargs = new Objects();
tiargs.reserve(td.parameters.length);
@@ -4106,7 +4109,7 @@ extern (C++) final class FuncExp : Expression
Parameter pto = tof.parameterList[u];
Type t = pto.type;
if (t.ty == Terror)
- return cannotInfer(this, to, flag);
+ return cannotInfer();
tf.parameterList[u].storageClass = tof.parameterList[u].storageClass;
tiargs.push(t);
}
@@ -4124,9 +4127,9 @@ extern (C++) final class FuncExp : Expression
if (ex.op == EXP.error)
return MATCH.nomatch;
if (auto ef = ex.isFuncExp())
- return ef.matchType(to, sc, presult, flag);
+ return ef.matchType(to, sc, presult, eSink);
else
- return cannotInfer(this, to, flag);
+ return cannotInfer();
}
if (!tof || !tof.next)
@@ -4198,10 +4201,10 @@ extern (C++) final class FuncExp : Expression
(*presult).fd.modifyReturns(sc, tof.next);
}
}
- else if (!flag)
+ else if (!cast(ErrorSinkNull)eSink)
{
auto ts = toAutoQualChars(tx, to);
- error("cannot implicitly convert expression `%s` of type `%s` to `%s`",
+ eSink.error(loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
toChars(), ts[0], ts[1]);
}
return m;
@@ -4674,8 +4677,8 @@ extern (C++) abstract class BinExp : Expression
extern (D) final bool checkArithmeticBin()
{
- bool r1 = e1.checkArithmetic();
- bool r2 = e2.checkArithmetic();
+ bool r1 = e1.checkArithmetic(this.op);
+ bool r2 = e2.checkArithmetic(this.op);
return (r1 || r2);
}
@@ -7217,7 +7220,7 @@ extern (C++) final class PrettyFuncInitExp : DefaultInitExp
{
const funcStr = fd.Dsymbol.toPrettyChars();
OutBuffer buf;
- functionToBufferWithIdent(fd.type.isTypeFunction(), &buf, funcStr, fd.isStatic);
+ functionToBufferWithIdent(fd.type.isTypeFunction(), buf, funcStr, fd.isStatic);
s = buf.extractChars();
}
else
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 1f04c6cb1db..2189757e61f 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -94,7 +94,7 @@ public:
const char *toChars() const override;
void error(const char *format, ...) const;
- void warning(const char *format, ...) const;
+ void warning(unsigned flag, const char *format, ...) const;
void deprecation(const char *format, ...) const;
virtual dinteger_t toInteger();
@@ -446,6 +446,7 @@ public:
OwnedBy ownedByCtfe;
Expressions *keys;
Expressions *values;
+ Expression* lowering;
bool equals(const RootObject * const o) const override;
AssocArrayLiteralExp *syntaxCopy() override;
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 69999cbf32a..30382bbc6bb 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -1197,6 +1197,11 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
if (thisAd == requiredAd)
return true;
+ // if outerfunc is the member of a nested aggregate, then let
+ // getRightThis take care of this.
+ if (thisAd.isNested())
+ return true;
+
// outerfunc is the member of a base class that contains calledFunc,
// then we consider that they have the same this.
auto cd = requiredAd.isClassDeclaration();
@@ -1206,11 +1211,6 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
if (cd.isBaseOf2(thisAd.isClassDeclaration()))
return true;
- // if outerfunc is the member of a nested aggregate, then let
- // getRightThis take care of this.
- if (thisAd.isNested())
- return true;
-
return false;
}
@@ -2319,6 +2319,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
}
err |= arg.checkValue();
err |= arg.checkSharedAccess(sc);
+ err |= checkParamArgumentEscape(sc, fd, Id.dotdotdot, null, cast(STC) tf.parameterList.stc, arg, false, false);
arg = arg.optimize(WANTvalue);
}
(*arguments)[i] = arg;
@@ -2331,14 +2332,14 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
{
if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
{
- checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
+ checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list, sc.eSink);
}
}
else if (fd && fd.scanf)
{
if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
{
- checkScanfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
+ checkScanfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list, sc.eSink);
}
}
else
@@ -2528,7 +2529,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
auto args = new Parameters(arguments.length - nparams);
for (size_t i = 0; i < arguments.length - nparams; i++)
{
- auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);
+ Expression earg = (*arguments)[nparams + i];
+ auto arg = new Parameter(earg.loc, STC.in_, earg.type, null, null, null);
(*args)[i] = arg;
}
auto tup = new TypeTuple(args);
@@ -3889,10 +3891,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
foreach (v; c.fields)
{
if (v.inuse || v._scope is null || v._init is null ||
- v._init.isVoidInitializer())
+ v._init.isVoidInitializer() || v.semanticRun >= PASS.semantic2done)
continue;
v.inuse++;
v._init = v._init.initializerSemantic(v._scope, v.type, INITinterpret);
+ import dmd.semantic2 : lowerStaticAAs;
+ lowerStaticAAs(v, sc);
v.inuse--;
}
}
@@ -4312,7 +4316,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.fd.treq) // defer type determination
{
FuncExp fe;
- if (exp.matchType(exp.fd.treq, sc, &fe) > MATCH.nomatch)
+ if (exp.matchType(exp.fd.treq, sc, &fe, sc.eSink) > MATCH.nomatch)
e = fe;
else
e = ErrorExp.get();
@@ -5275,10 +5279,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
OutBuffer buf;
buf.writeByte('(');
- argExpTypesToCBuffer(&buf, exp.arguments);
+ argExpTypesToCBuffer(buf, exp.arguments);
buf.writeByte(')');
if (tthis)
- tthis.modToBuffer(&buf);
+ tthis.modToBuffer(buf);
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
.error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
@@ -5348,7 +5352,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
OutBuffer buf;
buf.writeByte('(');
- argExpTypesToCBuffer(&buf, exp.arguments);
+ argExpTypesToCBuffer(buf, exp.arguments);
buf.writeByte(')');
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
@@ -5947,7 +5951,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* b = (*cd.baseclasses)[i];
- args.push(new Parameter(STC.in_, b.type, null, null, null));
+ args.push(new Parameter(Loc.initial, STC.in_, b.type, null, null, null));
}
tded = new TypeTuple(args);
}
@@ -5993,7 +5997,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
if (e.tok2 == TOK.parameters && arg.defaultArg && arg.defaultArg.op == EXP.error)
return setError();
- args.push(new Parameter(arg.storageClass, arg.type, (e.tok2 == TOK.parameters) ? arg.ident : null, (e.tok2 == TOK.parameters) ? arg.defaultArg : null, arg.userAttribDecl));
+ args.push(new Parameter(arg.loc, arg.storageClass, arg.type, (e.tok2 == TOK.parameters) ? arg.ident : null, (e.tok2 == TOK.parameters) ? arg.defaultArg : null, arg.userAttribDecl));
}
tded = new TypeTuple(args);
break;
@@ -7278,7 +7282,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
else if (!exp.e1.type.deco)
{
// try to resolve the type
- exp.e1.type = exp.e1.type.typeSemantic(exp.e1.loc, null);
+ exp.e1.type = exp.e1.type.typeSemantic(exp.e1.loc, sc);
if (!exp.e1.type.deco) // still couldn't resolve it
{
if (auto ve = exp.e1.isVarExp())
@@ -7527,7 +7531,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (exp.e1.checkNoBool())
return setError();
- if (exp.e1.checkArithmetic() ||
+ if (exp.e1.checkArithmetic(exp.op) ||
exp.e1.checkSharedAccess(sc))
return setError();
@@ -7557,7 +7561,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (exp.e1.checkNoBool())
return setError();
- if (exp.e1.checkArithmetic())
+ if (exp.e1.checkArithmetic(exp.op))
return setError();
if (exp.e1.checkSharedAccess(sc))
return setError();
@@ -10024,19 +10028,22 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- if (0 && global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
- e2x.op != EXP.slice && e2x.op != EXP.assign &&
- e2x.op != EXP.arrayLiteral && e2x.op != EXP.string_ &&
- !(e2x.op == EXP.add || e2x.op == EXP.min ||
- e2x.op == EXP.mul || e2x.op == EXP.div ||
- e2x.op == EXP.mod || e2x.op == EXP.xor ||
- e2x.op == EXP.and || e2x.op == EXP.or ||
- e2x.op == EXP.pow ||
- e2x.op == EXP.tilde || e2x.op == EXP.negate))
+ version (none)
{
- const(char)* e1str = exp.e1.toChars();
- const(char)* e2str = e2x.toChars();
- exp.warning("explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`", e1str, e2str, e1str, e2str);
+ if (global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
+ e2x.op != EXP.slice && e2x.op != EXP.assign &&
+ e2x.op != EXP.arrayLiteral && e2x.op != EXP.string_ &&
+ !(e2x.op == EXP.add || e2x.op == EXP.min ||
+ e2x.op == EXP.mul || e2x.op == EXP.div ||
+ e2x.op == EXP.mod || e2x.op == EXP.xor ||
+ e2x.op == EXP.and || e2x.op == EXP.or ||
+ e2x.op == EXP.pow ||
+ e2x.op == EXP.tilde || e2x.op == EXP.negate))
+ {
+ const(char)* e1str = exp.e1.toChars();
+ const(char)* e2str = e2x.toChars();
+ exp.warning("explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`", e1str, e2str, e1str, e2str);
+ }
}
Type t2n = t2.nextOf();
@@ -10085,17 +10092,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- if (0 && global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
- t1.ty == Tarray && t2.ty == Tsarray &&
- e2x.op != EXP.slice &&
- t2.implicitConvTo(t1))
+ version (none)
{
- // Disallow ar[] = sa (Converted to ar[] = sa[])
- // Disallow da = sa (Converted to da = sa[])
- const(char)* e1str = exp.e1.toChars();
- const(char)* e2str = e2x.toChars();
- const(char)* atypestr = exp.e1.op == EXP.slice ? "element-wise" : "slice";
- exp.warning("explicit %s assignment `%s = (%s)[]` is better than `%s = %s`", atypestr, e1str, e2str, e1str, e2str);
+ if (global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
+ t1.ty == Tarray && t2.ty == Tsarray &&
+ e2x.op != EXP.slice &&
+ t2.implicitConvTo(t1))
+ {
+ // Disallow ar[] = sa (Converted to ar[] = sa[])
+ // Disallow da = sa (Converted to da = sa[])
+ const(char)* e1str = exp.e1.toChars();
+ const(char)* e2str = e2x.toChars();
+ const(char)* atypestr = exp.e1.op == EXP.slice ? "element-wise" : "slice";
+ exp.warning("explicit %s assignment `%s = (%s)[]` is better than `%s = %s`", atypestr, e1str, e2str, e1str, e2str);
+ }
}
if (exp.op == EXP.blit)
e2x = e2x.castTo(sc, exp.e1.type);
@@ -10785,11 +10795,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
bool err = false;
if (tb1.ty == Tdelegate || tb1.isPtrToFunction())
{
- err |= exp.e1.checkArithmetic() || exp.e1.checkSharedAccess(sc);
+ err |= exp.e1.checkArithmetic(exp.op) || exp.e1.checkSharedAccess(sc);
}
if (tb2.ty == Tdelegate || tb2.isPtrToFunction())
{
- err |= exp.e2.checkArithmetic() || exp.e2.checkSharedAccess(sc);
+ err |= exp.e2.checkArithmetic(exp.op) || exp.e2.checkSharedAccess(sc);
}
if (err)
return setError();
@@ -10891,11 +10901,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
bool err = false;
if (t1.ty == Tdelegate || t1.isPtrToFunction())
{
- err |= exp.e1.checkArithmetic() || exp.e1.checkSharedAccess(sc);
+ err |= exp.e1.checkArithmetic(exp.op) || exp.e1.checkSharedAccess(sc);
}
if (t2.ty == Tdelegate || t2.isPtrToFunction())
{
- err |= exp.e2.checkArithmetic() || exp.e2.checkSharedAccess(sc);
+ err |= exp.e2.checkArithmetic(exp.op) || exp.e2.checkSharedAccess(sc);
}
if (err)
return setError();
@@ -11032,7 +11042,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
(exp.e2.isStringExp() && (exp.e1.isIntegerExp() || exp.e1.isStringExp())))
return exp;
- Identifier hook = global.params.tracegc ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX;
+ bool useTraceGCHook = global.params.tracegc && sc.needsCodegen();
+
+ Identifier hook = useTraceGCHook ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX;
if (!verifyHookExist(exp.loc, *sc, hook, "concatenating arrays"))
{
setError();
@@ -11061,7 +11073,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
auto arguments = new Expressions();
- if (global.params.tracegc)
+ if (useTraceGCHook)
{
auto funcname = (sc.callsc && sc.callsc.func) ?
sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
@@ -11088,7 +11100,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be
* used with `-betterC`, but only during CTFE.
*/
- if (!global.params.useGC || !sc.needsCodegen())
+ if (!global.params.useGC)
return;
if (auto ce = exp.isCatExp())
@@ -12087,8 +12099,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
- if (sc.needsCodegen() &&
- (t1.ty == Tarray || t1.ty == Tsarray) &&
+ if ((t1.ty == Tarray || t1.ty == Tsarray) &&
(t2.ty == Tarray || t2.ty == Tsarray))
{
if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays"))
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 73f1ba786cb..bf7ad7ee8d5 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -173,7 +173,7 @@ public:
Identifier id = Identifier.generateId("__o");
Statement handler = new PeelStatement(sexception);
- if (sexception.blockExit(fd, false) & BE.fallthru)
+ if (sexception.blockExit(fd, null) & BE.fallthru)
{
auto ts = new ThrowStatement(Loc.initial, new IdentifierExp(Loc.initial, id));
ts.internalThrow = true;
@@ -1311,7 +1311,7 @@ extern (C++) class FuncDeclaration : Declaration
final const(char)* toFullSignature()
{
OutBuffer buf;
- functionToBufferWithIdent(type.toTypeFunction(), &buf, toChars(), isStatic);
+ functionToBufferWithIdent(type.toTypeFunction(), buf, toChars(), isStatic);
return buf.extractChars();
}
@@ -2279,8 +2279,11 @@ extern (C++) class FuncDeclaration : Declaration
break LcheckAncestorsOfANestedRef;
}
a.push(f);
- .errorSupplemental(f.loc, "`%s` closes over variable `%s` at %s",
- f.toPrettyChars(), v.toChars(), v.loc.toChars());
+ .errorSupplemental(f.loc, "%s `%s` closes over variable `%s`",
+ f.kind, f.toPrettyChars(), v.toChars());
+ if (v.ident != Id.This)
+ .errorSupplemental(v.loc, "`%s` declared here", v.toChars());
+
break LcheckAncestorsOfANestedRef;
}
}
@@ -2657,7 +2660,7 @@ extern (C++) class FuncDeclaration : Declaration
auto fparams = new Parameters();
if (canBuildResultVar())
{
- Parameter p = new Parameter(STC.ref_ | STC.const_, f.nextOf(), Id.result, null, null);
+ Parameter p = new Parameter(loc, STC.ref_ | STC.const_, f.nextOf(), Id.result, null, null);
fparams.push(p);
}
auto fo = cast(TypeFunction)(originalType ? originalType : f);
@@ -3340,14 +3343,14 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
s = fd = td.funcroot;
OutBuffer tiargsBuf;
- arrayObjectsToBuffer(&tiargsBuf, tiargs);
+ arrayObjectsToBuffer(tiargsBuf, tiargs);
OutBuffer fargsBuf;
fargsBuf.writeByte('(');
- argExpTypesToCBuffer(&fargsBuf, fargs);
+ argExpTypesToCBuffer(fargsBuf, fargs);
fargsBuf.writeByte(')');
if (tthis)
- tthis.modToBuffer(&fargsBuf);
+ tthis.modToBuffer(fargsBuf);
// The call is ambiguous
if (m.lastf && m.nextf)
@@ -4623,7 +4626,7 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)
{
if (!gag)
{
- if (!sc.isDeprecated() && global.params.obsolete)
+ version (none) // disable obsolete warning
warning(loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
}
}
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index af711a0fd0a..840074e5d8f 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -101,6 +101,23 @@ extern(C++) struct Output
OutBuffer* buffer; // if this output is buffered, this is the buffer
int bufferLines; // number of lines written to the buffer
}
+
+/// Command line state related to printing usage about other switches
+extern(C++) struct Help
+{
+ bool manual; // open browser on compiler manual
+ bool usage; // print usage and exit
+ // print help of switch:
+ bool mcpu; // -mcpu
+ bool transition; // -transition
+ bool check; // -check
+ bool checkAction; // -checkaction
+ bool revert; // -revert
+ bool preview; // -preview
+ bool externStd; // -extern-std
+ bool hc; // -HC
+}
+
/// Put command line switches in here
extern (C++) struct Param
{
@@ -124,7 +141,6 @@ extern (C++) struct Param
bool release; // build release version
bool preservePaths; // true means don't strip path from source file
DiagnosticReporting warnings = DiagnosticReporting.off; // how compiler warnings are handled
- bool obsolete; // enable warnings about use of obsolete messages
bool color; // use ANSI colors in console output
bool cov; // generate code coverage data
ubyte covPercent; // 0..100 code coverage percentage required
@@ -143,16 +159,7 @@ extern (C++) struct Param
bool showGaggedErrors; // print gagged errors anyway
bool printErrorContext; // print errors with the error context (the error line in the source file)
- bool manual; // open browser on compiler manual
- bool usage; // print usage and exit
- bool mcpuUsage; // print help on -mcpu switch
- bool transitionUsage; // print help on -transition switch
- bool checkUsage; // print help on -check switch
- bool checkActionUsage; // print help on -checkaction switch
- bool revertUsage; // print help on -revert switch
- bool previewUsage; // print help on -preview switch
- bool externStdUsage; // print help on -extern-std switch
- bool hcUsage; // print help on -HC switch
+ Help help;
bool logo; // print compiler logo
// Options for `-preview=/-revert=`
@@ -258,6 +265,7 @@ extern (C++) struct Global
Array!(const(char)*)* filePath; /// Array of char*'s which form the file import lookup path
private enum string _version = import("VERSION");
+ char[26] datetime; /// string returned by ctime()
CompileEnv compileEnv;
Param params; /// command line parameters
@@ -281,6 +289,7 @@ extern (C++) struct Global
enum recursionLimit = 500; /// number of recursive template expansions before abort
ErrorSink errorSink; /// where the error messages go
+ ErrorSink errorSinkNull; /// where the error messages are ignored
extern (C++) FileName function(FileName, ref const Loc, out bool, OutBuffer*) preprocess;
@@ -337,6 +346,7 @@ extern (C++) struct Global
extern (C++) void _init()
{
errorSink = new ErrorSinkCompiler;
+ errorSinkNull = new ErrorSinkNull;
this.fileManager = new FileManager();
version (MARS)
@@ -369,6 +379,7 @@ extern (C++) struct Global
core.stdc.time.time(&ct);
const p = ctime(&ct);
assert(p);
+ datetime[] = p[0 .. 26];
__gshared char[11 + 1] date = 0; // put in BSS segment
__gshared char[8 + 1] time = 0;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 0ef9eed405c..e24042a4f21 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -96,6 +96,22 @@ struct Output
int bufferLines; // number of lines written to the buffer
};
+/// Command line state related to printing uasage about other switches
+struct Help
+{
+ d_bool manual; // open browser on compiler manual
+ d_bool usage; // print usage and exit
+ // print help of switch:
+ d_bool mcpu; // -mcpu
+ d_bool transition; // -transition
+ d_bool check; // -check
+ d_bool checkAction; // -checkaction
+ d_bool revert; // -revert
+ d_bool preview; // -preview
+ d_bool externStd; // -extern-std
+ d_bool hc; // -HC
+};
+
// Put command line switches in here
struct Param
{
@@ -119,7 +135,6 @@ struct Param
d_bool release; // build release version
d_bool preservePaths; // true means don't strip path from source file
Diagnostic warnings;
- d_bool obsolete; // warn about use of obsolete features
d_bool color; // use ANSI colors in console output
d_bool cov; // generate code coverage data
unsigned char covPercent; // 0..100 code coverage percentage required
@@ -136,16 +151,7 @@ struct Param
CppStdRevision cplusplus; // version of C++ name mangling to support
d_bool showGaggedErrors; // print gagged errors anyway
d_bool printErrorContext; // print errors with the error context (the error line in the source file)
- d_bool manual; // open browser on compiler manual
- d_bool usage; // print usage and exit
- d_bool mcpuUsage; // print help on -mcpu switch
- d_bool transitionUsage; // print help on -transition switch
- d_bool checkUsage; // print help on -check switch
- d_bool checkActionUsage; // print help on -checkaction switch
- d_bool revertUsage; // print help on -revert switch
- d_bool previewUsage; // print help on -preview switch
- d_bool externStdUsage; // print help on -extern-std switch
- d_bool hcUsage; // print help on -HC switch
+ Help help;
d_bool logo; // print logo;
// Options for `-preview=/-revert=`
@@ -265,7 +271,6 @@ struct CompileEnv
bool previewIn;
bool ddocOutput;
bool shortenedMethods;
- bool obsolete;
};
struct Global
@@ -277,6 +282,7 @@ struct Global
Array<const char *> *path; // Array of char*'s which form the import lookup path
Array<const char *> *filePath; // Array of char*'s which form the file import lookup path
+ char datetime[26]; /// string returned by ctime()
CompileEnv compileEnv;
Param params;
@@ -296,6 +302,7 @@ struct Global
FileManager* fileManager;
ErrorSink* errorSink; // where the error messages go
+ ErrorSink* errorSinkNull; // where the error messages disappear
FileName (*preprocess)(FileName, const Loc&, bool&, OutBuffer&);
@@ -358,8 +365,8 @@ struct Loc
{
private:
unsigned _linnum;
- unsigned short _charnum;
- unsigned short fileIndex;
+ unsigned _charnum;
+ unsigned fileIndex;
public:
static void set(bool showColumns, MessageStyle messageStyle);
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index 33cbc19c690..b4c8e8b899b 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -51,7 +51,6 @@ import dmd.statement;
import dmd.staticassert;
import dmd.target;
import dmd.tokens;
-import dmd.utils;
import dmd.visitor;
struct HdrGenState
@@ -73,16 +72,20 @@ struct HdrGenState
enum TEST_EMIT_ALL = 0;
-extern (C++) void genhdrfile(Module m)
+/****************************************
+ * Generate a header (.di) file for Module m.
+ * Params:
+ * m = Module to generate header for
+ * buf = buffer to write the data to
+ */
+extern (C++) void genhdrfile(Module m, ref OutBuffer buf)
{
- OutBuffer buf;
buf.doindent = 1;
buf.printf("// D import file generated from '%s'", m.srcfile.toChars());
buf.writenl();
HdrGenState hgs;
hgs.hdrgen = true;
- toCBuffer(m, &buf, &hgs);
- writeFile(m.loc, m.hdrfile.toString(), buf[]);
+ toCBuffer(m, buf, hgs);
}
/**
@@ -91,14 +94,14 @@ extern (C++) void genhdrfile(Module m)
* buf = buffer to write to.
* m = module to visit all members of.
*/
-extern (C++) void moduleToBuffer(OutBuffer* buf, Module m)
+extern (C++) void moduleToBuffer(ref OutBuffer buf, Module m)
{
HdrGenState hgs;
hgs.fullDump = true;
- toCBuffer(m, buf, &hgs);
+ toCBuffer(m, buf, hgs);
}
-void moduleToBuffer2(Module m, OutBuffer* buf, HdrGenState* hgs)
+void moduleToBuffer2(Module m, ref OutBuffer buf, HdrGenState* hgs)
{
if (m.md)
{
@@ -132,7 +135,7 @@ void moduleToBuffer2(Module m, OutBuffer* buf, HdrGenState* hgs)
}
}
-private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
+private void statementToBuffer(Statement s, ref OutBuffer buf, HdrGenState* hgs)
{
void visitDefaultCase(Statement s)
{
@@ -201,8 +204,7 @@ private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
auto d = ds.exp.isDeclarationExp().declaration;
if (auto v = d.isVarDeclaration())
{
- scope ppv = new DsymbolPrettyPrintVisitor(buf, hgs);
- ppv.visitVarDecl(v, anywritten);
+ visitVarDecl(v, anywritten, buf, *hgs);
}
else
d.dsymbolToBuffer(buf, hgs);
@@ -792,9 +794,9 @@ private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
visit.VisitStatement(s);
}
-private void dsymbolToBuffer(Dsymbol s, OutBuffer* buf, HdrGenState* hgs)
+private void dsymbolToBuffer(Dsymbol s, ref OutBuffer buf, HdrGenState* hgs)
{
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, hgs);
s.accept(v);
}
@@ -822,13 +824,13 @@ public:
{
buf.writestring(s.kind());
buf.writeByte('(');
- s.exp.expressionToBuffer(buf, hgs);
+ s.exp.expressionToBuffer(*buf, hgs);
if (s.msgs)
{
foreach (m; (*s.msgs)[])
{
buf.writestring(", ");
- m.expressionToBuffer(buf, hgs);
+ m.expressionToBuffer(*buf, hgs);
}
}
buf.writestring(");");
@@ -860,13 +862,13 @@ public:
override void visit(EnumMember em)
{
if (em.type)
- typeToBuffer(em.type, em.ident, buf, hgs);
+ typeToBuffer(em.type, em.ident, *buf, hgs);
else
buf.writestring(em.ident.toString());
if (em.value)
{
buf.writestring(" = ");
- em.value.expressionToBuffer(buf, hgs);
+ em.value.expressionToBuffer(*buf, hgs);
}
}
@@ -916,7 +918,7 @@ public:
bool hasSTC;
if (auto stcd = d.isStorageClassDeclaration)
{
- hasSTC = stcToBuffer(buf, stcd.stc);
+ hasSTC = stcToBuffer(*buf, stcd.stc);
}
if (!d.decl)
@@ -959,7 +961,7 @@ public:
override void visit(DeprecatedDeclaration d)
{
buf.writestring("deprecated(");
- d.msg.expressionToBuffer(buf, hgs);
+ d.msg.expressionToBuffer(*buf, hgs);
buf.writestring(") ");
visit(cast(AttribDeclaration)d);
}
@@ -994,7 +996,7 @@ public:
override void visit(VisibilityDeclaration d)
{
- visibilityToBuffer(buf, d.visibility);
+ visibilityToBuffer(*buf, d.visibility);
AttribDeclaration ad = cast(AttribDeclaration)d;
if (ad.decl.length <= 1)
buf.writeByte(' ');
@@ -1047,7 +1049,7 @@ public:
if (d.args && d.args.length)
{
buf.writestring(", ");
- argsToBuffer(d.args, buf, hgs);
+ argsToBuffer(d.args, *buf, hgs);
}
buf.writeByte(')');
@@ -1065,7 +1067,7 @@ public:
override void visit(ConditionalDeclaration d)
{
- d.condition.conditionToBuffer(buf, hgs);
+ d.condition.conditionToBuffer(*buf, hgs);
if (d.decl || d.elsedecl)
{
buf.writenl();
@@ -1108,15 +1110,15 @@ public:
{
if (i)
buf.writestring(", ");
- if (stcToBuffer(buf, p.storageClass))
+ if (stcToBuffer(*buf, p.storageClass))
buf.writeByte(' ');
if (p.type)
- typeToBuffer(p.type, p.ident, buf, hgs);
+ typeToBuffer(p.type, p.ident, *buf, hgs);
else
buf.writestring(p.ident.toString());
}
buf.writestring("; ");
- s.aggr.expressionToBuffer(buf, hgs);
+ s.aggr.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
}
@@ -1128,13 +1130,13 @@ public:
buf.writestring(Token.toString(s.op));
buf.writestring(" (");
if (s.prm.type)
- typeToBuffer(s.prm.type, s.prm.ident, buf, hgs);
+ typeToBuffer(s.prm.type, s.prm.ident, *buf, hgs);
else
buf.writestring(s.prm.ident.toString());
buf.writestring("; ");
- s.lwr.expressionToBuffer(buf, hgs);
+ s.lwr.expressionToBuffer(*buf, hgs);
buf.writestring(" .. ");
- s.upr.expressionToBuffer(buf, hgs);
+ s.upr.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
}
@@ -1162,7 +1164,7 @@ public:
override void visit(MixinDeclaration d)
{
buf.writestring("mixin(");
- argsToBuffer(d.exps, buf, hgs, null);
+ argsToBuffer(d.exps, *buf, hgs, null);
buf.writestring(");");
buf.writenl();
}
@@ -1170,7 +1172,7 @@ public:
override void visit(UserAttributeDeclaration d)
{
buf.writestring("@(");
- argsToBuffer(d.atts, buf, hgs);
+ argsToBuffer(d.atts, *buf, hgs);
buf.writeByte(')');
visit(cast(AttribDeclaration)d);
}
@@ -1221,9 +1223,9 @@ public:
if (FuncDeclaration fd = onemember.isFuncDeclaration())
{
assert(fd.type);
- if (stcToBuffer(buf, fd.storage_class))
+ if (stcToBuffer(*buf, fd.storage_class))
buf.writeByte(' ');
- functionToBufferFull(cast(TypeFunction)fd.type, buf, d.ident, hgs, d);
+ functionToBufferFull(cast(TypeFunction)fd.type, *buf, d.ident, hgs, d);
visitTemplateConstraint(d.constraint);
hgs.tpltMember++;
bodyToBuffer(fd);
@@ -1262,10 +1264,10 @@ public:
{
if (d.constraint)
return false;
- if (stcToBuffer(buf, vd.storage_class))
+ if (stcToBuffer(*buf, vd.storage_class))
buf.writeByte(' ');
if (vd.type)
- typeToBuffer(vd.type, vd.ident, buf, hgs);
+ typeToBuffer(vd.type, vd.ident, *buf, hgs);
else
buf.writestring(vd.ident.toString());
buf.writeByte('(');
@@ -1276,9 +1278,9 @@ public:
buf.writestring(" = ");
ExpInitializer ie = vd._init.isExpInitializer();
if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit))
- (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, hgs);
+ (cast(AssignExp)ie.exp).e2.expressionToBuffer(*buf, hgs);
else
- vd._init.initializerToBuffer(buf, hgs);
+ vd._init.initializerToBuffer(*buf, hgs);
}
buf.writeByte(';');
buf.writenl();
@@ -1295,7 +1297,7 @@ public:
{
if (i)
buf.writestring(", ");
- p.templateParameterToBuffer(buf, hgs);
+ p.templateParameterToBuffer(*buf, hgs);
}
}
@@ -1304,27 +1306,27 @@ public:
if (!constraint)
return;
buf.writestring(" if (");
- constraint.expressionToBuffer(buf, hgs);
+ constraint.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
}
override void visit(TemplateInstance ti)
{
buf.writestring(ti.name.toChars());
- tiargsToBuffer(ti, buf, hgs);
+ tiargsToBuffer(ti, *buf, hgs);
if (hgs.fullDump)
{
buf.writenl();
- dumpTemplateInstance(ti, buf, hgs);
+ dumpTemplateInstance(ti, *buf, hgs);
}
}
override void visit(TemplateMixin tm)
{
buf.writestring("mixin ");
- typeToBuffer(tm.tqual, null, buf, hgs);
- tiargsToBuffer(tm, buf, hgs);
+ typeToBuffer(tm.tqual, null, *buf, hgs);
+ tiargsToBuffer(tm, *buf, hgs);
if (tm.ident && memcmp(tm.ident.toChars(), cast(const(char)*)"__mixin", 7) != 0)
{
buf.writeByte(' ');
@@ -1333,7 +1335,7 @@ public:
buf.writeByte(';');
buf.writenl();
if (hgs.fullDump)
- dumpTemplateInstance(tm, buf, hgs);
+ dumpTemplateInstance(tm, *buf, hgs);
}
override void visit(EnumDeclaration d)
@@ -1349,7 +1351,7 @@ public:
if (d.memtype)
{
buf.writestring(" : ");
- typeToBuffer(d.memtype, null, buf, hgs);
+ typeToBuffer(d.memtype, null, *buf, hgs);
}
if (!d.members)
{
@@ -1452,7 +1454,7 @@ public:
{
if (i)
buf.writestring(", ");
- typeToBuffer(b.type, null, buf, hgs);
+ typeToBuffer(b.type, null, *buf, hgs);
}
}
@@ -1465,7 +1467,7 @@ public:
{
buf.writestring(d.ident.toString());
buf.writestring(" = ");
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
/*
https://issues.dlang.org/show_bug.cgi?id=23223
@@ -1484,18 +1486,18 @@ public:
}
else if (d.type.ty == Tfunction)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
- typeToBuffer(d.type, d.ident, buf, hgs);
+ typeToBuffer(d.type, d.ident, *buf, hgs);
}
else if (d.ident)
{
hgs.declstring = (d.ident == Id.string || d.ident == Id.wstring || d.ident == Id.dstring);
buf.writestring(d.ident.toString());
buf.writestring(" = ");
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
- typeToBuffer(d.type, null, buf, hgs);
+ typeToBuffer(d.type, null, *buf, hgs);
hgs.declstring = false;
}
buf.writeByte(';');
@@ -1509,7 +1511,7 @@ public:
if (d.aliassym)
d.aliassym.accept(this);
else // d.type
- typeToBuffer(d.type, null, buf, hgs);
+ typeToBuffer(d.type, null, *buf, hgs);
buf.writeByte(';');
buf.writenl();
}
@@ -1518,69 +1520,18 @@ public:
{
if (d.storage_class & STC.local)
return;
- visitVarDecl(d, false);
+ visitVarDecl(d, false, *buf, *hgs);
buf.writeByte(';');
buf.writenl();
}
- void visitVarDecl(VarDeclaration v, bool anywritten)
- {
- const bool isextern = hgs.hdrgen &&
- !hgs.insideFuncBody &&
- !hgs.tpltMember &&
- !hgs.insideAggregate &&
- !(v.storage_class & STC.manifest);
-
- void vinit(VarDeclaration v)
- {
- auto ie = v._init.isExpInitializer();
- if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit))
- (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, hgs);
- else
- v._init.initializerToBuffer(buf, hgs);
- }
-
- if (anywritten)
- {
- buf.writestring(", ");
- buf.writestring(v.ident.toString());
- }
- else
- {
- const bool useTypeof = isextern && v._init && !v.type;
- auto stc = v.storage_class;
- if (isextern)
- stc |= STC.extern_;
- if (useTypeof)
- stc &= ~STC.auto_;
- if (stcToBuffer(buf, stc))
- buf.writeByte(' ');
- if (v.type)
- typeToBuffer(v.type, v.ident, buf, hgs);
- else if (useTypeof)
- {
- buf.writestring("typeof(");
- vinit(v);
- buf.writestring(") ");
- buf.writestring(v.ident.toString());
- }
- else
- buf.writestring(v.ident.toString());
- }
- if (v._init && !isextern)
- {
- buf.writestring(" = ");
- vinit(v);
- }
- }
-
override void visit(FuncDeclaration f)
{
//printf("FuncDeclaration::toCBuffer() '%s'\n", f.toChars());
- if (stcToBuffer(buf, f.storage_class))
+ if (stcToBuffer(*buf, f.storage_class))
buf.writeByte(' ');
auto tf = cast(TypeFunction)f.type;
- typeToBuffer(tf, f.ident, buf, hgs);
+ typeToBuffer(tf, f.ident, *buf, hgs);
if (hgs.hdrgen)
{
@@ -1627,7 +1578,7 @@ public:
{
assert(es.exp && es.exp.op == EXP.assert_);
buf.writestring(" (");
- (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs);
+ (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
requireDo = false;
@@ -1635,7 +1586,7 @@ public:
else
{
buf.writenl();
- frequire.statementToBuffer(buf, hgs);
+ frequire.statementToBuffer(*buf, hgs);
requireDo = true;
}
}
@@ -1655,7 +1606,7 @@ public:
buf.writestring(fensure.id.toString());
}
buf.writestring("; ");
- (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs);
+ (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
requireDo = false;
@@ -1669,7 +1620,7 @@ public:
buf.writeByte(')');
}
buf.writenl();
- fensure.ensure.statementToBuffer(buf, hgs);
+ fensure.ensure.statementToBuffer(*buf, hgs);
requireDo = true;
}
}
@@ -1717,7 +1668,7 @@ public:
buf.writeByte('{');
buf.writenl();
buf.level++;
- f.fbody.statementToBuffer(buf, hgs);
+ f.fbody.statementToBuffer(*buf, hgs);
buf.level--;
buf.writeByte('}');
buf.writenl();
@@ -1740,8 +1691,8 @@ public:
TypeFunction tf = cast(TypeFunction)f.type;
if (!f.inferRetType && tf.next)
- typeToBuffer(tf.next, null, buf, hgs);
- parametersToBuffer(tf.parameterList, buf, hgs);
+ typeToBuffer(tf.next, null, *buf, hgs);
+ parametersToBuffer(tf.parameterList, *buf, hgs);
// https://issues.dlang.org/show_bug.cgi?id=20074
void printAttribute(string str)
@@ -1764,7 +1715,7 @@ public:
if (rs && rs.exp)
{
buf.writestring(" => ");
- rs.exp.expressionToBuffer(buf, hgs);
+ rs.exp.expressionToBuffer(*buf, hgs);
}
else
{
@@ -1776,7 +1727,7 @@ public:
override void visit(PostBlitDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("this(this)");
bodyToBuffer(d);
@@ -1784,7 +1735,7 @@ public:
override void visit(DtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("~this()");
bodyToBuffer(d);
@@ -1792,7 +1743,7 @@ public:
override void visit(StaticCtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class & ~STC.static_))
+ if (stcToBuffer(*buf, d.storage_class & ~STC.static_))
buf.writeByte(' ');
if (d.isSharedStaticCtorDeclaration())
buf.writestring("shared ");
@@ -1808,7 +1759,7 @@ public:
override void visit(StaticDtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class & ~STC.static_))
+ if (stcToBuffer(*buf, d.storage_class & ~STC.static_))
buf.writeByte(' ');
if (d.isSharedStaticDtorDeclaration())
buf.writestring("shared ");
@@ -1826,14 +1777,14 @@ public:
{
if (hgs.hdrgen)
return;
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("invariant");
if(auto es = d.fbody.isExpStatement())
{
assert(es.exp && es.exp.op == EXP.assert_);
buf.writestring(" (");
- (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs);
+ (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs);
buf.writestring(");");
buf.writenl();
}
@@ -1847,7 +1798,7 @@ public:
{
if (hgs.hdrgen)
return;
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("unittest");
bodyToBuffer(d);
@@ -1855,33 +1806,88 @@ public:
override void visit(BitFieldDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
Identifier id = d.isAnonymous() ? null : d.ident;
- typeToBuffer(d.type, id, buf, hgs);
+ typeToBuffer(d.type, id, *buf, hgs);
buf.writestring(" : ");
- d.width.expressionToBuffer(buf, hgs);
+ d.width.expressionToBuffer(*buf, hgs);
buf.writeByte(';');
buf.writenl();
}
override void visit(NewDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class & ~STC.static_))
+ if (stcToBuffer(*buf, d.storage_class & ~STC.static_))
buf.writeByte(' ');
buf.writestring("new();");
}
override void visit(Module m)
{
- moduleToBuffer2(m, buf, hgs);
+ moduleToBuffer2(m, *buf, hgs);
+ }
+}
+
+/*******************************************
+ * Pretty-print a VarDeclaration to buf.
+ */
+private void visitVarDecl(VarDeclaration v, bool anywritten, ref OutBuffer buf, ref HdrGenState hgs)
+{
+ const bool isextern = hgs.hdrgen &&
+ !hgs.insideFuncBody &&
+ !hgs.tpltMember &&
+ !hgs.insideAggregate &&
+ !(v.storage_class & STC.manifest);
+
+ void vinit(VarDeclaration v)
+ {
+ auto ie = v._init.isExpInitializer();
+ if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit))
+ (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, &hgs);
+ else
+ v._init.initializerToBuffer(buf, &hgs);
+ }
+
+ if (anywritten)
+ {
+ buf.writestring(", ");
+ buf.writestring(v.ident.toString());
+ }
+ else
+ {
+ const bool useTypeof = isextern && v._init && !v.type;
+ auto stc = v.storage_class;
+ if (isextern)
+ stc |= STC.extern_;
+ if (useTypeof)
+ stc &= ~STC.auto_;
+ if (stcToBuffer(buf, stc))
+ buf.writeByte(' ');
+ if (v.type)
+ typeToBuffer(v.type, v.ident, buf, &hgs);
+ else if (useTypeof)
+ {
+ buf.writestring("typeof(");
+ vinit(v);
+ buf.writestring(") ");
+ buf.writestring(v.ident.toString());
+ }
+ else
+ buf.writestring(v.ident.toString());
+ }
+ if (v._init && !isextern)
+ {
+ buf.writestring(" = ");
+ vinit(v);
}
}
+
/*********************************************
* Print expression to buffer.
*/
-private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hgs)
+private void expressionPrettyPrint(Expression e, ref OutBuffer buf, HdrGenState* hgs)
{
void visit(Expression e)
{
@@ -1922,7 +1928,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
case Tdchar:
{
const o = buf.length;
- writeSingleCharLiteral(*buf, cast(dchar) v);
+ writeSingleCharLiteral(buf, cast(dchar) v);
if (hgs.ddoc)
escapeDdocString(buf, o);
break;
@@ -2064,7 +2070,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
const o = buf.length;
foreach (i; 0 .. e.len)
{
- writeCharLiteral(*buf, e.getCodeUnit(i));
+ writeCharLiteral(buf, e.getCodeUnit(i));
}
if (hgs.ddoc)
escapeDdocString(buf, o);
@@ -2251,8 +2257,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
// which isn't correct as regular D code.
buf.writeByte('(');
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
- v.visitVarDecl(var, false);
+ visitVarDecl(var, false, buf, *hgs);
buf.writeByte(';');
buf.writeByte(')');
@@ -2308,7 +2313,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
if (e.parameters && e.parameters.length)
{
buf.writestring(", ");
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, hgs);
v.visitTemplateParameters(e.parameters);
}
buf.writeByte(')');
@@ -2717,7 +2722,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
* allowHex = whether hex floating point literals may be used
* for greater accuracy
*/
-void floatToBuffer(Type type, const real_t value, OutBuffer* buf, const bool allowHex)
+void floatToBuffer(Type type, const real_t value, ref OutBuffer buf, const bool allowHex)
{
/** sizeof(value)*3 is because each byte of mantissa is max
of 256 (3 characters). The string will be "-M.MMMMe-4932".
@@ -2762,9 +2767,9 @@ void floatToBuffer(Type type, const real_t value, OutBuffer* buf, const bool all
}
}
-private void templateParameterToBuffer(TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)
+private void templateParameterToBuffer(TemplateParameter tp, ref OutBuffer buf, HdrGenState* hgs)
{
- scope v = new TemplateParameterPrettyPrintVisitor(buf, hgs);
+ scope v = new TemplateParameterPrettyPrintVisitor(&buf, hgs);
tp.accept(v);
}
@@ -2787,12 +2792,12 @@ public:
if (tp.specType)
{
buf.writestring(" : ");
- typeToBuffer(tp.specType, null, buf, hgs);
+ typeToBuffer(tp.specType, null, *buf, hgs);
}
if (tp.defaultType)
{
buf.writestring(" = ");
- typeToBuffer(tp.defaultType, null, buf, hgs);
+ typeToBuffer(tp.defaultType, null, *buf, hgs);
}
}
@@ -2806,33 +2811,33 @@ public:
{
buf.writestring("alias ");
if (tp.specType)
- typeToBuffer(tp.specType, tp.ident, buf, hgs);
+ typeToBuffer(tp.specType, tp.ident, *buf, hgs);
else
buf.writestring(tp.ident.toString());
if (tp.specAlias)
{
buf.writestring(" : ");
- objectToBuffer(tp.specAlias, buf, hgs);
+ objectToBuffer(tp.specAlias, *buf, hgs);
}
if (tp.defaultAlias)
{
buf.writestring(" = ");
- objectToBuffer(tp.defaultAlias, buf, hgs);
+ objectToBuffer(tp.defaultAlias, *buf, hgs);
}
}
override void visit(TemplateValueParameter tp)
{
- typeToBuffer(tp.valType, tp.ident, buf, hgs);
+ typeToBuffer(tp.valType, tp.ident, *buf, hgs);
if (tp.specValue)
{
buf.writestring(" : ");
- tp.specValue.expressionToBuffer(buf, hgs);
+ tp.specValue.expressionToBuffer(*buf, hgs);
}
if (tp.defaultValue)
{
buf.writestring(" = ");
- tp.defaultValue.expressionToBuffer(buf, hgs);
+ tp.defaultValue.expressionToBuffer(*buf, hgs);
}
}
@@ -2843,9 +2848,9 @@ public:
}
}
-private void conditionToBuffer(Condition c, OutBuffer* buf, HdrGenState* hgs)
+private void conditionToBuffer(Condition c, ref OutBuffer buf, HdrGenState* hgs)
{
- scope v = new ConditionPrettyPrintVisitor(buf, hgs);
+ scope v = new ConditionPrettyPrintVisitor(&buf, hgs);
c.accept(v);
}
@@ -2885,42 +2890,42 @@ public:
override void visit(StaticIfCondition c)
{
buf.writestring("static if (");
- c.exp.expressionToBuffer(buf, hgs);
+ c.exp.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
}
}
-void toCBuffer(const Statement s, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const Statement s, ref OutBuffer buf, ref HdrGenState hgs)
{
- (cast()s).statementToBuffer(buf, hgs);
+ (cast()s).statementToBuffer(buf, &hgs);
}
-void toCBuffer(const Type t, OutBuffer* buf, const Identifier ident, HdrGenState* hgs)
+void toCBuffer(const Type t, ref OutBuffer buf, const Identifier ident, ref HdrGenState hgs)
{
- typeToBuffer(cast() t, ident, buf, hgs);
+ typeToBuffer(cast() t, ident, buf, &hgs);
}
-void toCBuffer(Dsymbol s, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
{
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, &hgs);
s.accept(v);
}
// used from TemplateInstance::toChars() and TemplateMixin::toChars()
-void toCBufferInstance(const TemplateInstance ti, OutBuffer* buf, bool qualifyTypes = false)
+void toCBufferInstance(const TemplateInstance ti, ref OutBuffer buf, bool qualifyTypes = false)
{
HdrGenState hgs;
hgs.fullQual = qualifyTypes;
- scope v = new DsymbolPrettyPrintVisitor(buf, &hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, &hgs);
v.visit(cast() ti);
}
-void toCBuffer(const Initializer iz, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const Initializer iz, ref OutBuffer buf, ref HdrGenState hgs)
{
- initializerToBuffer(cast() iz, buf, hgs);
+ initializerToBuffer(cast() iz, buf, &hgs);
}
-bool stcToBuffer(OutBuffer* buf, StorageClass stc) @safe
+bool stcToBuffer(ref OutBuffer buf, StorageClass stc) @safe
{
//printf("stc: %llx\n", stc);
bool result = false;
@@ -3039,7 +3044,7 @@ string stcToString(ref StorageClass stc) @safe
return null;
}
-private void linkageToBuffer(OutBuffer* buf, LINK linkage) @safe
+private void linkageToBuffer(ref OutBuffer buf, LINK linkage) @safe
{
const s = linkageToString(linkage);
if (s.length)
@@ -3077,7 +3082,7 @@ string linkageToString(LINK linkage) pure nothrow @safe
}
}
-void visibilityToBuffer(OutBuffer* buf, Visibility vis)
+void visibilityToBuffer(ref OutBuffer buf, Visibility vis)
{
buf.writestring(visibilityToString(vis.kind));
if (vis.kind == Visibility.Kind.package_ && vis.pkg)
@@ -3121,28 +3126,28 @@ extern (D) string visibilityToString(Visibility.Kind kind) nothrow pure @safe
}
// Print the full function signature with correct ident, attributes and template args
-void functionToBufferFull(TypeFunction tf, OutBuffer* buf, const Identifier ident, HdrGenState* hgs, TemplateDeclaration td)
+void functionToBufferFull(TypeFunction tf, ref OutBuffer buf, const Identifier ident, HdrGenState* hgs, TemplateDeclaration td)
{
//printf("TypeFunction::toCBuffer() this = %p\n", this);
visitFuncIdentWithPrefix(tf, ident, td, buf, hgs);
}
// ident is inserted before the argument list and will be "function" or "delegate" for a type
-void functionToBufferWithIdent(TypeFunction tf, OutBuffer* buf, const(char)* ident, bool isStatic)
+void functionToBufferWithIdent(TypeFunction tf, ref OutBuffer buf, const(char)* ident, bool isStatic)
{
HdrGenState hgs;
visitFuncIdentWithPostfix(tf, ident.toDString(), buf, &hgs, isStatic);
}
-void toCBuffer(const Expression e, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const Expression e, ref OutBuffer buf, ref HdrGenState hgs)
{
- expressionPrettyPrint(cast()e, buf, hgs);
+ expressionPrettyPrint(cast()e, buf, &hgs);
}
/**************************************************
* Write out argument types to buf.
*/
-void argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)
+void argExpTypesToCBuffer(ref OutBuffer buf, Expressions* arguments)
{
if (!arguments || !arguments.length)
return;
@@ -3155,13 +3160,13 @@ void argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)
}
}
-void toCBuffer(const TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const TemplateParameter tp, ref OutBuffer buf, ref HdrGenState hgs)
{
- scope v = new TemplateParameterPrettyPrintVisitor(buf, hgs);
+ scope v = new TemplateParameterPrettyPrintVisitor(&buf, &hgs);
(cast() tp).accept(v);
}
-void arrayObjectsToBuffer(OutBuffer* buf, Objects* objects)
+void arrayObjectsToBuffer(ref OutBuffer buf, Objects* objects)
{
if (!objects || !objects.length)
return;
@@ -3184,7 +3189,7 @@ extern (C++) const(char)* parametersTypeToChars(ParameterList pl)
{
OutBuffer buf;
HdrGenState hgs;
- parametersToBuffer(pl, &buf, &hgs);
+ parametersToBuffer(pl, buf, &hgs);
return buf.extractChars();
}
@@ -3202,7 +3207,7 @@ const(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQua
HdrGenState hgs;
hgs.fullQual = fullQual;
- parameterToBuffer(parameter, &buf, &hgs);
+ parameterToBuffer(parameter, buf, &hgs);
if (tf.parameterList.varargs == VarArg.typesafe && parameter == tf.parameterList[tf.parameterList.parameters.length - 1])
{
@@ -3220,7 +3225,7 @@ const(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQua
* hgs = context
*/
-private void parametersToBuffer(ParameterList pl, OutBuffer* buf, HdrGenState* hgs)
+private void parametersToBuffer(ParameterList pl, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('(');
foreach (i; 0 .. pl.length)
@@ -3258,7 +3263,7 @@ private void parametersToBuffer(ParameterList pl, OutBuffer* buf, HdrGenState* h
* buf = buffer to write it to
* hgs = context
*/
-private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
+private void parameterToBuffer(Parameter p, ref OutBuffer buf, HdrGenState* hgs)
{
if (p.userAttribDecl)
{
@@ -3330,7 +3335,7 @@ private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
* basis = replace `null`s in argument list with this expression (for sparse array literals)
* names = if non-null, use these as the names for the arguments
*/
-private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState* hgs, Expression basis = null, Identifiers* names = null)
+private void argsToBuffer(Expressions* expressions, ref OutBuffer buf, HdrGenState* hgs, Expression basis = null, Identifiers* names = null)
{
if (!expressions || !expressions.length)
return;
@@ -3381,7 +3386,7 @@ private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState*
}
}
-private void sizeToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
+private void sizeToBuffer(Expression e, ref OutBuffer buf, HdrGenState* hgs)
{
if (e.type == Type.tsize_t)
{
@@ -3409,7 +3414,7 @@ private void sizeToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
expToBuffer(e, PREC.assign, buf, hgs);
}
-private void expressionToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
+private void expressionToBuffer(Expression e, ref OutBuffer buf, HdrGenState* hgs)
{
expressionPrettyPrint(e, buf, hgs);
}
@@ -3418,7 +3423,7 @@ private void expressionToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
* Write expression out to buf, but wrap it
* in ( ) if its precedence is less than pr.
*/
-private void expToBuffer(Expression e, PREC pr, OutBuffer* buf, HdrGenState* hgs)
+private void expToBuffer(Expression e, PREC pr, ref OutBuffer buf, HdrGenState* hgs)
{
debug
{
@@ -3452,7 +3457,7 @@ private void expToBuffer(Expression e, PREC pr, OutBuffer* buf, HdrGenState* hgs
/**************************************************
* An entry point to pretty-print type.
*/
-private void typeToBuffer(Type t, const Identifier ident, OutBuffer* buf, HdrGenState* hgs,
+private void typeToBuffer(Type t, const Identifier ident, ref OutBuffer buf, HdrGenState* hgs,
ubyte modMask = 0)
{
if (auto tf = t.isTypeFunction())
@@ -3468,7 +3473,7 @@ private void typeToBuffer(Type t, const Identifier ident, OutBuffer* buf, HdrGen
}
}
-private void visitWithMask(Type t, ubyte modMask, OutBuffer* buf, HdrGenState* hgs)
+private void visitWithMask(Type t, ubyte modMask, ref OutBuffer buf, HdrGenState* hgs)
{
// Tuples and functions don't use the type constructor syntax
if (modMask == t.mod || t.ty == Tfunction || t.ty == Ttuple)
@@ -3504,7 +3509,7 @@ private void visitWithMask(Type t, ubyte modMask, OutBuffer* buf, HdrGenState* h
}
-private void dumpTemplateInstance(TemplateInstance ti, OutBuffer* buf, HdrGenState* hgs)
+private void dumpTemplateInstance(TemplateInstance ti, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('{');
buf.writenl();
@@ -3527,7 +3532,7 @@ private void dumpTemplateInstance(TemplateInstance ti, OutBuffer* buf, HdrGenSta
}
-private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hgs)
+private void tiargsToBuffer(TemplateInstance ti, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('!');
if (ti.nest)
@@ -3576,7 +3581,7 @@ private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hg
* This makes a 'pretty' version of the template arguments.
* It's analogous to genIdent() which makes a mangled version.
*/
-private void objectToBuffer(RootObject oarg, OutBuffer* buf, HdrGenState* hgs)
+private void objectToBuffer(RootObject oarg, ref OutBuffer buf, HdrGenState* hgs)
{
//printf("objectToBuffer()\n");
/* The logic of this should match what genIdent() does. The _dynamic_cast()
@@ -3629,7 +3634,7 @@ private void objectToBuffer(RootObject oarg, OutBuffer* buf, HdrGenState* hgs)
}
-private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, OutBuffer* buf, HdrGenState* hgs, bool isStatic)
+private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, ref OutBuffer buf, HdrGenState* hgs, bool isStatic)
{
if (t.inuse)
{
@@ -3674,7 +3679,7 @@ private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, OutBu
}
private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, TemplateDeclaration td,
- OutBuffer* buf, HdrGenState* hgs)
+ ref OutBuffer buf, HdrGenState* hgs)
{
if (t.inuse)
{
@@ -3743,7 +3748,7 @@ private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, Te
}
-private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* hgs)
+private void initializerToBuffer(Initializer inx, ref OutBuffer buf, HdrGenState* hgs)
{
void visitError(ErrorInitializer iz)
{
@@ -3811,7 +3816,7 @@ private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* h
if (d.exp)
{
buf.writeByte('[');
- toCBuffer(d.exp, buf, hgs);
+ toCBuffer(d.exp, buf, *hgs);
buf.writeByte(']');
}
else
@@ -3832,7 +3837,7 @@ private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* h
}
-private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
+private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs)
{
void visitType(Type t)
{
@@ -4020,7 +4025,7 @@ private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
buf.writeByte(' ');
if (t.id)
buf.writestring(t.id.toChars());
- if (t.tok == TOK.enum_ && t.base.ty != TY.Tint32)
+ if (t.tok == TOK.enum_ && t.base && t.base.ty != TY.Tint32)
{
buf.writestring(" : ");
visitWithMask(t.base, t.mod, buf, hgs);
diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h
index 43fea34255f..e43a35510c2 100644
--- a/gcc/d/dmd/hdrgen.h
+++ b/gcc/d/dmd/hdrgen.h
@@ -15,7 +15,7 @@
class Module;
-void genhdrfile(Module *m);
+void genhdrfile(Module *m, OutBuffer &buf);
void genCppHdrFiles(Modules &ms);
-void moduleToBuffer(OutBuffer *buf, Module *m);
+void moduleToBuffer(OutBuffer& buf, Module *m);
const char *parametersTypeToChars(ParameterList pl);
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 1d4dea47b81..5494fecd70c 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -330,7 +330,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
s.insn = semanticString(sc, s.insn, "asm instruction template");
if (s.labels && s.outputargs)
- s.error("extended asm statements with labels cannot have output constraints");
+ error(s.loc, "extended asm statements with labels cannot have output constraints");
// Analyse all input and output operands.
if (s.args)
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 43b2e5f5a50..62fb51f752e 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -114,6 +114,7 @@ immutable Msgtable[] msgtable =
{ "returnLabel", "__returnLabel" },
{ "line" },
{ "empty", "" },
+ { "dotdotdot", "..." }, // use for error messages
{ "p" },
{ "__vptr" },
{ "__monitor" },
@@ -305,6 +306,7 @@ immutable Msgtable[] msgtable =
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
+ { "_aaAsStruct" },
{ "monitorenter", "_d_monitorenter" },
{ "monitorexit", "_d_monitorexit" },
{ "criticalenter", "_d_criticalenter2" },
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index e7cf9051034..4501185b393 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -61,7 +61,7 @@ extern (C++) class Initializer : ASTNode
{
OutBuffer buf;
HdrGenState hgs;
- .toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
return buf.extractChars();
}
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index c60b4311ff5..45f09af8733 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -53,31 +53,38 @@ import dmd.typesem;
*/
Expression toAssocArrayLiteral(ArrayInitializer ai)
{
- Expression e;
- //printf("ArrayInitializer::toAssocArrayInitializer()\n");
+ //printf("ArrayInitializer::toAssocArrayInitializer(%s)\n", ai.toChars());
//static int i; if (++i == 2) assert(0);
const dim = ai.value.length;
+ if (!dim)
+ {
+ error(ai.loc, "invalid associative array initializer `%s`, use `null` instead",
+ ai.toChars());
+ return ErrorExp.get();
+ }
+ auto no(const char* format, Initializer i)
+ {
+ error(i.loc, format, i.toChars());
+ return ErrorExp.get();
+ }
+ Expression e;
auto keys = new Expressions(dim);
auto values = new Expressions(dim);
for (size_t i = 0; i < dim; i++)
{
- e = ai.index[i];
- if (!e)
- goto Lno;
- (*keys)[i] = e;
Initializer iz = ai.value[i];
- if (!iz)
- goto Lno;
+ assert(iz);
e = iz.initializerToExpression();
if (!e)
- goto Lno;
+ return no("invalid value `%s` in initializer", iz);
(*values)[i] = e;
+ e = ai.index[i];
+ if (!e)
+ return no("missing key for value `%s` in initializer", iz);
+ (*keys)[i] = e;
}
e = new AssocArrayLiteralExp(ai.loc, keys, values);
return e;
-Lno:
- error(ai.loc, "not an associative array initializer");
- return ErrorExp.get();
}
/******************************************
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index 96899869d52..c803bf80cc0 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -810,17 +810,14 @@ public:
Params:
modules = array of the "root modules"
*/
- private void generateModules(Modules* modules)
+ private void generateModules(ref Modules modules)
{
arrayStart();
- if (modules)
+ foreach (m; modules)
{
- foreach (m; *modules)
- {
- if (global.params.verbose)
- message("json gen %s", m.toChars());
- m.accept(this);
- }
+ if (global.params.verbose)
+ message("json gen %s", m.toChars());
+ m.accept(this);
}
arrayEnd();
}
@@ -981,9 +978,15 @@ public:
}
}
-extern (C++) void json_generate(OutBuffer* buf, Modules* modules)
+/***********************************
+ * Generate json for the modules.
+ * Params:
+ * modules = array of Modules
+ * buf = write json output to buf
+ */
+extern (C++) void json_generate(ref Modules modules, ref OutBuffer buf)
{
- scope ToJsonVisitor json = new ToJsonVisitor(buf);
+ scope ToJsonVisitor json = new ToJsonVisitor(&buf);
// write trailing newline
scope(exit) buf.writeByte('\n');
diff --git a/gcc/d/dmd/json.h b/gcc/d/dmd/json.h
index 7a238979e20..09fdecdb9ee 100644
--- a/gcc/d/dmd/json.h
+++ b/gcc/d/dmd/json.h
@@ -15,5 +15,5 @@
struct OutBuffer;
-void json_generate(OutBuffer *, Modules *);
+void json_generate(Modules &, OutBuffer &);
JsonFieldFlags tryParseJsonField(const char *fieldName);
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index c28fe5c2220..28ffbf8ed6d 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -51,7 +51,7 @@ struct CompileEnv
bool previewIn; /// `in` means `[ref] scope const`, accepts rvalues
bool ddocOutput; /// collect embedded documentation comments
bool shortenedMethods = true; /// allow => in normal function declarations
- bool obsolete; /// warn on use of legacy code
+ bool masm; /// use MASM inline asm syntax
}
/***********************************************************
@@ -484,6 +484,12 @@ class Lexer
goto default;
wysiwygStringConstant(t);
return;
+ case 'x':
+ if (p[1] != '"')
+ goto case_ident;
+ p++;
+ t.value = hexStringConstant(t);
+ return;
case 'q':
if (Ccompile)
goto case_ident;
@@ -526,7 +532,7 @@ class Lexer
//case 'u':
case 'v':
case 'w':
- case 'x':
+ /*case 'x':*/
case 'y':
case 'z':
case 'A':
@@ -1476,6 +1482,84 @@ class Lexer
}
}
+ /**************************************
+ * Lex hex strings:
+ * x"0A ae 34FE BD"
+ */
+ final TOK hexStringConstant(Token* t)
+ {
+ Loc start = loc();
+ uint n = 0;
+ uint v = ~0; // dead assignment, needed to suppress warning
+ p++;
+ stringbuffer.setsize(0);
+ while (1)
+ {
+ dchar c = *p++;
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ continue; // skip white space
+ case '\r':
+ if (*p == '\n')
+ continue; // ignore '\r' if followed by '\n'
+ // Treat isolated '\r' as if it were a '\n'
+ goto case '\n';
+ case '\n':
+ endOfLine();
+ continue;
+ case 0:
+ case 0x1A:
+ error("unterminated string constant starting at %s", start.toChars());
+ t.setString();
+ // decrement `p`, because it needs to point to the next token (the 0 or 0x1A character is the TOK.endOfFile token).
+ p--;
+ return TOK.hexadecimalString;
+ case '"':
+ if (n & 1)
+ {
+ error("odd number (%d) of hex characters in hex string", n);
+ stringbuffer.writeByte(v);
+ }
+ t.setString(stringbuffer);
+ stringPostfix(t);
+ return TOK.hexadecimalString;
+ default:
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'f')
+ c -= 'a' - 10;
+ else if (c >= 'A' && c <= 'F')
+ c -= 'A' - 10;
+ else if (c & 0x80)
+ {
+ p--;
+ const u = decodeUTF();
+ p++;
+ if (u == PS || u == LS)
+ endOfLine();
+ else
+ error("non-hex character \\u%04x in hex string", u);
+ }
+ else
+ error("non-hex character '%c' in hex string", c);
+ if (n & 1)
+ {
+ v = (v << 4) | c;
+ stringbuffer.writeByte(v);
+ }
+ else
+ v = c;
+ n++;
+ break;
+ }
+ }
+ assert(0); // see bug 15731
+ }
+
/**
Lex a delimited string. Some examples of delimited strings are:
---
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index 0f3b9a7aa44..ef2bd0af779 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -38,8 +38,8 @@ debug info etc.
struct Loc
{
private uint _linnum;
- private ushort _charnum;
- private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename)
+ private uint _charnum;
+ private uint fileIndex; // index into filenames[], starting from 1 (0 means no filename)
version (LocOffset)
uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
@@ -67,7 +67,7 @@ nothrow:
extern (D) this(const(char)* filename, uint linnum, uint charnum) @safe
{
this._linnum = linnum;
- this._charnum = cast(ushort) charnum;
+ this._charnum = charnum;
this.filename = filename;
}
@@ -80,7 +80,7 @@ nothrow:
/// ditto
extern (C++) uint charnum(uint num) @nogc @safe
{
- return _charnum = cast(ushort) num;
+ return _charnum = num;
}
/// line number, starting from 1
@@ -114,8 +114,16 @@ nothrow:
{
//printf("setting %s\n", name);
filenames.push(name);
- fileIndex = cast(ushort)filenames.length;
- assert(fileIndex); // no overflow
+ fileIndex = cast(uint)filenames.length;
+ if (!fileIndex)
+ {
+ import dmd.globals : global;
+ import dmd.errors : error, fatal;
+
+ global.gag = 0; // ensure error message gets printed
+ error(Loc.initial, "internal compiler error: file name index overflow!");
+ fatal();
+ }
}
else
fileIndex = 0;
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 8b481108f8c..ce512667694 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -142,7 +142,7 @@ public:
int doppelganger; // sub-module
Symbol *cov; // private uint[] __coverage;
- unsigned *covb; // bit array of valid code line numbers
+ DArray<unsigned> covb; // bit array of valid code line numbers
Symbol *sictor; // module order independent constructor
Symbol *sctor; // module constructor
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 9d83db13b67..63e20ed89d0 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -157,7 +157,7 @@ MOD MODmerge(MOD mod1, MOD mod2) pure nothrow @nogc @safe
/*********************************
* Store modifier name into buf.
*/
-void MODtoBuffer(OutBuffer* buf, MOD mod) nothrow @safe
+void MODtoBuffer(ref OutBuffer buf, MOD mod) nothrow @safe
{
buf.writestring(MODtoString(mod));
}
@@ -787,7 +787,7 @@ extern (C++) abstract class Type : ASTNode
HdrGenState hgs;
hgs.fullQual = (ty == Tclass && !mod);
- .toCBuffer(this, &buf, null, &hgs);
+ toCBuffer(this, buf, null, hgs);
return buf.extractChars();
}
@@ -799,7 +799,7 @@ extern (C++) abstract class Type : ASTNode
HdrGenState hgs;
hgs.fullQual = QualifyTypes;
- .toCBuffer(this, &buf, null, &hgs);
+ toCBuffer(this, buf, null, hgs);
return buf.extractChars();
}
@@ -973,7 +973,7 @@ extern (C++) abstract class Type : ASTNode
/*********************************
* Store this type's modifier name into buf.
*/
- final void modToBuffer(OutBuffer* buf) nothrow const
+ final void modToBuffer(ref OutBuffer buf) nothrow const
{
if (mod)
{
@@ -989,7 +989,7 @@ extern (C++) abstract class Type : ASTNode
{
OutBuffer buf;
buf.reserve(16);
- modToBuffer(&buf);
+ modToBuffer(buf);
return buf.extractChars();
}
@@ -4563,7 +4563,7 @@ extern (C++) final class TypeFunction : TypeNext
continue;
if (params == parameterList.parameters)
params = parameterList.parameters.copy();
- (*params)[i] = new Parameter(p.storageClass, t, null, null, null);
+ (*params)[i] = new Parameter(p.loc, p.storageClass, t, null, null, null);
}
if (next == tret && params == parameterList.parameters)
return this;
@@ -6218,7 +6218,7 @@ extern (C++) final class TypeTuple : Type
Expression e = (*exps)[i];
if (e.type.ty == Ttuple)
e.error("cannot form sequence of sequences");
- auto arg = new Parameter(STC.undefined_, e.type, null, null, null);
+ auto arg = new Parameter(e.loc, STC.undefined_, e.type, null, null, null);
(*arguments)[i] = arg;
}
}
@@ -6244,15 +6244,15 @@ extern (C++) final class TypeTuple : Type
{
super(Ttuple);
arguments = new Parameters();
- arguments.push(new Parameter(0, t1, null, null, null));
+ arguments.push(new Parameter(Loc.initial, 0, t1, null, null, null));
}
extern (D) this(Type t1, Type t2)
{
super(Ttuple);
arguments = new Parameters();
- arguments.push(new Parameter(0, t1, null, null, null));
- arguments.push(new Parameter(0, t2, null, null, null));
+ arguments.push(new Parameter(Loc.initial, 0, t1, null, null, null));
+ arguments.push(new Parameter(Loc.initial, 0, t2, null, null, null));
}
static TypeTuple create() @safe
@@ -6661,14 +6661,16 @@ extern (C++) final class Parameter : ASTNode
{
import dmd.attrib : UserAttributeDeclaration;
+ Loc loc;
StorageClass storageClass;
Type type;
Identifier ident;
Expression defaultArg;
UserAttributeDeclaration userAttribDecl; // user defined attributes
- extern (D) this(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
+ extern (D) this(const ref Loc loc, StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
{
+ this.loc = loc;
this.type = type;
this.ident = ident;
this.storageClass = storageClass;
@@ -6676,14 +6678,14 @@ extern (C++) final class Parameter : ASTNode
this.userAttribDecl = userAttribDecl;
}
- static Parameter create(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
+ static Parameter create(const ref Loc loc, StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
{
- return new Parameter(storageClass, type, ident, defaultArg, userAttribDecl);
+ return new Parameter(loc, storageClass, type, ident, defaultArg, userAttribDecl);
}
Parameter syntaxCopy()
{
- return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null, userAttribDecl ? userAttribDecl.syntaxCopy(null) : null);
+ return new Parameter(loc, storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null, userAttribDecl ? userAttribDecl.syntaxCopy(null) : null);
}
/****************************************************
@@ -7688,3 +7690,28 @@ pure string visitTYCase(string handler) @safe
}
assert(0);
}
+
+
+/**
+ * Returns:
+ * `TypeIdentifier` corresponding to `object.Throwable`
+ */
+TypeIdentifier getThrowable()
+{
+ auto tid = new TypeIdentifier(Loc.initial, Id.empty);
+ tid.addIdent(Id.object);
+ tid.addIdent(Id.Throwable);
+ return tid;
+}
+
+/**
+ * Returns:
+ * TypeIdentifier corresponding to `object.Exception`
+ */
+TypeIdentifier getException()
+{
+ auto tid = new TypeIdentifier(Loc.initial, Id.empty);
+ tid.addIdent(Id.object);
+ tid.addIdent(Id.Exception);
+ return tid;
+}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 457b91f1cee..aeeee8c7dad 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -237,7 +237,7 @@ public:
virtual unsigned alignsize();
Type *trySemantic(const Loc &loc, Scope *sc);
Type *merge2();
- void modToBuffer(OutBuffer *buf) const;
+ void modToBuffer(OutBuffer& buf) const;
char *modToChars() const;
virtual bool isintegral();
@@ -563,13 +563,14 @@ enum class PURE : unsigned char
class Parameter final : public ASTNode
{
public:
+ Loc loc;
StorageClass storageClass;
Type *type;
Identifier *ident;
Expression *defaultArg;
UserAttributeDeclaration *userAttribDecl; // user defined attributes
- static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,
+ static Parameter *create(const Loc &loc, StorageClass storageClass, Type *type, Identifier *ident,
Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
Parameter *syntaxCopy();
Type *isLazyArray();
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index 457e8b6479c..f9de1ee5a11 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -1767,10 +1767,10 @@ private FuncDeclaration findBestOpApplyMatch(Expression ethis, FuncDeclaration f
if (fd_ambig)
{
- .error(ethis.loc, "`%s.%s` matches more than one declaration:\n`%s`: `%s`\nand:\n`%s`: `%s`",
- ethis.toChars(), fstart.ident.toChars(),
- fd_best.loc.toChars(), fd_best.type.toChars(),
- fd_ambig.loc.toChars(), fd_ambig.type.toChars());
+ .error(ethis.loc, "`%s.%s` matches more than one declaration:",
+ ethis.toChars(), fstart.ident.toChars());
+ .errorSupplemental(fd_best.loc, "`%s`\nand:", fd_best.type.toChars());
+ .errorSupplemental(fd_ambig.loc, "`%s`", fd_ambig.type.toChars());
return null;
}
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index f98e7c76bcc..37563826a2d 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -1280,19 +1280,25 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
//printf("CatExp::optimize(%d) %s\n", result, e.toChars());
if (binOptimize(e, result))
return;
- if (auto ce1 = e.e1.isCatExp())
- {
- // https://issues.dlang.org/show_bug.cgi?id=12798
- // optimize ((expr ~ str1) ~ str2)
- scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
- cex.type = e.type;
- Expression ex = Expression_optimize(cex, result, false);
- if (ex != cex)
+
+ if (e.type == Type.tstring)
+ if (auto ce1 = e.e1.isCatExp())
{
- e.e1 = ce1.e1;
- e.e2 = ex;
+ // https://issues.dlang.org/show_bug.cgi?id=12798
+ // optimize ((expr ~ str1) ~ str2)
+ // https://issues.dlang.org/show_bug.cgi?id=24078
+ // This optimization is only valid if `expr` is a string.
+ // Otherwise it leads to:
+ // `["c"] ~ "a" ~ "b"` becoming `["c"] ~ "ab"`
+ scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
+ cex.type = e.type;
+ Expression ex = Expression_optimize(cex, result, false);
+ if (ex != cex)
+ {
+ e.e1 = ce1.e1;
+ e.e2 = ex;
+ }
}
- }
// optimize "str"[] -> "str"
if (auto se1 = e.e1.isSliceExp())
{
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 13bba4fb284..2a964151be5 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -1204,7 +1204,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (orig & added)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, added);
+ AST.stcToBuffer(buf, added);
error("redundant attribute `%s`", buf.peekChars());
return orig | added;
}
@@ -2007,6 +2007,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.wcharLiteral:
case TOK.dcharLiteral:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.file:
case TOK.fileFullPath:
case TOK.line:
@@ -2545,7 +2546,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "static constructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
@@ -2580,7 +2581,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "static destructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
@@ -2619,7 +2620,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "shared static constructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
@@ -2653,7 +2654,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "shared static destructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
@@ -2837,7 +2838,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (varargsStc & ~VarArgsStc)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, varargsStc & ~VarArgsStc);
+ AST.stcToBuffer(buf, varargsStc & ~VarArgsStc);
error("variadic parameter cannot have attributes `%s`", buf.peekChars());
varargsStc &= VarArgsStc;
}
@@ -2935,11 +2936,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
//error("scope cannot be ref or out");
const tv = peekNext();
+ Loc loc;
if (tpl && token.value == TOK.identifier &&
(tv == TOK.comma || tv == TOK.rightParenthesis || tv == TOK.dotDotDot))
{
Identifier id = Identifier.generateId("__T");
- const loc = token.loc;
+ loc = token.loc;
at = new AST.TypeIdentifier(loc, id);
if (!*tpl)
*tpl = new AST.TemplateParameters();
@@ -2951,7 +2953,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
else
{
- at = parseType(&ai);
+ at = parseType(&ai, null, &loc);
}
ae = null;
if (token.value == TOK.assign) // = defaultArg
@@ -2959,7 +2961,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
nextToken();
ae = parseDefaultInitExp();
}
- auto param = new AST.Parameter(storageClass | STC.parameter, at, ai, ae, null);
+ auto param = new AST.Parameter(loc, storageClass | STC.parameter, at, ai, ae, null);
if (udas)
{
auto a = new AST.Dsymbols();
@@ -3083,7 +3085,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else
{
OutBuffer buf;
- AST.stcToBuffer(&buf, _stc);
+ AST.stcToBuffer(buf, _stc);
error(attributeErrorMessage, buf.peekChars());
}
nextToken();
@@ -3284,8 +3286,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (token.value != TOK.rightCurly)
{
/* { */
- error(token.loc, "`}` expected following members in `%s` declaration at %s",
- Token.toChars(tok), loc.toChars());
+ error(token.loc, "`}` expected following members in `%s` declaration",
+ Token.toChars(tok));
+ if (id)
+ eSink.errorSupplemental(loc, "%s `%s` starts here",
+ Token.toChars(tok), id.toChars());
+ else
+ eSink.errorSupplemental(loc, "%s starts here",
+ Token.toChars(tok));
}
nextToken();
}
@@ -3481,8 +3489,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
* Params:
* pident = set to Identifier if there is one, null if not
* ptpl = if !null, then set to TemplateParameterList
+ * pdeclLoc = if !null, then set to location of the declarator
*/
- AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null)
+ AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null, Loc* pdeclLoc = null)
{
/* Take care of the storage class prefixes that
* serve as type attributes:
@@ -3539,6 +3548,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
AST.Type t;
t = parseBasicType();
+ if (pdeclLoc)
+ *pdeclLoc = token.loc;
int alt = 0;
t = parseDeclarator(t, alt, pident, ptpl);
checkCstyleTypeSyntax(typeLoc, t, alt, pident ? *pident : null);
@@ -4575,8 +4586,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
else if (t.ty == Tfunction)
{
+ /* @@@DEPRECATED_2.115@@@
+ * change to error, deprecated in 2.105.1 */
if (storage_class & STC.manifest)
- error("function cannot have enum storage class");
+ deprecation("function cannot have enum storage class");
AST.Expression constraint = null;
//printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t.toChars(), storage_class);
@@ -4953,7 +4966,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (remStc)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, remStc);
+ AST.stcToBuffer(buf, remStc);
// @@@DEPRECATED_2.103@@@
// Deprecated in 2020-07, can be made an error in 2.103
eSink.deprecation(token.loc, "storage class `%s` has no effect in type aliases", buf.peekChars());
@@ -5108,7 +5121,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (save == TOK.function_)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error("function literal cannot be `%s`", buf.peekChars());
}
else
@@ -5126,7 +5139,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
parameterList.parameters = new AST.Parameters();
Identifier id = Identifier.generateId("__T");
AST.Type t = new AST.TypeIdentifier(loc, id);
- parameterList.parameters.push(new AST.Parameter(STC.parameter, t, token.ident, null, null));
+ parameterList.parameters.push(new AST.Parameter(loc, STC.parameter, t, token.ident, null, null));
tpl = new AST.TemplateParameters();
AST.TemplateParameter tp = new AST.TemplateTypeParameter(loc, id, null, null);
@@ -5443,6 +5456,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
Identifier ai = null;
AST.Type at;
+ Loc aloc;
StorageClass storageClass = 0;
StorageClass stc = 0;
@@ -5524,6 +5538,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
lastai = token.ident;
ai = token.ident;
at = null; // infer argument type
+ aloc = token.loc;
nextToken();
goto Larg;
}
@@ -5532,7 +5547,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (!ai)
noIdentifierForDeclarator(at);
Larg:
- auto p = new AST.Parameter(storageClass, at, ai, null, null);
+ auto p = new AST.Parameter(aloc, storageClass, at, ai, null, null);
parameters.push(p);
if (token.value == TOK.comma)
{
@@ -5684,16 +5699,18 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
Identifier ai = token.ident;
AST.Type at = null; // infer parameter type
+ const aloc = token.loc;
nextToken();
check(TOK.assign);
- param = new AST.Parameter(storageClass, at, ai, null, null);
+ param = new AST.Parameter(aloc, storageClass, at, ai, null, null);
}
else if (isDeclaration(&token, NeedDeclaratorId.must, TOK.assign, null))
{
Identifier ai;
+ const aloc = token.loc;
AST.Type at = parseType(&ai);
check(TOK.assign);
- param = new AST.Parameter(storageClass, at, ai, null, null);
+ param = new AST.Parameter(aloc, storageClass, at, ai, null, null);
}
else if (storageClass != 0)
error("found `%s` while expecting `=` or identifier", n.toChars());
@@ -5789,6 +5806,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.true_:
case TOK.false_:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.leftParenthesis:
case TOK.cast_:
case TOK.mul:
@@ -5816,7 +5834,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
AST.Expression exp = parseExpression();
/* https://issues.dlang.org/show_bug.cgi?id=15103
* Improve declaration / initialization syntax error message
- * Error: found 'foo' when expecting ';' following statement
+ * Error: found 'foo' when expecting ';' following expression
* becomes Error: found `(` when expecting `;` or `=`, did you mean `Foo foo = 42`?
*/
if (token.value == TOK.identifier && exp.op == EXP.identifier)
@@ -5841,11 +5859,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
* otherwise we fall back on the old path (advancing the token).
*/
if (token.value != TOK.semicolon && peek(&token).value == TOK.semicolon)
- error("found `%s` when expecting `;` following statement", token.toChars());
+ error("found `%s` when expecting `;` following expression", token.toChars());
else
{
if (token.value != TOK.semicolon)
- error("found `%s` when expecting `;` following statement `%s` on line %s", token.toChars(), exp.toChars(), exp.loc.toChars());
+ {
+ error("found `%s` when expecting `;` following expression", token.toChars());
+ eSink.errorSupplemental(exp.loc, "expression: `%s`", exp.toChars());
+ }
nextToken();
}
}
@@ -6580,7 +6601,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
case TOK.asm_:
- s = parseAsm();
+ s = parseAsm(false);
break;
case TOK.import_:
@@ -6951,10 +6972,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
* AsmInstruction ;
* AsmInstruction ; AsmInstruction
*
+ * Params:
+ * endOfLine = true if EOL means end of asm statement
* Returns:
* inline assembler block as a Statement
*/
- AST.Statement parseAsm()
+ AST.Statement parseAsm(bool endOfLine)
{
// Parse the asm block into a sequence of AsmStatements,
// each AsmStatement is one instruction.
@@ -6977,6 +7000,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
size_t nestlevel = 0;
while (1)
{
+ if (endOfLine)
+ nextDefineLine();
switch (token.value)
{
case TOK.identifier:
@@ -7011,6 +7036,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
break;
+ case TOK.endOfLine:
+ nextDefineLine();
+ goto case;
+
case TOK.semicolon:
if (nestlevel != 0)
error("mismatched number of curly brackets");
@@ -7018,7 +7047,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (toklist || label)
{
// Create AsmStatement from list of tokens we've saved
- AST.Statement s = new AST.AsmStatement(token.loc, toklist);
+ AST.AsmStatement as = new AST.AsmStatement(token.loc, toklist);
+ as.caseSensitive = !endOfLine;
+ AST.Statement s = as;
toklist = null;
ptoklist = &toklist;
if (label)
@@ -7062,6 +7093,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
break;
}
nextToken();
+ if (token.value == TOK.endOfLine)
+ nextToken();
auto s = new AST.CompoundAsmStatement(loc, statements, stc);
return s;
}
@@ -7291,6 +7324,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.wcharLiteral:
case TOK.dcharLiteral:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.file:
case TOK.fileFullPath:
case TOK.line:
@@ -7562,7 +7596,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
continue;
- // Valid tokens that follow a declaration
+ // Valid tokens that follow the start of a declaration
case TOK.rightParenthesis:
case TOK.rightBracket:
case TOK.assign:
@@ -7581,6 +7615,23 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
return false;
+ // To recognize the shortened function declaration syntax
+ case TOK.goesTo:
+ /*
+ 1. https://issues.dlang.org/show_bug.cgi?id=24088
+
+ 2. We need to make sure the would-be
+ declarator has an identifier otherwise function literals
+ are handled incorrectly. Some special treatment is required
+ here, it turns out that a lot of code in the compiler relies
+ on this mess (in the parser), i.e. having isDeclarator be more
+ precise the parsing of other things go kaboom, so we do it in a
+ separate case.
+ */
+ if (*haveId)
+ goto case TOK.do_;
+ goto default;
+
case TOK.identifier:
if (t.ident == Id._body)
{
@@ -8148,6 +8199,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
break;
case TOK.string_:
+ case TOK.hexadecimalString:
{
// cat adjacent strings
auto s = token.ustring;
@@ -8157,7 +8209,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
const prev = token;
nextToken();
- if (token.value == TOK.string_)
+ if (token.value == TOK.string_ || token.value == TOK.hexadecimalString)
{
if (token.postfix)
{
@@ -9549,7 +9601,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
void usageOfBodyKeyword()
{
- if (compileEnv.obsolete)
+ version (none) // disable obsolete warning
{
eSink.warning(token.loc, "usage of identifer `body` as a keyword is obsolete. Use `do` instead.");
}
diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d
index e43ffad2570..e1deb2c8786 100644
--- a/gcc/d/dmd/printast.d
+++ b/gcc/d/dmd/printast.d
@@ -64,7 +64,7 @@ extern (C++) final class PrintASTVisitor : Visitor
import dmd.hdrgen : floatToBuffer;
import dmd.common.outbuffer : OutBuffer;
OutBuffer buf;
- floatToBuffer(e.type, e.value, &buf, false);
+ floatToBuffer(e.type, e.value, buf, false);
printf("Real %s %s\n", buf.peekChars(), e.type ? e.type.toChars() : "");
}
diff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d
index c3fa90d7f79..bd531c0081e 100644
--- a/gcc/d/dmd/safe.d
+++ b/gcc/d/dmd/safe.d
@@ -51,7 +51,7 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
DotVarExp dve = cast(DotVarExp)e;
if (VarDeclaration v = dve.var.isVarDeclaration())
{
- if (sc.intypeof || !sc.func || !sc.func.isSafeBypassingInference())
+ if (!sc.func)
return false;
auto ad = v.isMember2();
if (!ad)
@@ -65,6 +65,11 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
return true;
}
+ // This branch shouldn't be here, but unfortunately calling `ad.determineSize`
+ // breaks code with circular reference errors. Specifically, test23589.d fails
+ if (ad.sizeok != Sizeok.done && !sc.func.isSafeBypassingInference())
+ return false;
+
// needed to set v.overlapped and v.overlapUnsafe
if (ad.sizeok != Sizeok.done)
ad.determineSize(ad.loc);
@@ -74,9 +79,23 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
{
if (v.overlapped)
{
- if (sc.setUnsafe(!printmsg, e.loc,
+ if (sc.func.isSafeBypassingInference() && sc.setUnsafe(!printmsg, e.loc,
"field `%s.%s` cannot access pointers in `@safe` code that overlap other fields", ad, v))
+ {
return true;
+ }
+ else
+ {
+ import dmd.globals : FeatureState;
+ // @@@DEPRECATED_2.116@@@
+ // https://issues.dlang.org/show_bug.cgi?id=20655
+ // Inferring `@system` because of union access breaks code,
+ // so make it a deprecation safety violation as of 2.106
+ // To turn into an error, remove `isSafeBypassingInference` check in the
+ // above if statement and remove the else branch
+ sc.setUnsafePreview(FeatureState.default_, !printmsg, e.loc,
+ "field `%s.%s` cannot access pointers in `@safe` code that overlap other fields", ad, v);
+ }
}
}
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 53c8714510c..e2d2e041162 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -275,6 +275,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
// https://issues.dlang.org/show_bug.cgi?id=20417
// Don't run CTFE for the temporary variables inside typeof or __traits(compiles)
vd._init = vd._init.initializerSemantic(sc, vd.type, sc.intypeof == 1 || sc.flags & SCOPE.compile ? INITnointerpret : INITinterpret);
+ lowerStaticAAs(vd, sc);
vd.inuse--;
}
if (vd._init && vd.storage_class & STC.manifest)
@@ -819,3 +820,55 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag)
}
ale.elements.sort!predicate;
}
+
+/**
+ * Try lower a variable's static Associative Array to a newaa struct.
+ * Params:
+ * vd = Variable to lower
+ * sc = Scope
+ */
+void lowerStaticAAs(VarDeclaration vd, Scope* sc)
+{
+ if (vd.storage_class & STC.manifest)
+ return;
+ if (auto ei = vd._init.isExpInitializer())
+ {
+ scope v = new StaticAAVisitor(sc);
+ v.vd = vd;
+ ei.exp.accept(v);
+ }
+}
+
+/// Visit Associative Array literals and lower them to structs for static initialization
+private extern(C++) final class StaticAAVisitor : SemanticTimeTransitiveVisitor
+{
+ alias visit = SemanticTimeTransitiveVisitor.visit;
+ Scope* sc;
+ VarDeclaration vd;
+
+ this(Scope* sc) scope @safe
+ {
+ this.sc = sc;
+ }
+
+ override void visit(AssocArrayLiteralExp aaExp)
+ {
+ if (!verifyHookExist(aaExp.loc, *sc, Id._aaAsStruct, "initializing static associative arrays", Id.object))
+ return;
+
+ Expression hookFunc = new IdentifierExp(aaExp.loc, Id.empty);
+ hookFunc = new DotIdExp(aaExp.loc, hookFunc, Id.object);
+ hookFunc = new DotIdExp(aaExp.loc, hookFunc, Id._aaAsStruct);
+ auto arguments = new Expressions();
+ arguments.push(aaExp.syntaxCopy());
+ Expression loweredExp = new CallExp(aaExp.loc, hookFunc, arguments);
+
+ sc = sc.startCTFE();
+ loweredExp = loweredExp.expressionSemantic(sc);
+ loweredExp = resolveProperties(sc, loweredExp);
+ sc = sc.endCTFE();
+ loweredExp = loweredExp.ctfeInterpret();
+
+ aaExp.lowering = loweredExp;
+ }
+}
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index bff89f8eaf3..04f57a4c021 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -471,7 +471,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
stc |= STC.temp;
}
Type vtype = fparam.type;
- auto v = new VarDeclaration(funcdecl.loc, vtype, id, null);
+ auto v = new VarDeclaration(fparam.loc, vtype, id, null);
//printf("declaring parameter %s of type %s\n", v.toChars(), v.type.toChars());
stc |= STC.parameter;
if (f.parameterList.varargs == VarArg.typesafe && i + 1 == nparams)
@@ -749,7 +749,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
funcdecl.buildEnsureRequire();
// Check for errors related to 'nothrow'.
- const blockexit = funcdecl.fbody.blockExit(funcdecl, f.isnothrow);
+ const blockexit = funcdecl.fbody.blockExit(funcdecl, f.isnothrow ? global.errorSink : null);
if (f.isnothrow && blockexit & BE.throw_)
error(funcdecl.loc, "%s `%s` may throw but is marked as `nothrow`", funcdecl.kind(), funcdecl.toPrettyChars());
@@ -993,7 +993,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
freq = freq.statementSemantic(sc2);
// @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg`
- const blockExit = freq.blockExit(funcdecl, false);
+ const blockExit = freq.blockExit(funcdecl, null);
if (blockExit & BE.throw_)
{
if (isnothrow)
@@ -1040,7 +1040,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
fens = fens.statementSemantic(sc2);
// @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg`
- const blockExit = fens.blockExit(funcdecl, false);
+ const blockExit = fens.blockExit(funcdecl, null);
if (blockExit & BE.throw_)
{
if (isnothrow)
@@ -1177,7 +1177,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
s = s.statementSemantic(sc2);
- const blockexit = s.blockExit(funcdecl, isnothrow);
+ const blockexit = s.blockExit(funcdecl, isnothrow ? global.errorSink : null);
if (blockexit & BE.throw_)
{
funcdecl.hasNoEH = false;
@@ -1187,7 +1187,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
f.isnothrow = false;
}
- if (sbody.blockExit(funcdecl, f.isnothrow) == BE.fallthru)
+ if (sbody.blockExit(funcdecl, f.isnothrow ? global.errorSink : null) == BE.fallthru)
sbody = new CompoundStatement(Loc.initial, sbody, s);
else
sbody = new TryFinallyStatement(Loc.initial, sbody, s);
@@ -1453,7 +1453,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
{
// storage_class is apparently not set for dtor & ctor
OutBuffer ob;
- stcToBuffer(&ob,
+ stcToBuffer(ob,
(ngErr ? STC.nogc : 0) |
(puErr ? STC.pure_ : 0) |
(saErr ? STC.system : 0)
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index 607dd51e087..58550fe6ca4 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -16,20 +16,14 @@ module dmd.statement;
import core.stdc.stdarg;
import core.stdc.stdio;
-import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
import dmd.ast_node;
+import dmd.errors;
import dmd.gluelayer;
import dmd.cond;
-import dmd.dclass;
import dmd.declaration;
-import dmd.denum;
-import dmd.dimport;
-import dmd.dscope;
import dmd.dsymbol;
-import dmd.dtemplate;
-import dmd.errors;
import dmd.expression;
import dmd.func;
import dmd.globals;
@@ -37,40 +31,14 @@ import dmd.hdrgen;
import dmd.id;
import dmd.identifier;
import dmd.location;
-import dmd.dinterpret;
import dmd.mtype;
import dmd.common.outbuffer;
import dmd.root.rootobject;
import dmd.sapply;
-import dmd.sideeffect;
import dmd.staticassert;
import dmd.tokens;
import dmd.visitor;
-/**
- * Returns:
- * `TypeIdentifier` corresponding to `object.Throwable`
- */
-TypeIdentifier getThrowable()
-{
- auto tid = new TypeIdentifier(Loc.initial, Id.empty);
- tid.addIdent(Id.object);
- tid.addIdent(Id.Throwable);
- return tid;
-}
-
-/**
- * Returns:
- * TypeIdentifier corresponding to `object.Exception`
- */
-TypeIdentifier getException()
-{
- auto tid = new TypeIdentifier(Loc.initial, Id.empty);
- tid.addIdent(Id.object);
- tid.addIdent(Id.Exception);
- return tid;
-}
-
/***********************************************************
* Specification: https://dlang.org/spec/statement.html
*/
@@ -118,64 +86,11 @@ extern (C++) abstract class Statement : ASTNode
{
HdrGenState hgs;
OutBuffer buf;
- .toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
buf.writeByte(0);
return buf.extractSlice().ptr;
}
- static if (__VERSION__ < 2092)
- {
- final void error(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.error);
- va_end(ap);
- }
-
- final void warning(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.warning);
- va_end(ap);
- }
-
- final void deprecation(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.deprecation);
- va_end(ap);
- }
- }
- else
- {
- pragma(printf) final void error(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.error);
- va_end(ap);
- }
-
- pragma(printf) final void warning(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.warning);
- va_end(ap);
- }
-
- pragma(printf) final void deprecation(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.deprecation);
- va_end(ap);
- }
- }
-
Statement getRelatedLabeled()
{
return this;
@@ -1252,9 +1167,10 @@ extern (C++) final class SwitchStatement : Statement
if (v.isDataseg() || (v.storage_class & (STC.manifest | STC.temp) && vd.ident != Id.withSym) || v._init.isVoidInitializer())
continue;
if (vd.ident == Id.withSym)
- error("`switch` skips declaration of `with` temporary at %s", v.loc.toChars());
+ error(loc, "`switch` skips declaration of `with` temporary");
else
- error("`switch` skips declaration of variable `%s` at %s", v.toPrettyChars(), v.loc.toChars());
+ error(loc, "`switch` skips declaration of variable `%s`", v.toPrettyChars());
+ errorSupplemental(v.loc, "declared here");
return true;
}
return false;
@@ -1813,22 +1729,22 @@ extern (C++) final class GotoStatement : Statement
else
{
if (label.statement.os)
- error("cannot `goto` in to `%s` block", Token.toChars(label.statement.os.tok));
+ error(loc, "cannot `goto` in to `%s` block", Token.toChars(label.statement.os.tok));
else
- error("cannot `goto` out of `%s` block", Token.toChars(os.tok));
+ error(loc, "cannot `goto` out of `%s` block", Token.toChars(os.tok));
return true;
}
}
if (label.statement.tf != tf)
{
- error("cannot `goto` in or out of `finally` block");
+ error(loc, "cannot `goto` in or out of `finally` block");
return true;
}
if (label.statement.inCtfeBlock && !inCtfeBlock)
{
- error("cannot `goto` into `if (__ctfe)` block");
+ error(loc, "cannot `goto` into `if (__ctfe)` block");
return true;
}
@@ -1837,7 +1753,7 @@ extern (C++) final class GotoStatement : Statement
{
if (!stb)
{
- error("cannot `goto` into `try` block");
+ error(loc, "cannot `goto` into `try` block");
return true;
}
if (auto stf = stb.isTryFinallyStatement())
@@ -1863,17 +1779,15 @@ extern (C++) final class GotoStatement : Statement
{
// Lifetime ends at end of expression, so no issue with skipping the statement
}
- else if (vd.ident == Id.withSym)
- {
- error("`goto` skips declaration of `with` temporary at %s", vd.loc.toChars());
- return true;
- }
else
{
- error("`goto` skips declaration of variable `%s` at %s", vd.toPrettyChars(), vd.loc.toChars());
+ if (vd.ident == Id.withSym)
+ error(loc, "`goto` skips declaration of `with` temporary");
+ else
+ error(loc, "`goto` skips declaration of variable `%s`", vd.toPrettyChars());
+ errorSupplemental(vd.loc, "declared here");
return true;
}
-
return false;
}
@@ -1959,6 +1873,7 @@ extern (C++) final class LabelDsymbol : Dsymbol
extern (C++) class AsmStatement : Statement
{
Token* tokens;
+ bool caseSensitive; // for register names
extern (D) this(const ref Loc loc, Token* tokens) @safe
{
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index eb4849dfc1b..dd8b9f21c05 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -116,7 +116,7 @@ public:
const char *toChars() const override final;
void error(const char *format, ...);
- void warning(const char *format, ...);
+ void warning(unsigned flag, const char *format, ...);
void deprecation(const char *format, ...);
virtual Statement *getRelatedLabeled() { return this; }
virtual bool hasBreak() const;
@@ -712,6 +712,7 @@ class AsmStatement : public Statement
{
public:
Token *tokens;
+ bool caseSensitive; // for register names
AsmStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 178cef5af8c..304cb862f32 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -38,6 +38,7 @@ import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.escape;
import dmd.expression;
import dmd.expressionsem;
@@ -349,7 +350,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
Identifier id = Identifier.generateId("__o");
Statement handler = new PeelStatement(sexception);
- if (sexception.blockExit(sc.func, false) & BE.fallthru)
+ if (sexception.blockExit(sc.func, null) & BE.fallthru)
{
auto ts = new ThrowStatement(Loc.initial, new IdentifierExp(Loc.initial, id));
ts.internalThrow = true;
@@ -704,7 +705,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (!p.type)
{
- fs.error("cannot infer type for `foreach` variable `%s`, perhaps set it explicitly", p.ident.toChars());
+ error(fs.loc, "cannot infer type for `foreach` variable `%s`, perhaps set it explicitly", p.ident.toChars());
p.type = Type.terror;
result = true;
}
@@ -753,7 +754,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
assert(oaggr.type);
- fs.error("invalid `%s` aggregate `%s` of type `%s`",
+ error(fs.loc, "invalid `%s` aggregate `%s` of type `%s`",
Token.toChars(fs.op), oaggr.toChars(), oaggr.type.toPrettyChars());
if (auto ad = isAggregate(fs.aggr.type))
@@ -815,11 +816,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (foundMismatch && dim != foreachParamCount)
{
const(char)* plural = foreachParamCount > 1 ? "s" : "";
- fs.error("cannot infer argument types, expected %llu argument%s, not %llu",
+ error(fs.loc, "cannot infer argument types, expected %llu argument%s, not %llu",
cast(ulong) foreachParamCount, plural, cast(ulong) dim);
}
else
- fs.error("cannot uniquely infer `foreach` argument types");
+ error(fs.loc, "cannot uniquely infer `foreach` argument types");
return setError();
}
@@ -845,11 +846,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (p.storageClass & STC.manifest)
{
- fs.error("cannot declare `enum` loop variables for non-unrolled foreach");
+ error(fs.loc, "cannot declare `enum` loop variables for non-unrolled foreach");
}
if (p.storageClass & STC.alias_)
{
- fs.error("cannot declare `alias` loop variables for non-unrolled foreach");
+ error(fs.loc, "cannot declare `alias` loop variables for non-unrolled foreach");
}
}
@@ -861,7 +862,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
void rangeError()
{
- fs.error("cannot infer argument types");
+ error(fs.loc, "cannot infer argument types");
return retError();
}
@@ -959,7 +960,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (dim < 1 || dim > 2)
{
- fs.error("only one or two arguments for array `foreach`");
+ error(fs.loc, "only one or two arguments for array `foreach`");
return retError();
}
@@ -978,7 +979,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
Type tindex = (*fs.parameters)[0].type;
if (!tindex.isintegral())
{
- fs.error("foreach: key cannot be of non-integral type `%s`", tindex.toChars());
+ error(fs.loc, "foreach: key cannot be of non-integral type `%s`", tindex.toChars());
return retError();
}
/* What cases to deprecate implicit conversions for:
@@ -990,7 +991,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
(tn.ty != tv.ty && tn.ty.isSomeChar && tv.ty.isSomeChar)) &&
!Type.tsize_t.implicitConvTo(tindex))
{
- fs.deprecation("foreach: loop index implicitly converted from `size_t` to `%s`",
+ deprecation(fs.loc, "foreach: loop index implicitly converted from `size_t` to `%s`",
tindex.toChars());
}
}
@@ -1007,7 +1008,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (p.storageClass & STC.ref_)
{
- fs.error("`foreach`: value of UTF conversion cannot be `ref`");
+ error(fs.loc, "`foreach`: value of UTF conversion cannot be `ref`");
return retError();
}
if (dim == 2)
@@ -1015,7 +1016,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
p = (*fs.parameters)[0];
if (p.storageClass & STC.ref_)
{
- fs.error("`foreach`: key cannot be `ref`");
+ error(fs.loc, "`foreach`: key cannot be `ref`");
return retError();
}
}
@@ -1036,7 +1037,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (fs.key.type.constConv(p.type) == MATCH.nomatch)
{
- fs.error("key type mismatch, `%s` to `ref %s`",
+ error(fs.loc, "key type mismatch, `%s` to `ref %s`",
fs.key.type.toChars(), p.type.toChars());
return retError();
}
@@ -1048,7 +1049,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
if (!IntRange.fromType(fs.key.type).contains(dimrange))
{
- fs.error("index type `%s` cannot cover index range 0..%llu",
+ error(fs.loc, "index type `%s` cannot cover index range 0..%llu",
p.type.toChars(), ta.dim.toInteger());
return retError();
}
@@ -1071,7 +1072,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
Type t = tab.nextOf();
if (t.constConv(p.type) == MATCH.nomatch)
{
- fs.error("argument type mismatch, `%s` to `ref %s`",
+ error(fs.loc, "argument type mismatch, `%s` to `ref %s`",
t.toChars(), p.type.toChars());
return retError();
}
@@ -1197,13 +1198,13 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
case Taarray:
if (fs.op == TOK.foreach_reverse_)
- fs.warning("cannot use `foreach_reverse` with an associative array");
+ warning(fs.loc, "cannot use `foreach_reverse` with an associative array");
if (checkForArgTypes(fs))
return retError();
if (dim < 1 || dim > 2)
{
- fs.error("only one or two arguments for associative array `foreach`");
+ error(fs.loc, "only one or two arguments for associative array `foreach`");
return retError();
}
return retStmt(apply());
@@ -1308,7 +1309,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
if (tfront.ty == Tvoid)
{
- fs.error("`%s.front` is `void` and has no value", oaggr.toChars());
+ error(fs.loc, "`%s.front` is `void` and has no value", oaggr.toChars());
return retError();
}
@@ -1348,7 +1349,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (exps.length != dim)
{
const(char)* plural = exps.length > 1 ? "s" : "";
- fs.error("cannot infer argument types, expected %llu argument%s, not %llu",
+ error(fs.loc, "cannot infer argument types, expected %llu argument%s, not %llu",
cast(ulong) exps.length, plural, cast(ulong) dim);
return retError();
}
@@ -1371,7 +1372,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
p.type = p.type.addStorageClass(sc).typeSemantic(loc, sc2);
if (!exp.implicitConvTo(p.type))
{
- fs.error("cannot implicilty convert range element of type `%s` to variable `%s` of type `%s`",
+ error(fs.loc, "cannot implicilty convert range element of type `%s` to variable `%s` of type `%s`",
exp.type.toChars(), p.toChars(), p.type.toChars());
return retError();
}
@@ -1399,12 +1400,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
case Tdelegate:
if (fs.op == TOK.foreach_reverse_)
- fs.deprecation("cannot use `foreach_reverse` with a delegate");
+ deprecation(fs.loc, "cannot use `foreach_reverse` with a delegate");
return retStmt(apply());
case Terror:
return retError();
default:
- fs.error("`foreach`: `%s` is not an aggregate type", fs.aggr.type.toChars());
+ error(fs.loc, "`foreach`: `%s` is not an aggregate type", fs.aggr.type.toChars());
return retError();
}
}
@@ -1421,7 +1422,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
fs.lwr = fs.lwr.optimize(WANTvalue);
if (!fs.lwr.type)
{
- fs.error("invalid range lower bound `%s`", fs.lwr.toChars());
+ error(fs.loc, "invalid range lower bound `%s`", fs.lwr.toChars());
return setError();
}
@@ -1430,7 +1431,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
fs.upr = fs.upr.optimize(WANTvalue);
if (!fs.upr.type)
{
- fs.error("invalid range upper bound `%s`", fs.upr.toChars());
+ error(fs.loc, "invalid range upper bound `%s`", fs.upr.toChars());
return setError();
}
@@ -1584,7 +1585,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (fs.key.type.constConv(fs.prm.type) == MATCH.nomatch)
{
- fs.error("argument type mismatch, `%s` to `ref %s`", fs.key.type.toChars(), fs.prm.type.toChars());
+ error(fs.loc, "argument type mismatch, `%s` to `ref %s`", fs.key.type.toChars(), fs.prm.type.toChars());
return setError();
}
}
@@ -1762,14 +1763,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
/* Should this be allowed?
*/
- ps.error("`pragma(lib)` not allowed as statement");
+ error(ps.loc, "`pragma(lib)` not allowed as statement");
return setError();
}
else
{
if (!ps.args || ps.args.length != 1)
{
- ps.error("`string` expected for library name");
+ error(ps.loc, "`string` expected for library name");
return setError();
}
else
@@ -1789,7 +1790,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
/* Should this be allowed?
*/
- ps.error("`pragma(linkerDirective)` not allowed as statement");
+ error(ps.loc, "`pragma(linkerDirective)` not allowed as statement");
return setError();
}
else if (ps.ident == Id.startaddress)
@@ -1805,13 +1806,32 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
else
{
- ps.error("`pragma(inline)` is not inside a function");
+ error(ps.loc, "`pragma(inline)` is not inside a function");
return setError();
}
}
+ else if (ps.ident == Id.mangle)
+ {
+ auto es = ps._body ? ps._body.isExpStatement() : null;
+ auto de = es ? es.exp.isDeclarationExp() : null;
+ if (!de)
+ {
+ error(ps.loc, "`pragma(mangle)` must be attached to a declaration");
+ return setError();
+ }
+ const se = ps.args && (*ps.args).length == 1 ? semanticString(sc, (*ps.args)[0], "pragma mangle argument") : null;
+ if (!se)
+ {
+ error(ps.loc, "`pragma(mangle)` takes a single argument that must be a string literal");
+ return setError();
+ }
+ const cnt = setMangleOverride(de.declaration, cast(const(char)[])se.peekData());
+ if (cnt != 1)
+ assert(0);
+ }
else if (!global.params.ignoreUnsupportedPragmas)
{
- ps.error("unrecognized `pragma(%s)`", ps.ident.toChars());
+ error(ps.loc, "unrecognized `pragma(%s)`", ps.ident.toChars());
return setError();
}
@@ -1819,7 +1839,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (ps.ident == Id.msg || ps.ident == Id.startaddress)
{
- ps.error("`pragma(%s)` is missing a terminating `;`", ps.ident.toChars());
+ error(ps.loc, "`pragma(%s)` is missing a terminating `;`", ps.ident.toChars());
return setError();
}
ps._body = ps._body.statementSemantic(sc);
@@ -1885,7 +1905,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (!ss.condition.isErrorExp())
{
- ss.error("`%s` must be of integral or string type, it is a `%s`",
+ error(ss.loc, "`%s` must be of integral or string type, it is a `%s`",
ss.condition.toChars(), ss.condition.type.toChars());
conditionError = true;
break;
@@ -1924,7 +1944,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (!gcs.exp)
{
- gcs.error("no `case` statement following `goto case;`");
+ error(gcs.loc, "no `case` statement following `goto case;`");
sc.pop();
return setError();
}
@@ -1942,7 +1962,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
}
}
- gcs.error("`case %s` not found", gcs.exp.toChars());
+ error(gcs.loc, "`case %s` not found", gcs.exp.toChars());
sc.pop();
return setError();
}
@@ -1975,7 +1995,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
continue Lmembers;
}
if (missingMembers == 0)
- ss.error("missing cases for `enum` members in `final switch`:");
+ error(ss.loc, "missing cases for `enum` members in `final switch`:");
if (missingMembers < maxShown)
errorSupplemental(ss.loc, "`%s`", em.toChars());
@@ -2000,7 +2020,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
ss.hasNoDefault = 1;
if (!ss.isFinal && (!ss._body || !ss._body.isErrorStatement()) && !(sc.flags & SCOPE.Cfile))
- ss.error("`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`");
+ error(ss.loc, "`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`");
// Generate runtime error if the default is hit
auto a = new Statements();
@@ -2051,7 +2071,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
a.reserve(2);
sc.sw.sdefault = new DefaultStatement(ss.loc, s);
a.push(ss._body);
- if (ss._body.blockExit(sc.func, false) & BE.fallthru)
+ if (ss._body.blockExit(sc.func, null) & BE.fallthru)
a.push(new BreakStatement(Loc.initial, null));
a.push(sc.sw.sdefault);
cs = new CompoundStatement(ss.loc, a);
@@ -2193,12 +2213,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
*/
if (!v.isConst() && !v.isImmutable())
{
- cs.error("`case` variables have to be `const` or `immutable`");
+ error(cs.loc, "`case` variables have to be `const` or `immutable`");
}
if (sw.isFinal)
{
- cs.error("`case` variables not allowed in `final switch` statements");
+ error(cs.loc, "`case` variables not allowed in `final switch` statements");
errors = true;
}
@@ -2213,7 +2233,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (!scx.search(cs.exp.loc, v.ident, null))
{
- cs.error("`case` variable `%s` declared at %s cannot be declared in `switch` body",
+ error(cs.loc, "`case` variable `%s` declared at %s cannot be declared in `switch` body",
v.toChars(), v.loc.toChars());
errors = true;
}
@@ -2229,7 +2249,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
cs.exp = se;
else if (!cs.exp.isIntegerExp() && !cs.exp.isErrorExp())
{
- cs.error("`case` expression must be a compile-time `string` or an integral constant, not `%s`", cs.exp.toChars());
+ error(cs.loc, "`case` expression must be a compile-time `string` or an integral constant, not `%s`", cs.exp.toChars());
errors = true;
}
@@ -2242,7 +2262,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (cs2.exp.equals(cs.exp))
{
// https://issues.dlang.org/show_bug.cgi?id=15909
- cs.error("duplicate `case %s` in `switch` statement", initialExp.toChars());
+ error(cs.loc, "duplicate `case %s` in `switch` statement", initialExp.toChars());
errors = true;
break;
}
@@ -2265,18 +2285,18 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (sc.sw.tf != sc.tf)
{
- cs.error("`switch` and `case` are in different `finally` blocks");
+ error(cs.loc, "`switch` and `case` are in different `finally` blocks");
errors = true;
}
if (sc.sw.tryBody != sc.tryBody)
{
- cs.error("case cannot be in different `try` block level from `switch`");
+ error(cs.loc, "case cannot be in different `try` block level from `switch`");
errors = true;
}
}
else
{
- cs.error("`case` not in `switch` statement");
+ error(cs.loc, "`case` not in `switch` statement");
errors = true;
}
@@ -2299,7 +2319,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
SwitchStatement sw = sc.sw;
if (sw is null)
{
- crs.error("case range not in `switch` statement");
+ error(crs.loc, "case range not in `switch` statement");
return setError();
}
@@ -2307,7 +2327,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
bool errors = false;
if (sw.isFinal)
{
- crs.error("case ranges not allowed in `final switch`");
+ error(crs.loc, "case ranges not allowed in `final switch`");
errors = true;
}
@@ -2336,14 +2356,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
uinteger_t lval = crs.last.toInteger();
if ((crs.first.type.isunsigned() && fval > lval) || (!crs.first.type.isunsigned() && cast(sinteger_t)fval > cast(sinteger_t)lval))
{
- crs.error("first `case %s` is greater than last `case %s`", crs.first.toChars(), crs.last.toChars());
+ error(crs.loc, "first `case %s` is greater than last `case %s`", crs.first.toChars(), crs.last.toChars());
errors = true;
lval = fval;
}
if (lval - fval > 256)
{
- crs.error("had %llu cases which is more than 257 cases in case range", 1 + lval - fval);
+ error(crs.loc, "had %llu cases which is more than 257 cases in case range", 1 + lval - fval);
errors = true;
lval = fval + 256;
}
@@ -2385,30 +2405,30 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (sc.sw.sdefault)
{
- ds.error("`switch` statement already has a default");
+ error(ds.loc, "`switch` statement already has a default");
errors = true;
}
sc.sw.sdefault = ds;
if (sc.sw.tf != sc.tf)
{
- ds.error("`switch` and `default` are in different `finally` blocks");
+ error(ds.loc, "`switch` and `default` are in different `finally` blocks");
errors = true;
}
if (sc.sw.tryBody != sc.tryBody)
{
- ds.error("default cannot be in different `try` block level from `switch`");
+ error(ds.loc, "default cannot be in different `try` block level from `switch`");
errors = true;
}
if (sc.sw.isFinal)
{
- ds.error("`default` statement not allowed in `final switch` statement");
+ error(ds.loc, "`default` statement not allowed in `final switch` statement");
errors = true;
}
}
else
{
- ds.error("`default` not in `switch` statement");
+ error(ds.loc, "`default` not in `switch` statement");
errors = true;
}
@@ -2429,12 +2449,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
gds.sw = sc.sw;
if (!gds.sw)
{
- gds.error("`goto default` not in `switch` statement");
+ error(gds.loc, "`goto default` not in `switch` statement");
return setError();
}
if (gds.sw.isFinal)
{
- gds.error("`goto default` not allowed in `final switch` statement");
+ error(gds.loc, "`goto default` not allowed in `final switch` statement");
return setError();
}
result = gds;
@@ -2447,7 +2467,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (!sc.sw)
{
- gcs.error("`goto case` not in `switch` statement");
+ error(gcs.loc, "`goto case` not in `switch` statement");
return setError();
}
@@ -2512,7 +2532,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
bool errors = false;
if (sc.flags & SCOPE.contract)
{
- rs.error("`return` statements cannot be in contracts");
+ error(rs.loc, "`return` statements cannot be in contracts");
errors = true;
}
if (sc.os)
@@ -2521,18 +2541,18 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
// Deprecated in 2.100, transform into an error in 2.112
if (sc.os.tok == TOK.onScopeFailure)
{
- rs.deprecation("`return` statements cannot be in `scope(failure)` bodies.");
+ deprecation(rs.loc, "`return` statements cannot be in `scope(failure)` bodies.");
deprecationSupplemental(rs.loc, "Use try-catch blocks for this purpose");
}
else
{
- rs.error("`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok));
+ error(rs.loc, "`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok));
errors = true;
}
}
if (sc.tf)
{
- rs.error("`return` statements cannot be in `finally` bodies");
+ error(rs.loc, "`return` statements cannot be in `finally` bodies");
errors = true;
}
@@ -2540,7 +2560,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (rs.exp)
{
- rs.error("cannot return expression from constructor");
+ error(rs.loc, "cannot return expression from constructor");
errors = true;
}
@@ -2595,7 +2615,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (!convToVoid)
{
- rs.error("cannot return non-void from `void` function");
+ error(rs.loc, "cannot return non-void from `void` function");
errors = true;
rs.exp = new CastExp(rs.loc, rs.exp, Type.tvoid);
rs.exp = rs.exp.expressionSemantic(sc);
@@ -2655,7 +2675,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
else if (!rs.exp.isErrorExp())
{
- rs.error("expected return type of `%s`, not `%s`:",
+ error(rs.loc, "expected return type of `%s`, not `%s`:",
tret.toChars(),
rs.exp.type.toChars());
errorSupplemental((fd.returns) ? (*fd.returns)[0].loc : fd.loc,
@@ -2697,7 +2717,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
/* May return by ref
*/
- if (checkReturnEscapeRef(sc, rs.exp, true))
+ Scope* sc2 = sc.push();
+ sc2.eSink = global.errorSinkNull;
+ bool err = checkReturnEscapeRef(sc2, rs.exp, true);
+ sc2.pop();
+
+ if (err)
turnOffRef(() { checkReturnEscapeRef(sc, rs.exp, false); });
else if (!rs.exp.type.constConv(tf.next))
turnOffRef(
@@ -2736,7 +2761,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (tf.next.ty != Terror)
{
- rs.error("mismatched function return type inference of `void` and `%s`", tf.next.toChars());
+ error(rs.loc, "mismatched function return type inference of `void` and `%s`", tf.next.toChars());
}
errors = true;
tf.next = Type.terror;
@@ -2755,15 +2780,15 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (tbret.ty != Terror)
{
if (e0)
- rs.error("expected return type of `%s`, not `%s`", tret.toChars(), resType.toChars());
+ error(rs.loc, "expected return type of `%s`, not `%s`", tret.toChars(), resType.toChars());
else if (tbret.isTypeNoreturn())
{
- rs.error("cannot return from `noreturn` function");
+ error(rs.loc, "cannot return from `noreturn` function");
.errorSupplemental(rs.loc,
"Consider adding an endless loop, `assert(0)`, or another `noreturn` expression");
}
else
- rs.error("`return` expression expected");
+ error(rs.loc, "`return` expression expected");
}
errors = true;
}
@@ -2777,7 +2802,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
// If any branches have called a ctor, but this branch hasn't, it's an error
if (sc.ctorflow.callSuper & CSX.any_ctor && !(sc.ctorflow.callSuper & (CSX.this_ctor | CSX.super_ctor)))
{
- rs.error("`return` without calling constructor");
+ error(rs.loc, "`return` without calling constructor");
errors = true;
}
@@ -2790,7 +2815,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
bool mustInit = (v.storage_class & STC.nodefaultctor || v.type.needsNested());
if (mustInit && !(sc.ctorflow.fieldinit[i].csx & CSX.this_ctor))
{
- rs.error("an earlier `return` statement skips field `%s` initialization", v.toChars());
+ error(rs.loc, "an earlier `return` statement skips field `%s` initialization", v.toChars());
errors = true;
}
}
@@ -2904,9 +2929,9 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
Statement s = ls.statement;
if (!s || !s.hasBreak())
- bs.error("label `%s` has no `break`", bs.ident.toChars());
+ error(bs.loc, "label `%s` has no `break`", bs.ident.toChars());
else if (ls.tf != sc.tf)
- bs.error("cannot break out of `finally` block");
+ error(bs.loc, "cannot break out of `finally` block");
else
{
ls.breaks = true;
@@ -2916,14 +2941,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
return setError();
}
}
- bs.error("enclosing label `%s` for `break` not found", bs.ident.toChars());
+ error(bs.loc, "enclosing label `%s` for `break` not found", bs.ident.toChars());
return setError();
}
else if (!sc.sbreak)
{
if (sc.os && sc.os.tok != TOK.onScopeFailure)
{
- bs.error("`break` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
+ error(bs.loc, "`break` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
}
else if (sc.fes)
{
@@ -2932,12 +2957,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
return;
}
else
- bs.error("`break` is not inside a loop or `switch`");
+ error(bs.loc, "`break` is not inside a loop or `switch`");
return setError();
}
else if (sc.sbreak.isForwardingStatement())
{
- bs.error("must use labeled `break` within `static foreach`");
+ error(bs.loc, "must use labeled `break` within `static foreach`");
}
result = bs;
}
@@ -2992,9 +3017,9 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
Statement s = ls.statement;
if (!s || !s.hasContinue())
- cs.error("label `%s` has no `continue`", cs.ident.toChars());
+ error(cs.loc, "label `%s` has no `continue`", cs.ident.toChars());
else if (ls.tf != sc.tf)
- cs.error("cannot continue out of `finally` block");
+ error(cs.loc, "cannot continue out of `finally` block");
else
{
result = cs;
@@ -3003,14 +3028,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
return setError();
}
}
- cs.error("enclosing label `%s` for `continue` not found", cs.ident.toChars());
+ error(cs.loc, "enclosing label `%s` for `continue` not found", cs.ident.toChars());
return setError();
}
else if (!sc.scontinue)
{
if (sc.os && sc.os.tok != TOK.onScopeFailure)
{
- cs.error("`continue` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
+ error(cs.loc, "`continue` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
}
else if (sc.fes)
{
@@ -3019,12 +3044,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
return;
}
else
- cs.error("`continue` is not inside a loop");
+ error(cs.loc, "`continue` is not inside a loop");
return setError();
}
else if (sc.scontinue.isForwardingStatement())
{
- cs.error("must use labeled `continue` within `static foreach`");
+ error(cs.loc, "must use labeled `continue` within `static foreach`");
}
result = cs;
}
@@ -3050,7 +3075,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
ClassDeclaration cd = ss.exp.type.isClassHandle();
if (!cd)
{
- ss.error("can only `synchronize` on class objects, not `%s`", ss.exp.type.toChars());
+ error(ss.loc, "can only `synchronize` on class objects, not `%s`", ss.exp.type.toChars());
return setError();
}
else if (cd.isInterfaceDeclaration())
@@ -3060,7 +3085,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
*/
if (!ClassDeclaration.object)
{
- ss.error("missing or corrupt object.d");
+ error(ss.loc, "missing or corrupt object.d");
fatal();
}
@@ -3085,7 +3110,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
cs.push(new ExpStatement(ss.loc, tmp));
auto args = new Parameters();
- args.push(new Parameter(0, ClassDeclaration.object.type, null, null, null));
+ args.push(new Parameter(Loc.initial, 0, ClassDeclaration.object.type, null, null, null));
FuncDeclaration fdenter = FuncDeclaration.genCfunc(args, Type.tvoid, Id.monitorenter);
Expression e = new CallExp(ss.loc, fdenter, new VarExp(ss.loc, tmp));
@@ -3127,7 +3152,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
cs.push(new ExpStatement(ss.loc, v));
auto enterArgs = new Parameters();
- enterArgs.push(new Parameter(0, t.pointerTo(), null, null, null));
+ enterArgs.push(new Parameter(Loc.initial, 0, t.pointerTo(), null, null, null));
FuncDeclaration fdenter = FuncDeclaration.genCfunc(enterArgs, Type.tvoid, Id.criticalenter, STC.nothrow_);
Expression e = new AddrExp(ss.loc, tmpExp);
@@ -3137,7 +3162,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
cs.push(new ExpStatement(ss.loc, e));
auto exitArgs = new Parameters();
- exitArgs.push(new Parameter(0, t, null, null, null));
+ exitArgs.push(new Parameter(Loc.initial, 0, t, null, null, null));
FuncDeclaration fdexit = FuncDeclaration.genCfunc(exitArgs, Type.tvoid, Id.criticalexit, STC.nothrow_);
e = new CallExp(ss.loc, fdexit, tmpExp);
@@ -3177,7 +3202,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
Dsymbol s = (cast(TypeExp)ws.exp).type.toDsymbol(sc);
if (!s || !s.isScopeDsymbol())
{
- ws.error("`with` type `%s` has no members", ws.exp.toChars());
+ error(ws.loc, "`with` type `%s` has no members", ws.exp.toChars());
return setError();
}
sym = new WithScopeSymbol(ws);
@@ -3252,7 +3277,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
else
{
- ws.error("`with` expression types must be enums or aggregates or pointers to them, not `%s`", olde.type.toChars());
+ error(ws.loc, "`with` expression types must be enums or aggregates or pointers to them, not `%s`", olde.type.toChars());
return setError();
}
}
@@ -3281,13 +3306,13 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (!global.params.useExceptions)
{
- tcs.error("cannot use try-catch statements with -betterC");
+ error(tcs.loc, "cannot use try-catch statements with %s", global.params.betterC ? "-betterC".ptr : "-nothrow".ptr);
return setError();
}
if (!ClassDeclaration.throwable)
{
- tcs.error("cannot use try-catch statements because `object.Throwable` was not declared");
+ error(tcs.loc, "cannot use try-catch statements because `object.Throwable` was not declared");
return setError();
}
@@ -3320,7 +3345,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
const sj = cj.loc.toChars();
if (c.type.toBasetype().implicitConvTo(cj.type.toBasetype()))
{
- tcs.error("`catch` at %s hides `catch` at %s", sj, si);
+ error(tcs.loc, "`catch` at %s hides `catch` at %s", sj, si);
catchErrors = true;
}
}
@@ -3331,7 +3356,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
sc.func.hasCatches = true;
if (flags == (FLAGcpp | FLAGd))
{
- tcs.error("cannot mix catching D and C++ exceptions in the same try-catch");
+ error(tcs.loc, "cannot mix catching D and C++ exceptions in the same try-catch");
catchErrors = true;
}
}
@@ -3353,7 +3378,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
/* If the try body never throws, we can eliminate any catches
* of recoverable exceptions.
*/
- if (!(tcs._body.blockExit(sc.func, false) & BE.throw_) && ClassDeclaration.exception)
+ if (!(tcs._body.blockExit(sc.func, null) & BE.throw_) && ClassDeclaration.exception)
{
foreach_reverse (i; 0 .. tcs.catches.length)
{
@@ -3403,7 +3428,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
return;
}
- auto blockexit = tfs._body.blockExit(sc.func, false);
+ auto blockexit = tfs._body.blockExit(sc.func, null);
// if not worrying about exceptions
if (!(global.params.useExceptions && ClassDeclaration.throwable))
@@ -3429,7 +3454,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
// https://issues.dlang.org/show_bug.cgi?id=23159
if (!global.params.useExceptions)
{
- oss.error("`%s` cannot be used with -betterC", Token.toChars(oss.tok));
+ error(oss.loc, "`%s` cannot be used with -betterC", Token.toChars(oss.tok));
return setError();
}
@@ -3439,12 +3464,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (sc.os && sc.os.tok != TOK.onScopeFailure)
{
// If enclosing is scope(success) or scope(exit), this will be placed in finally block.
- oss.error("cannot put `%s` statement inside `%s`", Token.toChars(oss.tok), Token.toChars(sc.os.tok));
+ error(oss.loc, "cannot put `%s` statement inside `%s`", Token.toChars(oss.tok), Token.toChars(sc.os.tok));
return setError();
}
if (sc.tf)
{
- oss.error("cannot put `%s` statement inside `finally` block", Token.toChars(oss.tok));
+ error(oss.loc, "cannot put `%s` statement inside `finally` block", Token.toChars(oss.tok));
return setError();
}
}
@@ -3556,12 +3581,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (ls.loc == ls2.loc)
{
ls2.duplicated = true;
- ls.error("label `%s` is duplicated", ls2.toChars());
+ error(ls.loc, "label `%s` is duplicated", ls2.toChars());
.errorSupplemental(ls2.loc, "labels cannot be used in a static foreach with more than 1 iteration");
}
else
{
- ls.error("label `%s` is already defined", ls2.toChars());
+ error(ls.loc, "label `%s` is already defined", ls2.toChars());
.errorSupplemental(ls2.loc, "first definition is here");
}
return setError();
@@ -3620,14 +3645,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
assert(sc.func);
if (!(cas.stc & STC.pure_) && sc.func.setImpure(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not"))
- cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not");
+ error(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not");
if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not"))
- cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
+ error(cas.loc, "`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
// @@@DEPRECATED_2.114@@@
// change deprecation() to error(), add `else` and remove `| STC.safe`
// to turn deprecation into an error when deprecation cycle is over
if (cas.stc & STC.safe)
- cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
+ deprecation(cas.loc, "`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
if (!(cas.stc & (STC.trusted | STC.safe)))
{
sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
@@ -3696,7 +3721,7 @@ public bool throwSemantic(const ref Loc loc, ref Expression exp, Scope* sc)
{
if (!global.params.useExceptions)
{
- loc.error("cannot use `throw` statements with -betterC");
+ loc.error("cannot use `throw` statements with %s", global.params.betterC ? "-betterC".ptr : "-nothrow".ptr);
return false;
}
@@ -3767,7 +3792,7 @@ private extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde,
return null;
if (ec.type != Type.tint32)
{
- fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars());
+ error(fs.loc, "`opApply()` function for `%s` must return an `int`", tab.toChars());
return null;
}
return ec;
@@ -3792,7 +3817,7 @@ private extern(D) Expression applyDelegate(ForeachStatement fs, Expression flde,
return null;
if (ec.type != Type.tint32)
{
- fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars());
+ error(fs.loc, "`opApply()` function for `%s` must return an `int`", tab.toChars());
return null;
}
return ec;
@@ -3841,13 +3866,13 @@ private extern(D) Expression applyArray(ForeachStatement fs, Expression flde,
FuncDeclaration fdapply;
TypeDelegate dgty;
auto params = new Parameters();
- params.push(new Parameter(STC.in_, tn.arrayOf(), null, null, null));
+ params.push(new Parameter(Loc.initial, STC.in_, tn.arrayOf(), null, null, null));
auto dgparams = new Parameters();
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
if (dim == 2)
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d));
- params.push(new Parameter(0, dgty, null, null, null));
+ params.push(new Parameter(Loc.initial, 0, dgty, null, null, null));
fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr);
if (tab.isTypeSArray())
@@ -3879,7 +3904,7 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld
Type ti = (isRef ? taa.index.addMod(MODFlags.const_) : taa.index);
if (isRef ? !ti.constConv(ta) : !ti.implicitConvTo(ta))
{
- fs.error("`foreach`: index must be type `%s`, not `%s`",
+ error(fs.loc, "`foreach`: index must be type `%s`, not `%s`",
ti.toChars(), ta.toChars());
return null;
}
@@ -3890,7 +3915,7 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld
Type taav = taa.nextOf();
if (isRef ? !taav.constConv(ta) : !taav.implicitConvTo(ta))
{
- fs.error("`foreach`: value must be type `%s`, not `%s`",
+ error(fs.loc, "`foreach`: value must be type `%s`, not `%s`",
taav.toChars(), ta.toChars());
return null;
}
@@ -3908,14 +3933,14 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld
if (!fdapply[i])
{
auto params = new Parameters();
- params.push(new Parameter(0, Type.tvoid.pointerTo(), null, null, null));
- params.push(new Parameter(STC.const_, Type.tsize_t, null, null, null));
+ params.push(new Parameter(Loc.initial, 0, Type.tvoid.pointerTo(), null, null, null));
+ params.push(new Parameter(Loc.initial, STC.const_, Type.tsize_t, null, null, null));
auto dgparams = new Parameters();
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
if (dim == 2)
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d));
- params.push(new Parameter(0, fldeTy[i], null, null, null));
+ params.push(new Parameter(Loc.initial, 0, fldeTy[i], null, null, null));
fdapply[i] = FuncDeclaration.genCfunc(params, Type.tint32, i ? Id._aaApply2 : Id._aaApply);
}
@@ -4000,7 +4025,7 @@ private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFuncti
{
if (!(prm.storageClass & STC.ref_))
{
- fs.error("`foreach`: cannot make `%s` `ref`", p.ident.toChars());
+ error(fs.loc, "`foreach`: cannot make `%s` `ref`", p.ident.toChars());
return null;
}
goto LcopyArg;
@@ -4026,7 +4051,7 @@ private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFuncti
Statement s = new ExpStatement(fs.loc, v);
fs._body = new CompoundStatement(fs.loc, s, fs._body);
}
- params.push(new Parameter(stc, p.type, id, null, null));
+ params.push(new Parameter(fs.loc, stc, p.type, id, null, null));
}
// https://issues.dlang.org/show_bug.cgi?id=13840
// Throwable nested function inside nothrow function is acceptable.
@@ -4328,7 +4353,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
const bool skipCheck = isStatic && needExpansion;
if (!skipCheck && (dim < 1 || dim > 2))
{
- fs.error("only one (value) or two (key,value) arguments allowed for sequence `foreach`");
+ error(fs.loc, "only one (value) or two (key,value) arguments allowed for sequence `foreach`");
return returnEarly();
}
@@ -4390,7 +4415,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
// Declare key
if (p.isReference() || p.isLazy())
{
- fs.error("no storage class for key `%s`", p.ident.toChars());
+ error(fs.loc, "no storage class for key `%s`", p.ident.toChars());
return returnEarly();
}
@@ -4405,7 +4430,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
if (!p.type.isintegral())
{
- fs.error("foreach: key cannot be of non-integral type `%s`",
+ error(fs.loc, "foreach: key cannot be of non-integral type `%s`",
p.type.toChars());
return returnEarly();
}
@@ -4416,7 +4441,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
if (!IntRange.fromType(p.type).contains(dimrange))
{
- fs.error("index type `%s` cannot cover index range 0..%llu",
+ error(fs.loc, "index type `%s` cannot cover index range 0..%llu",
p.type.toChars(), cast(ulong)length);
return returnEarly();
}
@@ -4450,7 +4475,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
if (storageClass & (STC.out_ | STC.lazy_) ||
storageClass & STC.ref_ && !te)
{
- fs.error("no storage class for value `%s`", ident.toChars());
+ error(fs.loc, "no storage class for value `%s`", ident.toChars());
return false;
}
Declaration var;
@@ -4478,7 +4503,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
}
else if (storageClass & STC.alias_)
{
- fs.error("`foreach` loop variable cannot be both `enum` and `alias`");
+ error(fs.loc, "`foreach` loop variable cannot be both `enum` and `alias`");
return false;
}
@@ -4487,12 +4512,12 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
var = new AliasDeclaration(loc, ident, ds);
if (storageClass & STC.ref_)
{
- fs.error("symbol `%s` cannot be `ref`", ds.toChars());
+ error(fs.loc, "symbol `%s` cannot be `ref`", ds.toChars());
return false;
}
if (paramtype)
{
- fs.error("cannot specify element type for symbol `%s`", ds.toChars());
+ error(fs.loc, "cannot specify element type for symbol `%s`", ds.toChars());
return false;
}
}
@@ -4501,7 +4526,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
var = new AliasDeclaration(loc, ident, e.type);
if (paramtype)
{
- fs.error("cannot specify element type for type `%s`", e.type.toChars());
+ error(fs.loc, "cannot specify element type for type `%s`", e.type.toChars());
return false;
}
}
@@ -4522,17 +4547,17 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
{
if (!isStatic)
{
- fs.error("constant value `%s` cannot be `ref`", ie.toChars());
+ error(fs.loc, "constant value `%s` cannot be `ref`", ie.toChars());
}
else
{
if (!needExpansion)
{
- fs.error("constant value `%s` cannot be `ref`", ie.toChars());
+ error(fs.loc, "constant value `%s` cannot be `ref`", ie.toChars());
}
else
{
- fs.error("constant value `%s` cannot be `ref`", ident.toChars());
+ error(fs.loc, "constant value `%s` cannot be `ref`", ident.toChars());
}
}
return false;
@@ -4548,7 +4573,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
var = new AliasDeclaration(loc, ident, t);
if (paramtype)
{
- fs.error("cannot specify element type for symbol `%s`", fs.toChars());
+ error(fs.loc, "cannot specify element type for symbol `%s`", fs.toChars());
return false;
}
}
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index 950c830cb33..c76d549550a 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -124,6 +124,7 @@ enum TOK : ubyte
// Leaf operators
identifier,
string_,
+ hexadecimalString,
this_,
super_,
error,
@@ -855,6 +856,7 @@ extern (C++) struct Token
TOK.wcharLiteral: "wcharv",
TOK.dcharLiteral: "dcharv",
TOK.wchar_tLiteral: "wchar_tv",
+ TOK.hexadecimalString: "xstring",
TOK.endOfLine: "\\n",
TOK.whitespace: "whitespace",
@@ -898,7 +900,7 @@ extern (C++) struct Token
nothrow:
- int isKeyword() const @safe
+ int isKeyword() pure const @safe @nogc
{
foreach (kw; keywords)
{
@@ -1014,6 +1016,24 @@ nothrow:
p = buf.extractChars();
}
break;
+ case TOK.hexadecimalString:
+ {
+ OutBuffer buf;
+ buf.writeByte('x');
+ buf.writeByte('"');
+ foreach (size_t i; 0 .. len)
+ {
+ if (i)
+ buf.writeByte(' ');
+ buf.printf("%02x", ustring[i]);
+ }
+ buf.writeByte('"');
+ if (postfix)
+ buf.writeByte(postfix);
+ buf.writeByte(0);
+ p = buf.extractData();
+ break;
+ }
case TOK.identifier:
case TOK.enum_:
case TOK.struct_:
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index 6c1b9792dbb..b1f633fb9d9 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -133,6 +133,7 @@ enum class TOK : unsigned char
// Leaf operators
identifier,
string_,
+ hexadecimalString,
this_,
super_,
error,
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 0d9c95ff173..2bde9f2aee9 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -1920,7 +1920,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
StringExp se = ex ? ex.ctfeInterpret().toStringExp() : null;
if (!ex || !se || se.len == 0)
{
- e.error("string expected as argument of __traits `%s` instead of `%s`", e.ident.toChars(), ex.toChars());
+ e.error("string expected as argument of __traits `%s` instead of `%s`", e.ident.toChars(), (*e.args)[0].toChars());
return ErrorExp.get();
}
se = se.toUTF8(sc);
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index a80aa80a89d..1422689dce0 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -1170,8 +1170,8 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
StorageClass stc2 = narg.storageClass & (STC.ref_ | STC.out_ | STC.lazy_);
if (stc1 && stc2 && stc1 != stc2)
{
- OutBuffer buf1; stcToBuffer(&buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0));
- OutBuffer buf2; stcToBuffer(&buf2, stc2);
+ OutBuffer buf1; stcToBuffer(buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0));
+ OutBuffer buf2; stcToBuffer(buf2, stc2);
.error(loc, "incompatible parameter storage classes `%s` and `%s`",
buf1.peekChars(), buf2.peekChars());
@@ -1179,7 +1179,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
stc = stc1 | (stc & ~(STC.ref_ | STC.out_ | STC.lazy_));
}
(*newparams)[j] = new Parameter(
- stc, narg.type, narg.ident, narg.defaultArg, narg.userAttribDecl);
+ loc, stc, narg.type, narg.ident, narg.defaultArg, narg.userAttribDecl);
}
fparam.type = new TypeTuple(newparams);
fparam.type = fparam.type.typeSemantic(loc, argsc);
@@ -2089,6 +2089,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
{
e = new StringExp(loc, mt.deco.toDString());
Scope sc;
+ sc.eSink = global.errorSink;
e = e.expressionSemantic(&sc);
}
}
@@ -2097,6 +2098,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
const s = mt.toChars();
e = new StringExp(loc, s.toDString());
Scope sc;
+ sc.eSink = global.errorSink;
e = e.expressionSemantic(&sc);
}
else if (flag && mt != Type.terror)
@@ -2127,7 +2129,9 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
error(loc, "no property `%s` for `%s` of type `%s`", ident.toChars(), src.toChars(), mt.toPrettyChars(true));
else
error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
+
if (auto dsym = mt.toDsymbol(scope_))
+ {
if (auto sym = dsym.isAggregateDeclaration())
{
if (auto fd = search_function(sym, Id.opDispatch))
@@ -2135,6 +2139,9 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
else if (!sym.members)
errorSupplemental(sym.loc, "`%s %s` is opaque and has no members.", sym.kind, mt.toPrettyChars(true));
}
+ errorSupplemental(dsym.loc, "%s `%s` defined here",
+ dsym.kind, dsym.toChars());
+ }
}
}
e = ErrorExp.get();
@@ -3482,7 +3489,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
if (fd_aaLen is null)
{
auto fparams = new Parameters();
- fparams.push(new Parameter(STC.const_ | STC.scope_, mt, null, null, null));
+ fparams.push(new Parameter(Loc.initial, STC.const_ | STC.scope_, mt, null, null, null));
fd_aaLen = FuncDeclaration.genCfunc(fparams, Type.tsize_t, Id.aaLen);
TypeFunction tf = fd_aaLen.type.toTypeFunction();
tf.purity = PURE.const_;
@@ -3938,6 +3945,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
e.error("no property `%s` for type `%s`", ident.toChars(),
mt.toChars());
+ errorSupplemental(mt.sym.loc, "%s `%s` defined here",
+ mt.sym.kind, mt.toChars());
return ErrorExp.get();
}
return res;
@@ -4791,7 +4800,7 @@ Type stripDefaultArgs(Type t)
{
Type t = stripDefaultArgs(p.type);
return (t != p.type || p.defaultArg || p.ident || p.userAttribDecl)
- ? new Parameter(p.storageClass, t, null, null, null)
+ ? new Parameter(p.loc, p.storageClass, t, null, null, null)
: null;
}
diff --git a/gcc/d/dmd/utils.d b/gcc/d/dmd/utils.d
index dfb4cb5ee2d..bb389b65903 100644
--- a/gcc/d/dmd/utils.d
+++ b/gcc/d/dmd/utils.d
@@ -53,12 +53,6 @@ const(char)* toWinPath(const(char)* src)
* loc = The line number information from where the call originates
* filename = Path to file
*/
-Buffer readFile(Loc loc, const(char)* filename)
-{
- return readFile(loc, filename.toDString());
-}
-
-/// Ditto
Buffer readFile(Loc loc, const(char)[] filename)
{
auto result = File.read(filename);
@@ -78,15 +72,19 @@ Buffer readFile(Loc loc, const(char)[] filename)
* loc = The line number information from where the call originates
* filename = Path to file
* data = Full content of the file to be written
+ * Returns:
+ * false on error
*/
-extern (D) void writeFile(Loc loc, const(char)[] filename, const void[] data)
+extern (D) bool writeFile(Loc loc, const(char)[] filename, const void[] data)
{
- ensurePathToNameExists(Loc.initial, filename);
+ if (!ensurePathToNameExists(Loc.initial, filename))
+ return false;
if (!File.update(filename, data))
{
error(loc, "error writing file '%.*s'", cast(int) filename.length, filename.ptr);
- fatal();
+ return false;
}
+ return true;
}
@@ -97,8 +95,10 @@ extern (D) void writeFile(Loc loc, const(char)[] filename, const void[] data)
* Params:
* loc = The line number information from where the call originates
* name = a path to check (the name is stripped)
+ * Returns:
+ * false on error
*/
-void ensurePathToNameExists(Loc loc, const(char)[] name)
+bool ensurePathToNameExists(Loc loc, const(char)[] name)
{
const char[] pt = FileName.path(name);
if (pt.length)
@@ -106,10 +106,12 @@ void ensurePathToNameExists(Loc loc, const(char)[] name)
if (!FileName.ensurePathExists(pt))
{
error(loc, "cannot create directory %*.s", cast(int) pt.length, pt.ptr);
- fatal();
+ FileName.free(pt.ptr);
+ return false;
}
}
FileName.free(pt.ptr);
+ return true;
}
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 551d004c241..cc4aa03dfb9 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2725,6 +2725,15 @@ public:
void visit (AssocArrayLiteralExp *e) final override
{
+ if (e->lowering != NULL)
+ {
+ /* When an associative array literal gets lowered, it's converted into a
+ struct literal suitable for static initialization. */
+ gcc_assert (this->constp_);
+ this->result_ = build_expr (e->lowering, this->constp_, true);
+ return ;
+ }
+
/* Want the mutable type for typeinfo reference. */
Type *tb = e->type->toBasetype ()->mutableOf ();
diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d b/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d
index 2e36c7d02be..f8448d943e9 100644
--- a/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d
+++ b/gcc/testsuite/gdc.test/compilable/dtoh_StructDeclaration.d
@@ -224,6 +224,15 @@ struct Params final
ddocfiles(ddocfiles)
{}
};
+
+struct Loc final
+{
+ static int32_t showColumns;
+ void toChars(int32_t showColumns = Loc::showColumns);
+ Loc()
+ {
+ }
+};
---
*/
@@ -337,3 +346,9 @@ extern (C++) struct Params
bool obj = true;
Array ddocfiles;
}
+
+extern (C++) struct Loc
+{
+ __gshared int showColumns;
+ void toChars(int showColumns = Loc.showColumns) {}
+}
diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_functions.d b/gcc/testsuite/gdc.test/compilable/dtoh_functions.d
index 38607f6d4b1..90223cca81e 100644
--- a/gcc/testsuite/gdc.test/compilable/dtoh_functions.d
+++ b/gcc/testsuite/gdc.test/compilable/dtoh_functions.d
@@ -45,10 +45,10 @@ struct S final
int32_t get(int32_t , int32_t );
static int32_t get();
static const int32_t staticVar;
- void useVars(int32_t pi = i, int32_t psv = staticVar);
+ void useVars(int32_t pi = i, int32_t psv = S::staticVar);
struct Nested final
{
- void useStaticVar(int32_t i = staticVar);
+ void useStaticVar(int32_t i = S::staticVar);
Nested()
{
}
diff --git a/gcc/testsuite/gdc.test/compilable/issue22682.d b/gcc/testsuite/gdc.test/compilable/issue22682.d
new file mode 100644
index 00000000000..5301a5163cd
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/issue22682.d
@@ -0,0 +1,8 @@
+module issue22682;
+
+void main()
+{
+ pragma(mangle, "put" ~ "s")
+ extern(C) static int libcPuts(const char*);
+ libcPuts("issue 22682");
+}
diff --git a/gcc/testsuite/gdc.test/compilable/obsolete_body.d b/gcc/testsuite/gdc.test/compilable/obsolete_body.d
new file mode 100644
index 00000000000..71906e8f25e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/obsolete_body.d
@@ -0,0 +1,5 @@
+/* REQUIRED_ARGS: -w
+*/
+
+void test()
+in { } body { }
diff --git a/gcc/testsuite/gdc.test/compilable/shortened_methods.d b/gcc/testsuite/gdc.test/compilable/shortened_methods.d
index 71350af8739..785cb8e5cd0 100644
--- a/gcc/testsuite/gdc.test/compilable/shortened_methods.d
+++ b/gcc/testsuite/gdc.test/compilable/shortened_methods.d
@@ -27,7 +27,12 @@ string test() => "hello"; // works at any scope
static assert(test() == "hello"); // works normally
static assert(is(typeof(&test) == string function())); // same normal type
+struct S(T) {}
+
void func() {
int a;
int nested() => a; // and at nested scopes too
+
+ // Issue 24088 - https://issues.dlang.org/show_bug.cgi?id=24088
+ S!int f() => S!int();
}
diff --git a/gcc/testsuite/gdc.test/compilable/test23145.d b/gcc/testsuite/gdc.test/compilable/test23145.d
index 18eabfb51b5..c6bb55181b1 100644
--- a/gcc/testsuite/gdc.test/compilable/test23145.d
+++ b/gcc/testsuite/gdc.test/compilable/test23145.d
@@ -1,11 +1,4 @@
-/* REQUIRED_ARGS: -wo -wi
-TEST_OUTPUT:
----
-compilable/test23145.d(117): Warning: `scope` allocation of `c` requires that constructor be annotated with `scope`
-compilable/test23145.d(111): is the location of the constructor
-compilable/test23145.d(124): Warning: `scope` allocation of `c` requires that constructor be annotated with `scope`
-compilable/test23145.d(111): is the location of the constructor
----
+/* REQUIRED_ARGS: -wi
*/
// https://issues.dlang.org/show_bug.cgi?id=23145
@@ -28,14 +21,14 @@ class C
C foo(D d) @nogc @safe
{
scope e = new C(1); // ok
- scope c = new C(d); // deprecation
+ scope c = new C(d); // obsolete
return c.d.c;
}
C bax(D d) @safe
{
scope e = new C(1); // ok
- scope c = new C(d); // deprecation
+ scope c = new C(d); // obsolete
return c.d.c;
}
diff --git a/gcc/testsuite/gdc.test/compilable/test24066.d b/gcc/testsuite/gdc.test/compilable/test24066.d
new file mode 100644
index 00000000000..4b8a0b345bc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test24066.d
@@ -0,0 +1,11 @@
+// https://issues.dlang.org/show_bug.cgi?id=24066
+
+/*
+TEST_OUTPUT:
+---
+false
+---
+*/
+
+class C;
+pragma(msg, __traits(isAbstractClass, C));
diff --git a/gcc/testsuite/gdc.test/compilable/test24107.d b/gcc/testsuite/gdc.test/compilable/test24107.d
new file mode 100644
index 00000000000..d16c259f16c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test24107.d
@@ -0,0 +1,17 @@
+// https://issues.dlang.org/show_bug.cgi?id=24107
+
+/*
+TEST_OUTPUT:
+---
+This should not output an error message: false
+---
+*/
+
+bool recurse ()
+{
+ return recurse();
+}
+
+pragma(msg,
+ "This should not output an error message: ",
+ __traits(compiles, {enum bool r = recurse();}));
diff --git a/gcc/testsuite/gdc.test/compilable/test24109.d b/gcc/testsuite/gdc.test/compilable/test24109.d
new file mode 100644
index 00000000000..67d03b58b06
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test24109.d
@@ -0,0 +1,17 @@
+// https://issues.dlang.org/show_bug.cgi?id=24109
+
+struct Outer
+{
+ void method1() {}
+
+ void method2()
+ {
+ class Inner
+ {
+ void innerMethod()
+ {
+ method1();
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test24118.d b/gcc/testsuite/gdc.test/compilable/test24118.d
new file mode 100644
index 00000000000..25376b73b18
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test24118.d
@@ -0,0 +1,15 @@
+// https://issues.dlang.org/show_bug.cgi?id=24118
+
+void map(alias fun, T)(T[] arr)
+{
+ fun(arr);
+}
+
+
+void foo()
+{
+ if( __ctfe )
+ {
+ ["a", "b", "c"].map!( a => " " ~ a[0] );
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/aa_init.d b/gcc/testsuite/gdc.test/fail_compilation/aa_init.d
new file mode 100644
index 00000000000..b1473c136da
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/aa_init.d
@@ -0,0 +1,16 @@
+/*
+REQUIRED_ARGS: -vcolumns
+TEST_OUTPUT:
+---
+fail_compilation/aa_init.d(13,18): Error: invalid associative array initializer `[]`, use `null` instead
+fail_compilation/aa_init.d(14,24): Error: missing key for value `4` in initializer
+fail_compilation/aa_init.d(15,9): Error: cannot implicitly convert expression `[]` of type `void[]` to `int[int]`
+---
+*/
+
+void main()
+{
+ int[int] a = [];
+ int[int] b = [2:3, 4];
+ a = [];
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/body.d b/gcc/testsuite/gdc.test/fail_compilation/body.d
deleted file mode 100644
index 7b718c25060..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/body.d
+++ /dev/null
@@ -1,11 +0,0 @@
-/* REQUIRED_ARGS: -wo -w
-TEST_OUTPUT:
----
-fail_compilation/body.d(11): Warning: usage of identifer `body` as a keyword is obsolete. Use `do` instead.
-Error: warnings are treated as errors
- Use -wi if you wish to treat warnings only as informational.
----
-*/
-
-void test()
-in { } body { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d
index eb75f4267b9..bd924665e3a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/chkformat.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/chkformat.d
@@ -24,6 +24,7 @@ fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specif
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system|32=
fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system$
+fail_compilation/chkformat.d(123): Deprecation: argument `p` for format specification `"%n"` must be `int*`, not `const(int)*`
fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments
fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
@@ -86,6 +87,7 @@ void test19() { int u; printf("%ls\n", &u); }
//void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); }
//void test21() { int u; fprintf(null, "%d\n", &u); }
void test20() { printf("%lu", ulong.init); }
+void test22() { int i; const(int)* p = &i; printf("%n", p); }
#line 200
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d b/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d
deleted file mode 100644
index 553a0c64a20..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/dephexstrings.d
+++ /dev/null
@@ -1,9 +0,0 @@
-// REQUIRED_ARGS: -de
-/*
-TEST_OUTPUT:
----
-fail_compilation/dephexstrings.d(9): Error: semicolon expected following auto declaration, not `"60"`
-fail_compilation/dephexstrings.d(9): Error: declaration expected, not `"60"`
----
-*/
-enum xstr = x"60";
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10169.d b/gcc/testsuite/gdc.test/fail_compilation/diag10169.d
index 84d0ad4696b..e21a334548d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10169.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10169.d
@@ -2,7 +2,8 @@
EXTRA_FILES: imports/a10169.d
TEST_OUTPUT:
---
-fail_compilation/diag10169.d(12): Error: no property `x` for `B(0)` of type `imports.a10169.B`
+fail_compilation/diag10169.d(13): Error: no property `x` for `B(0)` of type `imports.a10169.B`
+fail_compilation/imports/a10169.d(3): struct `B` defined here
---
*/
import imports.a10169;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10783.d b/gcc/testsuite/gdc.test/fail_compilation/diag10783.d
index 80c7f5e56ea..e69eddbec03 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10783.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10783.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag10783.d(14): Error: no property `type` for `event` of type `diag10783.Event`
-fail_compilation/diag10783.d(14): Error: undefined identifier `En`
+fail_compilation/diag10783.d(15): Error: no property `type` for `event` of type `diag10783.Event`
+fail_compilation/diag10783.d(10): struct `Event` defined here
+fail_compilation/diag10783.d(15): Error: undefined identifier `En`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag12063.d b/gcc/testsuite/gdc.test/fail_compilation/diag12063.d
index 882a8091076..3e9535ab421 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag12063.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag12063.d
@@ -1,8 +1,13 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag12063.d(11): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
-fail_compilation/diag12063.d(14): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`
+fail_compilation/diag12063.d(19): Error: cannot check `diag12063.Bar.b` value for overflow
+fail_compilation/diag12063.d(16): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
+fail_compilation/diag12063.d(19): Error: cannot generate value for `diag12063.Bar.b`
+fail_compilation/diag12063.d(19): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`
+fail_compilation/diag12063.d(29): Error: cannot check `diag12063.b` value for overflow
+fail_compilation/diag12063.d(29): Error: incompatible types for `(S()) == (1)`: `S` and `int`
+fail_compilation/diag12063.d(38): Error: enum member `diag12063.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
---
*/
@@ -11,5 +16,36 @@ struct Foo {}
enum Bar : Foo
{
a = Foo(),
- b
+ b // no max, can't +1
+}
+
+struct S {
+ S opBinary(string s: "+")(int) => this;
+ enum max = 1; // wrong type
+}
+
+enum {
+ a = S(),
+ b // can't do S() == 1
+}
+
+struct Q {
+ enum max = Q();
+}
+
+enum {
+ c = Q(),
+ d // overflow detected
+}
+
+struct R {
+ int i;
+ R opBinary(string s: "+")(int) => this;
+ enum max = R(1);
+}
+
+enum ER
+{
+ e = R(),
+ f // OK
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag12829.d b/gcc/testsuite/gdc.test/fail_compilation/diag12829.d
index 1d37a1ecbfe..aaedd0f7217 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag12829.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag12829.d
@@ -1,11 +1,14 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag12829.d(12): Error: function `diag12829.test1` is `@nogc` yet allocates closure for `test1()` with the GC
-fail_compilation/diag12829.d(15): `diag12829.test1.__lambda2` closes over variable `x` at fail_compilation/diag12829.d(14)
-fail_compilation/diag12829.d(19): `diag12829.test1.bar` closes over variable `x` at fail_compilation/diag12829.d(14)
-fail_compilation/diag12829.d(26): Error: function `diag12829.test2` is `@nogc` yet allocates closure for `test2()` with the GC
-fail_compilation/diag12829.d(31): `diag12829.test2.S.foo` closes over variable `x` at fail_compilation/diag12829.d(28)
+fail_compilation/diag12829.d(15): Error: function `diag12829.test1` is `@nogc` yet allocates closure for `test1()` with the GC
+fail_compilation/diag12829.d(18): delegate `diag12829.test1.__lambda2` closes over variable `x`
+fail_compilation/diag12829.d(17): `x` declared here
+fail_compilation/diag12829.d(22): function `diag12829.test1.bar` closes over variable `x`
+fail_compilation/diag12829.d(17): `x` declared here
+fail_compilation/diag12829.d(29): Error: function `diag12829.test2` is `@nogc` yet allocates closure for `test2()` with the GC
+fail_compilation/diag12829.d(34): function `diag12829.test2.S.foo` closes over variable `x`
+fail_compilation/diag12829.d(31): `x` declared here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag13609a.d b/gcc/testsuite/gdc.test/fail_compilation/diag13609a.d
index 039129e770f..7d0e259e41b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag13609a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag13609a.d
@@ -1,10 +1,15 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag13609a.d(11): Error: `}` expected following members in `class` declaration at fail_compilation/diag13609a.d(8)
+fail_compilation/diag13609a.d(16): Error: `}` expected following members in `struct` declaration
+fail_compilation/diag13609a.d(15): struct starts here
+fail_compilation/diag13609a.d(16): Error: `}` expected following members in `class` declaration
+fail_compilation/diag13609a.d(11): class `C` starts here
---
*/
class C
{
void foo() {}
+
+ struct {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag14145.d b/gcc/testsuite/gdc.test/fail_compilation/diag14145.d
index fa7c6114ad6..fee73078e30 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag14145.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag14145.d
@@ -1,10 +1,11 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag14145.d(15): Error: no property `i` for `_` of type `diag14145.main.Capture!(i)`
-fail_compilation/diag14145.d(15): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
-fail_compilation/diag14145.d(34): Error: expression `*this.ptr` of type `shared(int)` is not implicitly convertible to return type `ref int`
-fail_compilation/diag14145.d(16): Error: template instance `diag14145.main.Capture!(i).Capture.opDispatch!"i"` error instantiating
+fail_compilation/diag14145.d(16): Error: no property `i` for `_` of type `diag14145.main.Capture!(i)`
+fail_compilation/diag14145.d(16): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/diag14145.d(26): struct `Capture` defined here
+fail_compilation/diag14145.d(35): Error: expression `*this.ptr` of type `shared(int)` is not implicitly convertible to return type `ref int`
+fail_compilation/diag14145.d(17): Error: template instance `diag14145.main.Capture!(i).Capture.opDispatch!"i"` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag15713.d b/gcc/testsuite/gdc.test/fail_compilation/diag15713.d
index e4cb2a7603a..00713449a5f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag15713.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag15713.d
@@ -1,10 +1,11 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag15713.d(19): Error: no property `widthSign` for `this` of type `diag15713.WrData.Data`
-fail_compilation/diag15713.d(39): Error: template instance `diag15713.conwritefImpl!("parse-int", "width", "\n", Data(null))` error instantiating
-fail_compilation/diag15713.d(44): instantiated from here: `conwritefImpl!("main", "\n", Data(null))`
-fail_compilation/diag15713.d(49): instantiated from here: `fdwritef!()`
+fail_compilation/diag15713.d(20): Error: no property `widthSign` for `this` of type `diag15713.WrData.Data`
+fail_compilation/diag15713.d(16): struct `Data` defined here
+fail_compilation/diag15713.d(40): Error: template instance `diag15713.conwritefImpl!("parse-int", "width", "\n", Data(null))` error instantiating
+fail_compilation/diag15713.d(45): instantiated from here: `conwritefImpl!("main", "\n", Data(null))`
+fail_compilation/diag15713.d(50): instantiated from here: `fdwritef!()`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag3913.d b/gcc/testsuite/gdc.test/fail_compilation/diag3913.d
index abf70b84ce7..41c08b0a76e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag3913.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag3913.d
@@ -1,8 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag3913.d(12): Error: no property `foobardoo` for type `Foo`
-fail_compilation/diag3913.d(13): Error: no property `secon` for type `Foo`. Did you mean `Foo.second` ?
+fail_compilation/diag3913.d(14): Error: no property `foobardoo` for type `Foo`
+fail_compilation/diag3913.d(13): enum `Foo` defined here
+fail_compilation/diag3913.d(15): Error: no property `secon` for type `Foo`. Did you mean `Foo.second` ?
+fail_compilation/diag3913.d(13): enum `Foo` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag5385.d b/gcc/testsuite/gdc.test/fail_compilation/diag5385.d
index 60455eca206..368fdfff529 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag5385.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag5385.d
@@ -2,14 +2,22 @@
EXTRA_FILES: imports/fail5385.d
TEST_OUTPUT:
---
-fail_compilation/diag5385.d(20): Error: no property `privX` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(21): Error: no property `packX` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(22): Error: no property `privX2` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(23): Error: no property `packX2` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(24): Error: no property `privX` for type `imports.fail5385.S`
-fail_compilation/diag5385.d(25): Error: no property `packX` for type `imports.fail5385.S`
-fail_compilation/diag5385.d(26): Error: no property `privX2` for type `imports.fail5385.S`
-fail_compilation/diag5385.d(27): Error: no property `packX2` for type `imports.fail5385.S`
+fail_compilation/diag5385.d(28): Error: no property `privX` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(29): Error: no property `packX` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(30): Error: no property `privX2` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(31): Error: no property `packX2` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(32): Error: no property `privX` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
+fail_compilation/diag5385.d(33): Error: no property `packX` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
+fail_compilation/diag5385.d(34): Error: no property `privX2` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
+fail_compilation/diag5385.d(35): Error: no property `packX2` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag7477.d b/gcc/testsuite/gdc.test/fail_compilation/diag7477.d
index b82b33de946..b14a3c5df65 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag7477.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag7477.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag7477.d(13): Error: integral constant must be scalar type, not `Foo`
-fail_compilation/diag7477.d(20): Error: integral constant must be scalar type, not `string`
+fail_compilation/diag7477.d(13): Error: cannot generate 0 value of type `Foo` for `a`
+fail_compilation/diag7477.d(20): Error: cannot generate 0 value of type `string` for `a`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8697.d b/gcc/testsuite/gdc.test/fail_compilation/diag8697.d
index a2abad58764..bcc0be09897 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8697.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8697.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag8697.d(10): Error: no property `Invalid` for type `diag8697.Base`
+fail_compilation/diag8697.d(11): Error: no property `Invalid` for type `diag8697.Base`
+fail_compilation/diag8697.d(9): class `Base` defined here
---
*/
interface InterBase : InterRoot { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag8894.d b/gcc/testsuite/gdc.test/fail_compilation/diag8894.d
index 7cf3023aedb..e8e0c74cc32 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag8894.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag8894.d
@@ -1,10 +1,14 @@
/*
TEST_OUTPUT:
---
-fail_compilation/diag8894.d(16): Error: no property `x` for `f` of type `diag8894.Foo`
-fail_compilation/diag8894.d(17): Error: no property `y` for `f` of type `diag8894.Foo`
-fail_compilation/diag8894.d(18): Error: no property `x` for `f` of type `diag8894.Foo`
-fail_compilation/diag8894.d(19): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(20): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
+fail_compilation/diag8894.d(21): Error: no property `y` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
+fail_compilation/diag8894.d(22): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
+fail_compilation/diag8894.d(23): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
index e591a1428a5..77ab52046fc 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/dip1000_deprecation.d
@@ -1,17 +1,14 @@
/*
-REQUIRED_ARGS: -de -wo
+REQUIRED_ARGS: -de
TEST_OUTPUT:
---
-fail_compilation/dip1000_deprecation.d(20): Deprecation: `@safe` function `main` calling `inferred`
-fail_compilation/dip1000_deprecation.d(28): which wouldn't be `@safe` because of:
-fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned
-fail_compilation/dip1000_deprecation.d(22): Deprecation: `@safe` function `main` calling `inferredC`
-fail_compilation/dip1000_deprecation.d(39): which calls `dip1000_deprecation.inferred`
-fail_compilation/dip1000_deprecation.d(28): which wouldn't be `@safe` because of:
-fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned
-fail_compilation/dip1000_deprecation.d(54): Warning: escaping reference to stack allocated value returned by `S(null)`
-fail_compilation/dip1000_deprecation.d(55): Warning: escaping reference to stack allocated value returned by `createS()`
-fail_compilation/dip1000_deprecation.d(58): Warning: returning `s.incorrectReturnRef()` escapes a reference to local variable `s`
+fail_compilation/dip1000_deprecation.d(17): Deprecation: `@safe` function `main` calling `inferred`
+fail_compilation/dip1000_deprecation.d(25): which wouldn't be `@safe` because of:
+fail_compilation/dip1000_deprecation.d(25): scope variable `x0` may not be returned
+fail_compilation/dip1000_deprecation.d(19): Deprecation: `@safe` function `main` calling `inferredC`
+fail_compilation/dip1000_deprecation.d(36): which calls `dip1000_deprecation.inferred`
+fail_compilation/dip1000_deprecation.d(25): which wouldn't be `@safe` because of:
+fail_compilation/dip1000_deprecation.d(25): scope variable `x0` may not be returned
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dip22a.d b/gcc/testsuite/gdc.test/fail_compilation/dip22a.d
index 324d21733af..661ebc33fa6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/dip22a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/dip22a.d
@@ -2,11 +2,13 @@
EXTRA_FILES: imports/dip22a.d
TEST_OUTPUT:
---
-fail_compilation/dip22a.d(16): Error: no property `bar` for `new Klass` of type `imports.dip22a.Klass`
-fail_compilation/dip22a.d(17): Error: no property `bar` for `Struct()` of type `imports.dip22a.Struct`
-fail_compilation/dip22a.d(18): Error: undefined identifier `bar` in module `imports.dip22a`
-fail_compilation/dip22a.d(19): Error: no property `bar` for `Template!int` of type `void`
-fail_compilation/dip22a.d(20): Error: no property `bar` for `12` of type `int`
+fail_compilation/dip22a.d(18): Error: no property `bar` for `new Klass` of type `imports.dip22a.Klass`
+fail_compilation/imports/dip22a.d(3): class `Klass` defined here
+fail_compilation/dip22a.d(19): Error: no property `bar` for `Struct()` of type `imports.dip22a.Struct`
+fail_compilation/imports/dip22a.d(8): struct `Struct` defined here
+fail_compilation/dip22a.d(20): Error: undefined identifier `bar` in module `imports.dip22a`
+fail_compilation/dip22a.d(21): Error: no property `bar` for `Template!int` of type `void`
+fail_compilation/dip22a.d(22): Error: no property `bar` for `12` of type `int`
---
*/
import imports.dip22a;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/enum_function.d b/gcc/testsuite/gdc.test/fail_compilation/enum_function.d
index b22f2ceccef..52b71d12f5d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/enum_function.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/enum_function.d
@@ -1,10 +1,11 @@
/*
+REQUIRED_ARGS: -de
TEST_OUTPUT:
---
-fail_compilation/enum_function.d(10): Error: function cannot have enum storage class
-fail_compilation/enum_function.d(11): Error: function cannot have enum storage class
-fail_compilation/enum_function.d(12): Error: function cannot have enum storage class
-fail_compilation/enum_function.d(13): Error: function cannot have enum storage class
+fail_compilation/enum_function.d(11): Deprecation: function cannot have enum storage class
+fail_compilation/enum_function.d(12): Deprecation: function cannot have enum storage class
+fail_compilation/enum_function.d(13): Deprecation: function cannot have enum storage class
+fail_compilation/enum_function.d(14): Deprecation: function cannot have enum storage class
---
*/
enum void f1() { return; }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10528.d b/gcc/testsuite/gdc.test/fail_compilation/fail10528.d
index 38c5a23a529..3b3f5bb7f79 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10528.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10528.d
@@ -2,14 +2,18 @@
EXTRA_FILES: imports/a10528.d
TEST_OUTPUT:
---
-fail_compilation/fail10528.d(20): Error: undefined identifier `a`
-fail_compilation/fail10528.d(21): Error: undefined identifier `a` in module `a10528`
-fail_compilation/fail10528.d(23): Error: undefined identifier `b`
-fail_compilation/fail10528.d(24): Error: undefined identifier `b` in module `a10528`
-fail_compilation/fail10528.d(26): Error: no property `c` for type `a10528.S`
-fail_compilation/fail10528.d(27): Error: no property `c` for type `a10528.S`
-fail_compilation/fail10528.d(29): Error: no property `d` for type `a10528.C`
-fail_compilation/fail10528.d(30): Error: no property `d` for type `a10528.C`
+fail_compilation/fail10528.d(24): Error: undefined identifier `a`
+fail_compilation/fail10528.d(25): Error: undefined identifier `a` in module `a10528`
+fail_compilation/fail10528.d(27): Error: undefined identifier `b`
+fail_compilation/fail10528.d(28): Error: undefined identifier `b` in module `a10528`
+fail_compilation/fail10528.d(30): Error: no property `c` for type `a10528.S`
+fail_compilation/imports/a10528.d(4): struct `S` defined here
+fail_compilation/fail10528.d(31): Error: no property `c` for type `a10528.S`
+fail_compilation/imports/a10528.d(4): struct `S` defined here
+fail_compilation/fail10528.d(33): Error: no property `d` for type `a10528.C`
+fail_compilation/imports/a10528.d(5): class `C` defined here
+fail_compilation/fail10528.d(34): Error: no property `d` for type `a10528.C`
+fail_compilation/imports/a10528.d(5): class `C` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10534.d b/gcc/testsuite/gdc.test/fail_compilation/fail10534.d
index fac37f444e3..b5bb67c2678 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10534.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10534.d
@@ -1,22 +1,22 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail10534.d(28): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(28): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(29): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(29): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(30): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(30): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(31): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(31): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(36): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(36): Error: `b` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(37): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(37): Error: `b` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(38): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(38): Error: `b` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(39): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(39): Error: `b` is not of arithmetic type, it is a `int function()`
+fail_compilation/fail10534.d(28): Error: illegal operator `+` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(28): Error: illegal operator `+` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(29): Error: illegal operator `-` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(29): Error: illegal operator `-` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(30): Error: illegal operator `/` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(30): Error: illegal operator `/` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(31): Error: illegal operator `*` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(31): Error: illegal operator `*` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(36): Error: illegal operator `+` for `a` of type `int function()`
+fail_compilation/fail10534.d(36): Error: illegal operator `+` for `b` of type `int function()`
+fail_compilation/fail10534.d(37): Error: illegal operator `-` for `a` of type `int function()`
+fail_compilation/fail10534.d(37): Error: illegal operator `-` for `b` of type `int function()`
+fail_compilation/fail10534.d(38): Error: illegal operator `/` for `a` of type `int function()`
+fail_compilation/fail10534.d(38): Error: illegal operator `/` for `b` of type `int function()`
+fail_compilation/fail10534.d(39): Error: illegal operator `*` for `a` of type `int function()`
+fail_compilation/fail10534.d(39): Error: illegal operator `*` for `b` of type `int function()`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail109.d b/gcc/testsuite/gdc.test/fail_compilation/fail109.d
index 87297dbacd7..003e65f9b80 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail109.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail109.d
@@ -34,6 +34,7 @@ enum E1 : short
/* https://issues.dlang.org/show_bug.cgi?id=14950
TEST_OUTPUT:
---
+fail_compilation/fail109.d(50): Error: cannot check `fail109.B.end` value for overflow
fail_compilation/fail109.d(50): Error: comparison between different enumeration types `B` and `C`; If this behavior is intended consider using `std.conv.asOriginalType`
fail_compilation/fail109.d(50): Error: enum member `fail109.B.end` initialization with `B.start+1` causes overflow for type `C`
---
@@ -43,7 +44,6 @@ enum C
start,
end
}
-
enum B
{
start = C.end,
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail121.d b/gcc/testsuite/gdc.test/fail_compilation/fail121.d
index 8d5af747ce1..110547be7ca 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail121.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail121.d
@@ -3,8 +3,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail121.d(23): Error: no property `typeinfo` for `list[1]` of type `fail121.myobject`
-fail_compilation/fail121.d(23): Error: no property `typeinfo` for `i` of type `int`
+fail_compilation/fail121.d(24): Error: no property `typeinfo` for `list[1]` of type `fail121.myobject`
+fail_compilation/fail121.d(12): struct `myobject` defined here
+fail_compilation/fail121.d(24): Error: no property `typeinfo` for `i` of type `int`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail136.d b/gcc/testsuite/gdc.test/fail_compilation/fail136.d
index 16659b5fdc1..3bc86537ed6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail136.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail136.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail136.d(10): Error: found `"EF BB BF"` when expecting `;` following statement
+fail_compilation\fail136.d(10): Error: `"\xef\xbb\xbf"` has no effect
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17570.d b/gcc/testsuite/gdc.test/fail_compilation/fail17570.d
index bee61cf0b22..9be7cd4b05f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17570.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17570.d
@@ -1,9 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail17570.d(11): Error: cannot use function constraints for non-template functions. Use `static if` instead
-fail_compilation/fail17570.d(11): Error: declaration expected, not `if`
-fail_compilation/fail17570.d(14): Error: `}` expected following members in `struct` declaration at fail_compilation/fail17570.d(10)
+fail_compilation/fail17570.d(12): Error: cannot use function constraints for non-template functions. Use `static if` instead
+fail_compilation/fail17570.d(12): Error: declaration expected, not `if`
+fail_compilation/fail17570.d(15): Error: `}` expected following members in `struct` declaration
+fail_compilation/fail17570.d(11): struct `S` starts here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17969.d b/gcc/testsuite/gdc.test/fail_compilation/fail17969.d
index e6b95564b44..29bc3f448d8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17969.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail17969.d
@@ -1,6 +1,7 @@
/* TEST_OUTPUT:
---
-fail_compilation/fail17969.d(9): Error: no property `sum` for type `fail17969.__lambda6!(int[]).__lambda6.MapResult2!((b) => b)`
+fail_compilation/fail17969.d(10): Error: no property `sum` for type `fail17969.__lambda6!(int[]).__lambda6.MapResult2!((b) => b)`
+fail_compilation/fail17969.d(16): struct `MapResult2` defined here
---
* https://issues.dlang.org/show_bug.cgi?id=17969
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18219.d b/gcc/testsuite/gdc.test/fail_compilation/fail18219.d
index f3ec6806f6b..bf4b189f6eb 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18219.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18219.d
@@ -3,10 +3,11 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18219.d(16): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
-fail_compilation/fail18219.d(17): Error: no property `Bar` for type `a18219.AST`
-fail_compilation/fail18219.d(18): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?
-fail_compilation/fail18219.d(19): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
+fail_compilation/fail18219.d(17): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
+fail_compilation/fail18219.d(18): Error: no property `Bar` for type `a18219.AST`
+fail_compilation/imports/a18219.d(3): struct `AST` defined here
+fail_compilation/fail18219.d(19): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?
+fail_compilation/fail18219.d(20): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
---
*/
import imports.a18219;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18892.d b/gcc/testsuite/gdc.test/fail_compilation/fail18892.d
index 0fb56d315e9..381ef3c7ef5 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18892.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18892.d
@@ -1,8 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18892.d(20): Error: no property `foo` for `a` of type `fail18892.MT`
-fail_compilation/fail18892.d(21): Error: no property `foo` for `MT` of type `fail18892.MT`
+fail_compilation/fail18892.d(22): Error: no property `foo` for `a` of type `fail18892.MT`
+fail_compilation/fail18892.d(13): struct `MT` defined here
+fail_compilation/fail18892.d(23): Error: no property `foo` for `MT` of type `fail18892.MT`
+fail_compilation/fail18892.d(13): struct `MT` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18970.d b/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
index a8156fe7d1e..9b1ec1d4589 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18970.d
@@ -1,10 +1,12 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18970.d(24): Error: no property `y` for `S()` of type `fail18970.S`
-fail_compilation/fail18970.d(24): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
-fail_compilation/fail18970.d(31): Error: no property `yyy` for `this` of type `fail18970.S2`
-fail_compilation/fail18970.d(31): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/fail18970.d(26): Error: no property `y` for `S()` of type `fail18970.S`
+fail_compilation/fail18970.d(26): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/fail18970.d(15): struct `S` defined here
+fail_compilation/fail18970.d(33): Error: no property `yyy` for `this` of type `fail18970.S2`
+fail_compilation/fail18970.d(33): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/fail18970.d(29): struct `S2` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail18979.d b/gcc/testsuite/gdc.test/fail_compilation/fail18979.d
index 04e36f623ff..9b7c59acd5b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail18979.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail18979.d
@@ -2,7 +2,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail18979.d(13): Error: no property `__ctor` for `Foo()` of type `imports.imp18979.Foo`
+fail_compilation/fail18979.d(14): Error: no property `__ctor` for `Foo()` of type `imports.imp18979.Foo`
+fail_compilation/imports/imp18979.d(3): struct `Foo` defined here
----
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail1900.d b/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
index edc463018db..7e5f05692b5 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail1900.d
@@ -3,9 +3,9 @@ EXTRA_FILES: imports/fail1900a.d imports/fail1900b.d
TEST_OUTPUT:
---
fail_compilation/fail1900.d(27): Error: template `fail1900.Mix1a!().Foo` matches more than one template declaration:
-fail_compilation/fail1900.d(14): `Foo(ubyte x)`
-and
-fail_compilation/fail1900.d(15): `Foo(byte x)`
+fail_compilation/fail1900.d(14): `Foo(ubyte x)`
+and:
+fail_compilation/fail1900.d(15): `Foo(byte x)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19076.d b/gcc/testsuite/gdc.test/fail_compilation/fail19076.d
index 2441d6f3cae..05ae21bf613 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19076.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19076.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail19076.d(11): Error: no property `V` for type `fail19076.I`
-fail_compilation/fail19076.d(11): Error: `(I).V` cannot be resolved
+fail_compilation/fail19076.d(12): Error: no property `V` for type `fail19076.I`
+fail_compilation/fail19076.d(11): interface `I` defined here
+fail_compilation/fail19076.d(12): Error: `(I).V` cannot be resolved
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19103.d b/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
index 40fafcdc1ae..c1abd0df90a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19103.d
@@ -1,9 +1,11 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail19103.d(12): Error: no property `puts` for `new C` of type `fail19103.C`
-fail_compilation/fail19103.d(14): Error: no property `puts` for `s1` of type `fail19103.S1`
-fail_compilation/fail19103.d(16): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
+fail_compilation/fail19103.d(14): Error: no property `puts` for `new C` of type `fail19103.C`
+fail_compilation/fail19103.d(26): class `C` defined here
+fail_compilation/fail19103.d(16): Error: no property `puts` for `s1` of type `fail19103.S1`
+fail_compilation/fail19103.d(30): struct `S1` defined here
+fail_compilation/fail19103.d(18): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail196.d b/gcc/testsuite/gdc.test/fail_compilation/fail196.d
index cdad5c491db..78c596390b5 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail196.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail196.d
@@ -1,26 +1,35 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail196.d(29): Error: delimited string must end in `)"`
-fail_compilation/fail196.d(29): Error: implicit string concatenation is error-prone and disallowed in D
-fail_compilation/fail196.d(29): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == "
-fail_compilation/fail196.d(30): Error: semicolon needed to end declaration of `s`, instead of `foo`
-fail_compilation/fail196.d(29): `s` declared here
-fail_compilation/fail196.d(30): Error: found `");\n\n s = q"` when expecting `;` following statement `foo(xxx)` on line fail_compilation/fail196.d(30)
-fail_compilation/fail196.d(32): Error: found `";\n assert(s == "` when expecting `;` following statement `[foo[xxx]]` on line fail_compilation/fail196.d(32)
-fail_compilation/fail196.d(33): Error: found `");\n\n s = q"` when expecting `;` following statement `foo[xxx]` on line fail_compilation/fail196.d(33)
-fail_compilation/fail196.d(35): Error: found `{` when expecting `;` following statement `foo` on line fail_compilation/fail196.d(35)
-fail_compilation/fail196.d(35): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(35)
-fail_compilation/fail196.d(36): Error: found `foo` when expecting `;` following statement `";\n assert(s == "` on line fail_compilation/fail196.d(35)
-fail_compilation/fail196.d(36): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(36)
-fail_compilation/fail196.d(38): Error: found `<` when expecting `;` following statement `");\n\n s = q" < foo` on line fail_compilation/fail196.d(36)
-fail_compilation/fail196.d(39): Error: found `foo` when expecting `;` following statement `xxx >> ";\n assert(s == "` on line fail_compilation/fail196.d(38)
-fail_compilation/fail196.d(39): Error: found `<` instead of statement
-fail_compilation/fail196.d(45): Error: unterminated string constant starting at fail_compilation/fail196.d(45)
-fail_compilation/fail196.d(47): Error: matching `}` expected following compound statement, not `End of File`
-fail_compilation/fail196.d(36): unmatched `{`
-fail_compilation/fail196.d(47): Error: matching `}` expected following compound statement, not `End of File`
-fail_compilation/fail196.d(28): unmatched `{`
+fail_compilation/fail196.d(38): Error: delimited string must end in `)"`
+fail_compilation/fail196.d(38): Error: implicit string concatenation is error-prone and disallowed in D
+fail_compilation/fail196.d(38): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == "
+fail_compilation/fail196.d(39): Error: semicolon needed to end declaration of `s`, instead of `foo`
+fail_compilation/fail196.d(38): `s` declared here
+fail_compilation/fail196.d(39): Error: found `");\n\n s = q"` when expecting `;` following expression
+fail_compilation/fail196.d(39): expression: `foo(xxx)`
+fail_compilation/fail196.d(41): Error: found `";\n assert(s == "` when expecting `;` following expression
+fail_compilation/fail196.d(41): expression: `[foo[xxx]]`
+fail_compilation/fail196.d(42): Error: found `");\n\n s = q"` when expecting `;` following expression
+fail_compilation/fail196.d(42): expression: `foo[xxx]`
+fail_compilation/fail196.d(44): Error: found `{` when expecting `;` following expression
+fail_compilation/fail196.d(44): expression: `foo`
+fail_compilation/fail196.d(44): Error: found `}` when expecting `;` following expression
+fail_compilation/fail196.d(44): expression: `xxx`
+fail_compilation/fail196.d(45): Error: found `foo` when expecting `;` following expression
+fail_compilation/fail196.d(44): expression: `";\n assert(s == "`
+fail_compilation/fail196.d(45): Error: found `}` when expecting `;` following expression
+fail_compilation/fail196.d(45): expression: `xxx`
+fail_compilation/fail196.d(47): Error: found `<` when expecting `;` following expression
+fail_compilation/fail196.d(45): expression: `");\n\n s = q" < foo`
+fail_compilation/fail196.d(48): Error: found `foo` when expecting `;` following expression
+fail_compilation/fail196.d(47): expression: `xxx >> ";\n assert(s == "`
+fail_compilation/fail196.d(48): Error: found `<` instead of statement
+fail_compilation/fail196.d(54): Error: unterminated string constant starting at fail_compilation/fail196.d(54)
+fail_compilation/fail196.d(56): Error: matching `}` expected following compound statement, not `End of File`
+fail_compilation/fail196.d(45): unmatched `{`
+fail_compilation/fail196.d(56): Error: matching `}` expected following compound statement, not `End of File`
+fail_compilation/fail196.d(37): unmatched `{`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20637.d b/gcc/testsuite/gdc.test/fail_compilation/fail20637.d
index 77c69eaa6e6..dd0a5f52b87 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail20637.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail20637.d
@@ -2,7 +2,8 @@
EXTRA_FILES: imports/fail20637b.d
TEST_OUTPUT:
---
-fail_compilation/fail20637.d(12): Error: no property `foo` for type `imports.fail20637b.A`
+fail_compilation/fail20637.d(13): Error: no property `foo` for type `imports.fail20637b.A`
+fail_compilation/imports/fail20637b.d(3): class `A` defined here
---
*/
module fail20637;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22054.d b/gcc/testsuite/gdc.test/fail_compilation/fail22054.d
index c172f089d9c..8b525d85fb2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22054.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22054.d
@@ -3,10 +3,12 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail22054.d(21): Error: no property `what` for type `fail22054.exception`
-fail_compilation/fail22054.d(16): `class fail22054.exception` is opaque and has no members.
-fail_compilation/fail22054.d(22): Error: no property `what` for type `fail22054.exception2`
-fail_compilation/fail22054.d(17): `struct fail22054.exception2` is opaque and has no members.
+fail_compilation/fail22054.d(23): Error: no property `what` for type `fail22054.exception`
+fail_compilation/fail22054.d(18): `class fail22054.exception` is opaque and has no members.
+fail_compilation/fail22054.d(18): class `exception` defined here
+fail_compilation/fail22054.d(24): Error: no property `what` for type `fail22054.exception2`
+fail_compilation/fail22054.d(19): `struct fail22054.exception2` is opaque and has no members.
+fail_compilation/fail22054.d(19): struct `exception2` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22529.d b/gcc/testsuite/gdc.test/fail_compilation/fail22529.d
index 3bec3c0f7d3..62eac25680d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22529.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22529.d
@@ -3,7 +3,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail22529.d(13): Error: found `return` when expecting `;` following statement
+fail_compilation/fail22529.d(13): Error: found `return` when expecting `;` following expression
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23109.d b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
index 5c5c11b7195..ee560759e41 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail23109.d
@@ -5,7 +5,9 @@ EXTRA_SOURCES: extra-files/test23109/object.d
TEST_OUTPUT:
---
Error: no property `getHash` for `typeid(const(Ensure[]))` of type `object.TypeInfo_Const`
+fail_compilation/extra-files/test23109/object.d(7): class `TypeInfo_Const` defined here
Error: no property `getHash` for `typeid(const(Ensure[1]))` of type `object.TypeInfo_Const`
+fail_compilation/extra-files/test23109/object.d(7): class `TypeInfo_Const` defined here
fail_compilation/imports/test23109a.d(10): Error: template instance `imports.test23109a.Array!(Ensure)` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail61.d b/gcc/testsuite/gdc.test/fail_compilation/fail61.d
index a2f01d7e3ef..e7175b44245 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail61.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail61.d
@@ -1,10 +1,13 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail61.d(22): Error: no property `B` for type `fail61.A.B`
-fail_compilation/fail61.d(23): Error: no property `B` for type `fail61.A.B`
-fail_compilation/fail61.d(32): Error: no property `A2` for type `fail61.B2`
-fail_compilation/fail61.d(41): Error: calling non-static function `foo` requires an instance of type `B3`
+fail_compilation/fail61.d(25): Error: no property `B` for type `fail61.A.B`
+fail_compilation/fail61.d(16): class `B` defined here
+fail_compilation/fail61.d(26): Error: no property `B` for type `fail61.A.B`
+fail_compilation/fail61.d(16): class `B` defined here
+fail_compilation/fail61.d(35): Error: no property `A2` for type `fail61.B2`
+fail_compilation/fail61.d(30): class `B2` defined here
+fail_compilation/fail61.d(44): Error: calling non-static function `foo` requires an instance of type `B3`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7861.d b/gcc/testsuite/gdc.test/fail_compilation/fail7861.d
index c7018c95762..a24eb95fbdf 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7861.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7861.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail7861.d(17): Error: no property `nonexistent` for type `test.B`
+fail_compilation/fail7861.d(18): Error: no property `nonexistent` for type `test.B`
+fail_compilation/fail7861.d(14): struct `B` defined here
---
*/
module test;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9.d b/gcc/testsuite/gdc.test/fail_compilation/fail9.d
index 08789954bb1..080ac1e5ebe 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail9.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail9.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail9.d(23): Error: no property `Vector` for type `fail9.Vector!int`
+fail_compilation/fail9.d(24): Error: no property `Vector` for type `fail9.Vector!int`
+fail_compilation/fail9.d(13): class `Vector` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
index 8508b27d164..a9e5429366a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_scope.d
@@ -1,23 +1,21 @@
/*
-REQUIRED_ARGS: -wo
TEST_OUTPUT:
---
-fail_compilation/fail_scope.d(30): Deprecation: scope parameter `da` may not be returned
-fail_compilation/fail_scope.d(32): Deprecation: scope parameter `o` may not be returned
-fail_compilation/fail_scope.d(33): Deprecation: scope parameter `dg` may not be returned
-fail_compilation/fail_scope.d(40): Deprecation: scope parameter `p` may not be returned
-fail_compilation/fail_scope.d(45): Error: returning `cast(char[])string` escapes a reference to local variable `string`
-fail_compilation/fail_scope.d(63): Error: returning `s.bar()` escapes a reference to local variable `s`
-fail_compilation/fail_scope.d(74): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
-fail_compilation/fail_scope.d(68): `fail_scope.foo8(ref int x)`
+fail_compilation/fail_scope.d(28): Deprecation: scope parameter `da` may not be returned
+fail_compilation/fail_scope.d(30): Deprecation: scope parameter `o` may not be returned
+fail_compilation/fail_scope.d(31): Deprecation: scope parameter `dg` may not be returned
+fail_compilation/fail_scope.d(38): Deprecation: scope parameter `p` may not be returned
+fail_compilation/fail_scope.d(43): Error: returning `cast(char[])string` escapes a reference to local variable `string`
+fail_compilation/fail_scope.d(61): Error: returning `s.bar()` escapes a reference to local variable `s`
+fail_compilation/fail_scope.d(72): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
+fail_compilation/fail_scope.d(66): `fail_scope.foo8(ref int x)`
and:
-fail_compilation/fail_scope.d(69): `fail_scope.foo8(return ref int x)`
-fail_compilation/fail_scope.d(82): Error: returning `& string` escapes a reference to local variable `string`
-fail_compilation/fail_scope.d(92): Error: returning `cast(int[])a` escapes a reference to local variable `a`
-fail_compilation/fail_scope.d(100): Error: returning `cast(int[])a` escapes a reference to local variable `a`
-fail_compilation/fail_scope.d(108): Error: escaping reference to outer local variable `x`
-fail_compilation/fail_scope.d(127): Warning: returning `s.bar()` escapes a reference to local variable `s`
-fail_compilation/fail_scope.d(137): Error: returning `foo16226(i)` escapes a reference to local variable `i`
+fail_compilation/fail_scope.d(67): `fail_scope.foo8(return ref int x)`
+fail_compilation/fail_scope.d(80): Error: returning `& string` escapes a reference to local variable `string`
+fail_compilation/fail_scope.d(90): Error: returning `cast(int[])a` escapes a reference to local variable `a`
+fail_compilation/fail_scope.d(98): Error: returning `cast(int[])a` escapes a reference to local variable `a`
+fail_compilation/fail_scope.d(106): Error: escaping reference to outer local variable `x`
+fail_compilation/fail_scope.d(135): Error: returning `foo16226(i)` escapes a reference to local variable `i`
---
//fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned
//fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned
diff --git a/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d b/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d
index c44b289ccec..9b62c26edd0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/faildottypeinfo.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/faildottypeinfo.d(11): Error: no property `typeinfo` for `0` of type `int`
-fail_compilation/faildottypeinfo.d(12): Error: no property `typeinfo` for type `object.Object`
+fail_compilation/faildottypeinfo.d(12): Error: no property `typeinfo` for `0` of type `int`
+fail_compilation/faildottypeinfo.d(13): Error: no property `typeinfo` for type `object.Object`
+$p:druntime/import/object.d$($n$): class `Object` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fnconstraint.d b/gcc/testsuite/gdc.test/fail_compilation/fnconstraint.d
index 5862f7a8c88..21603f725f6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fnconstraint.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fnconstraint.d
@@ -1,11 +1,12 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fnconstraint.d(13): Error: template constraint must follow parameter lists and attributes
-fail_compilation/fnconstraint.d(13): Error: declaration expected, not `if`
-fail_compilation/fnconstraint.d(22): Error: template constraint must follow parameter lists and attributes
-fail_compilation/fnconstraint.d(22): Error: declaration expected, not `if`
-fail_compilation/fnconstraint.d(26): Error: `}` expected following members in `struct` declaration at fail_compilation/fnconstraint.d(18)
+fail_compilation/fnconstraint.d(14): Error: template constraint must follow parameter lists and attributes
+fail_compilation/fnconstraint.d(14): Error: declaration expected, not `if`
+fail_compilation/fnconstraint.d(23): Error: template constraint must follow parameter lists and attributes
+fail_compilation/fnconstraint.d(23): Error: declaration expected, not `if`
+fail_compilation/fnconstraint.d(27): Error: `}` expected following members in `struct` declaration
+fail_compilation/fnconstraint.d(19): struct `S` starts here
---
*/
void foo()()
diff --git a/gcc/testsuite/gdc.test/fail_compilation/goto_skip.d b/gcc/testsuite/gdc.test/fail_compilation/goto_skip.d
new file mode 100644
index 00000000000..21bce5d2ec2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/goto_skip.d
@@ -0,0 +1,57 @@
+/*
+REQUIRED_ARGS: -verrors=context
+TEST_OUTPUT:
+---
+fail_compilation/goto_skip.d(28): Error: `goto` skips declaration of variable `goto_skip.skip.ch`
+ goto Lskip;
+ ^
+fail_compilation/goto_skip.d(29): declared here
+ char ch = '!';
+ ^
+fail_compilation/goto_skip.d(36): Error: `goto` skips declaration of `with` temporary
+ goto L1;
+ ^
+fail_compilation/goto_skip.d(38): declared here
+ with (S()) {
+ ^
+fail_compilation/goto_skip.d(46): Error: `goto` skips declaration of variable `goto_skip.test8.e`
+ goto L2;
+ ^
+fail_compilation/goto_skip.d(51): declared here
+ catch (Exception e) {
+ ^
+---
+*/
+char skip(bool b)
+{
+ if (b)
+ goto Lskip;
+ char ch = '!';
+Lskip:
+ return ch;
+}
+
+int f()
+{
+ goto L1;
+ struct S { int e = 5; }
+ with (S()) {
+L1:
+ return e;
+ }
+}
+
+void test8(int a)
+{
+ goto L2;
+
+ try {
+ a += 2;
+ }
+ catch (Exception e) {
+ a += 3;
+L2: ;
+ a += 100;
+ }
+ assert(a == 100);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10713.d b/gcc/testsuite/gdc.test/fail_compilation/ice10713.d
index f3680329941..e59a594da8a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10713.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10713.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice10713.d(10): Error: no property `nonExistingField` for type `ice10713.S`
+fail_compilation/ice10713.d(11): Error: no property `nonExistingField` for type `ice10713.S`
+fail_compilation/ice10713.d(9): struct `S` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10938.d b/gcc/testsuite/gdc.test/fail_compilation/ice10938.d
index d21ee47dec7..4d107c9e7b2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10938.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10938.d
@@ -1,8 +1,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice10938.d(13): Error: no property `opts` for `this` of type `ice10938.C`
-fail_compilation/ice10938.d(13): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/ice10938.d(14): Error: no property `opts` for `this` of type `ice10938.C`
+fail_compilation/ice10938.d(14): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/ice10938.d(10): class `C` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11518.d b/gcc/testsuite/gdc.test/fail_compilation/ice11518.d
index c8542f77252..4e4f6170a61 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11518.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11518.d
@@ -2,9 +2,9 @@
TEST_OUTPUT:
---
fail_compilation/ice11518.d(17): Error: class `ice11518.B` matches more than one template declaration:
-fail_compilation/ice11518.d(12): `B(T : A!T)`
-and
-fail_compilation/ice11518.d(13): `B(T : A!T)`
+fail_compilation/ice11518.d(12): `B(T : A!T)`
+and:
+fail_compilation/ice11518.d(13): `B(T : A!T)`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11982.d b/gcc/testsuite/gdc.test/fail_compilation/ice11982.d
index 0886df61678..f500700f674 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11982.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice11982.d
@@ -1,20 +1,22 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice11982.d(20): Error: basic type expected, not `scope`
-fail_compilation/ice11982.d(20): Error: found `scope` when expecting `;` following statement `new _error_` on line fail_compilation/ice11982.d(20)
-fail_compilation/ice11982.d(20): Error: basic type expected, not `}`
-fail_compilation/ice11982.d(20): Error: missing `{ ... }` for function literal
-fail_compilation/ice11982.d(20): Error: C style cast illegal, use `cast(funk)function _error_()
+fail_compilation/ice11982.d(22): Error: basic type expected, not `scope`
+fail_compilation/ice11982.d(22): Error: found `scope` when expecting `;` following expression
+fail_compilation/ice11982.d(22): expression: `new _error_`
+fail_compilation/ice11982.d(22): Error: basic type expected, not `}`
+fail_compilation/ice11982.d(22): Error: missing `{ ... }` for function literal
+fail_compilation/ice11982.d(22): Error: C style cast illegal, use `cast(funk)function _error_()
{
}
`
-fail_compilation/ice11982.d(20): Error: found `}` when expecting `;` following statement `cast(funk)function _error_()
+fail_compilation/ice11982.d(22): Error: found `}` when expecting `;` following expression
+fail_compilation/ice11982.d(22): expression: `cast(funk)function _error_()
{
}
-` on line fail_compilation/ice11982.d(20)
-fail_compilation/ice11982.d(21): Error: matching `}` expected following compound statement, not `End of File`
-fail_compilation/ice11982.d(20): unmatched `{`
+`
+fail_compilation/ice11982.d(23): Error: matching `}` expected following compound statement, not `End of File`
+fail_compilation/ice11982.d(22): unmatched `{`
---
*/
void main() { new scope ( funk ) function }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice8100.d b/gcc/testsuite/gdc.test/fail_compilation/ice8100.d
index dc68cfcce2b..b8b3155b688 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice8100.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice8100.d
@@ -1,9 +1,10 @@
/*
TEST_OUTPUT:
---
-fail_compilation/ice8100.d(10): Error: no property `Q` for type `ice8100.Bar!bool`
-fail_compilation/ice8100.d(11): Error: template instance `ice8100.Foo!(Bar!bool)` error instantiating
-fail_compilation/ice8100.d(12): instantiated from here: `Bar!bool`
+fail_compilation/ice8100.d(11): Error: no property `Q` for type `ice8100.Bar!bool`
+fail_compilation/ice8100.d(12): class `Bar` defined here
+fail_compilation/ice8100.d(12): Error: template instance `ice8100.Foo!(Bar!bool)` error instantiating
+fail_compilation/ice8100.d(13): instantiated from here: `Bar!bool`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue12652.d b/gcc/testsuite/gdc.test/fail_compilation/issue12652.d
deleted file mode 100644
index 0ddd6b48b53..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/issue12652.d
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-TEST_OUTPUT:
-----
-fail_compilation/issue12652.d(18): Error: static initializations of associative arrays is not allowed.
-fail_compilation/issue12652.d(18): associative arrays must be initialized at runtime: https://dlang.org/spec/hash-map.html#runtime_initialization
----
-*/
-
-enum A
-{
- x,
- y,
- z
-}
-
-struct S
-{
- string[A] t = [A.x : "aaa", A.y : "bbb"];
-}
-
-void main ()
-{
- S s;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue22682.d b/gcc/testsuite/gdc.test/fail_compilation/issue22682.d
new file mode 100644
index 00000000000..80e8311b3a7
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/issue22682.d
@@ -0,0 +1,18 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/issue22682.d(14): Error: `pragma(mangle)` must be attached to a declaration
+fail_compilation/issue22682.d(15): Error: `pragma(mangle)` takes a single argument that must be a string literal
+fail_compilation/issue22682.d(16): Error: `string` expected for pragma mangle argument, not `(0)` of type `int`
+fail_compilation/issue22682.d(16): Error: `pragma(mangle)` takes a single argument that must be a string literal
+fail_compilation/issue22682.d(17): Error: `pragma(mangle)` must be attached to a declaration
+---
+ */
+module issue22682;
+
+void main()
+{
+ pragma(mangle) {}
+ pragma(mangle) static int i0;
+ pragma(mangle, 0) static int i1;
+ pragma(mangle);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer1.d b/gcc/testsuite/gdc.test/fail_compilation/lexer1.d
index 0ad3f01156a..7fe2a537481 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/lexer1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/lexer1.d
@@ -1,8 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/lexer1.d(30): Error: no identifier for declarator `x`
-fail_compilation/lexer1.d(30): Error: declaration expected, not `"01 02 03"w`
+fail_compilation/lexer1.d(30): Error: declaration expected, not `x"01 02 03"w`
fail_compilation/lexer1.d(31): Error: declaration expected, not `2147483649U`
fail_compilation/lexer1.d(32): Error: declaration expected, not `0.1`
fail_compilation/lexer1.d(33): Error: declaration expected, not `0.1f`
@@ -26,6 +25,7 @@ fail_compilation/lexer1.d(52): Error: escape octal sequence \400 is larger than
fail_compilation/lexer1.d(53): Error: html entity requires 2 code units, use a string instead of a character
---
*/
+
// https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html
x"01 02 03"w;
0x80000001;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer2.d b/gcc/testsuite/gdc.test/fail_compilation/lexer2.d
index f895e644c44..f8fae85c9b3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/lexer2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/lexer2.d
@@ -1,16 +1,16 @@
/*
TEST_OUTPUT:
---
-fail_compilation/lexer2.d(16): Error: semicolon expected following auto declaration, not `"123"`
-fail_compilation/lexer2.d(16): Error: declaration expected, not `"123"`
-fail_compilation/lexer2.d(17): Error: semicolon expected following auto declaration, not `"123G"`
-fail_compilation/lexer2.d(17): Error: declaration expected, not `"123G"`
+fail_compilation/lexer2.d(16): Error: odd number (3) of hex characters in hex string
+fail_compilation/lexer2.d(17): Error: non-hex character 'G' in hex string
fail_compilation/lexer2.d(18): Error: heredoc rest of line should be blank
fail_compilation/lexer2.d(20): Error: unterminated delimited string constant starting at fail_compilation/lexer2.d(20)
fail_compilation/lexer2.d(22): Error: semicolon expected following auto declaration, not `End of File`
---
*/
+
+
// https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html
static s1 = x"123";
diff --git a/gcc/testsuite/gdc.test/fail_compilation/main.d b/gcc/testsuite/gdc.test/fail_compilation/main.d
new file mode 100644
index 00000000000..42a8a43062f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/main.d
@@ -0,0 +1,9 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/main.d(9): Error: only one entry point `main`$?:windows=, `WinMain` or `DllMain`$ is allowed
+fail_compilation/main.d(8): previously found `void main()` here
+---
+*/
+void main() {}
+void main(string[] args) {}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/match_func_ptr.d b/gcc/testsuite/gdc.test/fail_compilation/match_func_ptr.d
new file mode 100644
index 00000000000..7f59183f2ce
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/match_func_ptr.d
@@ -0,0 +1,17 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/match_func_ptr.d(13): Error: cannot match delegate literal to function pointer type `void function()`
+fail_compilation/match_func_ptr.d(14): Error: cannot match function literal to delegate type `void delegate()`
+fail_compilation/match_func_ptr.d(15): Error: cannot infer parameter types from `int function()`
+fail_compilation/match_func_ptr.d(16): Error: cannot infer parameter types from `int delegate(int, int)`
+---
+*/
+
+void main()
+{
+ void function() f = delegate {};
+ void delegate() d = function {};
+ int function() f2 = i => 2;
+ int delegate(int, int) d2 = i => 2;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
index 57706b59e41..9de436b0119 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/misc_parser_err_cov1.d
@@ -23,7 +23,8 @@ fail_compilation/misc_parser_err_cov1.d(40): Error: semicolon expected following
fail_compilation/misc_parser_err_cov1.d(40): Error: identifier or `new` expected following `.`, not `+`
fail_compilation/misc_parser_err_cov1.d(41): Error: identifier or new keyword expected following `(...)`.
fail_compilation/misc_parser_err_cov1.d(41): Error: expression expected, not `;`
-fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following statement `(__error) + 0` on line fail_compilation/misc_parser_err_cov1.d(41)
+fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following expression
+fail_compilation/misc_parser_err_cov1.d(41): expression: `(__error) + 0`
fail_compilation/misc_parser_err_cov1.d(43): Error: matching `}` expected following compound statement, not `End of File`
fail_compilation/misc_parser_err_cov1.d(33): unmatched `{`
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/nogc3.d b/gcc/testsuite/gdc.test/fail_compilation/nogc3.d
index 3bd7167acba..b53903ffbc0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/nogc3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/nogc3.d
@@ -43,10 +43,12 @@ fail_compilation/nogc3.d(35): Error: `@nogc` function `nogc3.testCall` cannot ca
/*
TEST_OUTPUT:
---
-fail_compilation/nogc3.d(52): Error: function `nogc3.testClosure1` is `@nogc` yet allocates closure for `testClosure1()` with the GC
-fail_compilation/nogc3.d(55): `nogc3.testClosure1.bar` closes over variable `x` at fail_compilation/nogc3.d(54)
-fail_compilation/nogc3.d(64): Error: function `nogc3.testClosure3` is `@nogc` yet allocates closure for `testClosure3()` with the GC
-fail_compilation/nogc3.d(67): `nogc3.testClosure3.bar` closes over variable `x` at fail_compilation/nogc3.d(66)
+fail_compilation/nogc3.d(54): Error: function `nogc3.testClosure1` is `@nogc` yet allocates closure for `testClosure1()` with the GC
+fail_compilation/nogc3.d(57): function `nogc3.testClosure1.bar` closes over variable `x`
+fail_compilation/nogc3.d(56): `x` declared here
+fail_compilation/nogc3.d(66): Error: function `nogc3.testClosure3` is `@nogc` yet allocates closure for `testClosure3()` with the GC
+fail_compilation/nogc3.d(69): function `nogc3.testClosure3.bar` closes over variable `x`
+fail_compilation/nogc3.d(68): `x` declared here
---
*/
@nogc auto testClosure1()
@@ -73,10 +75,10 @@ fail_compilation/nogc3.d(67): `nogc3.testClosure3.bar` closes over variab
/*
TEST_OUTPUT:
---
-fail_compilation/nogc3.d(85): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
-fail_compilation/nogc3.d(86): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
-fail_compilation/nogc3.d(92): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
-fail_compilation/nogc3.d(91): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
+fail_compilation/nogc3.d(87): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
+fail_compilation/nogc3.d(88): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
+fail_compilation/nogc3.d(94): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
+fail_compilation/nogc3.d(93): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
---
*/
int[] foo13702(bool b) @nogc
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn_expr.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn_expr.d
new file mode 100644
index 00000000000..c72bade8fa5
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn_expr.d
@@ -0,0 +1,16 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/noreturn_expr.d(10): Error: type `noreturn` is not an expression
+---
+*/
+
+int v(e)()
+{
+ return e + 0;
+}
+
+int main()
+{
+ return v!(noreturn)();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn_expr2.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn_expr2.d
new file mode 100644
index 00000000000..f5e0054823b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn_expr2.d
@@ -0,0 +1,14 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/noreturn_expr2.d(8): Error: cannot cast `noreturn` to `int` at compile time
+---
+*/
+
+enum E {e1 = 1, e2 = 2, illegal = noreturn}
+
+void main()
+{
+ E e;
+ e = E.illegal;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/operator_undefined.d b/gcc/testsuite/gdc.test/fail_compilation/operator_undefined.d
new file mode 100644
index 00000000000..3065bdb8e79
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/operator_undefined.d
@@ -0,0 +1,20 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/operator_undefined.d(19): Error: operator `-` is not defined for `toJson(2)` of type `Json`
+---
+*/
+
+import std.stdio;
+
+struct Json
+{
+ //int opUnary(string op : "-")();
+}
+
+Json toJson(int);
+
+void main()
+{
+ auto x = -2.toJson;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/parseStc.d b/gcc/testsuite/gdc.test/fail_compilation/parseStc.d
index d13006db0ab..9a24741689e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/parseStc.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/parseStc.d
@@ -3,12 +3,12 @@ TEST_OUTPUT:
---
fail_compilation/parseStc.d(12): Error: missing closing `)` after `if (x`
fail_compilation/parseStc.d(12): Error: use `{ }` for an empty statement, not `;`
-fail_compilation/parseStc.d(12): Error: found `)` when expecting `;` following statement `1` on line fail_compilation/parseStc.d(12)
+fail_compilation/parseStc.d(12): Error: found `)` when expecting `;` following expression
+fail_compilation/parseStc.d(12): expression: `1`
fail_compilation/parseStc.d(13): Error: redundant attribute `const`
---
*/
-void test1()
-{
+void test1() {
if (x; 1) {}
if (const const auto x = 1) {}
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
index c08747fa7e3..ce983c01fc6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d
@@ -55,7 +55,7 @@ void test2(scope int* p, int[] a ...) @safe
TEST_OUTPUT:
---
fail_compilation/retscope.d(75): Error: function `retscope.HTTP.Impl.onReceive` is `@nogc` yet allocates closure for `onReceive()` with the GC
-fail_compilation/retscope.d(77): `retscope.HTTP.Impl.onReceive.__lambda1` closes over variable `this` at fail_compilation/retscope.d(75)
+fail_compilation/retscope.d(77): delegate `retscope.HTTP.Impl.onReceive.__lambda1` closes over variable `this`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/skip.d b/gcc/testsuite/gdc.test/fail_compilation/skip.d
index 0f3a9ec7e56..6207a106ddb 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/skip.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/skip.d
@@ -2,8 +2,10 @@
* REQUIRED_ARGS: -de
* TEST_OUTPUT:
---
-fail_compilation/skip.d(21): Error: `switch` skips declaration of `with` temporary at fail_compilation/skip.d(26)
-fail_compilation/skip.d(43): Error: `switch` skips declaration of variable `skip.test14532.n` at fail_compilation/skip.d(45)
+fail_compilation/skip.d(23): Error: `switch` skips declaration of `with` temporary
+fail_compilation/skip.d(28): declared here
+fail_compilation/skip.d(45): Error: `switch` skips declaration of variable `skip.test14532.n`
+fail_compilation/skip.d(47): declared here
---
*/
// https://issues.dlang.org/show_bug.cgi?id=10524
diff --git a/gcc/testsuite/gdc.test/fail_compilation/switch_skip.d b/gcc/testsuite/gdc.test/fail_compilation/switch_skip.d
new file mode 100644
index 00000000000..7141fb16ba8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/switch_skip.d
@@ -0,0 +1,48 @@
+/*
+REQUIRED_ARGS: -verrors=context
+TEST_OUTPUT:
+---
+fail_compilation/switch_skip.d(22): Error: `switch` skips declaration of variable `switch_skip.test3.j`
+ switch (i)
+ ^
+fail_compilation/switch_skip.d(26): declared here
+ int j;
+ ^
+fail_compilation/switch_skip.d(39): Error: `switch` skips declaration of variable `switch_skip.test.z`
+ final switch(n)
+ ^
+fail_compilation/switch_skip.d(41): declared here
+ int z = 5;
+ ^
+---
+*/
+
+void test3(int i)
+{
+ switch (i)
+ {
+ case 1:
+ {
+ int j;
+ case 2:
+ ++j;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=18858
+int test(int n)
+{
+ final switch(n)
+ {
+ int z = 5;
+ enum e = 6;
+
+ case 1:
+ int y = 2;
+ return y;
+ }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/switches.d b/gcc/testsuite/gdc.test/fail_compilation/switches.d
index b53fb4c6375..06652c8cf34 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/switches.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/switches.d
@@ -1,13 +1,11 @@
-/************************************************************/
-
/*
TEST_OUTPUT:
---
-fail_compilation/switches.d(105): Error: `case 2` not found
+fail_compilation/switches.d(14): Error: `case 2` not found
+fail_compilation/switches.d(25): Error: no `case` statement following `goto case;`
---
*/
-#line 100
void test1(int i)
{
switch (i)
@@ -19,16 +17,6 @@ void test1(int i)
}
}
-/************************************************************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/switches.d(205): Error: no `case` statement following `goto case;`
----
-*/
-
-#line 200
void test2(int i)
{
switch (i)
@@ -39,55 +27,3 @@ void test2(int i)
break;
}
}
-
-/************************************************************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/switches.d(302): Error: `switch` skips declaration of variable `switches.test3.j` at fail_compilation/switches.d(306)
----
-*/
-
-#line 300
-void test3(int i)
-{
- switch (i)
- {
- case 1:
- {
- int j;
- case 2:
- ++j;
- break;
- }
- default:
- break;
- }
-}
-
-
-/************************************************************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/switches.d(404): Error: `switch` skips declaration of variable `switches.test.z` at fail_compilation/switches.d(406)
----
-*/
-
-#line 400
-// https://issues.dlang.org/show_bug.cgi?id=18858
-
-int test(int n)
-{
- final switch(n)
- {
- int z = 5;
- enum e = 6;
-
- case 1:
- int y = 2;
- return y;
- }
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test13536.d b/gcc/testsuite/gdc.test/fail_compilation/test13536.d
index 4a4bb2672be..eff807ab5a3 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test13536.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test13536.d
@@ -1,9 +1,8 @@
-/* REQUIRED_ARGS: -wo
+/*
TEST_OUTPUT:
---
-fail_compilation/test13536.d(23): Error: field `U.sysDg` cannot access pointers in `@safe` code that overlap other fields
-fail_compilation/test13536.d(23): Warning: address of variable `s` assigned to `u` with longer lifetime
-fail_compilation/test13536.d(24): Error: field `U.safeDg` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test13536.d(22): Error: field `U.sysDg` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test13536.d(23): Error: field `U.safeDg` cannot access pointers in `@safe` code that overlap other fields
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15785.d b/gcc/testsuite/gdc.test/fail_compilation/test15785.d
index 594b5d35e75..fc61e3db070 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15785.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15785.d
@@ -2,8 +2,9 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test15785.d(16): Error: no property `foo` for `super` of type `imports.test15785.Base`
-fail_compilation/test15785.d(17): Error: undefined identifier `bar`
+fail_compilation/test15785.d(17): Error: no property `foo` for `super` of type `imports.test15785.Base`
+fail_compilation/imports/test15785.d(3): class `Base` defined here
+fail_compilation/test15785.d(18): Error: undefined identifier `bar`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test15897.d b/gcc/testsuite/gdc.test/fail_compilation/test15897.d
index db554cb9e15..c911263718f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test15897.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test15897.d
@@ -3,7 +3,8 @@
/*
TEST_OUTPUT:
---
-fail_compilation/test15897.d(19): Error: no property `create` for `cat` of type `imports.test15897.Cat`
+fail_compilation/test15897.d(20): Error: no property `create` for `cat` of type `imports.test15897.Cat`
+fail_compilation/imports/test15897.d(4): class `Cat` defined here
---
*/
module test15897;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16188.d b/gcc/testsuite/gdc.test/fail_compilation/test16188.d
index bdaae94a6ca..0bd052ca6db 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16188.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16188.d
@@ -3,6 +3,7 @@
---
fail_compilation/test16188.d(101): Error: no property `name` for `Where()` of type `test16188.Where`
fail_compilation/test16188.d(101): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/test16188.d(103): struct `Where` defined here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16193.d b/gcc/testsuite/gdc.test/fail_compilation/test16193.d
index 6c80471c77b..39399cf01d8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16193.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16193.d
@@ -2,8 +2,9 @@
REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
-fail_compilation/test16193.d(38): Error: function `test16193.abc` is `@nogc` yet allocates closure for `abc()` with the GC
-fail_compilation/test16193.d(40): `test16193.abc.__foreachbody2` closes over variable `x` at fail_compilation/test16193.d(39)
+fail_compilation/test16193.d(39): Error: function `test16193.abc` is `@nogc` yet allocates closure for `abc()` with the GC
+fail_compilation/test16193.d(41): delegate `test16193.abc.__foreachbody2` closes over variable `x`
+fail_compilation/test16193.d(40): `x` declared here
---
*/
//fail_compilation/test16193.d(22): To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16365.d b/gcc/testsuite/gdc.test/fail_compilation/test16365.d
index 4d49365659c..5bfa5f8dba6 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test16365.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test16365.d
@@ -1,10 +1,9 @@
-/* REQUIRED_ARGS: -wo
+/*
TEST_OUTPUT:
---
-fail_compilation/test16365.d(21): Error: `this` reference necessary to take address of member `f1` in `@safe` function `main`
-fail_compilation/test16365.d(23): Error: cannot implicitly convert expression `&f2` of type `void delegate() pure nothrow @nogc @safe` to `void function() @safe`
-fail_compilation/test16365.d(27): Warning: address of variable `s` assigned to `dg` with longer lifetime
-fail_compilation/test16365.d(28): Error: `dg.funcptr` cannot be used in `@safe` code
+fail_compilation/test16365.d(20): Error: `this` reference necessary to take address of member `f1` in `@safe` function `main`
+fail_compilation/test16365.d(22): Error: cannot implicitly convert expression `&f2` of type `void delegate() pure nothrow @nogc @safe` to `void function() @safe`
+fail_compilation/test16365.d(27): Error: `dg.funcptr` cannot be used in `@safe` code
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d b/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d
index f523337037a..8ab8739d978 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17380spec.d
@@ -1,9 +1,10 @@
/* REQUIRED_ARGS: -verrors=spec
TEST_OUTPUT:
---
-(spec:1) fail_compilation/test17380spec.d(14): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
-(spec:1) fail_compilation/test17380spec.d(14): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for `this.opCast()` of type `test17380spec.Uint128`
-fail_compilation/test17380spec.d(14): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
+(spec:1) fail_compilation/test17380spec.d(15): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
+(spec:1) fail_compilation/test17380spec.d(15): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for `this.opCast()` of type `test17380spec.Uint128`
+(spec:1) fail_compilation/test17380spec.d(20): struct `Uint128` defined here
+fail_compilation/test17380spec.d(15): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20655.d b/gcc/testsuite/gdc.test/fail_compilation/test20655.d
new file mode 100644
index 00000000000..c3bb70af492
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20655.d
@@ -0,0 +1,32 @@
+/*
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/test20655.d(29): Deprecation: `@safe` function `g` calling `f1`
+fail_compilation/test20655.d(24): which wouldn't be `@safe` because of:
+fail_compilation/test20655.d(24): field `U.s` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test20655.d(30): Deprecation: `@safe` function `g` calling `f2`
+fail_compilation/test20655.d(25): which wouldn't be `@safe` because of:
+fail_compilation/test20655.d(25): field `U.s` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test20655.d(31): Deprecation: `@safe` function `g` calling `f3`
+fail_compilation/test20655.d(28): which wouldn't be `@safe` because of:
+fail_compilation/test20655.d(28): field `U.s` cannot access pointers in `@safe` code that overlap other fields
+---
+*/
+
+union U
+{
+ string s;
+ int x;
+}
+U u;
+
+auto f1() { auto s = u.s; } /* Should be inferred as @system. */
+void f2()() { auto s = u.s; } /* ditto */
+void g() @safe
+{
+ void f3() { auto s = u.s; } /* ditto */
+ f1(); /* Should be rejected with error "cannot call @system function". */
+ f2(); /* ditto */
+ f3(); /* ditto */
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21353.d b/gcc/testsuite/gdc.test/fail_compilation/test21353.d
index 55c84f996a1..14fa26dcce7 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21353.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21353.d
@@ -2,11 +2,14 @@
EXTRA_FILES: imports/imp21353.d
TEST_OUTPUT:
---
-fail_compilation/test21353.d(19): Error: no property `A` for type `imports.imp21353.B`
-fail_compilation/test21353.d(20): Error: no property `A` for type `imports.imp21353.B`
-fail_compilation/test21353.d(21): Error: no property `A` for type `imports.imp21353.B`
-fail_compilation/test21353.d(23): Error: undefined identifier `P` in module `imports.imp21353`
-fail_compilation/test21353.d(24): Error: undefined identifier `P` in module `imports.imp21353`
+fail_compilation/test21353.d(22): Error: no property `A` for type `imports.imp21353.B`
+fail_compilation/imports/imp21353.d(5): struct `B` defined here
+fail_compilation/test21353.d(23): Error: no property `A` for type `imports.imp21353.B`
+fail_compilation/imports/imp21353.d(5): struct `B` defined here
+fail_compilation/test21353.d(24): Error: no property `A` for type `imports.imp21353.B`
+fail_compilation/imports/imp21353.d(5): struct `B` defined here
+fail_compilation/test21353.d(26): Error: undefined identifier `P` in module `imports.imp21353`
+fail_compilation/test21353.d(27): Error: undefined identifier `P` in module `imports.imp21353`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21912.d b/gcc/testsuite/gdc.test/fail_compilation/test21912.d
index 9b07eba0df6..f8bcb40b5df 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test21912.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21912.d
@@ -2,14 +2,18 @@
PERMUTE_ARGS: -preview=dip1000
TEST_OUTPUT:
---
-fail_compilation/test21912.d(24): Error: function `test21912.escapeParam` is `@nogc` yet allocates closure for `escapeParam()` with the GC
-fail_compilation/test21912.d(26): `test21912.escapeParam.__lambda2` closes over variable `i` at fail_compilation/test21912.d(24)
-fail_compilation/test21912.d(29): Error: function `test21912.escapeAssign` is `@nogc` yet allocates closure for `escapeAssign()` with the GC
-fail_compilation/test21912.d(31): `test21912.escapeAssign.__lambda3` closes over variable `i` at fail_compilation/test21912.d(29)
-fail_compilation/test21912.d(40): Error: function `test21912.escapeAssignRef` is `@nogc` yet allocates closure for `escapeAssignRef()` with the GC
-fail_compilation/test21912.d(42): `test21912.escapeAssignRef.__lambda3` closes over variable `i` at fail_compilation/test21912.d(40)
-fail_compilation/test21912.d(51): Error: function `test21912.escapeParamInferred` is `@nogc` yet allocates closure for `escapeParamInferred()` with the GC
-fail_compilation/test21912.d(53): `test21912.escapeParamInferred.__lambda2` closes over variable `i` at fail_compilation/test21912.d(51)
+fail_compilation/test21912.d(28): Error: function `test21912.escapeParam` is `@nogc` yet allocates closure for `escapeParam()` with the GC
+fail_compilation/test21912.d(30): delegate `test21912.escapeParam.__lambda2` closes over variable `i`
+fail_compilation/test21912.d(28): `i` declared here
+fail_compilation/test21912.d(33): Error: function `test21912.escapeAssign` is `@nogc` yet allocates closure for `escapeAssign()` with the GC
+fail_compilation/test21912.d(35): delegate `test21912.escapeAssign.__lambda3` closes over variable `i`
+fail_compilation/test21912.d(33): `i` declared here
+fail_compilation/test21912.d(44): Error: function `test21912.escapeAssignRef` is `@nogc` yet allocates closure for `escapeAssignRef()` with the GC
+fail_compilation/test21912.d(46): delegate `test21912.escapeAssignRef.__lambda3` closes over variable `i`
+fail_compilation/test21912.d(44): `i` declared here
+fail_compilation/test21912.d(55): Error: function `test21912.escapeParamInferred` is `@nogc` yet allocates closure for `escapeParamInferred()` with the GC
+fail_compilation/test21912.d(57): delegate `test21912.escapeParamInferred.__lambda2` closes over variable `i`
+fail_compilation/test21912.d(55): `i` declared here
---
*/
@nogc:
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22329.d b/gcc/testsuite/gdc.test/fail_compilation/test22329.d
index 237f9c76667..25c83f5142d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test22329.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22329.d
@@ -4,8 +4,9 @@
TEST_OUTPUT:
---
fail_compilation/imports/imp22329.d(3): Error: no property `values` for type `test22329.Foo`
+fail_compilation/test22329.d(13): struct `Foo` defined here
fail_compilation/imports/imp22329.d(3): Error: incompatible types for `(arg) + (1)`: `Foo` and `int`
-fail_compilation/test22329.d(20): Error: template instance `imp22329.func!(Foo)` error instantiating
+fail_compilation/test22329.d(21): Error: template instance `imp22329.func!(Foo)` error instantiating
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23112.d b/gcc/testsuite/gdc.test/fail_compilation/test23112.d
index 325d89bd6c2..9bbab80e48c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test23112.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test23112.d
@@ -2,7 +2,8 @@
TEST_OUTPUT:
---
fail_compilation/test23112.d(106): Error: function `test23112.bar` is `@nogc` yet allocates closure for `bar()` with the GC
-fail_compilation/test23112.d(108): `test23112.bar.f` closes over variable `a` at fail_compilation/test23112.d(106)
+fail_compilation/test23112.d(108): function `test23112.bar.f` closes over variable `a`
+fail_compilation/test23112.d(106): `a` declared here
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24015.d b/gcc/testsuite/gdc.test/fail_compilation/test24015.d
new file mode 100644
index 00000000000..c9bc42e055e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24015.d
@@ -0,0 +1,20 @@
+/* REQUIRED_ARGS: -preview=dip1000
+ * TEST_OUTPUT:
+---
+fail_compilation/test24015.d(19): Error: scope variable `v` assigned to non-scope parameter `...` calling `jer`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=24105
+
+@safe:
+
+extern (C) void ben(int i, scope ...);
+
+extern (C) void jer(int i, ...);
+
+void bar(scope const char* v)
+{
+ ben(3, v);
+ jer(3, v);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24036.d b/gcc/testsuite/gdc.test/fail_compilation/test24036.d
new file mode 100644
index 00000000000..da529f90ee9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24036.d
@@ -0,0 +1,21 @@
+/*
+https://issues.dlang.org/show_bug.cgi?id=24036
+Issue 24036 - assert message in CTFE becomes `['m', 'e', 's', 's', 'a', 'g', 'e'][0..7]` if produced using std.format.format
+
+TEST_OUTPUT:
+---
+fail_compilation/test24036.d(19): Error: message
+fail_compilation/test24036.d(21): called from here: `(*function () pure nothrow @safe => 42)()`
+---
+*/
+
+auto format()
+{
+ return ['m', 'e', 's', 's', 'a', 'g', 'e'][0 .. 7];
+}
+
+immutable ctfeThing = ()
+{
+ assert(0, format());
+ return 42;
+}();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24065.d b/gcc/testsuite/gdc.test/fail_compilation/test24065.d
new file mode 100644
index 00000000000..9e4ebbf4d16
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24065.d
@@ -0,0 +1,18 @@
+// https://issues.dlang.org/show_bug.cgi?id=24065
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test24065.d(12): Error: string expected as argument of __traits `getTargetInfo` instead of `int`
+fail_compilation/test24065.d(15): Error: string expected as argument of __traits `getTargetInfo` instead of `foo`
+fail_compilation/test24065.d(18): Error: string expected as argument of __traits `getTargetInfo` instead of `e`
+---
+*/
+
+auto s1 = __traits(getTargetInfo, int);
+
+void foo() {}
+auto s2 = __traits(getTargetInfo, foo);
+
+enum e;
+auto s3 = __traits(getTargetInfo, e);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24084.d b/gcc/testsuite/gdc.test/fail_compilation/test24084.d
new file mode 100644
index 00000000000..51de15ea21a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24084.d
@@ -0,0 +1,28 @@
+/* REQUIRED_ARGS: -nothrow
+ * TEST_OUTPUT:
+---
+fail_compilation/test24084.d(110): Error: cannot use `throw` statements with -nothrow
+fail_compilation/test24084.d(112): Error: cannot use try-catch statements with -nothrow
+---
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=24084
+
+#line 100
+
+struct S
+{
+ int x;
+ ~this() { }
+}
+
+void xyzzy()
+{
+ S s;
+ throw new Exception("xx");
+
+ try
+ {
+ int y;
+ } catch (Exception) { }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test24110.d b/gcc/testsuite/gdc.test/fail_compilation/test24110.d
new file mode 100644
index 00000000000..acf7788c6e0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test24110.d
@@ -0,0 +1,12 @@
+// https://issues.dlang.org/show_bug.cgi?id=24110
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test24110.d(12): Error: static assert: `__traits(compiles, __error)` is false
+---
+*/
+
+struct S { int x; }
+alias T = shared S;
+static assert(__traits(compiles, (T[] a, T[] b) => a < b));
diff --git a/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d b/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d
index 9203685fdc8..8d6c736e5af 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d
@@ -48,9 +48,9 @@ void testSameAttr() @system
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(217): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(203)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(203): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(208)`: `int(int delegate(string) dg)`
+fail_compilation/testOpApply.d(208): `int(int delegate(string) dg)`
fail_compilation/testOpApply.d(217): Error: cannot uniquely infer `foreach` argument types
---
+/
@@ -79,9 +79,9 @@ void testDifferentTypes()
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(317): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(303)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(303): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(308)`: `int(int delegate(long) dg)`
+fail_compilation/testOpApply.d(308): `int(int delegate(long) dg)`
fail_compilation/testOpApply.d(317): Error: cannot uniquely infer `foreach` argument types
---
+/
@@ -112,9 +112,9 @@ See https://issues.dlang.org/show_bug.cgi?id=21683
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(420): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(404)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(404): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(410)`: `int(int delegate(ref int) dg)`
+fail_compilation/testOpApply.d(410): `int(int delegate(ref int) dg)`
fail_compilation/testOpApply.d(420): Error: cannot uniquely infer `foreach` argument types
---
+/
@@ -146,9 +146,9 @@ void testDifferentQualifiers()
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(504): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(404)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(404): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(410)`: `int(int delegate(ref int) dg)`
+fail_compilation/testOpApply.d(410): `int(int delegate(ref int) dg)`
fail_compilation/testOpApply.d(504): Error: cannot uniquely infer `foreach` argument types
---
+/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/testsemi.d b/gcc/testsuite/gdc.test/fail_compilation/testsemi.d
index fc9bc651070..77601a5e446 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/testsemi.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/testsemi.d
@@ -8,7 +8,8 @@ fail_compilation/testsemi.d(117): Error: found `int` when expecting `;` followin
fail_compilation/testsemi.d(117): Error: no identifier for declarator `x`
fail_compilation/testsemi.d(123): Error: found `int` when expecting `;` following mixin
fail_compilation/testsemi.d(129): Error: found `int` when expecting `;` following `import` Expression
-fail_compilation/testsemi.d(131): Error: `}` expected following members in `class` declaration at fail_compilation/testsemi.d(112)
+fail_compilation/testsemi.d(131): Error: `}` expected following members in `class` declaration
+fail_compilation/testsemi.d(112): class `C` starts here
---
*/
diff --git a/gcc/testsuite/gdc.test/runnable/staticaa.d b/gcc/testsuite/gdc.test/runnable/staticaa.d
new file mode 100644
index 00000000000..38678c92901
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/staticaa.d
@@ -0,0 +1,126 @@
+// https://issues.dlang.org/show_bug.cgi?id=23103
+// Issue 23103 - static initialization of associative arrays is not implemented
+
+nothrow @safe:
+
+/////////////////////////////////////////////
+
+int[int] globalAA = [1: 10, 2: 20];
+
+void testSimple()
+{
+ assert(globalAA[1] == 10);
+ assert(globalAA[2] == 20);
+ assert(!(30 in globalAA));
+
+ foreach (i; 0 .. 1000)
+ {
+ globalAA[i] = i * 10;
+ assert(globalAA[i] == i * 10);
+ }
+}
+
+/////////////////////////////////////////////
+
+struct Composit
+{
+ string[string][] aa;
+}
+
+auto getAA() { return ["a": "A"]; }
+
+immutable Composit compositAA = Composit([getAA(), ["b": "B"]]);
+
+void testComposit() pure
+{
+ assert(compositAA.aa[0]["a"] == "A");
+ assert(compositAA.aa[1]["b"] == "B");
+}
+
+/////////////////////////////////////////////
+
+struct Destructing
+{
+ int v;
+ static int destructorsCalled = 0;
+
+ ~this() nothrow
+ {
+ // FIXME: the lowering to newaa calls the destructor at CTFE, so we can't modify globals in it
+ if (!__ctfe)
+ destructorsCalled++;
+ }
+}
+
+struct Key
+{
+ int v;
+ bool opEquals(ref const Key o) const { return v == o.v; }
+ size_t toHash() const { return v; }
+}
+
+Destructing[Key] dAa = [Key(1): Destructing(10), Key(2): Destructing(20)];
+
+void testDestructor()
+{
+ assert(dAa[Key(1)].v == 10);
+ assert(dAa[Key(2)].v == 20);
+ assert(Destructing.destructorsCalled == 0);
+ dAa[Key(1)] = Destructing(100);
+ assert(dAa[Key(1)].v == 100);
+ assert(Destructing.destructorsCalled == 1);
+}
+
+/////////////////////////////////////////////
+
+enum A
+{
+ x, y, z
+}
+
+struct S
+{
+ string[A] t = [A.x : "A.x", A.y : "A.y"];
+}
+
+void testStructInit()
+{
+ S s;
+ assert(s.t[A.x] == "A.x");
+ assert(s.t[A.y] == "A.y");
+}
+
+/////////////////////////////////////////////
+
+class C
+{
+ string[int] t = [0 : "zero"];
+}
+
+void testClassInit()
+{
+ C c = new C();
+ assert(c.t[0] == "zero");
+}
+
+/////////////////////////////////////////////
+
+immutable(string)[immutable(int)] immutableAA = [1: "one", 2: "two"];
+
+void testImmutable()
+{
+ assert(immutableAA[1] == "one");
+ assert(immutableAA[2] == "two");
+}
+
+/////////////////////////////////////////////
+
+void main()
+{
+ testSimple();
+ testComposit();
+ testDestructor();
+ testStructInit();
+ testClassInit();
+ testImmutable();
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test24078.d b/gcc/testsuite/gdc.test/runnable/test24078.d
new file mode 100644
index 00000000000..99d74400cf8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test24078.d
@@ -0,0 +1,6 @@
+//https://issues.dlang.org/show_bug.cgi?id=24078
+
+void main()
+{
+ assert(["c"] ~ "a" ~ "b" == ["c", "a", "b"]);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test24139.d b/gcc/testsuite/gdc.test/runnable/test24139.d
new file mode 100644
index 00000000000..af6215dd2ac
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test24139.d
@@ -0,0 +1,25 @@
+// https://issues.dlang.org/show_bug.cgi?id=24139
+
+struct S1
+{
+ int x;
+ extern(C++) ~this() { assert(&this == s1); }
+}
+
+extern(C++) struct S2
+{
+ int x;
+ ~this() { assert(&this == s2); }
+}
+
+S1* s1;
+S2* s2;
+
+void main()
+{
+ s1 = new S1;
+ s2 = new S2;
+
+ typeid(S1).destroy(s1);
+ typeid(S2).destroy(s2);
+}
diff --git a/gcc/testsuite/lib/gdc-utils.exp b/gcc/testsuite/lib/gdc-utils.exp
index 25574cb8ec7..cbd25e9b9e3 100644
--- a/gcc/testsuite/lib/gdc-utils.exp
+++ b/gcc/testsuite/lib/gdc-utils.exp
@@ -163,6 +163,9 @@ proc gdc-convert-args { args } {
upvar 2 compilable_do_what compilable_do_what
set compilable_do_what "compile"
+ } elseif [string match "-nothrow" $arg] {
+ lappend out "-fno-exceptions"
+
} elseif [string match "-vgc" $arg] {
lappend out "-ftransition=nogc"
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index dc267787cab..d5dfe0d0edd 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-4574d1728d1f7e52ff40e6733b8c39889d128349
+f9efc98fd7954741333f72c6a50af273f3863a1a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 832a0524ab3..0aefbf22ca6 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -186,9 +186,9 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/internal/gc/impl/manual/gc.d core/internal/gc/impl/proto/gc.d \
core/internal/gc/os.d core/internal/gc/pooltable.d \
core/internal/gc/proxy.d core/internal/hash.d core/internal/lifetime.d \
- core/internal/moving.d core/internal/parseoptions.d \
- core/internal/postblit.d core/internal/qsort.d \
- core/internal/spinlock.d core/internal/string.d \
+ core/internal/moving.d core/internal/newaa.d \
+ core/internal/parseoptions.d core/internal/postblit.d \
+ core/internal/qsort.d core/internal/spinlock.d core/internal/string.d \
core/internal/switch_.d core/internal/traits.d core/internal/utf.d \
core/internal/util/array.d core/internal/util/math.d core/lifetime.d \
core/math.d core/memory.d core/runtime.d core/simd.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 61a2a770888..39066dd33cc 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -213,21 +213,21 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
core/internal/gc/impl/proto/gc.lo core/internal/gc/os.lo \
core/internal/gc/pooltable.lo core/internal/gc/proxy.lo \
core/internal/hash.lo core/internal/lifetime.lo \
- core/internal/moving.lo core/internal/parseoptions.lo \
- core/internal/postblit.lo core/internal/qsort.lo \
- core/internal/spinlock.lo core/internal/string.lo \
- core/internal/switch_.lo core/internal/traits.lo \
- core/internal/utf.lo core/internal/util/array.lo \
- core/internal/util/math.lo core/lifetime.lo core/math.lo \
- core/memory.lo core/runtime.lo core/simd.lo \
- core/stdc/assert_.lo core/stdc/complex.lo core/stdc/config.lo \
- core/stdc/ctype.lo core/stdc/errno.lo core/stdc/fenv.lo \
- core/stdc/float_.lo core/stdc/inttypes.lo core/stdc/limits.lo \
- core/stdc/locale.lo core/stdc/math.lo core/stdc/signal.lo \
- core/stdc/stdarg.lo core/stdc/stddef.lo core/stdc/stdint.lo \
- core/stdc/stdio.lo core/stdc/stdlib.lo core/stdc/string.lo \
- core/stdc/tgmath.lo core/stdc/time.lo core/stdc/wchar_.lo \
- core/stdc/wctype.lo core/sync/barrier.lo \
+ core/internal/moving.lo core/internal/newaa.lo \
+ core/internal/parseoptions.lo core/internal/postblit.lo \
+ core/internal/qsort.lo core/internal/spinlock.lo \
+ core/internal/string.lo core/internal/switch_.lo \
+ core/internal/traits.lo core/internal/utf.lo \
+ core/internal/util/array.lo core/internal/util/math.lo \
+ core/lifetime.lo core/math.lo core/memory.lo core/runtime.lo \
+ core/simd.lo core/stdc/assert_.lo core/stdc/complex.lo \
+ core/stdc/config.lo core/stdc/ctype.lo core/stdc/errno.lo \
+ core/stdc/fenv.lo core/stdc/float_.lo core/stdc/inttypes.lo \
+ core/stdc/limits.lo core/stdc/locale.lo core/stdc/math.lo \
+ core/stdc/signal.lo core/stdc/stdarg.lo core/stdc/stddef.lo \
+ core/stdc/stdint.lo core/stdc/stdio.lo core/stdc/stdlib.lo \
+ core/stdc/string.lo core/stdc/tgmath.lo core/stdc/time.lo \
+ core/stdc/wchar_.lo core/stdc/wctype.lo core/sync/barrier.lo \
core/sync/condition.lo core/sync/config.lo core/sync/event.lo \
core/sync/exception.lo core/sync/mutex.lo core/sync/package.lo \
core/sync/rwmutex.lo core/sync/semaphore.lo \
@@ -859,9 +859,9 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/internal/gc/impl/manual/gc.d core/internal/gc/impl/proto/gc.d \
core/internal/gc/os.d core/internal/gc/pooltable.d \
core/internal/gc/proxy.d core/internal/hash.d core/internal/lifetime.d \
- core/internal/moving.d core/internal/parseoptions.d \
- core/internal/postblit.d core/internal/qsort.d \
- core/internal/spinlock.d core/internal/string.d \
+ core/internal/moving.d core/internal/newaa.d \
+ core/internal/parseoptions.d core/internal/postblit.d \
+ core/internal/qsort.d core/internal/spinlock.d core/internal/string.d \
core/internal/switch_.d core/internal/traits.d core/internal/utf.d \
core/internal/util/array.d core/internal/util/math.d core/lifetime.d \
core/math.d core/memory.d core/runtime.d core/simd.d \
@@ -1268,6 +1268,7 @@ core/internal/gc/proxy.lo: core/internal/gc/$(am__dirstamp)
core/internal/hash.lo: core/internal/$(am__dirstamp)
core/internal/lifetime.lo: core/internal/$(am__dirstamp)
core/internal/moving.lo: core/internal/$(am__dirstamp)
+core/internal/newaa.lo: core/internal/$(am__dirstamp)
core/internal/parseoptions.lo: core/internal/$(am__dirstamp)
core/internal/postblit.lo: core/internal/$(am__dirstamp)
core/internal/qsort.lo: core/internal/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/internal/newaa.d b/libphobos/libdruntime/core/internal/newaa.d
new file mode 100644
index 00000000000..314f2554103
--- /dev/null
+++ b/libphobos/libdruntime/core/internal/newaa.d
@@ -0,0 +1,144 @@
+/**
+ Turn an Associative Array into a binary compatible struct for static initialization.
+
+ This does not implement all the pieces of
+ the associative array type in druntime, just enough to create an AA from an
+ existing range of key/value pairs.
+
+ Copyright: Copyright Digital Mars 2000 - 2015, Steven Schveighoffer 2022.
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: Martin Nowak, Steven Schveighoffer
+*/
+module core.internal.newaa;
+
+import core.memory;
+
+// grow threshold
+private enum GROW_NUM = 4;
+private enum GROW_DEN = 5;
+// shrink threshold
+private enum SHRINK_NUM = 1;
+private enum SHRINK_DEN = 8;
+// grow factor
+private enum GROW_FAC = 4;
+// growing the AA doubles it's size, so the shrink threshold must be
+// smaller than half the grow threshold to have a hysteresis
+static assert(GROW_FAC * SHRINK_NUM * GROW_DEN < GROW_NUM * SHRINK_DEN);
+// initial load factor (for literals), mean of both thresholds
+private enum INIT_NUM = (GROW_DEN * SHRINK_NUM + GROW_NUM * SHRINK_DEN) / 2;
+private enum INIT_DEN = SHRINK_DEN * GROW_DEN;
+
+private enum INIT_NUM_BUCKETS = 8;
+// magic hash constants to distinguish empty, deleted, and filled buckets
+private enum HASH_EMPTY = 0;
+private enum HASH_FILLED_MARK = size_t(1) << 8 * size_t.sizeof - 1;
+
+private struct Bucket
+{
+ size_t hash;
+ void *entry;
+}
+
+struct Impl
+{
+ Bucket[] buckets;
+ uint used;
+ uint deleted;
+ TypeInfo_Struct entryTI;
+ uint firstUsed;
+ immutable uint keysz;
+ immutable uint valsz;
+ immutable uint valoff;
+ Flags flags;
+
+ enum Flags : ubyte
+ {
+ none = 0x0,
+ keyHasPostblit = 0x1,
+ hasPointers = 0x2,
+ }
+}
+
+private struct AAShell
+{
+ Impl *impl;
+}
+
+private size_t mix(size_t h) @safe pure nothrow @nogc
+{
+ // final mix function of MurmurHash2
+ enum m = 0x5bd1e995;
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+ return h;
+}
+
+struct Entry(K, V)
+{
+ /*const*/ K key; // this really should be const, but legacy issues.
+ V value;
+}
+
+
+// create a binary-compatible AA structure that can be used directly as an
+// associative array.
+AAShell makeAA(K, V)(V[K] src)
+{
+ immutable srclen = src.length;
+ assert(srclen <= uint.max);
+ alias E = Entry!(K, V);
+ if (srclen == 0)
+ return AAShell.init;
+ // first, determine the size that would be used if we grew the bucket list
+ // one element at a time using the standard AA algorithm.
+ size_t dim = INIT_NUM_BUCKETS;
+ while (srclen * GROW_DEN > dim * GROW_NUM)
+ dim = dim * GROW_FAC;
+
+ Bucket[] buckets;
+ // Allocate and fill the buckets
+ if (__ctfe)
+ buckets = new Bucket[dim];
+ else
+ assert(0);
+
+ assert(buckets.length >= dim);
+
+ immutable mask = dim - 1;
+ assert((dim & mask) == 0); // must be a power of 2
+
+ Bucket* findSlotInsert(immutable size_t hash)
+ {
+ for (size_t i = hash & mask, j = 1;; ++j)
+ {
+ if (buckets[i].hash == HASH_EMPTY)
+ return &buckets[i];
+ i = (i + j) & mask;
+ }
+ }
+
+ uint firstUsed = cast(uint) buckets.length;
+ foreach (k, v; src)
+ {
+ immutable h = hashOf(k).mix | HASH_FILLED_MARK;
+ auto location = findSlotInsert(h);
+ immutable nfu = cast(uint) (location - &buckets[0]);
+ if (nfu < firstUsed)
+ firstUsed = nfu;
+ *location = Bucket(h, new E(k, v));
+ }
+
+ enum flags = () {
+ import core.internal.traits;
+ Impl.Flags flags;
+ static if (__traits(hasPostblit, K))
+ flags |= flags.keyHasPostblit;
+ static if (hasIndirections!E)
+ flags |= flags.hasPointers;
+ return flags;
+ } ();
+ // return the new implementation
+ return AAShell(new Impl(buckets, cast(uint)srclen, 0, typeid(E), firstUsed,
+ K.sizeof, V.sizeof, E.value.offsetof, flags));
+}
diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d
index 2666c952992..76b32b44de1 100644
--- a/libphobos/libdruntime/core/stdc/math.d
+++ b/libphobos/libdruntime/core/stdc/math.d
@@ -4129,7 +4129,18 @@ else version (CRuntime_UClibc)
///
pure float modff(float value, float* iptr);
///
- extern(D) pure real modfl(real value, real *iptr) { return modf(cast(double) value, cast(double*) iptr); }
+ extern(D) pure real modfl(real value, real *iptr)
+ {
+ static if (double.sizeof == real.sizeof)
+ return modf(cast(double) value, cast(double*) iptr);
+ else
+ {
+ double i;
+ double r = modf(cast(double) value, &i);
+ *iptr = i;
+ return r;
+ }
+ }
///
double scalbn(double x, int n);
diff --git a/libphobos/libdruntime/core/stdcpp/string.d b/libphobos/libdruntime/core/stdcpp/string.d
index defbd8330eb..722b82fe418 100644
--- a/libphobos/libdruntime/core/stdcpp/string.d
+++ b/libphobos/libdruntime/core/stdcpp/string.d
@@ -155,7 +155,7 @@ extern(D):
///
alias opDollar = length;
///
- bool empty() const nothrow @safe { return size() == 0; }
+ bool empty() const nothrow @trusted { return size() == 0; }
///
size_t[2] opSlice(size_t dim : 0)(size_t start, size_t end) const pure nothrow @safe @nogc { return [start, end]; }
@@ -1918,7 +1918,7 @@ extern(D):
///
size_type capacity() const nothrow { return (__is_long() ? __get_long_cap() : __min_cap) - 1; }
///
- inout(T)* data() inout @safe { return __get_pointer(); }
+ inout(T)* data() inout @trusted { return __get_pointer(); }
///
inout(T)[] as_array() scope return inout nothrow @trusted { return __get_pointer()[0 .. size()]; }
///
@@ -2355,7 +2355,7 @@ extern(D):
}
}
void __set_long_size(size_type __s) nothrow { __r_.first().__l.__size_ = __s; }
- size_type __get_long_size() const nothrow { return __r_.first().__l.__size_; }
+ size_type __get_long_size() const nothrow @trusted { return __r_.first().__l.__size_; }
void __set_size(size_type __s) nothrow { if (__is_long()) __set_long_size(__s); else __set_short_size(__s); }
void __set_long_cap(size_type __s) nothrow { __r_.first().__l.__cap_ = __long_mask | __s; }
diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d
index 0a58034087d..df66b27f723 100644
--- a/libphobos/libdruntime/core/sys/posix/fcntl.d
+++ b/libphobos/libdruntime/core/sys/posix/fcntl.d
@@ -135,6 +135,27 @@ version (linux)
enum F_SETLK = 6;
enum F_SETLKW = 7;
}
+ else version (MIPS_N64)
+ {
+ enum F_GETLK = 14;
+ enum F_SETLK = 6;
+ enum F_SETLKW = 7;
+ }
+ else version (MIPS_Any)
+ {
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ enum F_GETLK = 33;
+ enum F_SETLK = 34;
+ enum F_SETLKW = 35;
+ }
+ else
+ {
+ enum F_GETLK = 14;
+ enum F_SETLK = 6;
+ enum F_SETLKW = 7;
+ }
+ }
else
static if ( __USE_FILE_OFFSET64 )
{
diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d
index f722bc4df62..a2e229f6018 100644
--- a/libphobos/libdruntime/core/sys/posix/signal.d
+++ b/libphobos/libdruntime/core/sys/posix/signal.d
@@ -2390,11 +2390,23 @@ version (CRuntime_Glibc)
//ucontext_t (defined in core.sys.posix.ucontext)
//mcontext_t (defined in core.sys.posix.ucontext)
- struct stack_t
+ version (MIPS_Any)
{
- void* ss_sp;
- int ss_flags;
- size_t ss_size;
+ struct stack_t
+ {
+ void* ss_sp;
+ size_t ss_size;
+ int ss_flags;
+ }
+ }
+ else
+ {
+ struct stack_t
+ {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ }
}
struct sigstack
@@ -2760,7 +2772,7 @@ else version (CRuntime_UClibc)
enum MINSIGSTKSZ = 2048;
enum SIGSTKSZ = 8192;
- version (MIPS32)
+ version (MIPS_Any)
{
struct stack_t
{
diff --git a/libphobos/libdruntime/core/sys/posix/sys/resource.d b/libphobos/libdruntime/core/sys/posix/sys/resource.d
index b997f112e4d..3a9a1876393 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/resource.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/resource.d
@@ -22,6 +22,9 @@ else version (TVOS)
else version (WatchOS)
version = Darwin;
+version (MIPS32) version = MIPS_Any;
+version (MIPS64) version = MIPS_Any;
+
nothrow @nogc extern(C):
//
@@ -120,15 +123,31 @@ version (linux)
c_long[16] __reserved;
}
- enum
+ version (MIPS_Any)
{
- RLIMIT_CORE = 4,
- RLIMIT_CPU = 0,
- RLIMIT_DATA = 2,
- RLIMIT_FSIZE = 1,
- RLIMIT_NOFILE = 7,
- RLIMIT_STACK = 3,
- RLIMIT_AS = 9,
+ enum
+ {
+ RLIMIT_CORE = 4,
+ RLIMIT_CPU = 0,
+ RLIMIT_DATA = 2,
+ RLIMIT_FSIZE = 1,
+ RLIMIT_NOFILE = 5,
+ RLIMIT_STACK = 3,
+ RLIMIT_AS = 6,
+ }
+ }
+ else
+ {
+ enum
+ {
+ RLIMIT_CORE = 4,
+ RLIMIT_CPU = 0,
+ RLIMIT_DATA = 2,
+ RLIMIT_FSIZE = 1,
+ RLIMIT_NOFILE = 7,
+ RLIMIT_STACK = 3,
+ RLIMIT_AS = 9,
+ }
}
}
else version (Darwin)
diff --git a/libphobos/libdruntime/core/sys/windows/sql.d b/libphobos/libdruntime/core/sys/windows/sql.d
index 58c6d42bd04..9054ce589e8 100644
--- a/libphobos/libdruntime/core/sys/windows/sql.d
+++ b/libphobos/libdruntime/core/sys/windows/sql.d
@@ -1,4 +1,7 @@
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sql` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
@@ -6,6 +9,7 @@
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sql.d)
*/
+
module core.sys.windows.sql;
version (Windows):
diff --git a/libphobos/libdruntime/core/sys/windows/sqlext.d b/libphobos/libdruntime/core/sys/windows/sqlext.d
index 8702cda3359..b871fbbbb84 100644
--- a/libphobos/libdruntime/core/sys/windows/sqlext.d
+++ b/libphobos/libdruntime/core/sys/windows/sqlext.d
@@ -1,4 +1,7 @@
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sqlext` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
@@ -6,6 +9,7 @@
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sqlext.d)
*/
+
module core.sys.windows.sqlext;
version (Windows):
diff --git a/libphobos/libdruntime/core/sys/windows/sqltypes.d b/libphobos/libdruntime/core/sys/windows/sqltypes.d
index e86834faa6d..04fac6bac6a 100644
--- a/libphobos/libdruntime/core/sys/windows/sqltypes.d
+++ b/libphobos/libdruntime/core/sys/windows/sqltypes.d
@@ -1,4 +1,7 @@
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sqltypes` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
@@ -6,6 +9,7 @@
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sqltypes.d)
*/
+
module core.sys.windows.sqltypes;
version (Windows):
diff --git a/libphobos/libdruntime/core/sys/windows/sqlucode.d b/libphobos/libdruntime/core/sys/windows/sqlucode.d
index d4f03f62d94..e7ae1d276be 100644
--- a/libphobos/libdruntime/core/sys/windows/sqlucode.d
+++ b/libphobos/libdruntime/core/sys/windows/sqlucode.d
@@ -1,4 +1,7 @@
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sqlucode` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
@@ -6,6 +9,7 @@
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sqlucode.d)
*/
+
module core.sys.windows.sqlucode;
version (Windows):
diff --git a/libphobos/libdruntime/core/sys/windows/winnt.d b/libphobos/libdruntime/core/sys/windows/winnt.d
index 3bd9966e33e..ca4a903fb6a 100644
--- a/libphobos/libdruntime/core/sys/windows/winnt.d
+++ b/libphobos/libdruntime/core/sys/windows/winnt.d
@@ -1199,7 +1199,7 @@ enum size_t
PIMAGE_SECTION_HEADER IMAGE_FIRST_SECTION(PIMAGE_NT_HEADERS h) {
return cast(PIMAGE_SECTION_HEADER)
- (&h.OptionalHeader + h.FileHeader.SizeOfOptionalHeader);
+ (cast(ubyte*) &h.OptionalHeader + h.FileHeader.SizeOfOptionalHeader);
}
// ImageDirectoryEntryToDataEx()
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index f3af2097b39..294d34dbe35 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -2903,6 +2903,14 @@ void* aaLiteral(Key, Value)(Key[] keys, Value[] values) @trusted pure
return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);
}
+// Lower an Associative Array to a newaa struct for static initialization.
+auto _aaAsStruct(K, V)(V[K] aa) @safe
+{
+ import core.internal.newaa : makeAA;
+ assert(__ctfe);
+ return makeAA!(K, V)(aa);
+}
+
alias AssociativeArray(Key, Value) = Value[Key];
/***********************************
diff --git a/libphobos/libdruntime/rt/aaA.d b/libphobos/libdruntime/rt/aaA.d
index f264b014789..4014862b4e4 100644
--- a/libphobos/libdruntime/rt/aaA.d
+++ b/libphobos/libdruntime/rt/aaA.d
@@ -974,3 +974,22 @@ unittest
GC.runFinalizers((cast(char*)(&entryDtor))[0 .. 1]);
assert(T.dtor == 6 && T.postblit == 2);
}
+
+// Ensure the newaa struct layout (used for static initialization) is in sync
+unittest
+{
+ import newaa = core.internal.newaa;
+ static assert(newaa.Impl.sizeof == Impl.sizeof);
+ // ensure compatible types and offsets
+ static foreach (i; 0 .. Impl.tupleof.length)
+ {
+ // for bucket array and Flags, we "compatible" types, not exactly the same types.
+ static if (__traits(identifier, Impl.tupleof[i]) == "buckets"
+ || __traits(identifier, Impl.tupleof[i]) == "flags")
+ static assert(Impl.tupleof[i].sizeof == newaa.Impl.tupleof[i].sizeof);
+ else
+ static assert(is(typeof(Impl.tupleof[i]) == typeof(newaa.Impl.tupleof[i])));
+
+ static assert(Impl.tupleof[i].offsetof == newaa.Impl.tupleof[i].offsetof);
+ }
+}
diff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d
index b5c868f70bc..9bc10558981 100644
--- a/libphobos/libdruntime/rt/minfo.d
+++ b/libphobos/libdruntime/rt/minfo.d
@@ -267,10 +267,16 @@ struct ModuleGroup
edge[nEdges++] = *impidx;
}
}
- // trim space to what is needed.
- edges[i] = nEdges > 0
- ? (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges]
- : null;
+ if (nEdges > 0)
+ {
+ // trim space to what is needed
+ edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges];
+ }
+ else
+ {
+ edges[i] = null;
+ .free(edge);
+ }
}
}
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 0424d7b0cfa..455825b8781 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-d7e79f024606f18e989ae8b5fe298f9d07c7dced
+a3f22129dd2a134338ca02b79ff0de242d7f016e
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/int128.d b/libphobos/src/std/int128.d
index b20fa1fdddc..92895445aed 100644
--- a/libphobos/src/std/int128.d
+++ b/libphobos/src/std/int128.d
@@ -147,7 +147,7 @@ public struct Int128
/** Support casting to a bool
* Params: T = bool
- * Returns: boolean result
+ * Returns: true if value is not zero
*/
bool opCast(T : bool)() const
{
@@ -155,6 +155,50 @@ public struct Int128
}
} // @safe pure nothrow @nogc
+ /** Support casting to an integral type
+ * Params: T = integral type
+ * Returns: low bits of value reinterpreted as T
+ */
+ T opCast(T : long)() const
+ if (is(byte : T))
+ {
+ return cast(T) this.data.lo;
+ }
+
+ ///
+ @safe unittest
+ {
+ const Int128 a = Int128(0xffff_ffff_ffff_ffffL, 0x0123_4567_89ab_cdefL);
+ assert(cast(long) a == 0x0123_4567_89ab_cdefL);
+ assert(cast(int) a == 0x89ab_cdef);
+ assert(cast(byte) a == cast(byte) 0xef);
+ }
+
+ /** Support casting to floating point type
+ * Params: T = floating point type
+ * Returns: value cast to floating point with environment-dependent
+ * rounding if the value is not exactly representable
+ */
+ T opCast(T : real)() const
+ {
+ import core.math : ldexp;
+ if (cast(long) this.data.hi >= 0)
+ return ldexp(cast(T) this.data.hi, 64) + this.data.lo;
+ else
+ {
+ const absData = neg(this.data);
+ return -ldexp(cast(T) absData.hi, 64) - absData.lo;
+ }
+ }
+
+ ///
+ @safe unittest
+ {
+ const Int128 a = Int128(-1L << 60);
+ assert(cast(double) a == -(2.0 ^^ 60));
+ assert(cast(double) (a * a) == 2.0 ^^ 120);
+ }
+
/** Support binary arithmetic operators + - * / % & | ^ << >> >>>
* Params:
* op = one of the arithmetic binary operators
diff --git a/libphobos/src/std/string.d b/libphobos/src/std/string.d
index b1063ee0040..ca14c23747e 100644
--- a/libphobos/src/std/string.d
+++ b/libphobos/src/std/string.d
@@ -3815,6 +3815,7 @@ unittest
assert(chomp(" hello world \n\n" ~ [lineSep]) == " hello world \n\n");
assert(chomp(" hello world \n\n" ~ [paraSep]) == " hello world \n\n");
assert(chomp(" hello world \n\n" ~ [ nelSep]) == " hello world \n\n");
+ assert(chomp(" hello world ") == " hello world ");
assert(chomp(" hello world") == " hello world");
assert(chomp("") == "");
diff --git a/libphobos/testsuite/libphobos.hash/test_hash.d b/libphobos/testsuite/libphobos.hash/test_hash.d
index a6d7e5a5788..0ad2443c826 100644
--- a/libphobos/testsuite/libphobos.hash/test_hash.d
+++ b/libphobos/testsuite/libphobos.hash/test_hash.d
@@ -290,14 +290,14 @@ void issue22076()
extern(C++) static class C0
{
int foo() { return 0; } // Need at least one function in vtable.
- S0 a; alias a this; // { dg-warning "is deprecated" }
+ S0 a; alias a this;
}
extern(C++) static class C1
{
S1 a;
inout(S1)* b() inout nothrow { return &a; }
- alias b this; // { dg-warning "is deprecated" }
+ alias b this;
}
cast(void) hashOf(S0.init);
diff --git a/libphobos/testsuite/libphobos.phobos/phobos.exp b/libphobos/testsuite/libphobos.phobos/phobos.exp
index 374ef491d3c..fdd80ab0f80 100644
--- a/libphobos/testsuite/libphobos.phobos/phobos.exp
+++ b/libphobos/testsuite/libphobos.phobos/phobos.exp
@@ -46,7 +46,7 @@ dg-init
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]"
dg-runtest $test "-static-libphobos" \
- "-fmain -fbuilding-libphobos-tests $version_flags"
+ "-Wno-deprecated -fmain -fbuilding-libphobos-tests $version_flags"
set libphobos_test_name ""
}
diff --git a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
index 6c67b0828a0..0ea42cbf253 100644
--- a/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
+++ b/libphobos/testsuite/libphobos.phobos_shared/phobos_shared.exp
@@ -46,7 +46,7 @@ dg-init
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]"
dg-runtest $test "-shared-libphobos" \
- "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags"
+ "-Wno-deprecated -fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags"
set libphobos_test_name ""
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-10-15 11:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-15 11:12 [gcc r14-4644] d: Merge upstream dmd, druntime f9efc98fd7, phobos a3f22129d Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).