X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fpt.c;h=de70e531d0be678f8a5b9c130e797dc52ee47cec;hb=d8ae6d2235ad1bcbdc8ecb7aa0318303a1089804;hp=96c510f3d4c8d36b0f5d55ed1947c716216c0374;hpb=f25aa85d9f09c9974a2fda9f47f9ac11593d8d77;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 96c510f3d4c..de70e531d0b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3590,7 +3590,8 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, if (TREE_PURPOSE (parm)) seen_def_arg_p = 1; - else if (seen_def_arg_p) + else if (seen_def_arg_p + && !template_parameter_pack_p (TREE_VALUE (parm))) { error ("no default argument for %qD", TREE_VALUE (parm)); /* For better subsequent error-recovery, we indicate that @@ -3601,6 +3602,9 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, else if (is_primary && !is_partial && !is_friend_decl + /* Don't complain about an enclosing partial + specialization. */ + && parm_level == parms && TREE_CODE (decl) == TYPE_DECL && i < ntparms - 1 && template_parameter_pack_p (TREE_VALUE (parm))) @@ -4688,7 +4692,7 @@ coerce_template_template_parm (tree parm, D d; i.e. the parameter list of TT depends on earlier parameters. */ - if (!dependent_type_p (TREE_TYPE (arg)) + if (!uses_template_parms (TREE_TYPE (arg)) && !same_type_p (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl), TREE_TYPE (arg))) @@ -5060,7 +5064,19 @@ convert_template_argument (tree parm, if (invalid_nontype_parm_type_p (t, complain)) return error_mark_node; - if (!uses_template_parms (orig_arg) && !uses_template_parms (t)) + if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg)) + { + if (same_type_p (t, TREE_TYPE (orig_arg))) + val = orig_arg; + else + { + /* Not sure if this is reachable, but it doesn't hurt + to be robust. */ + error ("type mismatch in nontype parameter pack"); + val = error_mark_node; + } + } + else if (!uses_template_parms (orig_arg) && !uses_template_parms (t)) /* We used to call digest_init here. However, digest_init will report errors, which we don't want when complain is zero. More importantly, digest_init will try too @@ -5233,10 +5249,6 @@ coerce_template_parms (tree parms, parameters. */ int variadic_p = 0; - inner_args - = expand_template_argument_pack (INNERMOST_TEMPLATE_ARGS (args)); - - nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; nparms = TREE_VEC_LENGTH (parms); /* Determine if there are any parameter packs. */ @@ -5244,13 +5256,22 @@ coerce_template_parms (tree parms, { tree tparm = TREE_VALUE (TREE_VEC_ELT (parms, parm_idx)); if (template_parameter_pack_p (tparm)) - { - variadic_p = 1; - break; - } + ++variadic_p; } - if ((nargs > nparms - variadic_p && !variadic_p) + inner_args = INNERMOST_TEMPLATE_ARGS (args); + /* If there are 0 or 1 parameter packs, we need to expand any argument + packs so that we can deduce a parameter pack from some non-packed args + followed by an argument pack, as in variadic85.C. If there are more + than that, we need to leave argument packs intact so the arguments are + assigned to the right parameter packs. This should only happen when + dealing with a nested class inside a partial specialization of a class + template, as in variadic92.C. */ + if (variadic_p <= 1) + inner_args = expand_template_argument_pack (inner_args); + + nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; + if ((nargs > nparms && !variadic_p) || (nargs < nparms - variadic_p && require_all_args && (!use_default_args @@ -5297,42 +5318,48 @@ coerce_template_parms (tree parms, } /* Calculate the next argument. */ - if (template_parameter_pack_p (TREE_VALUE (parm))) + if (arg_idx < nargs) + arg = TREE_VEC_ELT (inner_args, arg_idx); + else + arg = NULL_TREE; + + if (template_parameter_pack_p (TREE_VALUE (parm)) + && !(arg && ARGUMENT_PACK_P (arg))) { - /* All remaining arguments will be placed in the - template parameter pack PARM. */ - arg = coerce_template_parameter_pack (parms, parm_idx, args, - inner_args, arg_idx, - new_args, &lost, - in_decl, complain); - + /* All remaining arguments will be placed in the + template parameter pack PARM. */ + arg = coerce_template_parameter_pack (parms, parm_idx, args, + inner_args, arg_idx, + new_args, &lost, + in_decl, complain); + /* Store this argument. */ if (arg == error_mark_node) lost++; TREE_VEC_ELT (new_inner_args, parm_idx) = arg; - /* We are done with all of the arguments. */ - arg_idx = nargs; - + /* We are done with all of the arguments. */ + arg_idx = nargs; + continue; } - else if (arg_idx < nargs) - { - arg = TREE_VEC_ELT (inner_args, arg_idx); - - if (arg && PACK_EXPANSION_P (arg)) + else if (arg) + { + if (PACK_EXPANSION_P (arg)) { if (complain & tf_error) { + /* FIXME this restriction was removed by N2555; see + bug 35722. */ /* If ARG is a pack expansion, but PARM is not a template parameter pack (if it were, we would have handled it above), we're trying to expand into a fixed-length argument list. */ if (TREE_CODE (arg) == EXPR_PACK_EXPANSION) - error ("cannot expand %<%E%> into a fixed-length " + sorry ("cannot expand %<%E%> into a fixed-length " "argument list", arg); else - error ("cannot expand %<%T%> into a fixed-length " + sorry ("cannot expand %<%T%> into a fixed-length " "argument list", arg); } return error_mark_node; @@ -5389,6 +5416,25 @@ template_args_equal (tree ot, tree nt) return PACK_EXPANSION_P (nt) && template_args_equal (PACK_EXPANSION_PATTERN (ot), PACK_EXPANSION_PATTERN (nt)); + else if (ARGUMENT_PACK_P (ot)) + { + int i, len; + tree opack, npack; + + if (!ARGUMENT_PACK_P (nt)) + return 0; + + opack = ARGUMENT_PACK_ARGS (ot); + npack = ARGUMENT_PACK_ARGS (nt); + len = TREE_VEC_LENGTH (opack); + if (TREE_VEC_LENGTH (npack) != len) + return 0; + for (i = 0; i < len; ++i) + if (!template_args_equal (TREE_VEC_ELT (opack, i), + TREE_VEC_ELT (npack, i))) + return 0; + return 1; + } else if (TYPE_P (nt)) return TYPE_P (ot) && same_type_p (ot, nt); else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot)) @@ -5405,9 +5451,6 @@ comp_template_args (tree oldargs, tree newargs) { int i; - oldargs = expand_template_argument_pack (oldargs); - newargs = expand_template_argument_pack (newargs); - if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs)) return 0; @@ -6384,6 +6427,30 @@ outermost_tinst_level (void) return level; } +/* Returns TRUE if PARM is a parameter of the template TEMPL. */ + +bool +parameter_of_template_p (tree parm, tree templ) +{ + tree parms; + int i; + + if (!parm || !templ) + return false; + + gcc_assert (DECL_TEMPLATE_PARM_P (parm)); + gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); + + parms = DECL_TEMPLATE_PARMS (templ); + parms = INNERMOST_TEMPLATE_PARMS (parms); + + for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) + if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i))) + return true; + + return false; +} + /* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the vector of template arguments, as for tsubst. @@ -10324,12 +10391,22 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv, #define RECUR(NODE) \ tsubst_expr ((NODE), args, complain, in_decl, \ integral_constant_expression_p) - tree decl, init, cond, incr; + tree decl, init, cond, incr, auto_node; init = TREE_VEC_ELT (OMP_FOR_INIT (t), i); gcc_assert (TREE_CODE (init) == MODIFY_EXPR); decl = RECUR (TREE_OPERAND (init, 0)); init = TREE_OPERAND (init, 1); + auto_node = type_uses_auto (TREE_TYPE (decl)); + if (auto_node && init) + { + tree init_expr = init; + if (TREE_CODE (init_expr) == DECL_EXPR) + init_expr = DECL_INITIAL (DECL_EXPR_DECL (init_expr)); + init_expr = RECUR (init_expr); + TREE_TYPE (decl) + = do_auto_deduction (TREE_TYPE (decl), init_expr, auto_node); + } gcc_assert (!type_dependent_expression_p (decl)); if (!CLASS_TYPE_P (TREE_TYPE (decl))) @@ -10560,8 +10637,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, pack expansion where the parameter packs used in that expansion were of length zero. */ - init = build_default_init (TREE_TYPE (decl), - NULL_TREE); + init = build_value_init (TREE_TYPE (decl)); else init = t; } @@ -11600,6 +11676,7 @@ tsubst_copy_and_build (tree t, } r = build_constructor (init_list_type_node, n); + CONSTRUCTOR_IS_DIRECT_INIT (r) = CONSTRUCTOR_IS_DIRECT_INIT (t); if (TREE_HAS_CONSTRUCTOR (t)) return finish_compound_literal (type, r); @@ -11697,58 +11774,76 @@ tsubst_copy_and_build (tree t, Emit an error under control of COMPLAIN, and return TRUE on error. */ static bool -check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) +check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain) { - int ix, len = DECL_NTPARMS (tmpl); - bool result = false; + if (ARGUMENT_PACK_P (t)) + { + tree vec = ARGUMENT_PACK_ARGS (t); + int len = TREE_VEC_LENGTH (vec); + bool result = false; + int i; - for (ix = 0; ix != len; ix++) + for (i = 0; i < len; ++i) + if (check_instantiated_arg (tmpl, TREE_VEC_ELT (vec, i), complain)) + result = true; + return result; + } + else if (TYPE_P (t)) { - tree t = TREE_VEC_ELT (args, ix); + /* [basic.link]: A name with no linkage (notably, the name + of a class or enumeration declared in a local scope) + shall not be used to declare an entity with linkage. + This implies that names with no linkage cannot be used as + template arguments. */ + tree nt = no_linkage_check (t, /*relaxed_p=*/false); - if (TYPE_P (t)) + if (nt) { - /* [basic.link]: A name with no linkage (notably, the name - of a class or enumeration declared in a local scope) - shall not be used to declare an entity with linkage. - This implies that names with no linkage cannot be used as - template arguments. */ - tree nt = no_linkage_check (t, /*relaxed_p=*/false); - - if (nt) - { - /* DR 488 makes use of a type with no linkage cause - type deduction to fail. */ - if (complain & tf_error) - { - if (TYPE_ANONYMOUS_P (nt)) - error ("%qT is/uses anonymous type", t); - else - error ("template argument for %qD uses local type %qT", - tmpl, t); - } - result = true; - } - /* In order to avoid all sorts of complications, we do not - allow variably-modified types as template arguments. */ - else if (variably_modified_type_p (t, NULL_TREE)) + /* DR 488 makes use of a type with no linkage cause + type deduction to fail. */ + if (complain & tf_error) { - if (complain & tf_error) - error ("%qT is a variably modified type", t); - result = true; + if (TYPE_ANONYMOUS_P (nt)) + error ("%qT is/uses anonymous type", t); + else + error ("template argument for %qD uses local type %qT", + tmpl, t); } + return true; } - /* A non-type argument of integral or enumerated type must be a - constant. */ - else if (TREE_TYPE (t) - && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) - && !TREE_CONSTANT (t)) + /* In order to avoid all sorts of complications, we do not + allow variably-modified types as template arguments. */ + else if (variably_modified_type_p (t, NULL_TREE)) { if (complain & tf_error) - error ("integral expression %qE is not constant", t); - result = true; + error ("%qT is a variably modified type", t); + return true; } } + /* A non-type argument of integral or enumerated type must be a + constant. */ + else if (TREE_TYPE (t) + && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) + && !TREE_CONSTANT (t)) + { + if (complain & tf_error) + error ("integral expression %qE is not constant", t); + return true; + } + return false; +} + +static bool +check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) +{ + int ix, len = DECL_NTPARMS (tmpl); + bool result = false; + + for (ix = 0; ix != len; ix++) + { + if (check_instantiated_arg (tmpl, TREE_VEC_ELT (args, ix), complain)) + result = true; + } if (result && (complain & tf_error)) error (" trying to instantiate %qD", tmpl); return result;