Commit 61f8d165 by Jason Merrill Committed by Jason Merrill

call.c (build_integral_nontype_arg_conv): New.

	* call.c (build_integral_nontype_arg_conv): New.
	* cp-tree.h: Declare it.
	* pt.c (convert_nontype_argument): Use it.

From-SVN: r166011
parent 2842beb6
2010-10-27 Jason Merrill <jason@redhat.com>
* call.c (build_integral_nontype_arg_conv): New.
* cp-tree.h: Declare it.
* pt.c (convert_nontype_argument): Use it.
* error.c (dump_simple_decl): Print constexpr.
* cvt.c (build_up_reference): Use target_type for the temporary var.
......
......@@ -3165,6 +3165,76 @@ build_user_type_conversion (tree totype, tree expr, int flags)
return NULL_TREE;
}
/* Subroutine of convert_nontype_argument.
EXPR is an argument for a template non-type parameter of integral or
enumeration type. Do any necessary conversions (that are permitted for
non-type arguments) to convert it to the parameter type.
If conversion is successful, returns the converted expression;
otherwise, returns error_mark_node. */
tree
build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain)
{
conversion *conv;
void *p;
tree t;
if (error_operand_p (expr))
return error_mark_node;
gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
/*c_cast_p=*/false,
LOOKUP_IMPLICIT);
/* for a non-type template-parameter of integral or
enumeration type, integral promotions (4.5) and integral
conversions (4.7) are applied. */
/* It should be sufficient to check the outermost conversion step, since
there are no qualification conversions to integer type. */
if (conv)
switch (conv->kind)
{
/* A conversion function is OK. If it isn't constexpr, we'll
complain later that the argument isn't constant. */
case ck_user:
/* The lvalue-to-rvalue conversion is OK. */
case ck_rvalue:
case ck_identity:
break;
case ck_std:
t = conv->u.next->type;
if (INTEGRAL_OR_ENUMERATION_TYPE_P (t))
break;
if (complain & tf_error)
error ("conversion from %qT to %qT not considered for "
"non-type template argument", t, type);
/* and fall through. */
default:
conv = NULL;
break;
}
if (conv)
expr = convert_like (conv, expr, complain);
else
expr = error_mark_node;
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
return expr;
}
/* Do any initial processing on the arguments to a function call. */
static VEC(tree,gc) *
......
......@@ -4651,6 +4651,7 @@ extern tree strip_top_quals (tree);
extern bool reference_related_p (tree, tree);
extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t);
extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int);
extern tree build_integral_nontype_arg_conv (tree, tree, tsubst_flags_t);
extern tree perform_direct_initialization_if_possible (tree, tree, bool,
tsubst_flags_t);
extern tree in_charge_arg_for_name (tree);
......
......@@ -5069,10 +5069,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
(_conv.integral_) are applied. */
if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
{
if (!INTEGRAL_OR_ENUMERATION_TYPE_P (expr_type))
tree t = build_integral_nontype_arg_conv (type, expr, complain);
t = fold_decl_constant_value (t);
if (t != error_mark_node)
expr = t;
if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr)))
return error_mark_node;
expr = fold_decl_constant_value (expr);
/* Conversion was allowed: fold it to a bare integer constant. */
expr = fold (expr);
/* Notice that there are constant expressions like '4 % 0' which
do not fold into integer constants. */
if (TREE_CODE (expr) != INTEGER_CST)
......@@ -5082,16 +5089,6 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
"because it is a non-constant expression", expr, type);
return NULL_TREE;
}
/* At this point, an implicit conversion does what we want,
because we already know that the expression is of integral
type. */
expr = perform_implicit_conversion (type, expr, complain);
if (expr == error_mark_node)
return error_mark_node;
/* Conversion was allowed: fold it to a bare integer constant. */
expr = fold (expr);
}
/* [temp.arg.nontype]/5, bullet 2
......
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