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

From-SVN: r171611
This commit is contained in:
Jason Merrill 2011-03-28 12:13:50 -04:00 committed by Jason Merrill
parent 0309d28824
commit 62add5e145
4 changed files with 82 additions and 2 deletions

View file

@ -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.

View file

@ -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))

View file

@ -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>

View file

@ -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");