diff mbox

[C++] PR 79361

Message ID 5817d25c-aa16-ff6a-e720-d34df14f9521@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Feb. 23, 2017, 2:02 p.m. UTC
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.

/////////////////////
/cp
2017-02-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/79361
	* pt.c (register_specialization): Check duplicate_decls return value
	for error_mark_node and pass it back.

/testsuite
2017-02-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/79361
	* g++.dg/cpp0x/pr79361-1.C: New.
	* g++.dg/cpp0x/pr79361-2.C: Likewise.

Comments

Jason Merrill Feb. 23, 2017, 4:43 p.m. UTC | #1
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.
>
> /////////////////////
>
>
diff mbox

Patch

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" }