Message ID | f0392178-1d4c-b33d-ff95-81b9cb31c290@oracle.com |
---|---|
State | New |
Headers | show |
Hi, gently pinging this... On 23/03/2017 20:07, Paolo Carlini wrote: > Hi, > > this ICE on invalid code isn't a regression, thus a patch probably > doesn't qualify for Stage 4, but IMHO I made good progress on it and > I'm sending what I have now anyway... The ICE happens during error > recovery after a sensible diagnostic for the first declaration in: > > auto* foo() { return 0; } > auto* foo(); > > After the error, finish_function does: > > apply_deduced_return_type (fndecl, void_type_node); > fntype = TREE_TYPE (fndecl); > > which then is inconsistent with the auto* return type of the second > declaration and leads to an ICE in merge_types (which duplicate_decls > thought was safe to call because types_match is true (evidently: > decls_match uses fndecl_declared_return_type)). Thus, in terms of > error recovery, I think that in cases like the one at issue it makes > sense not to replace auto* after the error and leave the return type > untouched: certainly the below passes testing and avoids ICEing on the > testcase at issue and a variant of it. Thanks, Paolo.
OK. On Thu, Mar 23, 2017 at 3:07 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > Hi, > > this ICE on invalid code isn't a regression, thus a patch probably doesn't > qualify for Stage 4, but IMHO I made good progress on it and I'm sending > what I have now anyway... The ICE happens during error recovery after a > sensible diagnostic for the first declaration in: > > auto* foo() { return 0; } > auto* foo(); > > After the error, finish_function does: > > apply_deduced_return_type (fndecl, void_type_node); > fntype = TREE_TYPE (fndecl); > > which then is inconsistent with the auto* return type of the second > declaration and leads to an ICE in merge_types (which duplicate_decls > thought was safe to call because types_match is true (evidently: decls_match > uses fndecl_declared_return_type)). Thus, in terms of error recovery, I > think that in cases like the one at issue it makes sense not to replace > auto* after the error and leave the return type untouched: certainly the > below passes testing and avoids ICEing on the testcase at issue and a > variant of it. > > Thanks, > Paolo. > > ////////////////// >
Index: cp/decl.c =================================================================== --- cp/decl.c (revision 246414) +++ cp/decl.c (working copy) @@ -15573,16 +15573,19 @@ finish_function (int flags) if (!processing_template_decl && FNDECL_USED_AUTO (fndecl) && TREE_TYPE (fntype) == current_function_auto_return_pattern) { - if (!is_auto (current_function_auto_return_pattern) - && !current_function_returns_value && !current_function_returns_null) + if (is_auto (current_function_auto_return_pattern)) { + apply_deduced_return_type (fndecl, void_type_node); + fntype = TREE_TYPE (fndecl); + } + else if (!current_function_returns_value + && !current_function_returns_null) + { error ("no return statements in function returning %qT", current_function_auto_return_pattern); inform (input_location, "only plain %<auto%> return type can be " "deduced to %<void%>"); } - apply_deduced_return_type (fndecl, void_type_node); - fntype = TREE_TYPE (fndecl); } // If this is a concept, check that the definition is reasonable. Index: testsuite/g++.dg/cpp1y/auto-fn37.C =================================================================== --- testsuite/g++.dg/cpp1y/auto-fn37.C (revision 0) +++ testsuite/g++.dg/cpp1y/auto-fn37.C (working copy) @@ -0,0 +1,5 @@ +// PR c++/80145 +// { dg-do compile { target c++14 } } + +auto* foo() { return 0; } // { dg-error "unable to deduce" } +auto* foo(); Index: testsuite/g++.dg/cpp1y/auto-fn38.C =================================================================== --- testsuite/g++.dg/cpp1y/auto-fn38.C (revision 0) +++ testsuite/g++.dg/cpp1y/auto-fn38.C (working copy) @@ -0,0 +1,5 @@ +// PR c++/80145 +// { dg-do compile { target c++14 } } + +auto* foo() { } // { dg-error "no return statements" } +auto* foo();