* [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513)
@ 2019-02-27 22:44 Jakub Jelinek
2019-02-28 0:08 ` Jason Merrill
0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2019-02-27 22:44 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513)
2019-02-27 22:44 [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513) Jakub Jelinek
@ 2019-02-28 0:08 ` Jason Merrill
2019-02-28 23:10 ` [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513, take 2) Jakub Jelinek
0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2019-02-28 0:08 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
On 2/27/19 5:37 PM, Jakub Jelinek wrote:
> 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.
That sounds better, yes.
> 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
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513, take 2)
2019-02-28 0:08 ` Jason Merrill
@ 2019-02-28 23:10 ` Jakub Jelinek
2019-03-01 14:07 ` Jason Merrill
0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2019-02-28 23:10 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
On Wed, Feb 27, 2019 at 06:48:13PM -0500, Jason Merrill wrote:
> > 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.
>
> That sounds better, yes.
Ok, here is an updated patch that does that.
Bootstrapped/regtested on x86_64-linux and i686-linux (98,11,14,17,2a in
both cases), ok for trunk?
2019-02-28 Jakub Jelinek <jakub@redhat.com>
Implement P1002R1, Try-catch blocks in constexpr functions
PR c++/89513
* parser.c (cp_parser_ctor_initializer_opt_and_function_body):
Diagnose constexpr ctor or function with function-try-block with
pedwarn for c++17 and earlier. Formatting fix.
(cp_parser_try_block): Use pedwarn instead of error and only for
c++17 and earlier when try block appears in constexpr function.
* constexpr.c (build_constexpr_constructor_member_initializers):
Handle TRY_BLOCK here instead of erroring on it.
* g++.dg/cpp2a/constexpr-try1.C: New test.
* g++.dg/cpp2a/constexpr-try2.C: New test.
* g++.dg/cpp2a/constexpr-try3.C: New test.
* g++.dg/cpp2a/constexpr-try4.C: New test.
* g++.dg/cpp2a/constexpr-try5.C: New test.
* g++.dg/cpp0x/constexpr-ctor10.C: Don't expect error for C++2a.
--- gcc/cp/parser.c.jj 2019-02-28 08:14:58.240563115 +0100
+++ gcc/cp/parser.c 2019-02-28 09:37:21.498804731 +0100
@@ -22590,11 +22590,25 @@ 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)
+ && cxx_dialect < cxx2a)
+ {
+ if (DECL_CONSTRUCTOR_P (current_function_decl))
+ pedwarn (input_location, 0,
+ "function-try-block body of %<constexpr%> constructor only "
+ "available with -std=c++2a or -std=gnu++2a");
+ else
+ pedwarn (input_location, 0,
+ "function-try-block body of %<constexpr%> function only "
+ "available with -std=c++2a or -std=gnu++2a");
+ }
+
/* Begin the function body. */
body = begin_function_body ();
/* Parse the optional ctor-initializer. */
@@ -25329,8 +25343,11 @@ cp_parser_try_block (cp_parser* parser)
cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
if (parser->in_function_body
- && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
- error ("%<try%> in %<constexpr%> function");
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+ && cxx_dialect < cxx2a)
+ pedwarn (input_location, 0,
+ "%<try%> in %<constexpr%> function only "
+ "available with -std=c++2a or -std=gnu++2a");
try_block = begin_try_block ();
cp_parser_compound_statement (parser, NULL, BCS_TRY_BLOCK, false);
--- gcc/cp/constexpr.c.jj 2019-02-27 15:49:26.946419095 +0100
+++ gcc/cp/constexpr.c 2019-02-28 10:07:48.219840527 +0100
@@ -601,6 +601,12 @@ build_constexpr_constructor_member_initi
gcc_unreachable ();
}
found:
+ if (TREE_CODE (body) == TRY_BLOCK)
+ {
+ body = TREE_OPERAND (body, 0);
+ if (TREE_CODE (body) == BIND_EXPR)
+ body = BIND_EXPR_BODY (body);
+ }
if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
{
body = TREE_OPERAND (body, 0);
@@ -626,12 +632,6 @@ build_constexpr_constructor_member_initi
break;
}
}
- else if (TREE_CODE (body) == TRY_BLOCK)
- {
- error ("body of %<constexpr%> constructor cannot be "
- "a function-try-block");
- return error_mark_node;
- }
else if (EXPR_P (body))
ok = build_data_member_initialization (body, &vec);
else
--- gcc/testsuite/g++.dg/cpp2a/constexpr-try1.C.jj 2019-02-28 09:38:13.651949049 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-try1.C 2019-02-28 10:15:15.301509905 +0100
@@ -0,0 +1,44 @@
+// PR c++/89513
+// { dg-do compile { target c++11 } }
+
+constexpr bool foo ()
+try { // { dg-error "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ return true;
+} catch (...) { // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ return false;
+} // { dg-error "body of 'constexpr' function" "" { target c++11_only } }
+
+constexpr bool bar ()
+try { // { dg-error "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ try { // { dg-error "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ return true; // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } .-1 }
+ } catch (int) { // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ return false;
+ }
+} catch (...) { // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ return false;
+} // { dg-error "not a return-statement" "" { target c++11_only } }
+
+constexpr bool baz ()
+{
+ try { return true; } catch (...) { return false; } // { dg-error "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+} // { dg-error "not a return-statement" "" { target c++11_only } }
+ // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } .-2 }
+
+struct S {
+ constexpr S () try : m (1) // { dg-error "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ {
+ try { // { dg-error "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ } catch (int) { // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ } // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } .-2 }
+ } catch (...) { // { dg-error "'constexpr' constructor does not have empty body" "" { target c++11_only } }
+ }
+ int m;
+};
+
+struct T {
+ constexpr T ()
+ try { // { dg-error "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ } catch (...) { // { dg-error "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ }
+};
--- gcc/testsuite/g++.dg/cpp2a/constexpr-try2.C.jj 2019-02-28 10:15:24.807354041 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-try2.C 2019-02-28 10:17:13.508571718 +0100
@@ -0,0 +1,45 @@
+// PR c++/89513
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic" }
+
+constexpr bool foo ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ return true;
+} catch (...) { // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ return false;
+} // { dg-error "body of 'constexpr' function" "" { target c++11_only } }
+
+constexpr bool bar ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ return true; // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } .-1 }
+ } catch (int) { // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ return false;
+ }
+} catch (...) { // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ return false;
+} // { dg-error "not a return-statement" "" { target c++11_only } }
+
+constexpr bool baz ()
+{
+ try { return true; } catch (...) { return false; } // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+} // { dg-error "not a return-statement" "" { target c++11_only } }
+ // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } .-2 }
+
+struct S {
+ constexpr S () try : m (1) // { dg-warning "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ {
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ } catch (int) { // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ } // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } .-2 }
+ } catch (...) { // { dg-error "'constexpr' constructor does not have empty body" "" { target c++11_only } }
+ }
+ int m;
+};
+
+struct T {
+ constexpr T ()
+ try { // { dg-warning "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ } catch (...) { // { dg-warning "compound-statement in 'constexpr' function" "" { target c++11_only } }
+ }
+};
--- gcc/testsuite/g++.dg/cpp2a/constexpr-try3.C.jj1 2019-02-28 10:49:41.436744795 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-try3.C 2019-02-28 10:21:37.469243648 +0100
@@ -0,0 +1,44 @@
+// PR c++/89513
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+constexpr bool foo ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ return true;
+} catch (...) {
+ return false;
+} // { dg-error "body of 'constexpr' function" "" { target c++11_only } }
+
+constexpr bool bar ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ return true;
+ } catch (int) {
+ return false;
+ }
+} catch (...) {
+ return false;
+} // { dg-error "not a return-statement" "" { target c++11_only } }
+
+constexpr bool baz ()
+{
+ try { return true; } catch (...) { return false; } // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+} // { dg-error "not a return-statement" "" { target c++11_only } }
+
+struct S {
+ constexpr S () try : m (1) // { dg-warning "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ {
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ } catch (int) {
+ }
+ } catch (...) { // { dg-error "'constexpr' constructor does not have empty body" "" { target c++11_only } }
+ }
+ int m;
+};
+
+struct T {
+ constexpr T ()
+ try { // { dg-warning "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ } catch (...) {
+ }
+};
--- gcc/testsuite/g++.dg/cpp2a/constexpr-try4.C.jj 2019-02-28 10:26:09.785798575 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-try4.C 2019-02-28 10:33:06.632994747 +0100
@@ -0,0 +1,61 @@
+// PR c++/89513
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+constexpr int foo ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ int a = 1;
+ for (int i = 0; i < 10; i++)
+ a += i;
+ return a;
+} catch (...) {
+ return -1;
+}
+
+constexpr int bar ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ int a = 0;
+ for (int i = 0; i < 9; i++)
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ a += i;
+ } catch (int) {
+ return -1;
+ }
+ return a;
+} catch (...) {
+ return -2;
+}
+
+constexpr bool baz ()
+{
+ try { return true; } catch (...) { return false; } // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+}
+
+struct S {
+ constexpr S () try : m (1) // { dg-warning "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ {
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ m += 2;
+ } catch (int) {
+ m = -1;
+ }
+ } catch (...) {
+ m = -2;
+ }
+ int m;
+ constexpr int get () const { return m; }
+};
+
+struct T {
+ constexpr T ()
+ try { // { dg-warning "function-try-block body of 'constexpr' constructor only available with" "" { target c++17_down } }
+ } catch (...) {
+ }
+};
+
+static_assert (foo () == 46, "");
+static_assert (bar () == 36, "");
+static_assert (baz (), "");
+constexpr S s;
+static_assert (s.get () == 3, "");
+constexpr T t;
--- gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C.jj 2019-02-28 10:33:53.783225162 +0100
+++ gcc/testsuite/g++.dg/cpp2a/constexpr-try5.C 2019-02-28 10:44:47.392549962 +0100
@@ -0,0 +1,40 @@
+// PR c++/89513
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+constexpr int foo ()
+try { // { dg-warning "function-try-block body of 'constexpr' function only available with" "" { target c++17_down } }
+ int a; // { dg-error "uninitialized variable 'a' in 'constexpr' function" }
+ static double b = 1.0;// { dg-error "'b' declared 'static' in 'constexpr' function" }
+ goto l; // { dg-error "'goto' in 'constexpr' function" }
+ l:;
+ return 0;
+} catch (...) {
+ long int c; // { dg-error "uninitialized variable 'c' in 'constexpr' function" }
+ static float d = 2.0f;// { dg-error "'d' declared 'static' in 'constexpr' function" }
+ goto l2; // { dg-error "'goto' in 'constexpr' function" }
+ l2:;
+ return -1;
+}
+
+constexpr int bar ()
+{
+ int a; // { dg-error "uninitialized variable 'a' in 'constexpr' function" }
+ static long double b = 3.0;// { dg-error "'b' declared 'static' in 'constexpr' function" }
+ goto l; // { dg-error "'goto' in 'constexpr' function" }
+ l:;
+ try { // { dg-warning "'try' in 'constexpr' function only available with" "" { target c++17_down } }
+ short c; // { dg-error "uninitialized variable 'c' in 'constexpr' function" }
+ static float d; // { dg-error "'d' declared 'static' in 'constexpr' function" }
+ // { dg-error "uninitialized variable 'd' in 'constexpr' function" "" { target *-*-* } .-1 }
+ goto l2; // { dg-error "'goto' in 'constexpr' function" }
+ l2:;
+ return 0;
+ } catch (int) {
+ char e; // { dg-error "uninitialized variable 'e' in 'constexpr' function" }
+ static int f = 5; // { dg-error "'f' declared 'static' in 'constexpr' function" }
+ goto l3; // { dg-error "'goto' in 'constexpr' function" }
+ l3:;
+ return 1;
+ }
+}
--- gcc/testsuite/g++.dg/cpp0x/constexpr-ctor10.C.jj 2014-03-10 10:50:13.252983951 +0100
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-ctor10.C 2019-02-28 09:40:47.378426863 +0100
@@ -2,5 +2,5 @@
// { dg-do compile { target c++11 } }
struct foo {
- constexpr foo() try { } catch(...) { }; // { dg-error "constexpr" }
+ constexpr foo() try { } catch(...) { }; // { dg-error "constexpr" "" { target c++17_down } }
};
Jakub
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513, take 2)
2019-02-28 23:10 ` [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513, take 2) Jakub Jelinek
@ 2019-03-01 14:07 ` Jason Merrill
0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2019-03-01 14:07 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
On 2/28/19 6:03 PM, Jakub Jelinek wrote:
> On Wed, Feb 27, 2019 at 06:48:13PM -0500, Jason Merrill wrote:
>>> 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.
>>
>> That sounds better, yes.
>
> Ok, here is an updated patch that does that.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux (98,11,14,17,2a in
> both cases), ok for trunk?
>
> 2019-02-28 Jakub Jelinek <jakub@redhat.com>
>
> Implement P1002R1, Try-catch blocks in constexpr functions
> PR c++/89513
> * parser.c (cp_parser_ctor_initializer_opt_and_function_body):
> Diagnose constexpr ctor or function with function-try-block with
> pedwarn for c++17 and earlier. Formatting fix.
> (cp_parser_try_block): Use pedwarn instead of error and only for
> c++17 and earlier when try block appears in constexpr function.
> * constexpr.c (build_constexpr_constructor_member_initializers):
> Handle TRY_BLOCK here instead of erroring on it.
OK.
Jason
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-03-01 14:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-27 22:44 [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513) Jakub Jelinek
2019-02-28 0:08 ` Jason Merrill
2019-02-28 23:10 ` [C++ PATCH] Reject constexpr functions with function-try-block (PR c++/89513, take 2) Jakub Jelinek
2019-03-01 14:07 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).