X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fpt.c;h=383f0d6d557bf4e6825e74241fe8fa217b426db4;hb=3848de0c8101dfb3ea8bbe7e26ea92d9fb2f1fec;hp=472508075776e109d0636e4c100fddd7edded127;hpb=fa00183093288ec94d5170baab0fab1d11d2b8d0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 47250807577..383f0d6d557 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1,6 +1,6 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 + 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -1860,6 +1860,7 @@ determine_specialization (tree template_id, { tree decl_arg_types; tree fn_arg_types; + tree insttype; /* In case of explicit specialization, we need to check if the number of template headers appearing in the specialization @@ -1927,7 +1928,8 @@ determine_specialization (tree template_id, template <> void f(); The specialization f is invalid but is not caught by get_bindings below. */ - if (list_length (fn_arg_types) != list_length (decl_arg_types)) + if (cxx_dialect < cxx11 + && list_length (fn_arg_types) != list_length (decl_arg_types)) continue; /* Function templates cannot be specializations; there are @@ -1950,6 +1952,18 @@ determine_specialization (tree template_id, specialize TMPL will produce DECL. */ continue; + if (cxx_dialect >= cxx11) + { + /* Make sure that the deduced arguments actually work. */ + insttype = tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE); + if (insttype == error_mark_node) + continue; + fn_arg_types + = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (insttype)); + if (!compparms (fn_arg_types, decl_arg_types)) + continue; + } + /* Save this template, and the arguments deduced. */ templates = tree_cons (targs, fn, templates); } @@ -2976,6 +2990,20 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) (struct find_parameter_pack_data*)data; bool parameter_pack_p = false; + /* Handle type aliases/typedefs. */ + if (TYPE_P (t) + && TYPE_NAME (t) + && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + && TYPE_DECL_ALIAS_P (TYPE_NAME (t))) + { + if (TYPE_TEMPLATE_INFO (t)) + cp_walk_tree (&TYPE_TI_ARGS (t), + &find_parameter_packs_r, + ppd, ppd->visited); + *walk_subtrees = 0; + return NULL_TREE; + } + /* Identify whether this is a parameter pack or not. */ switch (TREE_CODE (t)) { @@ -3224,6 +3252,8 @@ make_pack_expansion (tree arg) } PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs; + PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p (); + return result; } @@ -4905,7 +4935,10 @@ push_template_decl_real (tree decl, bool is_friend) if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type))) TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE; } - else if (check_for_bare_parameter_packs (TREE_TYPE (decl))) + else if (check_for_bare_parameter_packs ((TREE_CODE (decl) == TYPE_DECL + && TYPE_DECL_ALIAS_P (decl)) + ? DECL_ORIGINAL_TYPE (decl) + : TREE_TYPE (decl))) { TREE_TYPE (decl) = error_mark_node; return error_mark_node; @@ -5501,9 +5534,16 @@ static int unify_inconsistency (bool explain_p, tree parm, tree first, tree second) { if (explain_p) - inform (input_location, - " conflicting deductions for parameter %qE (%qE and %qE)", - parm, first, second); + { + if (TYPE_P (parm)) + inform (input_location, + " deduced conflicting types for parameter %qT (%qT and %qT)", + parm, first, second); + else + inform (input_location, + " deduced conflicting values for non-type parameter " + "%qE (%qE and %qE)", parm, first, second); + } return 1; } @@ -5696,11 +5736,15 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) to a null value, but otherwise still need to be of a specific form. */ if (cxx_dialect >= cxx0x) { - if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) + if (TREE_CODE (expr) == PTRMEM_CST) + /* A PTRMEM_CST is already constant, and a valid template + argument for a parameter of pointer to member type, we just want + to leave it in that form rather than lower it to a + CONSTRUCTOR. */; + else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) expr = maybe_constant_value (expr); else if (TYPE_PTR_P (type) - || (TYPE_PTR_TO_MEMBER_P (type) - && TREE_CODE (expr) != PTRMEM_CST)) + || TYPE_PTR_TO_MEMBER_P (type)) { tree folded = maybe_constant_value (expr); if (TYPE_PTR_P (type) ? integer_zerop (folded) @@ -5779,6 +5823,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) if (complain & tf_error) { int errs = errorcount, warns = warningcount; + if (processing_template_decl + && !require_potential_constant_expression (expr)) + return NULL_TREE; expr = cxx_constant_value (expr); if (errorcount > errs || warningcount > warns) inform (EXPR_LOC_OR_HERE (expr), @@ -6404,6 +6451,7 @@ convert_template_argument (tree parm, is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) + || (requires_tmpl_type && TREE_CODE (arg) == TYPE_ARGUMENT_PACK) || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); @@ -6417,8 +6465,16 @@ convert_template_argument (tree parm, if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM) { - permerror (input_location, "to refer to a type member of a template parameter, " - "use %", orig_arg); + if (TREE_CODE (TREE_OPERAND (arg, 1)) == BIT_NOT_EXPR) + { + if (complain & tf_error) + error ("invalid use of destructor %qE as a type", orig_arg); + return error_mark_node; + } + + permerror (input_location, + "to refer to a type member of a template parameter, " + "use %", orig_arg); orig_arg = make_typename_type (TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), @@ -6467,7 +6523,9 @@ convert_template_argument (tree parm, { if (requires_tmpl_type) { - if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE) + if (template_parameter_pack_p (parm) && ARGUMENT_PACK_P (orig_arg)) + val = orig_arg; + else if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE) /* The number of argument required is not known yet. Just accept it for now. */ val = TREE_TYPE (arg); @@ -6693,6 +6751,20 @@ coerce_template_parameter_pack (tree parms, return argument_pack; } +/* Returns true if the template argument vector ARGS contains + any pack expansions, false otherwise. */ + +static bool +any_pack_expanson_args_p (tree args) +{ + int i; + if (args) + for (i = 0; i < TREE_VEC_LENGTH (args); ++i) + if (PACK_EXPANSION_P (TREE_VEC_ELT (args, i))) + return true; + return false; +} + /* Convert all template arguments to their appropriate types, and return a vector containing the innermost resulting template arguments. If any error occurs, return error_mark_node. Error and @@ -6758,6 +6830,7 @@ coerce_template_parms (tree parms, if ((nargs > nparms && !variadic_p) || (nargs < nparms - variadic_p && require_all_args + && !any_pack_expanson_args_p (inner_args) && (!use_default_args || (TREE_VEC_ELT (parms, nargs) != error_mark_node && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))) @@ -6835,7 +6908,7 @@ coerce_template_parms (tree parms, { /* We don't know how many args we have yet, just use the unconverted ones for now. */ - new_inner_args = args; + new_inner_args = inner_args; break; } } @@ -7427,6 +7500,9 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, context = tsubst (DECL_CONTEXT (gen_tmpl), arglist, complain, in_decl); + if (context == error_mark_node) + return error_mark_node; + if (!context) context = global_namespace; @@ -8115,6 +8191,9 @@ parameter_of_template_p (tree parm, tree templ) for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { tree p = TREE_VALUE (TREE_VEC_ELT (parms, i)); + if (p == error_mark_node) + continue; + if (parm == p || (DECL_INITIAL (parm) && DECL_INITIAL (parm) == DECL_INITIAL (p))) @@ -9261,6 +9340,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, int i, len = -1; tree result; htab_t saved_local_specializations = NULL; + bool need_local_specializations = false; int levels; gcc_assert (PACK_EXPANSION_P (t)); @@ -9294,7 +9374,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } if (TREE_CODE (parm_pack) == PARM_DECL) { - if (!cp_unevaluated_operand) + if (PACK_EXPANSION_LOCAL_P (t)) arg_pack = retrieve_local_specialization (parm_pack); else { @@ -9310,6 +9390,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, arg_pack = NULL_TREE; else arg_pack = make_fnparm_pack (arg_pack); + need_local_specializations = true; } } else @@ -9440,7 +9521,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) return error_mark_node; - if (cp_unevaluated_operand) + if (need_local_specializations) { /* We're in a late-specified return type, so create our own local specializations table; the current table is either NULL or (in the @@ -9499,7 +9580,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } /* Substitute into the PATTERN with the altered arguments. */ - if (TREE_CODE (t) == EXPR_PACK_EXPANSION) + if (!TYPE_P (pattern)) TREE_VEC_ELT (result, i) = tsubst_expr (pattern, args, complain, in_decl, /*integral_constant_expression_p=*/false); @@ -9535,7 +9616,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } - if (saved_local_specializations) + if (need_local_specializations) { htab_delete (local_specializations); local_specializations = saved_local_specializations; @@ -10615,7 +10696,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) type = DECL_ORIGINAL_TYPE (t); else type = TREE_TYPE (t); - if (TREE_CODE (t) == VAR_DECL && VAR_HAD_UNKNOWN_BOUND (t)) + if (TREE_CODE (t) == VAR_DECL + && VAR_HAD_UNKNOWN_BOUND (t) + && type != error_mark_node) type = strip_array_domain (type); type = tsubst (type, args, complain, in_decl); } @@ -11127,7 +11210,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) complain | tf_ignore_bad_quals); return r; } - /* Else we must be instantiating the typedef, so fall through. */ + else + /* We don't have an instantiation yet, so drop the typedef. */ + t = DECL_ORIGINAL_TYPE (decl); } if (type @@ -11805,6 +11890,7 @@ tsubst_baselink (tree baselink, tree object_type, tree optype; tree template_args = 0; bool template_id_p = false; + bool qualified = BASELINK_QUALIFIED_P (baselink); /* A baselink indicates a function from a base class. Both the BASELINK_ACCESS_BINFO and the base class referenced may @@ -11853,9 +11939,12 @@ tsubst_baselink (tree baselink, tree object_type, if (!object_type) object_type = current_class_type; - return adjust_result_of_qualified_name_lookup (baselink, - qualifying_scope, - object_type); + + if (qualified) + baselink = adjust_result_of_qualified_name_lookup (baselink, + qualifying_scope, + object_type); + return baselink; } /* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID. DONE is @@ -12559,8 +12648,17 @@ tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain, if (purpose) purpose = RECUR (purpose); value = TREE_VALUE (t); - if (value && TREE_CODE (value) != LABEL_DECL) - value = RECUR (value); + if (value) + { + if (TREE_CODE (value) != LABEL_DECL) + value = RECUR (value); + else + { + value = lookup_label (DECL_NAME (value)); + gcc_assert (TREE_CODE (value) == LABEL_DECL); + TREE_USED (value) = 1; + } + } chain = TREE_CHAIN (t); if (chain && chain != void_type_node) chain = RECUR (chain); @@ -12801,6 +12899,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) /* Anonymous aggregates are a special case. */ finish_anon_union (decl); + else if (is_capture_proxy (DECL_EXPR_DECL (t))) + { + DECL_CONTEXT (decl) = current_function_decl; + insert_capture_proxy (decl); + } else { int const_init = false; @@ -13215,20 +13318,33 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, if (TRANSACTION_EXPR_IS_STMT (t)) { + tree body = TRANSACTION_EXPR_BODY (t); + tree noex = NULL_TREE; + if (TREE_CODE (body) == MUST_NOT_THROW_EXPR) + { + noex = MUST_NOT_THROW_COND (body); + if (noex == NULL_TREE) + noex = boolean_true_node; + body = TREE_OPERAND (body, 0); + } stmt = begin_transaction_stmt (input_location, NULL, flags); - RECUR (TRANSACTION_EXPR_BODY (t)); - finish_transaction_stmt (stmt, NULL, flags); + RECUR (body); + finish_transaction_stmt (stmt, NULL, flags, RECUR (noex)); } else { stmt = build_transaction_expr (EXPR_LOCATION (t), RECUR (TRANSACTION_EXPR_BODY (t)), - flags); + flags, NULL_TREE); return stmt; } } break; + case MUST_NOT_THROW_EXPR: + return build_must_not_throw_expr (RECUR (TREE_OPERAND (t, 0)), + RECUR (MUST_NOT_THROW_COND (t))); + case EXPR_PACK_EXPANSION: error ("invalid use of pack expansion expression"); return error_mark_node; @@ -13505,18 +13621,23 @@ tsubst_copy_and_build (tree t, case GT_EXPR: case MEMBER_REF: case DOTSTAR_EXPR: - return build_x_binary_op - (TREE_CODE (t), - RECUR (TREE_OPERAND (t, 0)), - (TREE_NO_WARNING (TREE_OPERAND (t, 0)) - ? ERROR_MARK - : TREE_CODE (TREE_OPERAND (t, 0))), - RECUR (TREE_OPERAND (t, 1)), - (TREE_NO_WARNING (TREE_OPERAND (t, 1)) - ? ERROR_MARK - : TREE_CODE (TREE_OPERAND (t, 1))), - /*overload=*/NULL, - complain); + { + tree r = build_x_binary_op + (TREE_CODE (t), + RECUR (TREE_OPERAND (t, 0)), + (TREE_NO_WARNING (TREE_OPERAND (t, 0)) + ? ERROR_MARK + : TREE_CODE (TREE_OPERAND (t, 0))), + RECUR (TREE_OPERAND (t, 1)), + (TREE_NO_WARNING (TREE_OPERAND (t, 1)) + ? ERROR_MARK + : TREE_CODE (TREE_OPERAND (t, 1))), + /*overload=*/NULL, + complain); + if (EXPR_P (r) && TREE_NO_WARNING (t)) + TREE_NO_WARNING (r) = TREE_NO_WARNING (t); + return r; + } case SCOPE_REF: return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true, @@ -14468,7 +14589,6 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) tree fndecl; tree gen_tmpl; tree spec; - HOST_WIDE_INT saved_processing_template_decl; if (tmpl == error_mark_node) return error_mark_node; @@ -14529,18 +14649,22 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) deferring all checks until we have the FUNCTION_DECL. */ push_deferring_access_checks (dk_deferred); - /* Although PROCESSING_TEMPLATE_DECL may be true at this point - (because, for example, we have encountered a non-dependent - function call in the body of a template function and must now - determine which of several overloaded functions will be called), - within the instantiation itself we are not processing a - template. */ - saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; + /* Instantiation of the function happens in the context of the function + template, not the context of the overload resolution we're doing. */ + push_to_top_level (); + if (DECL_CLASS_SCOPE_P (gen_tmpl)) + { + tree ctx = tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr, + complain, gen_tmpl); + push_nested_class (ctx); + } /* Substitute template parameters to obtain the specialization. */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), targ_ptr, complain, gen_tmpl); - processing_template_decl = saved_processing_template_decl; + if (DECL_CLASS_SCOPE_P (gen_tmpl)) + pop_nested_class (); + pop_from_top_level (); + if (fndecl == error_mark_node) return error_mark_node; @@ -15405,7 +15529,7 @@ resolve_overloaded_unification (tree tparms, elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE); if (try_one_overload (tparms, targs, tempargs, parm, elem, strict, sub_strict, addr_p, explain_p) - && (!goodfn || !decls_match (goodfn, elem))) + && (!goodfn || !same_type_p (goodfn, elem))) { goodfn = elem; ++good; @@ -16206,6 +16330,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, idx = TEMPLATE_TYPE_IDX (parm); targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); + if (tparm == error_mark_node) + return unify_invalid (explain_p); /* Check for mixed types and values. */ if ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM @@ -16566,6 +16692,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case BOOLEAN_TYPE: case ENUMERAL_TYPE: case VOID_TYPE: + case NULLPTR_TYPE: if (TREE_CODE (arg) != TREE_CODE (parm)) return unify_type_mismatch (explain_p, parm, arg); @@ -16818,7 +16945,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, default: /* An unresolved overload is a nondeduced context. */ - if (type_unknown_p (parm)) + if (is_overloaded_fn (parm) || type_unknown_p (parm)) return unify_success (explain_p); gcc_assert (EXPR_P (parm)); @@ -18827,6 +18954,7 @@ tsubst_initializer_list (tree t, tree argvec) /* Build a dummy EXPR_PACK_EXPANSION that will be used to expand each argument in the TREE_VALUE of t. */ expr = make_node (EXPR_PACK_EXPANSION); + PACK_EXPANSION_LOCAL_P (expr) = true; PACK_EXPANSION_PARAMETER_PACKS (expr) = PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t)); @@ -18887,6 +19015,7 @@ tsubst_initializer_list (tree t, tree argvec) } else { + tree tmp; decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_warning_or_error, NULL_TREE); @@ -18895,10 +19024,17 @@ tsubst_initializer_list (tree t, tree argvec) in_base_initializer = 1; init = TREE_VALUE (t); + tmp = init; if (init != void_type_node) init = tsubst_expr (init, argvec, tf_warning_or_error, NULL_TREE, /*integral_constant_expression_p=*/false); + if (init == NULL_TREE && tmp != NULL_TREE) + /* If we had an initializer but it instantiated to nothing, + value-initialize the object. This will only occur when + the initializer was a pack expansion where the parameter + packs used in that expansion were of length zero. */ + init = void_type_node; in_base_initializer = 0; } @@ -19457,6 +19593,11 @@ value_dependent_expression_p (tree expression) return false; } + case STMT_EXPR: + /* Treat a GNU statement expression as dependent to avoid crashing + under fold_non_dependent_expr; it can't be constant. */ + return true; + default: /* A constant expression is value-dependent if any subexpression is value-dependent. */