https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127076
Bug ID: 127076
Summary: [modules] ICE (segfault) in synthesize_method while
trial-evaluating a consteval function returning a
class holding std::meta::info as a stored value inside
a std::vector<std::variant<...>> member, across module
partitions
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jasio.lpn at gmail dot com
Target Milestone: ---
The following minimal, self-contained reproducer (3 module partition
files) causes an internal compiler error when compiling the last file
in the chain.
=== info.cppm ===
export module TestICE:Info;
import std;
export namespace Test
{
struct AltA final { std::meta::info refl; };
struct AltB final { std::string s; };
struct Item final
{
std::variant<AltA, AltB> value{};
bool flag{};
};
class Info final
{
friend class Definition;
friend class Builder;
std::vector<Item> items{};
consteval Info() = default;
public:
consteval auto getSize() const -> std::size_t
{
return items.size();
}
};
}
=== definition.cppm ===
export module TestICE:Definition;
import :Info;
export namespace Test
{
class Builder;
class Definition final
{
friend class Builder;
Info info;
Builder* owner;
consteval Definition(Builder* b)
: owner{b}
{}
public:
consteval auto addA(const std::meta::info refl) -> Definition&
{
info.items.push_back(Item{AltA{refl}, true});
return *this;
}
};
}
=== builder.cppm ===
export module TestICE:Builder;
import :Definition;
export namespace Test
{
class Builder final
{
public:
consteval auto registerService() -> Definition
{
return {this};
}
};
}
=== Build commands ===
# A pre-built BMI for module `std` matching the compiler flags below
# must exist first, e.g.:
# g++ -std=gnu++26 -freflection -fmodules-ts -x c++ -c \
# <gcc-install>/include/c++/17.0.0/bits/std.cc -o std.o
g++ -std=gnu++26 -freflection -fmodules-ts -x c++ -c info.cppm -o info.o
g++ -std=gnu++26 -freflection -fmodules-ts -x c++ -c definition.cppm -o
definition.o
g++ -std=gnu++26 -freflection -fmodules-ts -x c++ -c builder.cppm -o builder.o
# ^ crashes here
=== Actual output ===
In file included from
/opt/gcc-trunk/include/c++/17.0.0/x86_64-pc-linux-gnu/bits/stdc++.h:80,
from /opt/gcc-trunk/include/c++/17.0.0/bits/std.cc:26,
of module std, imported at info.cppm:3,
of module TestICE:Info, imported at definition.cppm:3,
of module TestICE:Definition, imported at builder.cppm:3:
/opt/gcc-trunk/include/c++/17.0.0/variant: In destructor ‘consteval
std::__detail::__variant::_Variant_base<Test::AltA@TestICE:Info,
Test::AltB@TestICE:Info>::~_Variant_base()’:
/opt/gcc-trunk/include/c++/17.0.0/variant:773:12: internal compiler error:
Naruszenie ochrony pamięci
773 | struct _Variant_base : _Move_assign_alias<_Types...>
| ^~~~~~~~~~~~~
0x2a2869f internal_error(char const*, ...)
../../source/gcc/diagnostic-global-context.cc:787
0x126a34f crash_signal
../../source/gcc/toplev.cc:325
0x8efe51 contains_struct_check(tree_node*, tree_node_structure_enum, char
const*, int, char const*)
../../source/gcc/tree.h:3976
0x8efe51 initialize_vtbl_ptrs(tree_node*)
../../source/gcc/cp/init.cc:124
0x891e27 begin_destructor_body
../../source/gcc/cp/decl.cc:20494
0x891e27 begin_function_body()
../../source/gcc/cp/decl.cc:20571
0x926bb5 synthesize_method(tree_node*)
../../source/gcc/cp/method.cc:1820
0x806cf3 instantiate_cx_fn_r
../../source/gcc/cp/constexpr.cc:10861
0x1654f9b walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:11864
0x1655915 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:12101
0x1658f2a walk_tree_without_duplicates_1(tree_node**, tree_node*
(*)(tree_node**, int*, void*), void*, tree_node* (*)(tree_node**, int*,
tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, false,
default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:12127
0x824e29 instantiate_constexpr_fns
../../source/gcc/cp/constexpr.cc:10881
0x824e29 cxx_eval_outermost_constant_expr
../../source/gcc/cp/constexpr.cc:11145
0x82614f cxx_constant_value(tree_node*, tree_node*, int)
../../source/gcc/cp/constexpr.cc:11421
0x859793 cxx_constant_value(tree_node*, int)
../../source/gcc/cp/cp-tree.h:9450
0x859793 cp_fold_immediate_r
../../source/gcc/cp/cp-gimplify.cc:1503
0x1654f9b walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:11864
0x1655915 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:12101
0x165586f walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:11980
0x1655915 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
../../source/gcc/tree.cc:12101
/opt/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/cc1plus -quiet
-D_GNU_SOURCE builder.cppm -quiet -dumpbase builder.cppm -dumpbase-ext .cppm
-mtune=generic -march=x86-64 -std=gnu++26 -freflection -fmodules -o
/tmp/ccxkBqQx.s
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.
=== Workaround ===
Explicitly declaring the copy constructor of Info (copy assignment is
not required) avoids the crash:
consteval Info(const Info& other)
: items{other.items}
{}
=== Additional observation ===
Replacing the type of the member stored inside the variant alternative
(AltA::refl, changed from std::meta::info to int) also avoids the crash
entirely, with everything else in the reproducer (including addA()'s parameter
type, still std::meta::info) left unchanged. This indicates the crash requires
std::meta::info specifically as a stored value inside the variant-holding
container, not merely its presence elsewhere in the translation unit. This
points to an interaction between GCC's handling of the consteval-only
std::meta::info type when held as data within an aggregate/variant, and
synthesis of implicit special member functions in this module +
trial-evaluation context.
=== Control case (non-module, compiles correctly) ===
Restructuring the exact same class definitions and logic into a single,
non-module translation unit (plain header, no export module/import) compiles
and runs correctly with no error or warning, confirming the issue is specific
to the module context:
--- test_header.h ---
#pragma once
#include <meta>
#include <string>
#include <string_view>
#include <vector>
#include <variant>
#include <cstddef>
namespace Test
{
struct AltA final { std::meta::info refl; };
struct AltB final { std::string s; };
struct Item final
{
std::variant<AltA, AltB> value{};
bool flag{};
};
class Info final
{
friend class Definition;
friend class Builder;
std::vector<Item> items{};
consteval Info() = default;
public:
consteval auto getSize() const -> std::size_t
{
return items.size();
}
};
class Builder;
class Definition final
{
friend class Builder;
Info info;
Builder* owner;
consteval Definition(Builder* b)
: owner{b}
{}
public:
consteval auto addA(const std::meta::info refl) -> Definition&
{
info.items.push_back(Item{AltA{refl}, true});
return *this;
}
};
class Builder final
{
public:
consteval auto registerService() -> Definition
{
return {this};
}
};
consteval auto neverCalled() -> void
{
Builder builder;
auto def = builder.registerService().addA(^^int);
}
}
--- test_header_main.cpp ---
#include "test_header.h"
auto main() -> int
{
return 0;
}
--- Build command ---
g++ -std=gnu++26 -freflection -x c++ -c test_header_main.cpp -o
test_header_main.o
# ^ compiles successfully, no error or warning
=== GCC VERSION ===
this bug happens both on 16.2.1 and 17.0.0 (current trunk)
g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../source/configure --prefix=/opt/gcc-trunk
--enable-languages=c,c++ --disable-bootstrap --disable-multilib
--disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 17.0.0 20260825 (experimental) (GCC)
---
g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/16/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,cobol,algol68,lto
--prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://bugzilla.redhat.com/ --enable-shared
--enable-threads=posix --enable-checking=release --enable-multilib
--with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --enable-libstdcxx-backtrace
--with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu
--enable-plugin --enable-initfini-array
--with-isl=/builddir/build/BUILD/gcc-16.2.1-build/gcc-16.2.1-20260819/obj-x86_64-redhat-linux/isl-install
--enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted
--without-cuda-driver --enable-gnu-indirect-function --enable-cet
--with-tune=generic --with-tls=gnu2 --with-arch_32=i686
--build=x86_64-redhat-linux --with-build-config=bootstrap-lto
--enable-link-serialization=1 --disable-libssp
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 16.2.1 20260819 (Red Hat 16.2.1-2) (GCC)