Message ID | 5817d25c-aa16-ff6a-e720-d34df14f9521@oracle.com |
---|---|
State | New |
Headers | show |
Ok. On Thu, Feb 23, 2017 at 6:02 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > Hi, > > in this error recovery regression, we ICE after (a lot after) a sensible > diagnostic, when lower_function_body encounters an error_mark_node. I worked > quite a bit on the issue, and, all in all, I propose to simply check the > return value of duplicate_decls as called by register_specialization and > bail out. > > In principle it may make sense to continue and, for example, also emit > diagnostic about '= default' making sense only for special member functions > - returning spec instead of error_mark_node would achieve that without > regressions for the second testcase - but I'm not sure we want to do this > kind of change right here right now together with fixing the ICE, because we > do *not* emit additional diagnostic in the non-template case, eg for: > > void foo(int) {} > void foo(int) = default; > > Tested x86_64-linux. > > Thanks, Paolo. > > ///////////////////// > >
Index: cp/pt.c =================================================================== --- cp/pt.c (revision 245655) +++ cp/pt.c (working copy) @@ -1599,7 +1599,12 @@ register_specialization (tree spec, tree tmpl, tre } else if (DECL_TEMPLATE_SPECIALIZATION (fn)) { - if (!duplicate_decls (spec, fn, is_friend) && DECL_INITIAL (spec)) + tree dd = duplicate_decls (spec, fn, is_friend); + if (dd == error_mark_node) + /* We've already complained in duplicate_decls. */ + return error_mark_node; + + if (dd == NULL_TREE && DECL_INITIAL (spec)) /* Dup decl failed, but this is a new definition. Set the line number so any errors match this new definition. */ Index: testsuite/g++.dg/cpp0x/pr79361-1.C =================================================================== --- testsuite/g++.dg/cpp0x/pr79361-1.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr79361-1.C (working copy) @@ -0,0 +1,7 @@ +// PR c++/79361 +// { dg-do compile { target c++11 } } + +template<typename T> void foo(T); + +template<> void foo<int>(int) {} // { dg-message "declared" } +template<> void foo<int>(int) = delete; // { dg-error "redefinition" } Index: testsuite/g++.dg/cpp0x/pr79361-2.C =================================================================== --- testsuite/g++.dg/cpp0x/pr79361-2.C (revision 0) +++ testsuite/g++.dg/cpp0x/pr79361-2.C (working copy) @@ -0,0 +1,7 @@ +// PR c++/79361 +// { dg-do compile { target c++11 } } + +template<typename T> void foo(T); + +template<> void foo<int>(int) {} // { dg-message "declared" } +template<> void foo<int>(int) = default; // { dg-error "redefinition" }