Commit e90b1c4a by Jason Merrill Committed by Jason Merrill

pt.c (tsubst_default_argument): Handle DEFAULT_ARG.

	* pt.c (tsubst_default_argument): Handle DEFAULT_ARG.
	(tsubst_default_arguments): Only do this once for cloned fns.
	(tsubst): Use typedef_variant_p.  Handle LANG_TYPE.  Don't
	handle expressions.
	(tsubst_expr): Avoid calling tsubst_expr for non-expressions.
	(tsubst_copy_and_build): Likewise.
	(tsubst_initializer_list): Likewise.
	(tsubst_copy): Change default to gcc_unreachable.  Handle
	OVERLOAD and PTRMEM_CST.

From-SVN: r165307
parent 9c3c8ad7
2010-10-10 Jason Merrill <jason@redhat.com> 2010-10-10 Jason Merrill <jason@redhat.com>
* pt.c (tsubst_default_argument): Handle DEFAULT_ARG.
(tsubst_default_arguments): Only do this once for cloned fns.
(tsubst): Use typedef_variant_p. Handle LANG_TYPE. Don't
handle expressions.
(tsubst_expr): Avoid calling tsubst_expr for non-expressions.
(tsubst_copy_and_build): Likewise.
(tsubst_initializer_list): Likewise.
(tsubst_copy): Change default to gcc_unreachable. Handle
OVERLOAD and PTRMEM_CST.
2010-10-10 Jason Merrill <jason@redhat.com>
PR lto/45959 PR lto/45959
PR lto/45960 PR lto/45960
* pt.c (tsubst_copy) [INTEGER_CST]: Instantiate the type. * pt.c (tsubst_copy) [INTEGER_CST]: Instantiate the type.
......
...@@ -8871,6 +8871,10 @@ tsubst_default_argument (tree fn, tree type, tree arg) ...@@ -8871,6 +8871,10 @@ tsubst_default_argument (tree fn, tree type, tree arg)
tree saved_class_ptr = NULL_TREE; tree saved_class_ptr = NULL_TREE;
tree saved_class_ref = NULL_TREE; tree saved_class_ref = NULL_TREE;
/* This can happen in invalid code. */
if (TREE_CODE (arg) == DEFAULT_ARG)
return arg;
/* This default argument came from a template. Instantiate the /* This default argument came from a template. Instantiate the
default argument here, not in tsubst. In the case of default argument here, not in tsubst. In the case of
something like: something like:
...@@ -8935,6 +8939,9 @@ tsubst_default_arguments (tree fn) ...@@ -8935,6 +8939,9 @@ tsubst_default_arguments (tree fn)
its default arguments. */ its default arguments. */
if (uses_template_parms (tmpl_args)) if (uses_template_parms (tmpl_args))
return; return;
/* Don't do this again for clones. */
if (DECL_CLONED_FUNCTION_P (fn))
return;
for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); for (arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
arg; arg;
...@@ -10033,8 +10040,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -10033,8 +10040,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* Reuse typedefs. We need to do this to handle dependent attributes, /* Reuse typedefs. We need to do this to handle dependent attributes,
such as attribute aligned. */ such as attribute aligned. */
if (TYPE_P (t) if (TYPE_P (t)
&& TYPE_NAME (t) && typedef_variant_p (t))
&& TYPE_NAME (t) != TYPE_MAIN_DECL (t))
{ {
tree decl = TYPE_NAME (t); tree decl = TYPE_NAME (t);
...@@ -10090,9 +10096,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -10090,9 +10096,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case COMPLEX_TYPE: case COMPLEX_TYPE:
case VECTOR_TYPE: case VECTOR_TYPE:
case BOOLEAN_TYPE: case BOOLEAN_TYPE:
case INTEGER_CST: case LANG_TYPE:
case REAL_CST:
case STRING_CST:
return t; return t;
case INTEGER_TYPE: case INTEGER_TYPE:
...@@ -10541,29 +10545,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -10541,29 +10545,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return r; return r;
} }
case PLUS_EXPR:
case MINUS_EXPR:
{
tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
if (e1 == error_mark_node || e2 == error_mark_node)
return error_mark_node;
return fold_build2_loc (input_location,
code, TREE_TYPE (t), e1, e2);
}
case NEGATE_EXPR:
case NOP_EXPR:
{
tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
if (e == error_mark_node)
return error_mark_node;
return fold_build1_loc (input_location, code, TREE_TYPE (t), e);
}
case TYPENAME_TYPE: case TYPENAME_TYPE:
{ {
tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain, tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
...@@ -10639,33 +10620,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -10639,33 +10620,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return make_unbound_class_template (ctx, name, parm_list, complain); return make_unbound_class_template (ctx, name, parm_list, complain);
} }
case INDIRECT_REF:
case ADDR_EXPR:
case CALL_EXPR:
gcc_unreachable ();
case ARRAY_REF:
{
tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl,
/*integral_constant_expression_p=*/false);
if (e1 == error_mark_node || e2 == error_mark_node)
return error_mark_node;
return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE);
}
case SCOPE_REF:
{
tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl);
tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
if (e1 == error_mark_node || e2 == error_mark_node)
return error_mark_node;
return build_qualified_name (/*type=*/NULL_TREE,
e1, e2, QUALIFIED_NAME_IS_TEMPLATE (t));
}
case TYPEOF_TYPE: case TYPEOF_TYPE:
{ {
tree type; tree type;
...@@ -10734,6 +10688,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -10734,6 +10688,21 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
} }
break; break;
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
case PLUS_EXPR:
case MINUS_EXPR:
case NEGATE_EXPR:
case NOP_EXPR:
case INDIRECT_REF:
case ADDR_EXPR:
case CALL_EXPR:
case ARRAY_REF:
case SCOPE_REF:
/* We should use one of the expression tsubsts for these codes. */
gcc_unreachable ();
default: default:
sorry ("use of %qs in template", tree_code_name [(int) code]); sorry ("use of %qs in template", tree_code_name [(int) code]);
return error_mark_node; return error_mark_node;
...@@ -11047,6 +11016,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -11047,6 +11016,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
mark_used (t); mark_used (t);
return t; return t;
case OVERLOAD:
/* An OVERLOAD will always be a non-dependent overload set; an
overload set from function scope will just be represented with an
IDENTIFIER_NODE, and from class scope with a BASELINK. */
gcc_assert (!uses_template_parms (t));
return t;
case BASELINK: case BASELINK:
return tsubst_baselink (t, current_class_type, args, complain, in_decl); return tsubst_baselink (t, current_class_type, args, complain, in_decl);
...@@ -11384,8 +11360,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -11384,8 +11360,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return r; return r;
} }
default: case PTRMEM_CST:
/* These can sometimes show up in a partial instantiation, but never
involve template parms. */
gcc_assert (!uses_template_parms (t));
return t; return t;
default:
gcc_unreachable ();
} }
} }
...@@ -11666,7 +11648,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, ...@@ -11666,7 +11648,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break; break;
case USING_STMT: case USING_STMT:
do_using_directive (RECUR (USING_STMT_NAMESPACE (t))); do_using_directive (USING_STMT_NAMESPACE (t));
break; break;
case DECL_EXPR: case DECL_EXPR:
...@@ -11683,7 +11665,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, ...@@ -11683,7 +11665,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
tree name = DECL_NAME (decl); tree name = DECL_NAME (decl);
tree decl; tree decl;
scope = RECUR (scope); scope = tsubst (scope, args, complain, in_decl);
decl = lookup_qualified_name (scope, name, decl = lookup_qualified_name (scope, name,
/*is_type_p=*/false, /*is_type_p=*/false,
/*complain=*/false); /*complain=*/false);
...@@ -12276,15 +12258,15 @@ tsubst_copy_and_build (tree t, ...@@ -12276,15 +12258,15 @@ tsubst_copy_and_build (tree t,
case ADDR_EXPR: case ADDR_EXPR:
op1 = TREE_OPERAND (t, 0); op1 = TREE_OPERAND (t, 0);
if (TREE_CODE (op1) == LABEL_DECL)
return finish_label_address_expr (DECL_NAME (op1),
EXPR_LOCATION (op1));
if (TREE_CODE (op1) == SCOPE_REF) if (TREE_CODE (op1) == SCOPE_REF)
op1 = tsubst_qualified_id (op1, args, complain, in_decl, op1 = tsubst_qualified_id (op1, args, complain, in_decl,
/*done=*/true, /*address_p=*/true); /*done=*/true, /*address_p=*/true);
else else
op1 = tsubst_non_call_postfix_expression (op1, args, complain, op1 = tsubst_non_call_postfix_expression (op1, args, complain,
in_decl); in_decl);
if (TREE_CODE (op1) == LABEL_DECL)
return finish_label_address_expr (DECL_NAME (op1),
EXPR_LOCATION (op1));
return build_x_unary_op (ADDR_EXPR, op1, complain); return build_x_unary_op (ADDR_EXPR, op1, complain);
case PLUS_EXPR: case PLUS_EXPR:
...@@ -12459,7 +12441,7 @@ tsubst_copy_and_build (tree t, ...@@ -12459,7 +12441,7 @@ tsubst_copy_and_build (tree t,
} }
ret = build_new (&placement_vec, ret = build_new (&placement_vec,
RECUR (TREE_OPERAND (t, 1)), tsubst (TREE_OPERAND (t, 1), args, complain, in_decl),
RECUR (TREE_OPERAND (t, 2)), RECUR (TREE_OPERAND (t, 2)),
&init_vec, &init_vec,
NEW_EXPR_USE_GLOBAL (t), NEW_EXPR_USE_GLOBAL (t),
...@@ -12909,10 +12891,17 @@ tsubst_copy_and_build (tree t, ...@@ -12909,10 +12891,17 @@ tsubst_copy_and_build (tree t,
case TYPEID_EXPR: case TYPEID_EXPR:
{ {
tree operand_0 = RECUR (TREE_OPERAND (t, 0)); tree operand_0 = TREE_OPERAND (t, 0);
if (TYPE_P (operand_0)) if (TYPE_P (operand_0))
return get_typeid (operand_0); {
return build_typeid (operand_0); operand_0 = tsubst (operand_0, args, complain, in_decl);
return get_typeid (operand_0);
}
else
{
operand_0 = RECUR (operand_0);
return build_typeid (operand_0);
}
} }
case VAR_DECL: case VAR_DECL:
...@@ -17279,9 +17268,11 @@ tsubst_initializer_list (tree t, tree argvec) ...@@ -17279,9 +17268,11 @@ tsubst_initializer_list (tree t, tree argvec)
if (decl && !DECL_P (decl)) if (decl && !DECL_P (decl))
in_base_initializer = 1; in_base_initializer = 1;
init = tsubst_expr (TREE_VALUE (t), argvec, init = TREE_VALUE (t);
tf_warning_or_error, NULL_TREE, if (init != void_type_node)
/*integral_constant_expression_p=*/false); init = tsubst_expr (init, argvec,
tf_warning_or_error, NULL_TREE,
/*integral_constant_expression_p=*/false);
in_base_initializer = 0; in_base_initializer = 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