From 62add5e145ffe3f87f93bb40e0d9ccbf20044420 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 28 Mar 2011 12:13:50 -0400 Subject: [PATCH] Core 898 Core 898 * semantics.c (constexpr_fn_retval): New. Allow using-declaration and using-definition. (register_constexpr_fundef): Call it. From-SVN: r171611 --- gcc/cp/ChangeLog | 5 ++ gcc/cp/semantics.c | 50 +++++++++++++++++++- gcc/testsuite/ChangeLog | 2 + gcc/testsuite/g++.dg/cpp0x/constexpr-using.C | 27 +++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-using.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3bbeddf8c64..baaf94e9a53 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2011-03-28 Jason Merrill + Core 898 + * semantics.c (constexpr_fn_retval): New. Allow using-declaration + and using-definition. + (register_constexpr_fundef): Call it. + * except.c (build_noexcept_spec): Call cxx_constant_value after converting to bool. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 41ab8589dad..6906c1be825 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5585,6 +5585,52 @@ build_constexpr_constructor_member_initializers (tree type, tree body) return error_mark_node; } +/* Subroutine of register_constexpr_fundef. BODY is the body of a function + declared to be constexpr, or a sub-statement thereof. Returns the + return value if suitable, error_mark_node for a statement not allowed in + a constexpr function, or NULL_TREE if no return value was found. */ + +static tree +constexpr_fn_retval (tree body) +{ + switch (TREE_CODE (body)) + { + case STATEMENT_LIST: + { + tree_stmt_iterator i; + tree expr = NULL_TREE; + for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i)) + { + tree s = constexpr_fn_retval (tsi_stmt (i)); + if (s == error_mark_node) + return error_mark_node; + else if (s == NULL_TREE) + /* Keep iterating. */; + else if (expr) + /* Multiple return statements. */ + return error_mark_node; + else + expr = s; + } + return expr; + } + + case RETURN_EXPR: + return unshare_expr (TREE_OPERAND (body, 0)); + + case DECL_EXPR: + if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL) + return NULL_TREE; + return error_mark_node; + + case USING_STMT: + return NULL_TREE; + + default: + return error_mark_node; + } +} + /* We are processing the definition of the constexpr function FUN. Check that its BODY fulfills the propriate requirements and enter it in the constexpr function definition table. @@ -5610,13 +5656,13 @@ register_constexpr_fundef (tree fun, tree body) body = TREE_OPERAND (body, 0); if (TREE_CODE (body) == CLEANUP_POINT_EXPR) body = TREE_OPERAND (body, 0); - if (TREE_CODE (body) != RETURN_EXPR) + body = constexpr_fn_retval (body); + if (body == NULL_TREE || body == error_mark_node) { error ("body of constexpr function %qD not a return-statement", fun); DECL_DECLARED_CONSTEXPR_P (fun) = false; return NULL; } - body = unshare_expr (TREE_OPERAND (body, 0)); } if (!potential_rvalue_constant_expression (body)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 863f5994587..35b8c530649 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-03-28 Jason Merrill + * g++.dg/cpp0x/constexpr-using.C: New. + * g++.dg/cpp0x/constexpr-noexcept.C: New. 2011-03-28 H.J. Lu diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-using.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-using.C new file mode 100644 index 00000000000..fc794e9abdf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-using.C @@ -0,0 +1,27 @@ +// Core issue 898 +// { dg-options -std=c++0x } + +namespace N { const int i = 42; } +namespace M { const int j = 42; } + +constexpr int g() { + using namespace N; + using M::j; + static_assert (i == 42, "i == 42"); + return i + j; +} + +template +constexpr int h() { + using namespace N; + using M::j; + static_assert (i == 42, "i == 42"); + return i + j; +} + +constexpr int i = g(); +constexpr int i2 = h(); + +static_assert (i == 84, "i == 84"); +static_assert (i2 == 84, "i2 == 84"); + -- 2.30.2