https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123880
Bug ID: 123880
Summary: [16 Regression] ICE with -fanalyzer in
ana::exploded_node::on_throw
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: ice-on-valid-code
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: dmalcolm at gcc dot gnu.org
Target Milestone: ---
(reported downstream at https://bugzilla.redhat.com/show_bug.cgi?id=2435317)
This C++ code crashes -fanalyzer:
// this is the source code...
#include <generator>
#include <iostream>
template<typename T> struct Tree
{
T value;
Tree *left{}, *right{};
std::generator<const T &> traverse_preorder() const
{
co_yield value;
if (left)
co_yield std::ranges::elements_of(left->traverse_preorder());
if (right)
co_yield std::ranges::elements_of(right->traverse_preorder());
}
};
int main()
{
Tree<char> tree[]
{
{'D', tree + 1, tree + 2},
// │
// ┌───────────────┴────────────────┐
// │ │
{'B', tree + 3, tree + 4}, {'F', tree + 5, tree + 6},
// │ │
// ┌─────────┴─────────────┐ ┌───────────┴─────────────┐
// │ │ │ │
{'A'}, {'C'}, {'E'}, {'G'}
};
std::cout << " Preorder: ";
for (char x : tree->traverse_preorder())
std::cout << x << ' ';
std::cout << '\n';
}
Crashes with trunk with: -fanalyzer -std=c++23: https://godbolt.org/z/Ez7xnbddf
(gdb) bt
#0 fancy_abort (file=0x2f47ec8 "../../src/gcc/analyzer/engine.cc", line=1814,
function=0x2f4858e "on_throw")
at ../../src/gcc/diagnostics/context.cc:1779
#1 0x0000000001c9e893 in ana::exploded_node::on_throw
(this=<ana::exploded_node 0x67b5360 (EN 6478)>, eg=...,
throw_call=..., after_throw_point=..., new_state=0x7fffffff7cf0,
is_rethrow=true, ctxt=0x7fffffff7c80)
at ../../src/gcc/analyzer/engine.cc:1814
#2 0x0000000001d09f15 in ana::cxa_throw_op::execute (this=0x42ee0b0,
op_ctxt=...)
at ../../src/gcc/analyzer/ops.cc:1205
#3 0x0000000001ca4162 in ana::exploded_graph::process_node
(this=0x7fffffff8140,
node=<ana::exploded_node 0x67b5360 (EN 6478)>) at
../../src/gcc/analyzer/engine.cc:3768
#4 0x0000000001ca2e76 in ana::exploded_graph::process_worklist
(this=0x7fffffff8140)
at ../../src/gcc/analyzer/engine.cc:3397
#5 0x0000000001ca7482 in ana::impl_run_checkers (logger=0x0) at
../../src/gcc/analyzer/engine.cc:5257
#6 0x0000000001ca78ce in ana::run_checkers () at
../../src/gcc/analyzer/engine.cc:5348
#7 0x0000000001c9b207 in (anonymous namespace)::pass_analyzer::execute
(this=0x3e6d1b0)
at ../../src/gcc/analyzer/analyzer-pass.cc:81
#8 0x00000000016f8b29 in execute_one_pass (pass=<opt_pass* 0x3e6d1b0
"analyzer"(93)>)
at ../../src/gcc/passes.cc:2656
#9 0x0000000001702105 in execute_ipa_pass_list (pass=<opt_pass* 0x3e6d1b0
"analyzer"(93)>)
at ../../src/gcc/passes.cc:3118
#10 0x000000000129b510 in ipa_passes () at ../../src/gcc/cgraphunit.cc:2299
#11 symbol_table::compile (this=0x7fffea648000) at
../../src/gcc/cgraphunit.cc:2364
#12 symbol_table::compile (this=0x7fffea648000) at
../../src/gcc/cgraphunit.cc:2340
#13 0x000000000129e505 in symbol_table::finalize_compilation_unit
(this=0x7fffea648000)
at ../../src/gcc/cgraphunit.cc:2623
#14 0x000000000182c104 in compile_file () at ../../src/gcc/toplev.cc:482
#15 0x0000000000dfb447 in do_compile () at ../../src/gcc/toplev.cc:2225
#16 toplev::main (this=this@entry=0x7fffffffdb7e, argc=<optimized out>,
argc@entry=29, argv=<optimized out>,
argv@entry=0x7fffffffdc88) at ../../src/gcc/toplev.cc:2390
#17 0x0000000000dfd5b5 in main (argc=29, argv=0x7fffffffdc88) at
../../src/gcc/main.cc:39
where this assertion is failing:
* rhbz#2435317 ("error interno del compilador: en on_throw, en
analyzer/engine.cc:1814")
#1 0x0000000001c9e893 in ana::exploded_node::on_throw
(this=<ana::exploded_node 0x67b5360 (EN 6478)>, eg=...,
throw_call=..., after_throw_point=..., new_state=0x7fffffff7cf0,
is_rethrow=true, ctxt=0x7fffffff7c80)
at ../../src/gcc/analyzer/engine.cc:1814
li1814 gcc_assert (eh_node);
(gdb) list
1809 /* Create an enode and eedge for the "throw". */
1810 tree type = NULL_TREE;
1811 if (is_rethrow)
1812 {
1813 const exception_node *eh_node =
model->get_current_caught_exception ();
1814 gcc_assert (eh_node);
1815 type = eh_node->maybe_get_type ();
1816 }
1817 else
1818 {
(gdb) p eh_node
$1 = (const ana::exception_node *) 0x0
(gdb) call model->dump()
Region Model
├─ Current Frame: frame: ‘std::__gen::_Promise_erased<const
char&>::unhandled_exception’@1
├─ Store
│ ├─ m_called_unknown_fn: false
│ ╰─ root region
│ ╰─ (*INIT_VAL(this_3(D))): (ESCAPED)
╰─ Constraints
├─ Equivalence class ec0
│ ╰─ &CAST_REG(‘const struct _Subyield_state’,
(*INIT_VAL(this_3(D))).std::__gen::_Promise_erased<const
char&>::_Subyield_state std::__gen::_Promise_erased<const
char&>::_M_nest).std::variant<std::__gen::_Promise_erased<const
char&>::_Subyield_state::_Bottom_frame, std::__gen::_Promise_erased<const
char&>::_Subyield_state::_Frame> std::__gen::_Promise_erased<const
char&>::_Subyield_state::_M_stack
├─ Equivalence class ec1
│ ╰─ &(*INIT_VAL(this_3(D))).std::__gen::_Promise_erased<const
char&>::_Subyield_state std::__gen::_Promise_erased<const char&>::_M_nest
├─ Equivalence class ec2
│ ├─ (void *)0B
│ ╰─ ‘0B’
├─ Equivalence class ec3
│ ╰─ INIT_VAL(this_3(D))
├─ ec0: {&CAST_REG(‘const struct _Subyield_state’,
(*INIT_VAL(this_3(D))).std::__gen::_Promise_erased<const
char&>::_Subyield_state std::__gen::_Promise_erased<const
char&>::_M_nest).std::variant<std::__gen::_Promise_erased<const
char&>::_Subyield_state::_Bottom_frame, std::__gen::_Promise_erased<const
char&>::_Subyield_state::_Frame> std::__gen::_Promise_erased<const
char&>::_Subyield_state::_M_stack} != ec2: {(void *)0B == [m_constant]‘0B’}
├─ ec1: {&(*INIT_VAL(this_3(D))).std::__gen::_Promise_erased<const
char&>::_Subyield_state std::__gen::_Promise_erased<const char&>::_M_nest} !=
ec2: {(void *)0B == [m_constant]‘0B’}
╰─ ec3: {INIT_VAL(this_3(D))} != ec2: {(void *)0B == [m_constant]‘0B’}