Bug 101420 - ICE in build_special_member_call, at cp/call.c:10179
Summary: ICE in build_special_member_call, at cp/call.c:10179
Status: RESOLVED DUPLICATE of bug 98056
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-07-11 15:39 UTC by Avi Kivity
Modified: 2021-07-12 09:03 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Avi Kivity 2021-07-11 15:39:13 UTC
The attached file ICEs with gcc 11.1.1. It compiles cleanly with clang 11.

Command line:

g++ -MD -MT build/dev/table.o -MF build/dev/table.o.d -I/home/avi/scylla/seastar/include -I/home/avi/scylla/build/dev/seastar/gen/include -std=gnu++20 -U_FORTIFY_SOURCE -Wno-maybe-uninitialized -DSEASTAR_SSTRING -Werror=unused-result -fstack-clash-protection -DSEASTAR_API_LEVEL=6 -DSEASTAR_ENABLE_ALLOC_FAILURE_INJECTION -DSEASTAR_TYPE_ERASE_MORE -DFMT_LOCALE -DFMT_SHARED -I/usr/include/p11-kit-1  -DDEVEL -DSEASTAR_ENABLE_ALLOC_FAILURE_INJECTION -DSCYLLA_ENABLE_ERROR_INJECTION -Wstack-usage=21504 -Wno-error=stack-usage= -O2 -iquote. -iquote build/dev/gen --std=gnu++20 -Wno-array-bounds -Wno-unused-but-set-variable -Wno-sign-compare -Wno-narrowing -ffile-prefix-map=/home/avi/scylla=.  -march=westmere -DBOOST_TEST_DYN_LINK   -Iabseil -fvisibility=hidden  -Wall -Werror -Wno-mismatched-tags -Wno-maybe-uninitialized -Wno-tautological-compare -Wno-missing-braces -Wno-misleading-indentation -Wno-overflow -Wno-noexcept-type -Wno-nonnull-compare -Wno-error=cpp -Wno-ignored-attributes -Wno-overloaded-virtual -Wno-stringop-overflow -Wno-redundant-move -Wno-unused-variable -Wno-psabi -Wno-error=deprecated-declarations -DXXH_PRIVATE_API -DSEASTAR_TESTING_MAIN -DHAVE_LZ4_COMPRESS_DEFAULT  -c -o build/dev/table.o ice.cc
Comment 1 Avi Kivity 2021-07-11 15:44:49 UTC
File is in https://scratch.scylladb.com/ice.cc (too large to upload to bugzilla). I'll try to reduce it a little.
Comment 2 Avi Kivity 2021-07-11 15:45:19 UTC
Simplified command line:

