diff options
author | Jason Merrill <jason@redhat.com> | 2011-03-28 12:13:50 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-03-28 12:13:50 -0400 |
commit | 62add5e145ffe3f87f93bb40e0d9ccbf20044420 (patch) | |
tree | 00c7516b10cc587b3cba7257e430c1e64a83a2e7 | |
parent | 0309d28824f040972a212183b34c45d59449b529 (diff) | |
download | gcc-62add5e145ffe3f87f93bb40e0d9ccbf20044420.zip gcc-62add5e145ffe3f87f93bb40e0d9ccbf20044420.tar.gz gcc-62add5e145ffe3f87f93bb40e0d9ccbf20044420.tar.bz2 |
Core 898
Core 898
* semantics.c (constexpr_fn_retval): New. Allow using-declaration
and using-definition.
(register_constexpr_fundef): Call it.
From-SVN: r171611
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 50 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-using.C | 27 |
4 files changed, 82 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3bbeddf..baaf94e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2011-03-28 Jason Merrill <jason@redhat.com> + 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 41ab858..6906c1b 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 863f599..35b8c53 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-03-28 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/constexpr-using.C: New. + * g++.dg/cpp0x/constexpr-noexcept.C: New. 2011-03-28 H.J. Lu <hongjiu.lu@intel.com> 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 0000000..fc794e9 --- /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 <class T> +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<int>(); + +static_assert (i == 84, "i == 84"); +static_assert (i2 == 84, "i2 == 84"); + |