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

            Bug ID: 118513
           Summary: ICE with modules and structured binding using
                    std::tuple*
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

--- gcc/testsuite/g++.dg/modules/decomp-3_a.H.jj        2025-01-16
13:43:36.492879734 +0100
+++ gcc/testsuite/g++.dg/modules/decomp-3_a.H   2025-01-16 13:43:11.314224231
+0100
@@ -0,0 +1,19 @@
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+namespace std {
+  template<typename T> struct tuple_size;
+  template<int, typename> struct tuple_element;
+}
+
+struct A {
+  int a, b;
+  template <int I> int &get () { if (I == 0) return a; else return b; }
+};
+
+template <> struct std::tuple_size <A> { static const int value = 2; };
+template <int I> struct std::tuple_element <I, A> { using type = int; };
+
+namespace {
+auto [x, y] = A { 42, 43 };
+}
--- gcc/testsuite/g++.dg/modules/decomp-3_b.C.jj        2025-01-16
13:43:41.782807354 +0100
+++ gcc/testsuite/g++.dg/modules/decomp-3_b.C   2025-01-16 13:41:49.256346946
+0100
@@ -0,0 +1,11 @@
+// { dg-do run }
+// { dg-additional-options "-fmodules-ts" }
+
+import "decomp-3_a.H";
+
+int
+main ()
+{
+  if (x != 42 || y != 43)
+    __builtin_abort ();
+}

testcase ICEs with
FAIL: g++.dg/modules/decomp-3_b.C -std=c++17 (internal compiler error: in
import_export_decl, at cp/decl2.cc:3442)
FAIL: g++.dg/modules/decomp-3_b.C -std=c++17 (test for excess errors)
FAIL: g++.dg/modules/decomp-3_b.C -std=c++2a (internal compiler error: in
import_export_decl, at cp/decl2.cc:3442)
FAIL: g++.dg/modules/decomp-3_b.C -std=c++2a (test for excess errors)
FAIL: g++.dg/modules/decomp-3_b.C -std=c++2b (internal compiler error: in
import_export_decl, at cp/decl2.cc:3442)
FAIL: g++.dg/modules/decomp-3_b.C -std=c++2b (test for excess errors)

If I use #include "decomp-3_a.H" instead of import "decomp-3_a.H"; then
the x and y VAR_DECLs, initially TREE_PUBLIC, first go through (in
cp_finish_decomp)
through layout_decl (v[i], 0);, then copy_linkage (v[i], decl); which among
other things clears TREE_PUBLIC and then
              cp_finish_decl (v[i], init, /*constexpr*/false,
                              /*asm*/NULL_TREE, LOOKUP_NORMAL);
which among other things calls
9291          make_rtl_for_nonlocal_decl (decl, init, asmspec);
and so var_finalized_p is since then true, so write_out_vars does nothing for
it.

Now, when reading the module header, the VAR_DECLs are streamed in with proper
!TREE_PUBLIC flag, but var_finalized_p is not true, and as the var doesn't have
DECL_INTERFACE_KNOWN, we ICE in import_export_decl.

I'm afraid I have no idea what should be done in the module case, whether the
vars need to be finalized somewhere during the streaming in (just namespace
scope structured bindings, something else?) or whether something should arrange
for DECL_INTERFACE_KNOWN to be set for those.

Reply via email to