https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68475

This patch fixes an ICE with -fno-exceptions. We were not checking eh spec equality when merging decls, leading to a checking-assert blowing up later. As postulated in the bug report, always checking leads to good behaviour. Even though we ignore the eh spec when generating code, we should check the source is well formed.

tested on x86_64-linux, ok?

nathan
2016-03-30  Nathan Sidwell  <nat...@acm.org>

	PR c++/68475
	* decl.c (check_redeclaration_exception_specification): Check
	regardless of -fno-exceptions.

	PR c++/68475
	* g++.dg/eh/spec12.C: New.

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 234516)
+++ cp/decl.c	(working copy)
@@ -1200,9 +1200,11 @@ check_redeclaration_exception_specificat
      If any declaration of a function has an exception-specification,
      all declarations, including the definition and an explicit
      specialization, of that function shall have an
-     exception-specification with the same set of type-ids.  */
+     exception-specification with the same set of type-ids.
+
+     Even when fno-exceptions is in effect, any specifications must
+     still  match.   */
   if (! DECL_IS_BUILTIN (old_decl)
-      && flag_exceptions
       && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
     {
       const char *msg
Index: testsuite/g++.dg/eh/spec12.C
===================================================================
--- testsuite/g++.dg/eh/spec12.C	(nonexistent)
+++ testsuite/g++.dg/eh/spec12.C	(working copy)
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-additional-options "-fno-exceptions" }
+
+// PR68475 we used to not check eh spec matching with -fno-exceptions,
+// but this could lead to ICEs.
+
+template < typename > struct traits;
+
+template < typename T > struct X
+{
+  X & operator = (X &&) noexcept (traits < T >::foo ()); // { dg-inform "previous declaration" }
+};
+
+template < typename T >
+X < T > &
+X < T >::operator = (X &&) noexcept (traits < T >::bar ()) // { dg-error "different exception specifier" }
+{
+  return *this;
+}

Reply via email to