[C++] PR 89914 ("[9 Regression] ICE in nothrow_spec_p, at cp/except.c:1238")

Message ID 9284ea1a-c881-6f69-01b0-e5c7f8fbb2e9@oracle.com
State New
Headers show
Series
  • [C++] PR 89914 ("[9 Regression] ICE in nothrow_spec_p, at cp/except.c:1238")
Related show

Commit Message

Paolo Carlini April 5, 2019, 11:11 a.m.
Hi,

this error-recovery regressions is mostly another case - similar to 
c++/89488 - where we want to check that maybe_instantiate_noexcept 
actually succeeds before calling a function that asserts 
!DEFERRED_NOEXCEPT_SPEC_P, nothrow_spec_p this time. I think we want to 
do that consistently in both the semantics.c places. Beyond that, there 
is a secondary issue with -std=c++98, because, in that case, 
synthesized_method_walk, called by implicitly_declare_fn, sets raises to 
error_mark_node and we can't pass it to build_exception_variant (we 
explicitly avoid that elsewhere too). Tested x86_64-linux.

Thanks, Paolo.

////////////////////
/cp
2019-04-05  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/89914
	* semantics.c (trait_expr_value): Don't use TYPE_NOTHROW_P
	when maybe_instantiate_noexcept fails.
	(classtype_has_nothrow_assign_or_copy_p): Likewise.
	* method.c (implicitly_declare_fn): Avoid passing error_mark_node
	to build_exception_variant.

/testsuite
2019-04-05  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/89914
	* g++.dg/ext/has_nothrow_constructor-3.C: New.

Comments

Jason Merrill April 5, 2019, 7:35 p.m. | #1
On 4/5/19 7:11 AM, Paolo Carlini wrote:
> Hi,

> 

> this error-recovery regressions is mostly another case - similar to 

> c++/89488 - where we want to check that maybe_instantiate_noexcept 

> actually succeeds before calling a function that asserts 

> !DEFERRED_NOEXCEPT_SPEC_P, nothrow_spec_p this time. I think we want to 

> do that consistently in both the semantics.c places. Beyond that, there 

> is a secondary issue with -std=c++98, because, in that case, 

> synthesized_method_walk, called by implicitly_declare_fn, sets raises to 

> error_mark_node and we can't pass it to build_exception_variant (we 

> explicitly avoid that elsewhere too). Tested x86_64-linux.


OK.

Jason

Patch

Index: cp/method.c
===================================================================
--- cp/method.c	(revision 270145)
+++ cp/method.c	(working copy)
@@ -2061,7 +2061,14 @@  implicitly_declare_fn (special_function_kind kind,
   /* Create the function.  */
   fn_type = build_method_type_directly (type, return_type, parameter_types);
   if (raises)
-    fn_type = build_exception_variant (fn_type, raises);
+    {
+      if (raises != error_mark_node)
+	fn_type = build_exception_variant (fn_type, raises);
+      else
+	/* Can happen, eg, in C++98 mode for an ill-formed non-static data
+	   member initializer (c++/89914).  */
+	gcc_assert (seen_error ());
+    }
   fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
   if (kind != sfk_inheriting_constructor)
     DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
Index: cp/semantics.c
===================================================================
--- cp/semantics.c	(revision 270145)
+++ cp/semantics.c	(working copy)
@@ -9551,8 +9551,8 @@  classtype_has_nothrow_assign_or_copy_p (tree type,
       if (copy_fn_p (fn) > 0)
 	{
 	  saw_copy = true;
-	  maybe_instantiate_noexcept (fn);
-	  if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
+	  if (!maybe_instantiate_noexcept (fn)
+	      || !TYPE_NOTHROW_P (TREE_TYPE (fn)))
 	    return false;
 	}
     }
@@ -9594,8 +9594,8 @@  trait_expr_value (cp_trait_kind kind, tree type1,
       return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2) 
 	      || (CLASS_TYPE_P (type1)
 		  && (t = locate_ctor (type1))
-		  && (maybe_instantiate_noexcept (t),
-		      TYPE_NOTHROW_P (TREE_TYPE (t)))));
+		  && maybe_instantiate_noexcept (t)
+		  && TYPE_NOTHROW_P (TREE_TYPE (t))));
 
     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
       type1 = strip_array_types (type1);
Index: testsuite/g++.dg/ext/has_nothrow_constructor-3.C
===================================================================
--- testsuite/g++.dg/ext/has_nothrow_constructor-3.C	(nonexistent)
+++ testsuite/g++.dg/ext/has_nothrow_constructor-3.C	(working copy)
@@ -0,0 +1,9 @@ 
+// PR c++/89914
+
+struct A
+{
+  int i = ;  // { dg-error "expected" }
+  // { dg-error "non-static data member" "" { target c++98_only } .-1 }
+};
+
+bool b = __has_nothrow_constructor (A);