https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125647
Bug ID: 125647
Summary: [gcc17] ICE when a specific maliciously crafted custom
version of std::initializer_list is provided
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: programmer00001h at gmail dot com
Target Milestone: ---
Created attachment 64651
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64651&action=edit
Problematic source file
The attached source code defines a specifically engineered custom version of
std::initializer_list that crashes GCC. This is extremely unlikely to happen in
real code, so probably not a high-priority issue.
Observation: GCC verifies that the ABI of std::initializer_list is as expected,
specifically that it has a pointer member, and then a size_t member, but any
base classes are not checked. I also observed that if a base class (say, Foo)
was derived from, Foo's constructor would be called with one single argument,
namely a pointer to the static storage. (but the size is not passed to Foo!)
using the_size_t = decltype(0uz);
template<typename T>
consteval the_size_t constexpr_probe(const T* mem){
the_size_t len = 0;
while(__builtin_constant_p(mem[len]))
++len;
return len;
}
namespace std{
template<typename T>
struct _Il_base{
const T* _mem;
the_size_t _size = constexpr_probe(_mem);
};
template<class T>
class initializer_list : _Il_base<T>{
T* _;
the_size_t _;
};
}
int main(){
for(int i : {0}){
return i;
}
}
My system gcc (16.1.1 20260430) is built with release mode, so it only says
"confused by earlier errors, bailing out" after the first "not a constant
expression" error. Nevertheless, it is still an ICE. The following stacktrace
and gcc -v output are from Compiler Explorer (godbolt.org):
<source>: In function 'int main()':
<source>:22:19: error: call to consteval function
'constexpr_probe<int>((&*this)->std::_Il_base<int>::_mem)' is not a constant
expression
22 | for(int i : {0}){
| ^
<source>:22:19: internal compiler error: in cxx_eval_constant_expression, at
cp/constexpr.cc:10482
0x29f4c28 diagnostics::context::diagnostic_impl(rich_location*,
diagnostics::metadata const*, diagnostics::option_id, char const*,
__va_list_tag (*) [1], diagnostics::kind)
???:0
0x29e986b internal_error(char const*, ...)
???:0
0xb33dde fancy_abort(char const*, int, char const*)
???:0
0xba17e1 cxx_eval_constant_expression(constexpr_ctx const*, tree_node*,
value_cat, bool*, bool*, tree_node**)
???:0
0xba3438 cxx_eval_constant_expression(constexpr_ctx const*, tree_node*,
value_cat, bool*, bool*, tree_node**)
???:0
0xba183c cxx_eval_constant_expression(constexpr_ctx const*, tree_node*,
value_cat, bool*, bool*, tree_node**)
???:0
0xbb3863 cxx_constant_value(tree_node*, tree_node*, int)
???:0
0x19236c3 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*> >*))
???:0
0x1923abd 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*> >*))
???:0
0x1923908 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*> >*))
???:0
0xbeaab7 cp_fully_fold_init(tree_node*)
???:0
0xe959a8 store_init_value(tree_node*, tree_node*, vec<tree_node*, va_gc,
vl_embed>**, int)
???:0
0xc453e6 cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int,
cp_decomp*)
???:0
0xd2811d cp_build_range_for_decls(unsigned long, tree_node*, tree_node**,
tree_node*)
???:0
0xd2861a cp_convert_range_for(tree_node*, tree_node*, tree_node*, cp_decomp*,
bool, tree_node*, bool)
???:0
0xd87813 c_parse_file()
???:0
0xf173d9 c_common_parse_file()
???:0
Output of gcc -v:
Using built-in specs.
COLLECT_GCC=/opt/compiler-explorer/gcc-snapshot/bin/g++
Target: x86_64-linux-gnu
Configured with: ../gcc-trunk-20260607/configure
--prefix=/opt/compiler-explorer/gcc-build/staging --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap
--enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32
--enable-multilib --enable-clocale=gnu
--enable-languages=c,c++,fortran,ada,objc,obj-c++,go,d,rust,m2,cobol,algol68
--enable-ld=yes --enable-gold=yes --enable-libstdcxx-time=yes
--enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix
--with-pkgversion=Compiler-Explorer-Build-gcc-68d3f1e2c20efe07f99de3720d1732c4b987ff22-binutils-2.44
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 17.0.0 20260604 (experimental)
(Compiler-Explorer-Build-gcc-68d3f1e2c20efe07f99de3720d1732c4b987ff22-binutils-2.44)