From 7421802276e737c2da297599121480833db92de9 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Tue, 25 Aug 2020 11:23:24 +0200 Subject: [PATCH] d: Use read() to load contents of stdin into memory. This would be an improvement over reading one character at a time. An ICE was discovered when mixing reading from stdin with `-v', this has been fixed in upstream DMD and backported as well. Reviewed-on: https://github.com/dlang/dmd/pull/11620 gcc/d/ChangeLog: * d-lang.cc (d_parse_file): Use read() to load contents from stdin, allow the front-end to free the memory after parsing. * dmd/MERGE: Merge upstream dmd 2cc25c219. --- gcc/d/d-lang.cc | 43 +++++++++++++++++++++++++++---------------- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/func.c | 5 +++-- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 6183389007ad..c5254a02446d 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -906,32 +906,43 @@ d_parse_file (void) { if (strcmp (in_fnames[i], "-") == 0) { - /* Handling stdin, generate a unique name for the module. */ - obstack buffer; - gcc_obstack_init (&buffer); - int c; + /* Load the entire contents of stdin into memory. 8 kilobytes should + be a good enough initial size, but double on each iteration. + 16 bytes are added for the final '\n' and 15 bytes of padding. */ + ssize_t size = 8 * 1024; + uchar *buffer = XNEWVEC (uchar, size + 16); + ssize_t len = 0; + ssize_t count; + + while ((count = read (STDIN_FILENO, buffer + len, size - len)) > 0) + { + len += count; + if (len == size) + { + size *= 2; + buffer = XRESIZEVEC (uchar, buffer, size + 16); + } + } + if (count < 0) + { + error (Loc ("stdin", 0, 0), "%s", xstrerror (errno)); + free (buffer); + continue; + } + + /* Handling stdin, generate a unique name for the module. */ Module *m = Module::create (in_fnames[i], Identifier::generateId ("__stdin"), global.params.doDocComments, global.params.doHdrGeneration); modules.push (m); - /* Load the entire contents of stdin into memory. */ - while ((c = getc (stdin)) != EOF) - obstack_1grow (&buffer, c); - - if (!obstack_object_size (&buffer)) - obstack_1grow (&buffer, '\0'); - /* Overwrite the source file for the module, the one created by Module::create would have a forced a `.d' suffix. */ m->srcfile = File::create (""); - m->srcfile->len = obstack_object_size (&buffer); - m->srcfile->buffer = (unsigned char *) obstack_finish (&buffer); - - /* Tell the front-end not to free the buffer after parsing. */ - m->srcfile->ref = 1; + m->srcfile->len = len; + m->srcfile->buffer = buffer; } else { diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index d0e5f4422476..8445bfaf3433 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -1b5a53d01c465109ce47edf49ace6143b69b118b +2cc25c2191928f865e1b711f30b6a4268d6a0d9a 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/func.c b/gcc/d/dmd/func.c index b6849559bf6c..30ba8dd93be9 100644 --- a/gcc/d/dmd/func.c +++ b/gcc/d/dmd/func.c @@ -1212,8 +1212,9 @@ Ldone: if (type && mod) { printedMain = true; - const char *name = FileName::searchPath(global.path, mod->srcfile->toChars(), true); - message("entry %-10s\t%s", type, name); + const char *name = mod->srcfile->toChars(); + const char *path = FileName::searchPath(global.path, name, true); + message("entry %-10s\t%s", type, path ? path : name); } } -- 2.43.5