unsigned int, int, unification_kind_t, int);
static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree);
-static tree convert_nontype_argument (tree, tree);
+static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
static tree convert_template_argument (tree, tree, tree,
tsubst_flags_t, int, tree);
static int for_each_template_parm (tree, tree_fn_t, void*,
/* Simplify EXPR if it is a non-dependent expression. Returns the
(possibly simplified) expression. */
-tree
-fold_non_dependent_expr (tree expr)
+static tree
+fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
{
if (expr == NULL_TREE)
return NULL_TREE;
processing_template_decl = 0;
expr = tsubst_copy_and_build (expr,
/*args=*/NULL_TREE,
- tf_error,
+ complain,
/*in_decl=*/NULL_TREE,
/*function_p=*/false,
/*integral_constant_expression_p=*/true);
return expr;
}
+tree
+fold_non_dependent_expr (tree expr)
+{
+ return fold_non_dependent_expr_sfinae (expr, tf_error);
+}
+
/* EXPR is an expression which is used in a constant-expression context.
For instance, it could be a VAR_DECL with a constant initializer.
Extract the innermost constant expression.
hacks can go away after we fix the double coercion problem. */
static tree
-convert_nontype_argument (tree type, tree expr)
+convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
tree expr_type;
catch this later), but only to provide better diagnostic for this
common user mistake. As suggested by DR 100, we do not mention
linkage issues in the diagnostic as this is not the point. */
+ /* FIXME we're making this OK. */
if (TREE_CODE (expr) == STRING_CST)
{
- error ("%qE is not a valid template argument for type %qT "
- "because string literals can never be used in this context",
- expr, type);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because string literals can never be used in this context",
+ expr, type);
return NULL_TREE;
}
if (TYPE_REF_OBJ_P (type)
&& has_value_dependent_address (expr))
/* If we want the address and it's value-dependent, don't fold. */;
- else
- expr = fold_non_dependent_expr (expr);
+ else if (!type_unknown_p (expr))
+ expr = fold_non_dependent_expr_sfinae (expr, complain);
if (error_operand_p (expr))
return error_mark_node;
expr_type = TREE_TYPE (expr);
do not fold into integer constants. */
if (TREE_CODE (expr) != INTEGER_CST)
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is a non-constant expression", expr, type);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "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 = ocp_convert (type, expr, CONV_IMPLICIT, LOOKUP_PROTECT);
+ expr = perform_implicit_conversion (type, expr, complain);
if (expr == error_mark_node)
return error_mark_node;
/* Sanity check: did we actually convert the argument to the
right type? */
- gcc_assert (same_type_p (type, TREE_TYPE (expr)));
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (type, TREE_TYPE (expr)));
return expr;
}
conversions can occur is part of determining which
function template to call, or whether a given explicit
argument specification is valid. */
- val = convert_nontype_argument (t, orig_arg);
+ val = convert_nontype_argument (t, orig_arg, complain);
else
val = orig_arg;
r = tsubst (t, args, complain, in_decl);
else
{
+ if (!(complain & tf_warning))
+ ++c_inhibit_evaluation_warnings;
r = tsubst_expr (t, args, complain, in_decl,
/*integral_constant_expression_p=*/true);
- r = fold_non_dependent_expr (r);
+ if (!(complain & tf_warning))
+ --c_inhibit_evaluation_warnings;
}
return r;
}