r221115 on arm-linux-gnueabihf $ g++ -std=c++11 -c -O2 schema-parser.ii schema-parser.ii: In member function 'Maybe<ParsedSchema> ParsedSchema::findNested() const': schema-parser.ii:45:21: internal compiler error: Segmentation fault Maybe<ParsedSchema> ParsedSchema::findNested() const { ^ Please submit a full bug report, with preprocessed source if appropriate. $ gdb --args /usr/lib/gcc/arm-linux-gnueabihf/5/cc1plus -fpreprocessed schema-parser.ii -quiet -dumpbase schema-parser.ii -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mthumb -mtls-dialect=gnu -auxbase schema-parser -O2 -std=c++11 -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/ccABpp5w.s (gdb) bt #0 0x00346d52 in maybe_canonicalize_mem_ref_addr(tree_node**) () #1 0x0034ee4c in fold_stmt_1(gimple_stmt_iterator*, bool, tree_node* (*)(tree_node*)) () #2 0x0053bb56 in (anonymous namespace)::pass_forwprop::execute(function*) () #3 0x00434e5e in execute_one_pass(opt_pass*) () #4 0x00435148 in execute_pass_list_1(opt_pass*) [clone .constprop.59] () #5 0x00435152 in execute_pass_list_1(opt_pass*) [clone .constprop.59] () #6 0x00435180 in execute_pass_list(function*, opt_pass*) () #7 0x00298eb6 in cgraph_node::expand() () #8 0x0029a93c in symbol_table::compile() [clone .part.42] () #9 0x0029ab78 in symbol_table::finalize_compilation_unit() () #10 0x001a34e4 in cp_write_global_declarations() () #11 0x004aa082 in compile_file() () #12 0x001571a6 in toplev::main(int, char**) () #13 0x00157bf4 in main () $ cat schema-parser.ii namespace _ { template <typename T> class NullableValue { public: T operator*(); NullableValue(T); }; } template <typename T> class Maybe { public: Maybe(T t) : ptr(t) {} template <typename Func> auto map(Func f) -> Maybe<decltype(f(T()))> { return f(*ptr); } _::NullableValue<T> ptr; }; template <typename T> class A { public: T *operator->(); }; typedef int uint64_t; class B { public: long getId(); }; class C { struct D; A<D> impl; friend class ParsedSchema; }; class ParsedSchema { Maybe<ParsedSchema> findNested() const; ParsedSchema(ParsedSchema, C); C *parser; B getProto() const; int raw; }; class F { public: Maybe<uint64_t> lookup(uint64_t, int); ParsedSchema get(uint64_t); }; struct C::D { F compiler; }; Maybe<ParsedSchema> ParsedSchema::findNested() const { int name; parser->impl->compiler.lookup(getProto().getId(), name) .map([this](uint64_t childId) { return ParsedSchema(parser->impl->compiler.get(childId), *parser); }); }
I get (on x86_64-linux): ./cc1plus -quiet t.ii -std=c++11 t.ii: In lambda function: t.ii:50:7: error: using result of function returning 'void' }); ^ so assuming the testcase is valid this is a C++ rejects-valid bug now (4.9 accepts it)? and with a cross to arm: > ./cc1plus -quiet -std=c++11 ../../trunk-g/gcc/t.ii -I include ../../trunk-g/gcc/t.ii: In lambda function: ../../trunk-g/gcc/t.ii:48:30: error: non-trivial conversion at assignment .map([this](uint64_t childId) { ^ struct ParsedSchema struct ParsedSchema * <retval> = D.4929; ../../trunk-g/gcc/t.ii:48:30: internal compiler error: verify_gimple failed 0xf83713 verify_gimple_in_seq(gimple_statement_base*) /space/rguenther/src/svn/trunk2/gcc/tree-cfg.c:4736 0xcb9d25 gimplify_body(tree_node*, bool) do you have checking disabled?
> do you have checking disabled? configured with --enable-checking=release
Confirmed with --enable-checking=release and a cross build: $ ./cc1plus a.ii -quiet -std=c++11 -I./ -O2 a.ii: In member function ‘Maybe<ParsedSchema> ParsedSchema::findNested() const’: a.ii:45:21: internal compiler error: Segmentation fault Maybe<ParsedSchema> ParsedSchema::findNested() const { I'll take a look.
This was caused by r210292: commit f1ec53b67367cb5d4aba65b5648e5faa5f29bdf0 Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri May 9 20:07:45 2014 +0000 PR c++/60463 PR c++/60755 * lambda.c (lambda_expr_this_capture): Add new parameter add_capture_p controlling whether the functions will try to capture 'this' via the default capture. (maybe_resolve_dummy): Likewise. * cp-tree.h: Adjust prototypes. * call.c, semantics.c: Change callers of these functions. * call.c (build_new_method_call_1): Use the actual 'this' that would be potentially captured for the overload resolution, instead of the dummy object. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210292 138bc75d-0d04-0410-961f-82ee72b054a4 Jason, just so I know what I'm looking at here, is the testcase even valid? Because mainline on x86-64 has a totally different symptom than ppc with --enable-checking and a totally different symptom than ppc with --enable-checking=release. On mainline on x86-64 (with either default checking or --enable-checking=release), we get: reynosa:/build/t/gcc$ ./cc1plus ~/a.ii -quiet -std=c++11 -O2 -I./ /home/aldyh/a.ii: In lambda function: /home/aldyh/a.ii:50:7: error: using result of function returning ‘void’ }); On a cross PPC with default checking we get: reynosa:/build/arm-linux-gnueabihf-checking/gcc$ ./cc1plus ~/a.ii -quiet -std=c++11 -O2 -I./ /home/aldyh/a.ii: In lambda function: /home/aldyh/a.ii:48:35: error: non-trivial conversion at assignment .map([this](uint64_t childId) { ^ struct ParsedSchema struct ParsedSchema * <retval> = D.4925; /home/aldyh/a.ii:48:35: internal compiler error: verify_gimple failed 0xf4da3b verify_gimple_in_seq(gimple_statement_base*) /source/gcc/gcc/tree-cfg.c:4736 0xc7fe6d gimplify_body(tree_node*, bool) /source/gcc/gcc/gimplify.c:9117 0xc802a7 gimplify_function_tree(tree_node*) /source/gcc/gcc/gimplify.c:9202 0xa2f3e0 cgraph_node::analyze() /source/gcc/gcc/cgraphunit.c:633 0xa306ba analyze_functions /source/gcc/gcc/cgraphunit.c:1023 0xa34a5f symbol_table::finalize_compilation_unit() /source/gcc/gcc/cgraphunit.c:2435 0x799173 cp_write_global_declarations() /source/gcc/gcc/cp/decl2.c:4754 Please submit a full bug report, Finally, on a cross PPC with --enable-checking=release we get: reynosa:/build/arm-linux-gnueabihf/gcc$ ./cc1plus ~/a.ii -quiet -std=c++11 -O2 -I./ /home/aldyh/a.ii: In member function ‘Maybe<ParsedSchema> ParsedSchema::findNested() const’: /home/aldyh/a.ii:45:21: internal compiler error: Segmentation fault Maybe<ParsedSchema> ParsedSchema::findNested() const { ^ 0xd1b9a4 crash_signal /source/gcc/gcc/toplev.c:383 0xa40122 maybe_canonicalize_mem_ref_addr /source/gcc/gcc/gimple-fold.c:3504 0xa402c3 fold_stmt_1 /source/gcc/gcc/gimple-fold.c:3556 0xa40e07 fold_stmt(gimple_stmt_iterator*, tree_node* (*)(tree_node*)) /source/gcc/gcc/gimple-fold.c:3810 0xe438c7 execute /source/gcc/gcc/tree-ssa-forwprop.c:2347 Please submit a full bug report, Odd indeed. A little guidance would be appreciated, as I don't even know which one of the three is the correct path.
Created attachment 34959 [details] reduced testcase
For the construction of the lambda in the simplified testcase I have just uploaded: MaybeInt().xmap([abc](int childId) { return ParsedSchema(bark, childId + 666); }); We initially generate the following tree: ParsedSchema::findNested()::<lambda(int)> (const struct __lambda0 * const __closure, int childId) { const int abc [value-expr: __closure->__abc]; <<cleanup_point return D.2331 = <<< Unknown tree: aggr_init_expr 6 __comp_ctor *NON_LVALUE_EXPR <this> NON_LVALUE_EXPR <this> *NON_LVALUE_EXPR <this> = bark;, <<< Unknown tree: empty_class_expr >>>; childId + 666 >>>>>; } Whose AGGR_INIT_EXPR will be gimplified into: ParsedSchema::findNested()::<lambda(int)> (const struct __lambda0 * const __closure, int childId) { const int abc [value-expr: __closure->__abc]; <<cleanup_point return D.2331 = ParsedSchema::ParsedSchema (&*NON_LVALUE_EXPR <this>, *NON_LVALUE_EXPR <this> = bark;, <<< Unknown tree: empty_class_expr >>>;, childId + 666)>>; } Notice the non-existent return value from ParsedSchema::ParsedSchema is being read from, and constructors do not return anything. I suppose D.2331 should be set from NON_LVALUE_EXPR<this>, although even the assignment into *NON_LVALUE_EXPR looks odd. Isn't a NON_LVALUE_EXPR by definition not assignable? Before the patch that broke this, we had: <<cleanup_point return <retval> = TARGET_EXPR <D.2133, <<< Unknown tree: aggr_init_expr 6 __comp_ctor D.2133 (struct ParsedSchema *) 0 TARGET_EXPR <D.2123, bark>;, <<< Unknown tree: empty_class_expr >>>; childId + 666 >>>>;, D.2133>>; Notice the TARGET_EXPR, which then does the right thing when gimplified.
Created attachment 34977 [details] smaller and simpler testcase In cp_simplify_init_expr(), we are lowering part of the return statement for the lambda function from this: *NON_LVALUE_EXPR <this> = TARGET_EXPR <D.2173, <<< Unknown tree: aggr_init_expr 4 __comp_ctor D.2173 NON_LVALUE_EXPR <this> >>>>; into: <<< Unknown tree: aggr_init_expr 4 __comp_ctor *NON_LVALUE_EXPR <this> <-- notice we've dropped D.2173 NON_LVALUE_EXPR <this> >>>; This last blob cannot be stored into retval because the value of the aggr_init_expr is a read from the constructor which has a void return type.
Fixed on mainline by Jason's fix to PR c++/65339. Thanks. *** This bug has been marked as a duplicate of bug 65339 ***