]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Use read() to load contents of stdin into memory.
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 25 Aug 2020 09:23:24 +0000 (11:23 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sun, 30 Aug 2020 14:23:54 +0000 (16:23 +0200)
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/func.c (FuncDeclaration::semantic): Use module filename if
searchPath returns NULL.

(cherry picked from commit 7421802276e737c2da297599121480833db92de9)

gcc/d/d-lang.cc
gcc/d/dmd/func.c

index 6848c5e9a1cc7a279d2ecdd129d703fa3deae8a5..4f1bf4a6e6a603fdb4e67d67d206d70b2b800955 100644 (file)
@@ -1026,32 +1026,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 ("<stdin>");
-         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
        {
index 621405eef3e27bf55612d69380ad6cd89b62d819..8389c00608ccc54a9978e5a43c507554a8c1c607 100644 (file)
@@ -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);
         }
     }