https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120013

Nathaniel Shead <nshead at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nshead at gcc dot gnu.org
             Status|WAITING                     |NEW
           Keywords|                            |ice-on-valid-code
             Blocks|                            |103524

--- Comment #7 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
Confirmed.  All three test cases do indeed seem to be the same underlying cause
(I'll close the others as duplicates); here's a reduction:

  // array.hpp
  template <int, typename> struct tuple_element;
  template <typename> struct tuple;
  template <int __i, typename _Elements>
    tuple_element<__i, tuple<_Elements>> get();

  // a.cpp
  module;
  #include "array.hpp"
  template <int __i, typename _Types>
    struct tuple_element<__i, tuple<_Types>>;
  module m:a;
  template <typename T> void a(T t) { ::get(t); }

  // b.cpp
  module;
  #include "array.hpp"
  module m:b;
  template <typename T> void b(T t) { ::get(t); }

  // c.cpp
  export module m;
  import :a;
  import :b;

$ g++-15 -S -fmodules -Wno-global-module *.cpp
c.cpp:3:11: internal compiler error: Segmentation fault
    3 | import :b;
      |           ^
0x22a2ef6 internal_error(char const*, ...)
        ../../gcc-15/gcc/diagnostic-global-context.cc:517
0xfe2de3 crash_signal
        ../../gcc-15/gcc/toplev.cc:322
0x7fa720c6d32f ???
        ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0x78c87a install_entity
        ../../gcc-15/gcc/cp/module.cc:8109
0x78c87a decl_value
        ../../gcc-15/gcc/cp/module.cc:8657
0x8fa81f tree_node
        ../../gcc-15/gcc/cp/module.cc:10062
0x8ff363 module_state::read_cluster(unsigned int)
        ../../gcc-15/gcc/cp/module.cc:16673
0x8ffe0d module_state::load_section(unsigned int, binding_slot*)
        ../../gcc-15/gcc/cp/module.cc:20217
0x903cb3 module_state::read_language(bool)
        ../../gcc-15/gcc/cp/module.cc:20146
0x903e07 module_state::read_language(bool)
        ../../gcc-15/gcc/cp/module.cc:21206
0x903e07 direct_import
        ../../gcc-15/gcc/cp/module.cc:21208
0x981a3a cp_parser_translation_unit
        ../../gcc-15/gcc/cp/parser.cc:5434
0x981a3a c_parse_file()
        ../../gcc-15/gcc/cp/parser.cc:53961
0xa8a8d9 c_common_parse_file()
        ../../gcc-15/gcc/c-family/c-opts.cc:1379
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

The crash occurs in 'install_entity' here:

  tree not_tmpl = STRIP_TEMPLATE (decl);
  if (!DECL_LANG_SPECIFIC (not_tmpl)
      || !DECL_MODULE_ENTITY_P (not_tmpl))
    {
      retrofit_lang_decl (not_tmpl);
      DECL_MODULE_ENTITY_P (not_tmpl) = true;

      /* Insert into the entity hash (it cannot already be there).  */
      bool existed;
      unsigned &slot = entity_map->get_or_insert (DECL_UID (decl), &existed);
      gcc_checking_assert (!existed);
      slot = ident;
    }
  else if (state->is_partition ())
    {
      /* The decl is already in the entity map, but we see it again now from a
         partition: we want to overwrite if the original decl wasn't also from
         a (possibly different) partition.  Otherwise, for things like template
         instantiations, make_dependency might not realise that this is also
         provided from a partition and should be considered part of this module
         (and thus always emitted into the primary interface's CMI).  */
      unsigned *slot = entity_map->get (DECL_UID (decl));
!     module_state *imp = import_entity_module (*slot);  // segfault here, slot
is null
      if (!imp->is_partition ())
        *slot = ident;
    }

This seems to be because we get confused since 'DECL_MODULE_ENTITY_P' is only
set on the 'DECL_TEMPLATE_RESULT' of an entity, while here we're importing
first a TEMPLATE_DECL and then the inner TYPE_DECL from a separate partition:
the latter thinks we've already added it to the entity_map, when we actually
haven't (we've only added the TEMPLATE_DECL).

Also adding the DECL_TEMPLATE_RESULT to the entity map when we first see it
fixes this ICE, but doesn't seem like the correct solution (as two separate
decls will get the same ID), and I imagine could cause other issues down the
line.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103524
[Bug 103524] [meta-bug] modules issue

Reply via email to