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)

Reply via email to