Commit 62add5e1 by Jason Merrill Committed by Jason Merrill

Core 898

	Core 898
	* semantics.c (constexpr_fn_retval): New.  Allow using-declaration
	and using-definition.
	(register_constexpr_fundef): Call it.

From-SVN: r171611
parent 0309d288
2011-03-28 Jason Merrill <jason@redhat.com> 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 * except.c (build_noexcept_spec): Call cxx_constant_value after
converting to bool. converting to bool.
......
...@@ -5585,6 +5585,52 @@ build_constexpr_constructor_member_initializers (tree type, tree body) ...@@ -5585,6 +5585,52 @@ build_constexpr_constructor_member_initializers (tree type, tree body)
return error_mark_node; 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. /* We are processing the definition of the constexpr function FUN.
Check that its BODY fulfills the propriate requirements and Check that its BODY fulfills the propriate requirements and
enter it in the constexpr function definition table. enter it in the constexpr function definition table.
...@@ -5610,13 +5656,13 @@ register_constexpr_fundef (tree fun, tree body) ...@@ -5610,13 +5656,13 @@ register_constexpr_fundef (tree fun, tree body)
body = TREE_OPERAND (body, 0); body = TREE_OPERAND (body, 0);
if (TREE_CODE (body) == CLEANUP_POINT_EXPR) if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
body = TREE_OPERAND (body, 0); 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); error ("body of constexpr function %qD not a return-statement", fun);
DECL_DECLARED_CONSTEXPR_P (fun) = false; DECL_DECLARED_CONSTEXPR_P (fun) = false;
return NULL; return NULL;
} }
body = unshare_expr (TREE_OPERAND (body, 0));
} }
if (!potential_rvalue_constant_expression (body)) if (!potential_rvalue_constant_expression (body))
......
2011-03-28 Jason Merrill <jason@redhat.com> 2011-03-28 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-using.C: New.
* g++.dg/cpp0x/constexpr-noexcept.C: New. * g++.dg/cpp0x/constexpr-noexcept.C: New.
2011-03-28 H.J. Lu <hongjiu.lu@intel.com> 2011-03-28 H.J. Lu <hongjiu.lu@intel.com>
......
// 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");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment