[C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513)

Jakub Jelinek jakub@redhat.com
Wed Feb 27 22:44:00 GMT 2019


Hi!

C++ before 2a says that constexpr constructors may not have function-try-block
body, for other constexpr functions it instead says that the function body
can be (=delete, =default or compound-statement), but that rules out
function-try-block as well.

For ctors we were diagnostic this in
build_constexpr_constructor_member_initializers, but with worse locus, so
this patch diagnoses it for both ctors and other constexpr functions in the
same place.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Or would you prefer to have P1002R1 implemented and thus make this perhaps a
pedwarn before cxx2a, similarly for the error on try block in the body and
tweak build_constexpr_constructor_member_initializers?  I think constexpr
evaluation handles TRY_BLOCK already.

2019-02-27  Jakub Jelinek  <jakub@redhat.com>

	PR c++/89513
	* parser.c (cp_parser_ctor_initializer_opt_and_function_body):
	Diagnose constexpr ctor or function with function-try-block.
	Formatting fix.
	* constexpr.c (build_constexpr_constructor_member_initializers):
	Don't diagnose constexpr ctor with function-try-block here.

	* g++.dg/cpp0x/constexpr-89513.C: New test.

--- gcc/cp/parser.c.jj	2019-02-23 11:32:45.705614155 +0100
+++ gcc/cp/parser.c	2019-02-27 14:18:26.211248671 +0100
@@ -22589,11 +22589,22 @@ cp_parser_ctor_initializer_opt_and_funct
 						  bool in_function_try_block)
 {
   tree body, list;
-  const bool check_body_p =
-     DECL_CONSTRUCTOR_P (current_function_decl)
-     && DECL_DECLARED_CONSTEXPR_P (current_function_decl);
+  const bool check_body_p
+     = (DECL_CONSTRUCTOR_P (current_function_decl)
+	&& DECL_DECLARED_CONSTEXPR_P (current_function_decl));
   tree last = NULL;
 
+  if (in_function_try_block
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
+    {
+      if (DECL_CONSTRUCTOR_P (current_function_decl))
+	error ("body of %<constexpr%> constructor cannot be "
+	       "a function-try-block");
+      else
+	error ("body of %<constexpr%> function cannot be "
+	       "a function-try-block");
+    }
+
   /* Begin the function body.  */
   body = begin_function_body ();
   /* Parse the optional ctor-initializer.  */
--- gcc/cp/constexpr.c.jj	2019-02-26 15:37:06.475371073 +0100
+++ gcc/cp/constexpr.c	2019-02-27 14:17:34.434096156 +0100
@@ -627,11 +627,8 @@ build_constexpr_constructor_member_initi
 	}
     }
   else if (TREE_CODE (body) == TRY_BLOCK)
-    {
-      error ("body of %<constexpr%> constructor cannot be "
-	     "a function-try-block");
-      return error_mark_node;
-    }
+    /* This should have been diagnosed earlier.  */
+    return error_mark_node;
   else if (EXPR_P (body))
     ok = build_data_member_initialization (body, &vec);
   else
--- gcc/testsuite/g++.dg/cpp0x/constexpr-89513.C.jj	2019-02-27 14:28:50.280033938 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-89513.C	2019-02-27 14:34:51.585120108 +0100
@@ -0,0 +1,48 @@
+// PR c++/89513
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+constexpr bool foo ()
+try {			// { dg-error "body of 'constexpr' function cannot be a function-try-block" }
+  return true;
+} catch (...) {
+  return false;
+}			// { dg-error "body of 'constexpr' function" "" { target c++11_only } }
+
+#if __cplusplus > 201103L
+constexpr bool bar ()
+try {			// { dg-error "body of 'constexpr' function cannot be a function-try-block" "" { target c++14 } }
+  try {			// { dg-error "'try' in 'constexpr' function" "" { target c++14 } }
+    return true;
+  } catch (int) {
+    return false;
+  }
+} catch (...) {
+  return false;
+}
+
+constexpr bool baz ()
+{
+  try { return true; } catch (...) { return false; }	// { dg-error "'try' in 'constexpr' function" "" { target c++14 } }
+}
+#endif
+
+struct S {
+  constexpr S () try : m (1)	// { dg-error "body of 'constexpr' constructor cannot be a function-try-block" }
+  {
+#if __cplusplus > 201103L
+    try {		// { dg-error "'try' in 'constexpr' function" "" { target c++14 } }
+    } catch (int) {
+    }
+#endif
+  } catch (...) {
+  }
+  int m;
+};
+
+struct T {
+  constexpr T ()
+  try {			// { dg-error "body of 'constexpr' constructor cannot be a function-try-block" }
+  } catch (...) {
+  }
+};

	Jakub



More information about the Gcc-patches mailing list