g++ -march=westmere --std=c++20 -fext-numeric-literals  ice.cc
Comment 3 Avi Kivity 2021-07-12 07:35:03 UTC
Adding Iain since the ICE happens in a coroutine. Meanwhile my desktop is reducing the testcase.
Comment 4 Iain Sandoe 2021-07-12 07:40:08 UTC
(In reply to Avi Kivity from comment #3)
> Adding Iain since the ICE happens in a coroutine. Meanwhile my desktop is
> reducing the testcase.

do you have a backtrace?
Comment 5 Avi Kivity 2021-07-12 07:48:16 UTC
How does one ask gcc to generate a backtrace on ICE?
Comment 6 Iain Sandoe 2021-07-12 08:02:41 UTC
(In reply to Avi Kivity from comment #5)
> How does one ask gcc to generate a backtrace on ICE?

It produces one when libbacktrace is available, not aware of needing to do anything special; is there any other text from the ICE?
Comment 7 Avi Kivity 2021-07-12 08:04:43 UTC
ice.cc: In member function 'seastar::future<> table::generate_and_propagate_view_updates(const schema_ptr&, reader_permit, std::vector<db::view::view_and_base>&&, mutation&&, flat_mutation_reader_opt, tracing::trace_state_ptr, gc_clock::time_point) const':
ice.cc:199329:1: internal compiler error: in build_special_member_call, at cp/call.c:10179
199329 | }
       | ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.



libbacktrace should have been available, since it's the distro package. Is there a breakpoint I can set in gcc to obtain the backtrace?
Comment 8 Avi Kivity 2021-07-12 08:06:25 UTC
Ugh, I forgot g++ isn't the compiler proper and setting a breakpoint is going to be tricky.
Comment 9 Avi Kivity 2021-07-12 08:10:46 UTC
I found -dH and have a core:

(gdb) bt
#0  0x00007f26600e02a2 in ?? () from /lib64/libc.so.6
#1  0x00007f26600c98a4 in ?? () from /lib64/libc.so.6
#2  0x0000000000ff1af4 in diagnostic_action_after_output(diagnostic_context*, diagnostic_t) [clone .cold] ()
#3  0x000000000142bdab in diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*) ()
#4  0x000000000162d12a in diagnostic_impl(rich_location*, diagnostic_metadata const*, int, char const*, __va_list_tag (*) [1], diagnostic_t) ()
#5  0x0000000000ff2ac8 in internal_error(char const*, ...) ()
#6  0x0000000000ff2ba3 in fancy_abort(char const*, int, char const*) ()
#7  0x0000000000620c80 in build_special_member_call(tree_node*, tree_node*, vec<tree_node*, va_gc, vl_embed>**, tree_node*, int, int) [clone .cold] ()
#8  0x00000000006400fa in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#9  0x0000000000640252 in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#10 0x0000000000640252 in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#11 0x0000000000640262 in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#12 0x0000000000640252 in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#13 0x0000000000640252 in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#14 0x0000000000640252 in flatten_await_stmt(var_nest_node*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*, tree_node**) ()
#15 0x000000000064116f in await_statement_walker(tree_node**, int*, void*) ()
#16 0x00000000012fb259 in 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*> >*)) ()
#17 0x000000000064094e in await_statement_walker(tree_node**, int*, void*) ()
#18 0x00000000012fb259 in 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*> >*)) ()
#19 0x0000000000640904 in await_statement_walker(tree_node**, int*, void*) ()
#20 0x00000000012fb259 in 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*> >*)) ()
#21 0x000000000064094e in await_statement_walker(tree_node**, int*, void*) ()
#22 0x00000000012fb259 in 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*> >*)) ()
#23 0x00000000012fb3da in 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*> >*)) ()
#24 0x000000000064094e in await_statement_walker(tree_node**, int*, void*) ()
#25 0x00000000012fb259 in 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*> >*)) ()
#26 0x0000000000640904 in await_statement_walker(tree_node**, int*, void*) ()
#27 0x00000000012fb259 in 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*> >*)) ()
#28 0x000000000063d33b in morph_fn_to_coro(tree_node*, tree_node**, tree_node**) ()
#29 0x0000000000655a90 in finish_function(bool) [clone .cold] ()
#30 0x00000000010a3210 in cp_parser_function_definition_after_declarator(cp_parser*, bool) ()
#31 0x00000000006a46b4 in cp_parser_init_declarator(cp_parser*, int, cp_decl_specifier_seq*, vec<deferred_access_check, va_gc, vl_embed>*, bool, bool, int, bool*, tree_node**, unsigned int*, tree_node**) [clone .cold] ()
#32 0x00000000010937dc in cp_parser_simple_declaration(cp_parser*, bool, tree_node**) ()
#33 0x00000000006a1966 in cp_parser_declaration(cp_parser*, tree_node*) [clone .cold] ()
#34 0x00000000014578dc in c_parse_file() ()
#35 0x0000000001488094 in c_common_parse_file() ()
#36 0x0000000001525c41 in compile_file() ()
#37 0x000000000103ba92 in toplev::main(int, char**) ()
#38 0x000000000103cc23 in main ()
Comment 10 Avi Kivity 2021-07-12 08:30:57 UTC
Reproduces on trunk:

#7  0x0000000000b439af in cp_build_modify_expr (loc=1376651745, lhs=0x7f0c55c12c60, modifycode=<optimized out>, rhs=0x7f0c55e63ee0, complain=<optimized out>) at ../../gcc/gcc/cp/typeck.c:8919

8919			error_at (loc, "array used as initializer");


8914	          /* This routine is used for both initialization and assignment.
8915	             Make sure the diagnostic message differentiates the context.  */
8916		  if (complain & tf_error)
8917		    {
8918		      if (modifycode == INIT_EXPR)
8919			error_at (loc, "array used as initializer");
8920		      else
8921			error_at (loc, "invalid array assignment");
8922		    }
8923		  return error_mark_node;
Comment 11 Iain Sandoe 2021-07-12 08:33:03 UTC
(In reply to Avi Kivity from comment #10)
> Reproduces on trunk:
> 
> #7  0x0000000000b439af in cp_build_modify_expr (loc=1376651745,
> lhs=0x7f0c55c12c60, modifycode=<optimized out>, rhs=0x7f0c55e63ee0,
> complain=<optimized out>) at ../../gcc/gcc/cp/typeck.c:8919
> 
> 8919			error_at (loc, "array used as initializer");
> 
> 
> 8914	          /* This routine is used for both initialization and
> assignment.
> 8915	             Make sure the diagnostic message differentiates the
> context.  */
> 8916		  if (complain & tf_error)
> 8917		    {
> 8918		      if (modifycode == INIT_EXPR)
> 8919			error_at (loc, "array used as initializer");
> 8920		      else
> 8921			error_at (loc, "invalid array assignment");
> 8922		    }
> 8923		  return error_mark_node;

thanks, probably the compiler needs to be built with -g to get the backtrace.

this looks like a dup of PR 96056 - but I am happy to check the reduced case.
Comment 12 Iain Sandoe 2021-07-12 08:34:06 UTC
(In reply to Iain Sandoe from comment #11)
> (In reply to Avi Kivity from comment #10)
> > Reproduces on trunk:


> this looks like a dup of PR 96056 - but I am happy to check the reduced case.
erm PR 98056 I meant
Comment 13 Avi Kivity 2021-07-12 08:34:45 UTC
The coroutine that breaks is

future<> table::generate_and_propagate_view_updates(const schema_ptr& base,
        reader_permit permit,
        std::vector<db::view::view_and_base>&& views,
        mutation&& m,
        flat_mutation_reader_opt existings,
        tracing::trace_state_ptr tr_state,
        gc_clock::time_point now) const {
    auto base_token = m.token();
    db::view::view_update_builder builder = co_await db::view::make_view_update_builder(
            base,
            std::move(views),
            flat_mutation_reader_from_mutations(std::move(permit), {std::move(m)}),
            std::move(existings),
            now);
    while (true) {
        try {
            auto updates = co_await builder.build_some();
            if (updates.empty()) {
                break;
            }
            tracing::trace(tr_state, "Generated {} view update mutations", updates.size());
            auto units = seastar::consume_units(*_config.view_update_concurrency_semaphore, memory_usage_of(updates));
            co_await db::view::mutate_MV(base_token, std::move(updates), _view_stats, *_config.cf_stats, tr_state,
                std::move(units), service::allow_hints::yes, db::view::wait_for_all_updates::no).handle_exception([] (auto ignored) { });
        } catch (...) {
        }
    }
    co_await builder.close();
}


Nothing special in there, in particular nothing that looks like an array.
Comment 14 Avi Kivity 2021-07-12 08:42:51 UTC
Very likely it's a dup:

    db::view::view_update_builder builder = co_await db::view::make_view_update_builder(
            base,
            std::move(views),
            flat_mutation_reader_from_mutations(std::move(permit), {std::move(m)}),
            std::move(existings),
            now);


The {std::move(m)} thing becomes an std::initializer_list used to initialize an std::vector, and that other bug also had an std::initializer_list.
Comment 15 Avi Kivity 2021-07-12 08:51:31 UTC
If I move the sub-expression that contains the std::initializer_list outside co_await, the internal error is avoided.
Comment 16 Avi Kivity 2021-07-12 08:52:13 UTC
So I confirm it's a dup. Are you still interested in a reduced testcase?
Comment 17 Iain Sandoe 2021-07-12 09:01:47 UTC
(In reply to Avi Kivity from comment #16)
> So I confirm it's a dup. Are you still interested in a reduced testcase?

Not necessary.
However, if you already have it - then I can add to my existing set of tests for 98056.

marking this as a dup.

*** This bug has been marked as a duplicate of bug 98056 ***
Comment 18 Avi Kivity 2021-07-12 09:03:12 UTC
It's still >7MB long, so I'll stop reducing.