Hi gcc-patches mailing list,
Torbjörn Svensson via Sourceware Forge 
<[email protected]> has requested that the following 
forgejo pull request
be published on the mailing list.

Created on: 2026-07-27 06:22:31+00:00
Latest update: 2026-07-29 12:03:01+00:00
Changes: 1 changed files, 7 additions, 3 deletions
Head revision: azoff/gcc ref pr/gcc/cp/module.cc commit 
aa8c325659399a55734cce46b318b2417586df70
Base revision: gcc/gcc ref trunk commit 
5dfea15a44343841a5d3d18ee736eaeb4f48fb1d r17-2772-g5dfea15a443438
Merge base: 5dfea15a44343841a5d3d18ee736eaeb4f48fb1d
Full diff url: https://forge.sourceware.org/gcc/gcc/pulls/204.diff
Discussion:  https://forge.sourceware.org/gcc/gcc/pulls/204
Requested Reviewers:

Changes since v1:

- Removed all changes in v1.
- Added member `elf_out::begun`, of type bool, that will track when 
`elf_out::begin()` has executed.
- If `elf_out::begun` is true in `efl_out::end()`, then the file is written, 
otherwise the write is ignored and only cleanup is performed.

--

Regtested on x86_64-linux-gnu where the `#if 0` has been temporarily changed to 
`#if 1` on line 240 of gcc/cp/module.cc to simulate no mmap support.
With this change, I no longer see cc1plus crashing.
I've also confirmed, by only running the modules.exp tests for arm-none-eabi on 
Windows, and with the patch, the failures in PR124806 are fixed.

Ok for trunk, releases/gcc-16 and releases/gcc-15?

--

On systems without mmap support, cc1plus can crash when finishing module
output after earlier errors prevented elf_out::begin from running.  In
that case elf_out::end attempts to fill in the ELF header even though
hdr.buffer was never initialized.

gcc/cp/ChangeLog:

        PR c++/124806
        * module.cc (elf_out::begun): New data member
        (elf_out::begin): Set it after successful initialization.
        (elf_out::end): Do not finalize output that was never begun.

Signed-off-by: Torbjörn SVENSSON <[email protected]>

--


Changed files:
- M: gcc/cp/module.cc


Torbjörn SVENSSON (1):
  c++: ICE on on systems without mmap support [PR124806]

 gcc/cp/module.cc | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Range-diff against v1:
1:  cac4230528a0 ! 1:  aa8c32565939 c++: ICE on on systems without mmap support 
[PR124806]
    @@ Metadata
      ## Commit message ##
         c++: ICE on on systems without mmap support [PR124806]
     
    +    On systems without mmap support, cc1plus can crash when finishing 
module
    +    output after earlier errors prevented elf_out::begin from running.  In
    +    that case elf_out::end attempts to fill in the ELF header even though
    +    hdr.buffer was never initialized.
    +
         gcc/cp/ChangeLog:
     
                 PR c++/124806
    -            * module.cc (late_finish_module): Fix nullptr dereference.
    +            * module.cc (elf_out::begun): New data member.
    +            (elf_out::begin): Set it after successful initialization.
    +            (elf_out::end): Do not finalize output that was never begun.
     
         Signed-off-by: Torbjörn SVENSSON <[email protected]>
     
      ## gcc/cp/module.cc ##
    -@@ gcc/cp/module.cc: late_finish_module (cpp_reader *reader,  
module_processing_cookie *cookie,
    - 
    -   cookie->config.active_init = init_fn_non_empty;
    -   if (cookie->began)
    --    state->write_end (&cookie->out, reader, cookie->config, cookie->crc);
    --
    --  if (cookie->out.end () && cookie->cmi_name)
    -     {
    --      /* Some OS's do not replace NEWNAME if it already exists.
    --   This'll have a race condition in erroneous concurrent
    --   builds.  */
    --      unlink (cookie->cmi_name);
    --      if (rename (cookie->tmp_name, cookie->cmi_name))
    -+      state->write_end (&cookie->out, reader, cookie->config, 
cookie->crc);
    -+
    -+      if (cookie->out.end () && cookie->cmi_name)
    -   {
    --    dump () && dump ("Rename ('%s','%s') errno=%u",
    --                     cookie->tmp_name, cookie->cmi_name, errno);
    --    cookie->out.set_error (errno);
    -+    /* Some OS's do not replace NEWNAME if it already exists.
    -+       This'll have a race condition in erroneous concurrent
    -+       builds.  */
    -+    unlink (cookie->cmi_name);
    -+    if (rename (cookie->tmp_name, cookie->cmi_name))
    -+      {
    -+        dump () && dump ("Rename ('%s','%s') errno=%u",
    -+                         cookie->tmp_name, cookie->cmi_name, errno);
    -+        cookie->out.set_error (errno);
    -+      }
    -   }
    --    }
    +@@ gcc/cp/module.cc: class elf_out : public elf, public data::allocator {
    + private:
    +   ptr_int_hash_map identtab;      /* Map of IDENTIFIERS to strtab 
offsets. */
    +   unsigned pos;                   /* Write position in file.  */
    ++  bool begun;                     /* True if begin initialized output 
state.  */
    + #if MAPPED_WRITING
    +   unsigned offset;                /* Offset of the mapping.  */
    +   unsigned extent;                /* Length of mapping.  */
    +@@ gcc/cp/module.cc: private:
      
    --  if (cookie->out.get_error () && cookie->began)
    --    {
    --      error_at (state->loc, "failed to write compiled module: %s",
    --          cookie->out.get_error (state->filename));
    --      state->note_cmi_name ();
    -+  if (cookie->out.get_error ())
    -+    {
    -+      error_at (state->loc, "failed to write compiled module: %s",
    -+                cookie->out.get_error (state->filename));
    -+      state->note_cmi_name ();
    -+    }
    -     }
    + public:
    +   elf_out (int fd, int e)
    +-    :parent (fd, e), identtab (500), pos (0)
    ++    :parent (fd, e), identtab (500), pos (0), begun (false)
    +   {
    + #if MAPPED_WRITING
    +     offset = extent = 0;
    +@@ gcc/cp/module.cc: elf_out::begin ()
    +   memset (h, 0, sizeof (header));
    +   hdr.pos = hdr.size;
    +   write (hdr);
    +-  return !get_error ();
    ++  if (get_error ())
    ++    return false;
    ++  begun = true;
    ++  return true;
    + }
      
    -+
    -   if (!errorcount)
    + /* Finish writing the file.  Write out the string & section tables.
    +@@ gcc/cp/module.cc: elf_out::begin ()
    + bool
    + elf_out::end ()
    + {
    +-  if (fd >= 0)
    ++  if (fd >= 0 && begun)
          {
    -       auto *mapper = get_mapper (cpp_main_loc (reader), cpp_get_deps 
(reader));
    +       /* Write the string table.  */
    +       unsigned strnam = name (".strtab");
-- 
2.54.0

Reply via email to