Commit 40013af7 by Jason Merrill Committed by Jason Merrill

pt.c (fold_non_dependent_expr_sfinae): Split out from...

	* pt.c (fold_non_dependent_expr_sfinae): Split out from...
	(fold_non_dependent_expr): ...here.
	(convert_nontype_argument): Use it.  Take complain parm.
	Use perform_implicit_conversion	instead of ocp_convert.
	Allow cv-qual changes.
	(convert_template_argument): Pass complain down.
	(tsubst_template_arg): Suppress constant expression warnings.
	Don't fold here.

From-SVN: r163895
parent ea76c60a
2010-09-06 Jason Merrill <jason@redhat.com> 2010-09-06 Jason Merrill <jason@redhat.com>
* pt.c (fold_non_dependent_expr_sfinae): Split out from...
(fold_non_dependent_expr): ...here.
(convert_nontype_argument): Use it. Take complain parm.
Use perform_implicit_conversion instead of ocp_convert.
Allow cv-qual changes.
(convert_template_argument): Pass complain down.
(tsubst_template_arg): Suppress constant expression warnings.
Don't fold here.
* method.c (synthesized_method_walk): In constructors, also check * method.c (synthesized_method_walk): In constructors, also check
subobject destructors. subobject destructors.
......
...@@ -131,7 +131,7 @@ static int type_unification_real (tree, tree, tree, const tree *, ...@@ -131,7 +131,7 @@ static int type_unification_real (tree, tree, tree, const tree *,
unsigned int, int, unification_kind_t, int); unsigned int, int, unification_kind_t, int);
static void note_template_header (int); static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree); 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, static tree convert_template_argument (tree, tree, tree,
tsubst_flags_t, int, tree); tsubst_flags_t, int, tree);
static int for_each_template_parm (tree, tree_fn_t, void*, static int for_each_template_parm (tree, tree_fn_t, void*,
...@@ -4800,8 +4800,8 @@ redeclare_class_template (tree type, tree parms) ...@@ -4800,8 +4800,8 @@ redeclare_class_template (tree type, tree parms)
/* Simplify EXPR if it is a non-dependent expression. Returns the /* Simplify EXPR if it is a non-dependent expression. Returns the
(possibly simplified) expression. */ (possibly simplified) expression. */
tree static tree
fold_non_dependent_expr (tree expr) fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
{ {
if (expr == NULL_TREE) if (expr == NULL_TREE)
return NULL_TREE; return NULL_TREE;
...@@ -4823,7 +4823,7 @@ fold_non_dependent_expr (tree expr) ...@@ -4823,7 +4823,7 @@ fold_non_dependent_expr (tree expr)
processing_template_decl = 0; processing_template_decl = 0;
expr = tsubst_copy_and_build (expr, expr = tsubst_copy_and_build (expr,
/*args=*/NULL_TREE, /*args=*/NULL_TREE,
tf_error, complain,
/*in_decl=*/NULL_TREE, /*in_decl=*/NULL_TREE,
/*function_p=*/false, /*function_p=*/false,
/*integral_constant_expression_p=*/true); /*integral_constant_expression_p=*/true);
...@@ -4832,6 +4832,12 @@ fold_non_dependent_expr (tree expr) ...@@ -4832,6 +4832,12 @@ fold_non_dependent_expr (tree expr)
return expr; 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. /* EXPR is an expression which is used in a constant-expression context.
For instance, it could be a VAR_DECL with a constant initializer. For instance, it could be a VAR_DECL with a constant initializer.
Extract the innermost constant expression. Extract the innermost constant expression.
...@@ -4960,7 +4966,7 @@ has_value_dependent_address (tree op) ...@@ -4960,7 +4966,7 @@ has_value_dependent_address (tree op)
hacks can go away after we fix the double coercion problem. */ hacks can go away after we fix the double coercion problem. */
static tree static tree
convert_nontype_argument (tree type, tree expr) convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{ {
tree expr_type; tree expr_type;
...@@ -4969,11 +4975,13 @@ convert_nontype_argument (tree type, tree expr) ...@@ -4969,11 +4975,13 @@ convert_nontype_argument (tree type, tree expr)
catch this later), but only to provide better diagnostic for this catch this later), but only to provide better diagnostic for this
common user mistake. As suggested by DR 100, we do not mention common user mistake. As suggested by DR 100, we do not mention
linkage issues in the diagnostic as this is not the point. */ linkage issues in the diagnostic as this is not the point. */
/* FIXME we're making this OK. */
if (TREE_CODE (expr) == STRING_CST) if (TREE_CODE (expr) == STRING_CST)
{ {
error ("%qE is not a valid template argument for type %qT " if (complain & tf_error)
"because string literals can never be used in this context", error ("%qE is not a valid template argument for type %qT "
expr, type); "because string literals can never be used in this context",
expr, type);
return NULL_TREE; return NULL_TREE;
} }
...@@ -4992,8 +5000,8 @@ convert_nontype_argument (tree type, tree expr) ...@@ -4992,8 +5000,8 @@ convert_nontype_argument (tree type, tree expr)
if (TYPE_REF_OBJ_P (type) if (TYPE_REF_OBJ_P (type)
&& has_value_dependent_address (expr)) && has_value_dependent_address (expr))
/* If we want the address and it's value-dependent, don't fold. */; /* If we want the address and it's value-dependent, don't fold. */;
else else if (!type_unknown_p (expr))
expr = fold_non_dependent_expr (expr); expr = fold_non_dependent_expr_sfinae (expr, complain);
if (error_operand_p (expr)) if (error_operand_p (expr))
return error_mark_node; return error_mark_node;
expr_type = TREE_TYPE (expr); expr_type = TREE_TYPE (expr);
...@@ -5061,15 +5069,16 @@ convert_nontype_argument (tree type, tree expr) ...@@ -5061,15 +5069,16 @@ convert_nontype_argument (tree type, tree expr)
do not fold into integer constants. */ do not fold into integer constants. */
if (TREE_CODE (expr) != INTEGER_CST) if (TREE_CODE (expr) != INTEGER_CST)
{ {
error ("%qE is not a valid template argument for type %qT " if (complain & tf_error)
"because it is a non-constant expression", expr, type); error ("%qE is not a valid template argument for type %qT "
"because it is a non-constant expression", expr, type);
return NULL_TREE; return NULL_TREE;
} }
/* At this point, an implicit conversion does what we want, /* At this point, an implicit conversion does what we want,
because we already know that the expression is of integral because we already know that the expression is of integral
type. */ type. */
expr = ocp_convert (type, expr, CONV_IMPLICIT, LOOKUP_PROTECT); expr = perform_implicit_conversion (type, expr, complain);
if (expr == error_mark_node) if (expr == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -5319,7 +5328,8 @@ convert_nontype_argument (tree type, tree expr) ...@@ -5319,7 +5328,8 @@ convert_nontype_argument (tree type, tree expr)
/* Sanity check: did we actually convert the argument to the /* Sanity check: did we actually convert the argument to the
right type? */ 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; return expr;
} }
...@@ -5784,7 +5794,7 @@ convert_template_argument (tree parm, ...@@ -5784,7 +5794,7 @@ convert_template_argument (tree parm,
conversions can occur is part of determining which conversions can occur is part of determining which
function template to call, or whether a given explicit function template to call, or whether a given explicit
argument specification is valid. */ argument specification is valid. */
val = convert_nontype_argument (t, orig_arg); val = convert_nontype_argument (t, orig_arg, complain);
else else
val = orig_arg; val = orig_arg;
...@@ -8270,9 +8280,12 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -8270,9 +8280,12 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
r = tsubst (t, args, complain, in_decl); r = tsubst (t, args, complain, in_decl);
else else
{ {
if (!(complain & tf_warning))
++c_inhibit_evaluation_warnings;
r = tsubst_expr (t, args, complain, in_decl, r = tsubst_expr (t, args, complain, in_decl,
/*integral_constant_expression_p=*/true); /*integral_constant_expression_p=*/true);
r = fold_non_dependent_expr (r); if (!(complain & tf_warning))
--c_inhibit_evaluation_warnings;
} }
return r; return r;
} }
......
2010-09-06 Jason Merrill <jason@redhat.com> 2010-09-06 Jason Merrill <jason@redhat.com>
* g++.dg/template/sfinae25.C: New.
* g++.dg/template/char1.C: Expect warning.
* g++.dg/template/nontype10.C: Likewise.
* g++.dg/cpp0x/implicit9.C: New. * g++.dg/cpp0x/implicit9.C: New.
* g++.dg/cpp0x/initlist43.C: New. * g++.dg/cpp0x/initlist43.C: New.
......
template <class CharType, CharType line_terminator = 0> template <class CharType, CharType line_terminator = 0>
class String {}; class String {};
String<char, 255> s; String<char, 255> s; // { dg-warning "overflow" }
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
template <int T> struct A {}; template <int T> struct A {};
template <void* T> struct B {}; template <void* T> struct B {};
A<NULL> a; A<NULL> a; // { dg-warning "NULL" }
B<NULL> b; // { dg-error "" } B<NULL> b; // { dg-error "" }
template <int I>
struct A { };
template <int J>
void f(A<1/J>);
template <int J>
void f(...) { }
int main()
{
f<0>();
}
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