2016-03-31 Nathan Sidwell <nathan@acm.org>
PR c++/68475
* decl.c (check_redeclaration_exception_specification): Check
regardless of -fno-exceptions.
* typeck2.c (merge_exception_specifiers): Relax assert by checking
flag_exceptions too.
PR c++/68475
* g++.dg/g++.dg/cpp0x/noexcept29.C: New.
===================================================================
@@ -1202,16 +1202,19 @@ check_redeclaration_exception_specificat
specialization, of that function shall have an
exception-specification with the same set of type-ids. */
if (! DECL_IS_BUILTIN (old_decl)
- && flag_exceptions
&& !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
{
const char *msg
= "declaration of %q+F has a different exception specifier";
bool complained = true;
- if (! DECL_IN_SYSTEM_HEADER (old_decl))
- error (msg, new_decl);
- else
+ if (DECL_IN_SYSTEM_HEADER (old_decl))
complained = pedwarn (0, OPT_Wsystem_headers, msg, new_decl);
+ else if (!flag_exceptions)
+ /* We used to silently permit mismatched eh specs with
+ -fno-exceptions, so make them a pedwarn now. */
+ complained = pedwarn (0, OPT_Wpedantic, msg, new_decl);
+ else
+ error (msg, new_decl);
if (complained)
inform (0, "from previous declaration %q+F", old_decl);
}
===================================================================
@@ -2143,7 +2143,7 @@ merge_exception_specifiers (tree list, t
return add;
noex = TREE_PURPOSE (list);
gcc_checking_assert (!TREE_PURPOSE (add)
- || errorcount
+ || errorcount || !flag_exceptions
|| cp_tree_equal (noex, TREE_PURPOSE (add)));
/* Combine the dynamic-exception-specifiers, if any. */
===================================================================
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+// { 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
+{
+ void Foo () noexcept (traits <T>::foo ()); // { dg-message "previous declaration" }
+};
+
+template <typename T>
+void
+X<T>::Foo () noexcept (traits <T>::bar ()) // { dg-error "different exception specifier" }
+{
+}
+