X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fcp%2Fpt.c;h=6b73d49ce29c3d69db6485a6c6064ca9e6a1c9c5;hb=3048c0c746443b1402bc3b7ebca39c030a3f991c;hp=7d380e54b4ac1c005da6b311937baf262bcbd248;hpb=a41bb2c947782287f983daac7807f0e0e4ef4b65;p=gcc.git diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7d380e54b4a..6b73d49ce29 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1,5 +1,5 @@ /* Handle parameterized types (templates) for GNU -*- C++ -*-. - Copyright (C) 1992-2014 Free Software Foundation, Inc. + Copyright (C) 1992-2015 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +#include "alias.h" +#include "symtab.h" #include "tree.h" #include "stringpool.h" #include "varasm.h" @@ -80,18 +82,22 @@ static tree cur_stmt_expr; /* True if we've recursed into fn_type_unification too many times. */ static bool excessive_deduction_depth; -typedef struct GTY(()) spec_entry +struct GTY((for_user)) spec_entry { tree tmpl; tree args; tree spec; -} spec_entry; +}; -static GTY ((param_is (spec_entry))) - htab_t decl_specializations; +struct spec_hasher : ggc_ptr_hash +{ + static hashval_t hash (spec_entry *); + static bool equal (spec_entry *, spec_entry *); +}; -static GTY ((param_is (spec_entry))) - htab_t type_specializations; +static GTY (()) hash_table *decl_specializations; + +static GTY (()) hash_table *type_specializations; /* Contains canonical template parameter types. The vector is indexed by the TEMPLATE_TYPE_IDX of the template parameter. Each element is a @@ -125,7 +131,7 @@ static int unify (tree, tree, tree, tree, int, bool); static void add_pending_template (tree); static tree reopen_tinst_level (struct tinst_level *); static tree tsubst_initializer_list (tree, tree); -static tree get_class_bindings (tree, tree, tree, tree); +static tree get_partial_spec_bindings (tree, tree, tree, tree); static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, bool, bool); static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t, @@ -153,7 +159,6 @@ static bool inline_needs_template_parms (tree, bool); static void push_inline_template_parms_recursive (tree, int); static tree retrieve_local_specialization (tree); static void register_local_specialization (tree, tree); -static hashval_t hash_specialization (const void *p); static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t); static int mark_template_parm (tree, void *); static int template_parm_this_level_p (tree, void *); @@ -170,7 +175,7 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static void regenerate_decl_from_template (tree, tree); -static tree most_specialized_class (tree, tsubst_flags_t); +static tree most_specialized_partial_spec (tree, tsubst_flags_t); static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int); static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree); static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); @@ -205,6 +210,7 @@ static tree template_parm_to_arg (tree t); static tree current_template_args (void); static tree tsubst_template_parm (tree, tree, tsubst_flags_t); static tree instantiate_alias_template (tree, tree, tsubst_flags_t); +static bool complex_alias_template_p (const_tree tmpl); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -931,18 +937,18 @@ maybe_process_partial_specialization (tree type) new member specialization template. */ spec_entry elt; spec_entry *entry; - void **slot; elt.tmpl = most_general_template (tmpl); elt.args = CLASSTYPE_TI_ARGS (inst); elt.spec = inst; - htab_remove_elt (type_specializations, &elt); + type_specializations->remove_elt (&elt); elt.tmpl = tmpl; elt.args = INNERMOST_TEMPLATE_ARGS (elt.args); - slot = htab_find_slot (type_specializations, &elt, INSERT); + spec_entry **slot + = type_specializations->find_slot (&elt, INSERT); entry = ggc_alloc (); *entry = elt; *slot = entry; @@ -1013,6 +1019,35 @@ optimize_specialization_lookup_p (tree tmpl) && !DECL_FRIEND_P (DECL_TEMPLATE_RESULT (tmpl))); } +/* Make sure ARGS doesn't use any inappropriate typedefs; we should have + gone through coerce_template_parms by now. */ + +static void +check_unstripped_args (tree args ATTRIBUTE_UNUSED) +{ +#ifdef ENABLE_CHECKING + ++processing_template_decl; + if (!any_dependent_template_arguments_p (args)) + { + tree inner = INNERMOST_TEMPLATE_ARGS (args); + for (int i = 0; i < TREE_VEC_LENGTH (inner); ++i) + { + tree arg = TREE_VEC_ELT (inner, i); + if (TREE_CODE (arg) == TEMPLATE_DECL) + /* OK */; + else if (TYPE_P (arg)) + gcc_assert (strip_typedefs (arg, NULL) == arg); + else if (strip_typedefs (TREE_TYPE (arg), NULL) != TREE_TYPE (arg)) + /* Allow typedefs on the type of a non-type argument, since a + parameter can have them. */; + else + gcc_assert (strip_typedefs_expr (arg, NULL) == arg); + } + } + --processing_template_decl; +#endif +} + /* Retrieve the specialization (in the sense of [temp.spec] - a specialization is either an instantiation or an explicit specialization) of TMPL for the given template ARGS. If there is @@ -1046,6 +1081,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) : template_class_depth (DECL_CONTEXT (tmpl)))); + check_unstripped_args (args); + if (optimize_specialization_lookup_p (tmpl)) { tree class_template; @@ -1085,7 +1122,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) { spec_entry *found; spec_entry elt; - htab_t specializations; + hash_table *specializations; elt.tmpl = tmpl; elt.args = args; @@ -1097,8 +1134,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) specializations = decl_specializations; if (hash == 0) - hash = hash_specialization (&elt); - found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash); + hash = spec_hasher::hash (&elt); + found = specializations->find_with_hash (&elt, hash); if (found) return found->spec; } @@ -1343,7 +1380,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, hashval_t hash) { tree fn; - void **slot = NULL; + spec_entry **slot = NULL; spec_entry elt; gcc_assert ((TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec)) @@ -1376,10 +1413,10 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, elt.spec = spec; if (hash == 0) - hash = hash_specialization (&elt); + hash = spec_hasher::hash (&elt); slot = - htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT); + decl_specializations->find_slot_with_hash (&elt, hash, INSERT); if (*slot) fn = ((spec_entry *) *slot)->spec; else @@ -1482,12 +1519,17 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, gcc_assert (tmpl && args && spec); *entry = elt; *slot = entry; - if (TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec) - && PRIMARY_TEMPLATE_P (tmpl) - && DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (tmpl)) == NULL_TREE) - /* TMPL is a forward declaration of a template function; keep a list + if ((TREE_CODE (spec) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (spec) + && PRIMARY_TEMPLATE_P (tmpl) + && DECL_SAVED_TREE (DECL_TEMPLATE_RESULT (tmpl)) == NULL_TREE) + || variable_template_p (tmpl)) + /* If TMPL is a forward declaration of a template function, keep a list of all specializations in case we need to reassign them to a friend - template later in tsubst_friend_function. */ + template later in tsubst_friend_function. + + Also keep a list of all variable template instantiations so that + process_partial_specialization can check whether a later partial + specialization would have used it. */ DECL_TEMPLATE_INSTANTIATIONS (tmpl) = tree_cons (args, spec, DECL_TEMPLATE_INSTANTIATIONS (tmpl)); } @@ -1500,11 +1542,9 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, int comparing_specializations; -static int -eq_specializations (const void *p1, const void *p2) +bool +spec_hasher::equal (spec_entry *e1, spec_entry *e2) { - const spec_entry *e1 = (const spec_entry *)p1; - const spec_entry *e2 = (const spec_entry *)p2; int equal; ++comparing_specializations; @@ -1527,10 +1567,9 @@ hash_tmpl_and_args (tree tmpl, tree args) /* Returns a hash for a spec_entry node based on the TMPL and ARGS members, ignoring SPEC. */ -static hashval_t -hash_specialization (const void *p) +hashval_t +spec_hasher::hash (spec_entry *e) { - const spec_entry *e = (const spec_entry *)p; return hash_tmpl_and_args (e->tmpl, e->args); } @@ -1598,6 +1637,7 @@ iterative_hash_template_arg (tree arg, hashval_t val) case CONSTRUCTOR: { tree field, value; + iterative_hash_template_arg (TREE_TYPE (arg), val); FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg), i, field, value) { val = iterative_hash_template_arg (field, val); @@ -1668,6 +1708,18 @@ iterative_hash_template_arg (tree arg, hashval_t val) switch (tclass) { case tcc_type: + if (alias_template_specialization_p (arg)) + { + // We want an alias specialization that survived strip_typedefs + // to hash differently from its TYPE_CANONICAL, to avoid hash + // collisions that compare as different in template_args_equal. + // These could be dependent specializations that strip_typedefs + // left alone, or untouched specializations because + // coerce_template_parms returns the unconverted template + // arguments if it sees incomplete argument packs. + tree ti = TYPE_TEMPLATE_INFO (arg); + return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti)); + } if (TYPE_CANONICAL (arg)) return iterative_hash_object (TYPE_HASH (TYPE_CANONICAL (arg)), val); @@ -1709,7 +1761,7 @@ reregister_specialization (tree spec, tree tinfo, tree new_spec) elt.args = TI_ARGS (tinfo); elt.spec = NULL_TREE; - entry = (spec_entry *) htab_find (decl_specializations, &elt); + entry = decl_specializations->find (&elt); if (entry != NULL) { gcc_assert (entry->spec == spec || entry->spec == new_spec); @@ -1892,7 +1944,13 @@ determine_specialization (tree template_id, ++header_count; if (variable_template_p (fns)) - templates = tree_cons (explicit_targs, fns, templates); + { + tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (fns)); + targs = coerce_template_parms (parms, explicit_targs, fns, + tf_warning_or_error, + /*req_all*/true, /*use_defarg*/true); + templates = tree_cons (targs, fns, templates); + } else for (; fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); @@ -2397,7 +2455,7 @@ check_explicit_specialization (tree declarator, switch (tsk) { case tsk_none: - if (processing_specialization) + if (processing_specialization && !VAR_P (decl)) { specialization = 1; SET_DECL_TEMPLATE_SPECIALIZATION (decl); @@ -2470,13 +2528,24 @@ check_explicit_specialization (tree declarator, /* This case handles bogus declarations like template <> template void f(); */ - if (uses_template_parms (declarator)) + if (!uses_template_parms (declarator)) + error ("template-id %qD in declaration of primary template", + declarator); + else if (variable_template_p (TREE_OPERAND (declarator, 0))) + { + /* Partial specialization of variable template. */ + SET_DECL_TEMPLATE_SPECIALIZATION (decl); + specialization = 1; + goto ok; + } + else if (cxx_dialect < cxx14) error ("non-type partial specialization %qD " "is not allowed", declarator); else - error ("template-id %qD in declaration of primary template", - declarator); + error ("non-class, non-variable partial specialization %qD " + "is not allowed", declarator); return decl; + ok:; } if (ctype && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) @@ -2515,9 +2584,10 @@ check_explicit_specialization (tree declarator, { tree tmpl = NULL_TREE; tree targs = NULL_TREE; + bool was_template_id = (TREE_CODE (declarator) == TEMPLATE_ID_EXPR); /* Make sure that the declarator is a TEMPLATE_ID_EXPR. */ - if (TREE_CODE (declarator) != TEMPLATE_ID_EXPR) + if (!was_template_id) { tree fns; @@ -2584,7 +2654,7 @@ check_explicit_specialization (tree declarator, else if (ctype != NULL_TREE && (identifier_p (TREE_OPERAND (declarator, 0)))) { - // Ignore variable templates. + // We'll match variable templates in start_decl. if (VAR_P (decl)) return decl; @@ -2721,7 +2791,7 @@ check_explicit_specialization (tree declarator, /* If this is a specialization of a member template of a template class, we want to return the TEMPLATE_DECL, not the specialization of it. */ - if (tsk == tsk_template) + if (tsk == tsk_template && !was_template_id) { tree result = DECL_TEMPLATE_RESULT (tmpl); SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); @@ -2746,6 +2816,9 @@ check_explicit_specialization (tree declarator, /* Set up the DECL_TEMPLATE_INFO for DECL. */ DECL_TEMPLATE_INFO (decl) = build_template_info (tmpl, targs); + if (was_template_id) + TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (decl)) = true; + /* Inherit default function arguments from the template DECL is specializing. */ if (DECL_FUNCTION_TEMPLATE_P (tmpl)) @@ -2815,7 +2888,7 @@ check_explicit_specialization (tree declarator, /* A specialization is not necessarily COMDAT. */ DECL_COMDAT (decl) = (TREE_PUBLIC (decl) && DECL_DECLARED_INLINE_P (decl)); - else if (TREE_CODE (decl) == VAR_DECL) + else if (VAR_P (decl)) DECL_COMDAT (decl) = false; /* Register this specialization so that we can find it @@ -3296,9 +3369,9 @@ make_pack_expansion (tree arg) if (!arg || arg == error_mark_node) return arg; - if (TREE_CODE (arg) == TREE_LIST) + if (TREE_CODE (arg) == TREE_LIST && TREE_PURPOSE (arg)) { - /* The only time we will see a TREE_LIST here is for a base + /* A TREE_LIST with a non-null TREE_PURPOSE is for a base class initializer. In this case, the TREE_PURPOSE will be a _TYPE node (representing the base class expansion we're initializing) and the TREE_VALUE will be a TREE_LIST @@ -4086,8 +4159,9 @@ static tree process_partial_specialization (tree decl) { tree type = TREE_TYPE (decl); - tree maintmpl = CLASSTYPE_TI_TEMPLATE (type); - tree specargs = CLASSTYPE_TI_ARGS (type); + tree tinfo = get_template_info (decl); + tree maintmpl = TI_TEMPLATE (tinfo); + tree specargs = TI_ARGS (tinfo); tree inner_args = INNERMOST_TEMPLATE_ARGS (specargs); tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); tree inner_parms; @@ -4172,11 +4246,11 @@ process_partial_specialization (tree decl) The argument list of the specialization shall not be identical to the implicit argument list of the primary template. */ - if (comp_template_args - (inner_args, - INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE - (maintmpl))))) - error ("partial specialization %qT does not specialize any template arguments", type); + tree main_args + = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (maintmpl))); + if (comp_template_args (inner_args, INNERMOST_TEMPLATE_ARGS (main_args))) + error ("partial specialization %qD does not specialize " + "any template arguments", decl); /* A partial specialization that replaces multiple parameters of the primary template with a pack expansion is less specialized for those @@ -4316,7 +4390,8 @@ process_partial_specialization (tree decl) } /* We should only get here once. */ - gcc_assert (!COMPLETE_TYPE_P (type)); + if (TREE_CODE (decl) == TYPE_DECL) + gcc_assert (!COMPLETE_TYPE_P (type)); tree tmpl = build_template_decl (decl, current_template_parms, DECL_MEMBER_TEMPLATE_P (maintmpl)); @@ -4334,15 +4409,21 @@ process_partial_specialization (tree decl) for (inst = DECL_TEMPLATE_INSTANTIATIONS (maintmpl); inst; inst = TREE_CHAIN (inst)) { - tree inst_type = TREE_VALUE (inst); - if (COMPLETE_TYPE_P (inst_type) - && CLASSTYPE_IMPLICIT_INSTANTIATION (inst_type)) + tree instance = TREE_VALUE (inst); + if (TYPE_P (instance) + ? (COMPLETE_TYPE_P (instance) + && CLASSTYPE_IMPLICIT_INSTANTIATION (instance)) + : DECL_TEMPLATE_INSTANTIATION (instance)) { - tree spec = most_specialized_class (inst_type, tf_none); - if (spec && TREE_TYPE (spec) == type) - permerror (input_location, - "partial specialization of %qT after instantiation " - "of %qT", type, inst_type); + tree spec = most_specialized_partial_spec (instance, tf_none); + if (spec && TREE_VALUE (spec) == tmpl) + { + tree inst_decl = (DECL_P (instance) + ? instance : TYPE_NAME (instance)); + permerror (input_location, + "partial specialization of %qD after instantiation " + "of %qD", decl, inst_decl); + } } } @@ -4362,6 +4443,7 @@ get_template_parm_index (tree parm) || TREE_CODE (parm) == TEMPLATE_DECL) parm = TREE_TYPE (parm); if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM + || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM) parm = TEMPLATE_TYPE_PARM_INDEX (parm); gcc_assert (TREE_CODE (parm) == TEMPLATE_PARM_INDEX); @@ -4537,13 +4619,8 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, parameter pack, at the end of the template parameter list. */ - if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL) - error ("parameter pack %qE must be at the end of the" - " template parameter list", TREE_VALUE (parm)); - else - error ("parameter pack %qT must be at the end of the" - " template parameter list", - TREE_TYPE (TREE_VALUE (parm))); + error ("parameter pack %q+D must be at the end of the" + " template parameter list", TREE_VALUE (parm)); TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) = error_mark_node; @@ -4691,9 +4768,13 @@ push_template_decl_real (tree decl, bool is_friend) return error_mark_node; /* See if this is a partial specialization. */ - is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl) - && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE - && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))); + is_partial = ((DECL_IMPLICIT_TYPEDEF_P (decl) + && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE + && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))) + || (VAR_P (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_SPECIALIZATION (decl) + && TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (decl)))); if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)) is_friend = true; @@ -4736,7 +4817,7 @@ push_template_decl_real (tree decl, bool is_friend) if (DECL_CLASS_SCOPE_P (decl)) member_template_p = true; if (TREE_CODE (decl) == TYPE_DECL - && ANON_AGGRNAME_P (DECL_NAME (decl))) + && anon_aggrname_p (DECL_NAME (decl))) { error ("template class without a name"); return error_mark_node; @@ -5039,6 +5120,11 @@ template arguments to %qD do not match original template %qD", if (TREE_CODE (parm) == TEMPLATE_DECL) DECL_CONTEXT (parm) = tmpl; } + + if (TREE_CODE (decl) == TYPE_DECL + && TYPE_DECL_ALIAS_P (decl) + && complex_alias_template_p (tmpl)) + TEMPLATE_DECL_COMPLEX_ALIAS_P (tmpl) = true; } /* The DECL_TI_ARGS of DECL contains full set of arguments referring @@ -5211,11 +5297,29 @@ redeclare_class_template (tree type, tree parms) return true; } +/* The actual substitution part of instantiate_non_dependent_expr_sfinae, + to be used when the caller has already checked + (processing_template_decl + && !instantiation_dependent_expression_p (expr) + && potential_constant_expression (expr)) + and cleared processing_template_decl. */ + +tree +instantiate_non_dependent_expr_internal (tree expr, tsubst_flags_t complain) +{ + return tsubst_copy_and_build (expr, + /*args=*/NULL_TREE, + complain, + /*in_decl=*/NULL_TREE, + /*function_p=*/false, + /*integral_constant_expression_p=*/true); +} + /* Simplify EXPR if it is a non-dependent expression. Returns the (possibly simplified) expression. */ tree -fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) +instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) { if (expr == NULL_TREE) return NULL_TREE; @@ -5231,25 +5335,16 @@ fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) && !instantiation_dependent_expression_p (expr) && potential_constant_expression (expr)) { - HOST_WIDE_INT saved_processing_template_decl; - - saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; - expr = tsubst_copy_and_build (expr, - /*args=*/NULL_TREE, - complain, - /*in_decl=*/NULL_TREE, - /*function_p=*/false, - /*integral_constant_expression_p=*/true); - processing_template_decl = saved_processing_template_decl; + processing_template_decl_sentinel s; + expr = instantiate_non_dependent_expr_internal (expr, complain); } return expr; } tree -fold_non_dependent_expr (tree expr) +instantiate_non_dependent_expr (tree expr) { - return fold_non_dependent_expr_sfinae (expr, tf_error); + return instantiate_non_dependent_expr_sfinae (expr, tf_error); } /* Return TRUE iff T is a type alias, a TEMPLATE_DECL for an alias @@ -5267,18 +5362,78 @@ alias_type_or_template_p (tree t) || DECL_ALIAS_TEMPLATE_P (t)); } -/* Return TRUE iff is a specialization of an alias template. */ +/* Return TRUE iff T is a specialization of an alias template. */ bool alias_template_specialization_p (const_tree t) { - if (t == NULL_TREE) - return false; - - return (TYPE_P (t) - && TYPE_TEMPLATE_INFO (t) - && PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t)) - && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t))); + /* It's an alias template specialization if it's an alias and its + TYPE_NAME is a specialization of a primary template. */ + if (TYPE_ALIAS_P (t)) + { + tree name = TYPE_NAME (t); + if (DECL_LANG_SPECIFIC (name)) + if (tree ti = DECL_TEMPLATE_INFO (name)) + { + tree tmpl = TI_TEMPLATE (ti); + return PRIMARY_TEMPLATE_P (tmpl); + } + } + return false; +} + +/* An alias template is complex from a SFINAE perspective if a template-id + using that alias can be ill-formed when the expansion is not, as with + the void_t template. We determine this by checking whether the + expansion for the alias template uses all its template parameters. */ + +struct uses_all_template_parms_data +{ + int level; + bool *seen; +}; + +static int +uses_all_template_parms_r (tree t, void *data_) +{ + struct uses_all_template_parms_data &data + = *(struct uses_all_template_parms_data*)data_; + tree idx = get_template_parm_index (t); + + if (TEMPLATE_PARM_LEVEL (idx) == data.level) + data.seen[TEMPLATE_PARM_IDX (idx)] = true; + return 0; +} + +static bool +complex_alias_template_p (const_tree tmpl) +{ + struct uses_all_template_parms_data data; + tree pat = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); + tree parms = DECL_TEMPLATE_PARMS (tmpl); + data.level = TMPL_PARMS_DEPTH (parms); + int len = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS (parms)); + data.seen = XALLOCAVEC (bool, len); + for (int i = 0; i < len; ++i) + data.seen[i] = false; + + for_each_template_parm (pat, uses_all_template_parms_r, &data, NULL, true); + for (int i = 0; i < len; ++i) + if (!data.seen[i]) + return true; + return false; +} + +/* Return TRUE iff T is a specialization of a complex alias template with + dependent template-arguments. */ + +bool +dependent_alias_template_spec_p (const_tree t) +{ + return (alias_template_specialization_p (t) + && TEMPLATE_DECL_COMPLEX_ALIAS_P (DECL_TI_TEMPLATE (TYPE_NAME (t))) + && (any_dependent_template_arguments_p + (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t))))); } /* Return the number of innermost template parameters in TMPL. */ @@ -5725,11 +5880,15 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) so that access checking can be performed when the template is instantiated -- but here we need the resolved form so that we can convert the argument. */ + bool non_dep = false; 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 if (!type_unknown_p (expr)) - expr = fold_non_dependent_expr_sfinae (expr, complain); + else if (!type_unknown_p (expr) + && processing_template_decl + && !instantiation_dependent_expression_p (expr) + && potential_constant_expression (expr)) + non_dep = true; if (error_operand_p (expr)) return error_mark_node; expr_type = TREE_TYPE (expr); @@ -5738,6 +5897,12 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) else expr = mark_rvalue_use (expr); + /* If the argument is non-dependent, perform any conversions in + non-dependent context as well. */ + processing_template_decl_sentinel s (non_dep); + if (non_dep) + expr = instantiate_non_dependent_expr_internal (expr, complain); + /* 14.3.2/5: The null pointer{,-to-member} conversion is applied to a non-type argument of "nullptr". */ if (expr == nullptr_node && TYPE_PTR_OR_PTRMEM_P (type)) @@ -6144,7 +6309,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) right type? */ gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr))); - return expr; + return convert_from_reference (expr); } /* Subroutine of coerce_template_template_parms, which returns 1 if @@ -6408,20 +6573,14 @@ template_template_parm_bindings_ok_p (tree tparms, tree targs) static tree canonicalize_type_argument (tree arg, tsubst_flags_t complain) { - tree mv; if (!arg || arg == error_mark_node || arg == TYPE_CANONICAL (arg)) return arg; - mv = TYPE_MAIN_VARIANT (arg); - arg = strip_typedefs (arg); - if (TYPE_ALIGN (arg) != TYPE_ALIGN (mv) - || TYPE_ATTRIBUTES (arg) != TYPE_ATTRIBUTES (mv)) - { - if (complain & tf_warning) - warning (0, "ignoring attributes on template argument %qT", arg); - arg = build_aligned_type (arg, TYPE_ALIGN (mv)); - arg = cp_build_type_attribute_variant (arg, TYPE_ATTRIBUTES (mv)); - } - return arg; + bool removed_attributes = false; + tree canon = strip_typedefs (arg, &removed_attributes); + if (removed_attributes + && (complain & tf_warning)) + warning (0, "ignoring attributes on template argument %qT", arg); + return canon; } /* Convert the indicated template ARG as necessary to match the @@ -6443,6 +6602,9 @@ convert_template_argument (tree parm, tree val; int is_type, requires_type, is_tmpl_type, requires_tmpl_type; + if (parm == error_mark_node) + return error_mark_node; + if (TREE_CODE (arg) == TREE_LIST && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF) { @@ -6655,7 +6817,10 @@ convert_template_argument (tree parm, argument specification is valid. */ val = convert_nontype_argument (t, orig_arg, complain); else - val = strip_typedefs_expr (orig_arg); + { + bool removed_attr = false; + val = strip_typedefs_expr (orig_arg, &removed_attr); + } if (val == NULL_TREE) val = error_mark_node; @@ -6737,6 +6902,9 @@ coerce_template_parameter_pack (tree parms, if (invalid_nontype_parm_type_p (t, complain)) return error_mark_node; } + /* We don't know how many args we have yet, just + use the unconverted ones for now. */ + return NULL_TREE; } packed_args = make_tree_vec (TREE_VEC_LENGTH (packed_parms)); @@ -7216,11 +7384,39 @@ template_args_equal (tree ot, tree nt) return template_args_equal (ot, nt); } else if (TYPE_P (nt)) - return TYPE_P (ot) && same_type_p (ot, nt); + { + if (!TYPE_P (ot)) + return false; + /* Don't treat an alias template specialization with dependent + arguments as equivalent to its underlying type when used as a + template argument; we need them to be distinct so that we + substitute into the specialization arguments at instantiation + time. And aliases can't be equivalent without being ==, so + we don't need to look any deeper. */ + if (TYPE_ALIAS_P (nt) || TYPE_ALIAS_P (ot)) + return false; + else + return same_type_p (ot, nt); + } else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot)) return 0; else - return cp_tree_equal (ot, nt); + { + /* Try to treat a template non-type argument that has been converted + to the parameter type as equivalent to one that hasn't yet. */ + for (enum tree_code code1 = TREE_CODE (ot); + CONVERT_EXPR_CODE_P (code1) + || code1 == NON_LVALUE_EXPR; + code1 = TREE_CODE (ot)) + ot = TREE_OPERAND (ot, 0); + for (enum tree_code code2 = TREE_CODE (nt); + CONVERT_EXPR_CODE_P (code2) + || code2 == NON_LVALUE_EXPR; + code2 = TREE_CODE (nt)) + nt = TREE_OPERAND (nt, 0); + + return cp_tree_equal (ot, nt); + } } /* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets of @@ -7417,7 +7613,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, { tree templ = NULL_TREE, parmlist; tree t; - void **slot; + spec_entry **slot; spec_entry *entry; spec_entry elt; hashval_t hash; @@ -7605,60 +7801,10 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, /* Calculate the BOUND_ARGS. These will be the args that are actually tsubst'd into the definition to create the instantiation. */ - if (parm_depth > 1) - { - /* We have multiple levels of arguments to coerce, at once. */ - int i; - int saved_depth = TMPL_ARGS_DEPTH (arglist); - - tree bound_args = make_tree_vec (parm_depth); - - for (i = saved_depth, - t = DECL_TEMPLATE_PARMS (gen_tmpl); - i > 0 && t != NULL_TREE; - --i, t = TREE_CHAIN (t)) - { - tree a; - if (i == saved_depth) - a = coerce_template_parms (TREE_VALUE (t), - arglist, gen_tmpl, - complain, - /*require_all_args=*/true, - /*use_default_args=*/true); - else - /* Outer levels should have already been coerced. */ - a = TMPL_ARGS_LEVEL (arglist, i); - - /* Don't process further if one of the levels fails. */ - if (a == error_mark_node) - { - /* Restore the ARGLIST to its full size. */ - TREE_VEC_LENGTH (arglist) = saved_depth; - return error_mark_node; - } - - SET_TMPL_ARGS_LEVEL (bound_args, i, a); - - /* We temporarily reduce the length of the ARGLIST so - that coerce_template_parms will see only the arguments - corresponding to the template parameters it is - examining. */ - TREE_VEC_LENGTH (arglist)--; - } - - /* Restore the ARGLIST to its full size. */ - TREE_VEC_LENGTH (arglist) = saved_depth; - - arglist = bound_args; - } - else - arglist - = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), - INNERMOST_TEMPLATE_ARGS (arglist), - gen_tmpl, - complain, - /*require_all_args=*/true, - /*use_default_args=*/true); + arglist = coerce_innermost_template_parms (parmlist, arglist, gen_tmpl, + complain, + /*require_all_args=*/true, + /*use_default_args=*/true); if (arglist == error_mark_node) /* We were unable to bind the arguments. */ @@ -7683,9 +7829,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, /* If we already have this specialization, return it. */ elt.tmpl = gen_tmpl; elt.args = arglist; - hash = hash_specialization (&elt); - entry = (spec_entry *) htab_find_with_hash (type_specializations, - &elt, hash); + hash = spec_hasher::hash (&elt); + entry = type_specializations->find_with_hash (&elt, hash); if (entry) return entry->spec; @@ -7826,15 +7971,22 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, if (OVERLOAD_TYPE_P (t) && !DECL_ALIAS_TEMPLATE_P (gen_tmpl)) { - if (tree attributes - = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (template_type))) + static const char *tags[] = {"abi_tag", "may_alias"}; + + for (unsigned ix = 0; ix != 2; ix++) { - if (!TREE_CHAIN (attributes)) + tree attributes + = lookup_attribute (tags[ix], TYPE_ATTRIBUTES (template_type)); + + if (!attributes) + ; + else if (!TREE_CHAIN (attributes) && !TYPE_ATTRIBUTES (t)) TYPE_ATTRIBUTES (t) = attributes; else TYPE_ATTRIBUTES (t) - = build_tree_list (TREE_PURPOSE (attributes), - TREE_VALUE (attributes)); + = tree_cons (TREE_PURPOSE (attributes), + TREE_VALUE (attributes), + TYPE_ATTRIBUTES (t)); } } @@ -7929,8 +8081,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist)); elt.spec = t; - slot = htab_find_slot_with_hash (type_specializations, - &elt, hash, INSERT); + slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT); entry = ggc_alloc (); *entry = elt; *slot = entry; @@ -7981,22 +8132,36 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, return ret; } -/* Return a TEMPLATE_ID_EXPR for the given variable template and ARGLIST. - If the ARGLIST refers to any template parameters, the type of the - expression is the unknown_type_node since the template-id could - refer to an explicit or partial specialization. */ +/* Return a TEMPLATE_ID_EXPR for the given variable template and ARGLIST. + The type of the expression is the unknown_type_node since the + template-id could refer to an explicit or partial specialization. */ tree lookup_template_variable (tree templ, tree arglist) { - tree type; - if (uses_template_parms (arglist)) - type = unknown_type_node; - else - type = TREE_TYPE (templ); + tree type = unknown_type_node; return build2 (TEMPLATE_ID_EXPR, type, templ, arglist); } +/* Instantiate a variable declaration from a TEMPLATE_ID_EXPR for use. */ + +tree +finish_template_variable (tree var) +{ + tree templ = TREE_OPERAND (var, 0); + + tree arglist = TREE_OPERAND (var, 1); + tree tmpl_args = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (templ)); + arglist = add_outermost_template_args (tmpl_args, arglist); + + tree parms = DECL_TEMPLATE_PARMS (templ); + tsubst_flags_t complain = tf_warning_or_error; + arglist = coerce_innermost_template_parms (parms, arglist, templ, complain, + /*req_all*/true, + /*use_default*/true); + + return instantiate_template (templ, arglist, complain); +} struct pair_fn_data { @@ -8245,6 +8410,9 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data, int uses_template_parms (tree t) { + if (t == NULL_TREE) + return false; + bool dependent_p; int saved_processing_template_decl; @@ -8284,7 +8452,7 @@ uses_template_parms (tree t) /* Returns true iff current_function_decl is an incompletely instantiated template. Useful instead of processing_template_decl because the latter - is set to 0 during fold_non_dependent_expr. */ + is set to 0 during instantiate_non_dependent_expr. */ bool in_template_function (void) @@ -8363,7 +8531,8 @@ push_tinst_level_loc (tree d, location_t loc) if (tinst_depth >= max_tinst_depth) { - fatal_error ("template instantiation depth exceeds maximum of %d" + fatal_error (input_location, + "template instantiation depth exceeds maximum of %d" " (use -ftemplate-depth= to increase the maximum)", max_tinst_depth); return false; @@ -8651,7 +8820,7 @@ tsubst_friend_function (tree decl, tree args) elt.args = DECL_TI_ARGS (spec); elt.spec = NULL_TREE; - htab_remove_elt (decl_specializations, &elt); + decl_specializations->remove_elt (&elt); DECL_TI_ARGS (spec) = add_outermost_template_args (new_args, @@ -8930,6 +9099,21 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)), chain); } + else if (TREE_VALUE (t) && PACK_EXPANSION_P (TREE_VALUE (t))) + { + /* An attribute pack expansion. */ + tree purp = TREE_PURPOSE (t); + tree pack = (tsubst_pack_expansion + (TREE_VALUE (t), args, complain, in_decl)); + int len = TREE_VEC_LENGTH (pack); + for (int i = 0; i < len; ++i) + { + tree elt = TREE_VEC_ELT (pack, i); + *q = build_tree_list (purp, elt); + q = &TREE_CHAIN (*q); + } + continue; + } else TREE_VALUE (t) = tsubst_expr (TREE_VALUE (t), args, complain, in_decl, @@ -9010,7 +9194,7 @@ instantiate_class_template_1 (tree type) /* Determine what specialization of the original template to instantiate. */ - t = most_specialized_class (type, tf_warning_or_error); + t = most_specialized_partial_spec (type, tf_warning_or_error); if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; @@ -9054,12 +9238,20 @@ instantiate_class_template_1 (tree type) it now. */ push_deferring_access_checks (dk_no_deferred); + int saved_unevaluated_operand = cp_unevaluated_operand; + int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + fn_context = decl_function_context (TYPE_MAIN_DECL (type)); /* Also avoid push_to_top_level for a lambda in an NSDMI. */ if (!fn_context && LAMBDA_TYPE_P (type) && TYPE_CLASS_SCOPE_P (type)) fn_context = error_mark_node; if (!fn_context) push_to_top_level (); + else + { + cp_unevaluated_operand = 0; + c_inhibit_evaluation_warnings = 0; + } /* Use #pragma pack from the template context. */ saved_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = TYPE_PRECISION (pattern); @@ -9475,6 +9667,14 @@ instantiate_class_template_1 (tree type) } } + if (fn_context) + { + /* Restore these before substituting into the lambda capture + initializers. */ + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; + } + if (tree expr = CLASSTYPE_LAMBDA_EXPR (type)) { tree decl = lambda_function (type); @@ -9625,16 +9825,22 @@ make_fnparm_pack (tree spec_parm) return extract_fnparm_pack (NULL_TREE, &spec_parm); } -/* Return true iff the Ith element of the argument pack ARG_PACK is a - pack expansion. */ +/* Return 1 if the Ith element of the argument pack ARG_PACK is a + pack expansion with no extra args, 2 if it has extra args, or 0 + if it is not a pack expansion. */ -static bool +static int argument_pack_element_is_expansion_p (tree arg_pack, int i) { tree vec = ARGUMENT_PACK_ARGS (arg_pack); if (i >= TREE_VEC_LENGTH (vec)) - return false; - return PACK_EXPANSION_P (TREE_VEC_ELT (vec, i)); + return 0; + tree elt = TREE_VEC_ELT (vec, i); + if (!PACK_EXPANSION_P (elt)) + return 0; + if (PACK_EXPANSION_EXTRA_ARGS (elt)) + return 2; + return 1; } @@ -9684,7 +9890,12 @@ use_pack_expansion_extra_args_p (tree parm_packs, { tree arg = TREE_VALUE (parm_pack); - if (argument_pack_element_is_expansion_p (arg, i)) + int exp = argument_pack_element_is_expansion_p (arg, i); + if (exp == 2) + /* We can't substitute a pack expansion with extra args into + our pattern. */ + return true; + else if (exp) has_expansion_arg = true; else has_non_expansion_arg = true; @@ -9748,7 +9959,8 @@ gen_elem_of_pack_expansion_instantiation (tree pattern, if (index == 0) { aps = make_argument_pack_select (arg_pack, index); - mark_used (parm); + if (!mark_used (parm, complain) && !(complain & tf_error)) + return error_mark_node; register_local_specialization (aps, parm); } else @@ -10472,7 +10684,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (new_type == error_mark_node) RETURN (error_mark_node); /* If we get a real template back, return it. This can happen in - the context of most_specialized_class. */ + the context of most_specialized_partial_spec. */ if (TREE_CODE (new_type) == TEMPLATE_DECL) return new_type; @@ -10580,7 +10792,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) if (PRIMARY_TEMPLATE_P (t)) DECL_PRIMARY_TEMPLATE (r) = r; - if (TREE_CODE (decl) != TYPE_DECL && TREE_CODE (decl) != VAR_DECL) + if (TREE_CODE (decl) != TYPE_DECL && !VAR_P (decl)) /* Record this non-type partial instantiation. */ register_specialization (r, t, DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)), @@ -11132,8 +11344,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) { /* T is a static data member or namespace-scope entity. We have to substitute into namespace-scope variables - (even though such entities are never templates) because - of cases like: + (not just variable templates) because of cases like: template void f() { extern T t; } @@ -11167,6 +11378,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tmpl = DECL_TI_TEMPLATE (t); gen_tmpl = most_general_template (tmpl); argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); + if (argvec != error_mark_node) + argvec = (coerce_innermost_template_parms + (DECL_TEMPLATE_PARMS (gen_tmpl), + argvec, t, complain, + /*all*/true, /*defarg*/true)); if (argvec == error_mark_node) RETURN (error_mark_node); hash = hash_tmpl_and_args (gen_tmpl, argvec); @@ -11251,8 +11467,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) } SET_DECL_VALUE_EXPR (r, ve); } - if (TREE_STATIC (r) || DECL_EXTERNAL (r)) - set_decl_tls_model (r, decl_tls_model (t)); + if (CP_DECL_THREAD_LOCAL_P (r) + && !processing_template_decl) + set_decl_tls_model (r, decl_default_tls_model (r)); } else if (DECL_SELF_REFERENCE_P (t)) SET_DECL_SELF_REFERENCE_P (r); @@ -11289,10 +11506,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) initializer is present. We mimic the non-template processing here. */ DECL_EXTERNAL (r) = 1; + if (DECL_NAMESPACE_SCOPE_P (t)) + DECL_NOT_REALLY_EXTERN (r) = 1; - register_specialization (r, gen_tmpl, argvec, false, hash); DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec); SET_DECL_IMPLICIT_INSTANTIATION (r); + register_specialization (r, gen_tmpl, argvec, false, hash); } else if (!cp_unevaluated_operand) register_local_specialization (r, t); @@ -12162,21 +12381,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t)); r = cp_build_qualified_type_real (r, cp_type_quals (t), complain); - if (cxx_dialect >= cxx14 - && !(TREE_CODE (t) == REFERENCE_TYPE && REFERENCE_VLA_OK (t)) - && array_of_runtime_bound_p (type) - && (flag_iso || warn_vla > 0)) - { - if (complain & tf_warning_or_error) - pedwarn - (input_location, OPT_Wvla, - code == REFERENCE_TYPE - ? G_("cannot declare reference to array of runtime bound") - : G_("cannot declare pointer to array of runtime bound")); - else - r = error_mark_node; - } - if (r != error_mark_node) /* Will this ever be needed for TYPE_..._TO values? */ layout_type (r); @@ -12432,7 +12636,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) return cp_build_qualified_type_real (type, cp_type_quals (t) | cp_type_quals (type), - complain); + complain | tf_ignore_bad_quals); } case UNDERLYING_TYPE: @@ -12533,8 +12737,9 @@ tsubst_baselink (tree baselink, tree object_type, point.) */ if (BASELINK_P (baselink)) fns = BASELINK_FUNCTIONS (baselink); - if (!template_id_p && !really_overloaded_fn (fns)) - mark_used (OVL_CURRENT (fns)); + if (!template_id_p && !really_overloaded_fn (fns) + && !mark_used (OVL_CURRENT (fns), complain) && !(complain & tf_error)) + return error_mark_node; /* Add back the template arguments, if present. */ if (BASELINK_P (baselink) && template_id_p) @@ -12649,7 +12854,8 @@ tsubst_qualified_id (tree qualified_id, tree args, check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE, scope); /* Remember that there was a reference to this entity. */ - mark_used (expr); + if (!mark_used (expr, complain) && !(complain & tf_error)) + return error_mark_node; } if (expr == error_mark_node || TREE_CODE (expr) == TREE_LIST) @@ -12759,7 +12965,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) r = ARGUMENT_PACK_SELECT_ARG (r); - mark_used (r); + if (!mark_used (r, complain) && !(complain & tf_error)) + return error_mark_node; return r; case CONST_DECL: @@ -12775,7 +12982,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) return t; /* If ARGS is NULL, then T is known to be non-dependent. */ if (args == NULL_TREE) - return integral_constant_value (t); + return scalar_constant_value (t); /* Unfortunately, we cannot just call lookup_name here. Consider: @@ -12903,10 +13110,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TREE_STATIC (r)) rest_of_decl_compilation (r, toplevel_bindings_p (), at_eof); - else if (decl_constant_var_p (r)) - /* A use of a local constant decays to its value. - FIXME update for core DR 696. */ - r = integral_constant_value (r); + else + r = process_outer_var_ref (r, complain); } } /* Remember this for subsequent uses. */ @@ -12916,7 +13121,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } else r = t; - mark_used (r); + if (!mark_used (r, complain) && !(complain & tf_error)) + return error_mark_node; return r; case NAMESPACE_DECL: @@ -13280,7 +13486,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl); r = build2 (code, type, op0, op1); PTRMEM_OK_P (r) = PTRMEM_OK_P (t); - mark_used (TREE_OPERAND (r, 1)); + if (!mark_used (TREE_OPERAND (r, 1), complain) + && !(complain & tf_error)) + return error_mark_node; return r; } @@ -13321,6 +13529,32 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } +/* Helper function for tsubst_omp_clauses, used for instantiation of + OMP_CLAUSE_DECL of clauses that handles also OpenMP array sections + represented with TREE_LIST. */ + +static tree +tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain, + tree in_decl) +{ + if (TREE_CODE (decl) == TREE_LIST) + { + tree low_bound + = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl, + /*integral_constant_expression_p=*/false); + tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl, + /*integral_constant_expression_p=*/false); + tree chain = tsubst_omp_clause_decl (TREE_CHAIN (decl), args, complain, + in_decl); + if (TREE_PURPOSE (decl) == low_bound + && TREE_VALUE (decl) == length + && TREE_CHAIN (decl) == chain) + return decl; + return tree_cons (low_bound, length, chain); + } + return tsubst_copy (decl, args, complain, in_decl); +} + /* Like tsubst_copy, but specifically for OpenMP clauses. */ static tree @@ -13352,16 +13586,23 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_COPYIN: case OMP_CLAUSE_COPYPRIVATE: + case OMP_CLAUSE_UNIFORM: + OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args, + complain, in_decl); + break; + case OMP_CLAUSE_DEPEND: + case OMP_CLAUSE_FROM: + case OMP_CLAUSE_TO: + case OMP_CLAUSE_MAP: + OMP_CLAUSE_DECL (nc) + = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, + in_decl); + break; case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_COLLAPSE: case OMP_CLAUSE_FINAL: - case OMP_CLAUSE_DEPEND: - case OMP_CLAUSE_FROM: - case OMP_CLAUSE_TO: - case OMP_CLAUSE_UNIFORM: - case OMP_CLAUSE_MAP: case OMP_CLAUSE_DEVICE: case OMP_CLAUSE_DIST_SCHEDULE: case OMP_CLAUSE_NUM_TEAMS: @@ -13388,20 +13629,17 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, else gcc_assert (identifier_p (placeholder)); } - OMP_CLAUSE_OPERAND (nc, 0) - = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, - in_decl, /*integral_constant_expression_p=*/false); + OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args, + complain, in_decl); break; case OMP_CLAUSE_LINEAR: case OMP_CLAUSE_ALIGNED: - OMP_CLAUSE_OPERAND (nc, 0) - = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, - in_decl, /*integral_constant_expression_p=*/false); + OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args, + complain, in_decl); OMP_CLAUSE_OPERAND (nc, 1) = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain, in_decl, /*integral_constant_expression_p=*/false); break; - case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_DEFAULT: @@ -14129,7 +14367,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tmp = tsubst_omp_clauses (OMP_TARGET_UPDATE_CLAUSES (t), false, args, complain, in_decl); t = copy_node (t); - OMP_CLAUSES (t) = tmp; + OMP_TARGET_UPDATE_CLAUSES (t) = tmp; add_stmt (t); break; @@ -14374,16 +14612,6 @@ tsubst_non_call_postfix_expression (tree t, tree args, return t; } -/* Sentinel to disable certain warnings during template substitution. */ - -struct warning_sentinel { - int &flag; - int val; - warning_sentinel(int& flag, bool suppress=true) - : flag(flag), val(flag) { if (suppress) flag = 0; } - ~warning_sentinel() { flag = val; } -}; - /* Like tsubst but deals with expressions and performs semantic analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */ @@ -14808,8 +15036,9 @@ tsubst_copy_and_build (tree t, op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); /* Remember that there was a reference to this entity. */ - if (DECL_P (op1)) - mark_used (op1); + if (DECL_P (op1) + && !mark_used (op1, complain) && !(complain & tf_error)) + RETURN (error_mark_node); RETURN (build_x_arrow (input_location, op1, complain)); case NEW_EXPR: @@ -15060,8 +15289,9 @@ tsubst_copy_and_build (tree t, } /* Remember that there was a reference to this entity. */ - if (DECL_P (function)) - mark_used (function); + if (DECL_P (function) + && !mark_used (function, complain) && !(complain & tf_error)) + RETURN (error_mark_node); /* Put back tf_decltype for the actual call. */ complain |= decltype_flag; @@ -15108,11 +15338,12 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { tree cond = RECUR (TREE_OPERAND (t, 0)); + tree folded_cond = fold_non_dependent_expr (cond); tree exp1, exp2; - if (TREE_CODE (cond) == INTEGER_CST) + if (TREE_CODE (folded_cond) == INTEGER_CST) { - if (integer_zerop (cond)) + if (integer_zerop (folded_cond)) { ++c_inhibit_evaluation_warnings; exp1 = RECUR (TREE_OPERAND (t, 1)); @@ -15126,6 +15357,7 @@ tsubst_copy_and_build (tree t, exp2 = RECUR (TREE_OPERAND (t, 2)); --c_inhibit_evaluation_warnings; } + cond = folded_cond; } else { @@ -15242,8 +15474,9 @@ tsubst_copy_and_build (tree t, object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); /* Remember that there was a reference to this entity. */ - if (DECL_P (object)) - mark_used (object); + if (DECL_P (object) + && !mark_used (object, complain) && !(complain & tf_error)) + RETURN (error_mark_node); object_type = TREE_TYPE (object); member = TREE_OPERAND (t, 1); @@ -15459,17 +15692,24 @@ tsubst_copy_and_build (tree t, case PARM_DECL: { tree r = tsubst_copy (t, args, complain, in_decl); + /* ??? We're doing a subset of finish_id_expression here. */ if (VAR_P (r) && !processing_template_decl && !cp_unevaluated_operand && (TREE_STATIC (r) || DECL_EXTERNAL (r)) - && DECL_THREAD_LOCAL_P (r)) + && CP_DECL_THREAD_LOCAL_P (r)) { if (tree wrap = get_tls_wrapper_fn (r)) /* Replace an evaluated use of the thread_local variable with a call to its wrapper. */ r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error); } + else if (outer_automatic_var_p (r)) + { + r = process_outer_var_ref (r, complain); + if (is_capture_proxy (r)) + register_local_specialization (r, t); + } if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE) /* If the original type was a reference, we'll be wrapped in @@ -15686,6 +15926,7 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain) constant. */ else if (TREE_TYPE (t) && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) + && !REFERENCE_REF_P (t) && !TREE_CONSTANT (t)) { if (complain & tf_error) @@ -15821,13 +16062,32 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) ++processing_template_decl; if (DECL_CLASS_SCOPE_P (gen_tmpl)) { - tree ctx = tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr, - complain, gen_tmpl); + tree ctx = tsubst_aggr_type (DECL_CONTEXT (gen_tmpl), targ_ptr, + complain, gen_tmpl, true); push_nested_class (ctx); } + + tree pattern = DECL_TEMPLATE_RESULT (gen_tmpl); + + if (VAR_P (pattern)) + { + /* We need to determine if we're using a partial or explicit + specialization now, because the type of the variable could be + different. */ + tree tid = lookup_template_variable (gen_tmpl, targ_ptr); + tree elt = most_specialized_partial_spec (tid, complain); + if (elt == error_mark_node) + pattern = error_mark_node; + else if (elt) + { + tmpl = TREE_VALUE (elt); + pattern = DECL_TEMPLATE_RESULT (tmpl); + targ_ptr = TREE_PURPOSE (elt); + } + } + /* Substitute template parameters to obtain the specialization. */ - fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), - targ_ptr, complain, gen_tmpl); + fndecl = tsubst (pattern, targ_ptr, complain, gen_tmpl); if (DECL_CLASS_SCOPE_P (gen_tmpl)) pop_nested_class (); pop_from_top_level (); @@ -16309,15 +16569,11 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, break; case DEDUCE_CONV: - { - /* Swap PARM and ARG throughout the remainder of this - function; the handling is precisely symmetric since PARM - will initialize ARG rather than vice versa. */ - tree* temp = parm; - parm = arg; - arg = temp; - break; - } + /* Swap PARM and ARG throughout the remainder of this + function; the handling is precisely symmetric since PARM + will initialize ARG rather than vice versa. */ + std::swap (parm, arg); + break; case DEDUCE_EXACT: /* Core issue #873: Do the DR606 thing (see below) for these cases, @@ -16571,7 +16827,7 @@ uses_deducible_template_parms (tree type) static int unify_one_argument (tree tparms, tree targs, tree parm, tree arg, - int subr, unification_kind_t strict, int flags, + int subr, unification_kind_t strict, bool explain_p) { tree arg_expr = NULL_TREE; @@ -16588,16 +16844,10 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg, argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction. */ - if (TYPE_P (parm) && !uses_template_parms (parm)) - /* For function parameters that contain no template-parameters at all, - we have historically checked for convertibility in order to shortcut - consideration of this candidate. */ - return check_non_deducible_conversion (parm, arg, strict, flags, - explain_p); - else if (strict == DEDUCE_CALL - && TYPE_P (parm) && !uses_deducible_template_parms (parm)) - /* For function parameters with only non-deducible template parameters, - just return. */ + if (strict != DEDUCE_EXACT + && TYPE_P (parm) && !uses_deducible_template_parms (parm)) + /* For function parameters with no deducible template parameters, + just return. We'll check non-dependent conversions later. */ return unify_success (explain_p); switch (strict) @@ -16736,7 +16986,7 @@ type_unification_real (tree tparms, ++ia; if (unify_one_argument (tparms, targs, parm, arg, subr, strict, - flags, explain_p)) + explain_p)) return 1; } @@ -16818,8 +17068,11 @@ type_unification_real (tree tparms, this parameter can be deduced. */ if (TREE_CODE (tparm) == PARM_DECL && uses_template_parms (TREE_TYPE (tparm)) - && !saw_undeduced++) - goto again; + && saw_undeduced < 2) + { + saw_undeduced = 1; + continue; + } /* Core issue #226 (C++0x) [temp.deduct]: @@ -16830,32 +17083,9 @@ type_unification_real (tree tparms, be NULL_TREE or ERROR_MARK_NODE, so we do not need to explicitly check cxx_dialect here. */ if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i))) - { - tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); - tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i)); - reopen_deferring_access_checks (*checks); - location_t save_loc = input_location; - if (DECL_P (parm)) - input_location = DECL_SOURCE_LOCATION (parm); - arg = tsubst_template_arg (arg, targs, complain, NULL_TREE); - arg = convert_template_argument (parm, arg, targs, complain, - i, NULL_TREE); - input_location = save_loc; - *checks = get_deferred_access_checks (); - pop_deferring_access_checks (); - if (arg == error_mark_node) - return 1; - else - { - TREE_VEC_ELT (targs, i) = arg; - /* The position of the first default template argument, - is also the number of non-defaulted arguments in TARGS. - Record that. */ - if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) - SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i); - continue; - } - } + /* OK, there is a default argument. Wait until after the + conversion check to do substitution. */ + continue; /* If the type parameter is a parameter pack, then it will be deduced to an empty parameter pack. */ @@ -16880,6 +17110,84 @@ type_unification_real (tree tparms, return unify_parameter_deduction_failure (explain_p, tparm); } + + /* DR 1391: All parameters have args, now check non-dependent parms for + convertibility. */ + if (saw_undeduced < 2) + for (ia = 0, parms = xparms, args = xargs, nargs = xnargs; + parms && parms != void_list_node && ia < nargs; ) + { + parm = TREE_VALUE (parms); + + if (TREE_CODE (parm) == TYPE_PACK_EXPANSION + && (!TREE_CHAIN (parms) + || TREE_CHAIN (parms) == void_list_node)) + /* For a function parameter pack that occurs at the end of the + parameter-declaration-list, the type A of each remaining + argument of the call is compared with the type P of the + declarator-id of the function parameter pack. */ + break; + + parms = TREE_CHAIN (parms); + + if (TREE_CODE (parm) == TYPE_PACK_EXPANSION) + /* For a function parameter pack that does not occur at the + end of the parameter-declaration-list, the type of the + parameter pack is a non-deduced context. */ + continue; + + arg = args[ia]; + ++ia; + + if (uses_template_parms (parm)) + continue; + if (check_non_deducible_conversion (parm, arg, strict, flags, + explain_p)) + return 1; + } + + /* Now substitute into the default template arguments. */ + for (i = 0; i < ntparms; i++) + { + tree targ = TREE_VEC_ELT (targs, i); + tree tparm = TREE_VEC_ELT (tparms, i); + + if (targ || tparm == error_mark_node) + continue; + tree parm = TREE_VALUE (tparm); + + if (TREE_CODE (parm) == PARM_DECL + && uses_template_parms (TREE_TYPE (parm)) + && saw_undeduced < 2) + continue; + + tree arg = TREE_PURPOSE (tparm); + reopen_deferring_access_checks (*checks); + location_t save_loc = input_location; + if (DECL_P (parm)) + input_location = DECL_SOURCE_LOCATION (parm); + arg = tsubst_template_arg (arg, targs, complain, NULL_TREE); + arg = convert_template_argument (parm, arg, targs, complain, + i, NULL_TREE); + input_location = save_loc; + *checks = get_deferred_access_checks (); + pop_deferring_access_checks (); + if (arg == error_mark_node) + return 1; + else + { + TREE_VEC_ELT (targs, i) = arg; + /* The position of the first default template argument, + is also the number of non-defaulted arguments in TARGS. + Record that. */ + if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) + SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i); + continue; + } + } + + if (saw_undeduced++ == 1) + goto again; } #ifdef ENABLE_CHECKING if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs)) @@ -17494,7 +17802,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, /* Unify the pattern with the current argument. */ if (unify_one_argument (tparms, targs, parm, arg, subr, strict, - LOOKUP_IMPLICIT, explain_p)) + explain_p)) return 1; /* For each parameter pack, collect the deduced value. */ @@ -17753,7 +18061,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, if (TREE_CODE (parm) == ARRAY_TYPE) elttype = TREE_TYPE (parm); else - elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0); + { + elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0); + /* Deduction is defined in terms of a single type, so just punt + on the (bizarre) std::initializer_list. */ + if (PACK_EXPANSION_P (elttype)) + return unify_success (explain_p); + } FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt) { @@ -17765,6 +18079,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, if (!BRACE_ENCLOSED_INITIALIZER_P (elt)) { tree type = TREE_TYPE (elt); + if (type == error_mark_node) + return unify_invalid (explain_p); /* It should only be possible to get here for a call. */ gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL); elt_strict |= maybe_adjust_types_for_deduction @@ -18099,7 +18415,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, && !TEMPLATE_PARM_PARAMETER_PACK (parm)) return unify_parameter_pack_mismatch (explain_p, parm, arg); - arg = strip_typedefs_expr (arg); + { + bool removed_attr = false; + arg = strip_typedefs_expr (arg, &removed_attr); + } TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; return unify_success (explain_p); @@ -18385,7 +18704,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case CONST_DECL: if (DECL_TEMPLATE_PARM_P (parm)) return unify (tparms, targs, DECL_INITIAL (parm), arg, strict, explain_p); - if (arg != integral_constant_value (parm)) + if (arg != scalar_constant_value (parm)) return unify_template_argument_mismatch (explain_p, parm, arg); return unify_success (explain_p); @@ -18419,8 +18738,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case INDIRECT_REF: if (REFERENCE_REF_P (parm)) - return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, - strict, explain_p); + { + if (REFERENCE_REF_P (arg)) + arg = TREE_OPERAND (arg, 0); + return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, + strict, explain_p); + } /* FALLTHRU */ default: @@ -18824,8 +19147,8 @@ more_specialized_fn (tree pat1, tree pat2, int len) /* Determine which of two partial specializations of TMPL is more specialized. - PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding - to the first partial specialization. The TREE_VALUE is the + PAT1 is a TREE_LIST whose TREE_VALUE is the TEMPLATE_DECL corresponding + to the first partial specialization. The TREE_PURPOSE is the innermost set of template parameters for the partial specialization. PAT2 is similar, but for the second template. @@ -18837,33 +19160,32 @@ more_specialized_fn (tree pat1, tree pat2, int len) two templates is more specialized. */ static int -more_specialized_class (tree tmpl, tree pat1, tree pat2) +more_specialized_partial_spec (tree tmpl, tree pat1, tree pat2) { tree targs; - tree tmpl1, tmpl2; int winner = 0; bool any_deductions = false; - tmpl1 = TREE_TYPE (pat1); - tmpl2 = TREE_TYPE (pat2); + tree tmpl1 = TREE_VALUE (pat1); + tree tmpl2 = TREE_VALUE (pat2); + tree parms1 = DECL_INNERMOST_TEMPLATE_PARMS (tmpl1); + tree parms2 = DECL_INNERMOST_TEMPLATE_PARMS (tmpl2); + tree specargs1 = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl1))); + tree specargs2 = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (tmpl2))); /* Just like what happens for functions, if we are ordering between - different class template specializations, we may encounter dependent + different template specializations, we may encounter dependent types in the arguments, and we need our dependency check functions to behave correctly. */ ++processing_template_decl; - targs = get_class_bindings (tmpl, TREE_VALUE (pat1), - CLASSTYPE_TI_ARGS (tmpl1), - CLASSTYPE_TI_ARGS (tmpl2)); + targs = get_partial_spec_bindings (tmpl, parms1, specargs1, specargs2); if (targs) { --winner; any_deductions = true; } - targs = get_class_bindings (tmpl, TREE_VALUE (pat2), - CLASSTYPE_TI_ARGS (tmpl2), - CLASSTYPE_TI_ARGS (tmpl1)); + targs = get_partial_spec_bindings (tmpl, parms2, specargs2, specargs1); if (targs) { ++winner; @@ -18871,7 +19193,7 @@ more_specialized_class (tree tmpl, tree pat1, tree pat2) } --processing_template_decl; - /* In the case of a tie where at least one of the class templates + /* In the case of a tie where at least one of the templates has a parameter pack at the end, the template with the most non-packed parameters wins. */ if (winner == 0 @@ -18957,7 +19279,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) is bound to `double'. */ static tree -get_class_bindings (tree tmpl, tree tparms, tree spec_args, tree args) +get_partial_spec_bindings (tree tmpl, tree tparms, tree spec_args, tree args) { int i, ntparms = TREE_VEC_LENGTH (tparms); tree deduced_args; @@ -19125,6 +19447,7 @@ most_general_template (tree decl) break; if (CLASS_TYPE_P (TREE_TYPE (decl)) + && !TYPE_DECL_ALIAS_P (TYPE_NAME (TREE_TYPE (decl))) && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))) break; @@ -19140,20 +19463,20 @@ most_general_template (tree decl) return decl; } -/* Return the most specialized of the class template partial - specializations which can produce TYPE, a specialization of some class - template. The value returned is actually a TREE_LIST; the TREE_TYPE is - a _TYPE node corresponding to the partial specialization, while the - TREE_PURPOSE is the set of template arguments that must be - substituted into the TREE_TYPE in order to generate TYPE. +/* Return the most specialized of the template partial specializations + which can produce TARGET, a specialization of some class or variable + template. The value returned is actually a TREE_LIST; the TREE_VALUE is + a TEMPLATE_DECL node corresponding to the partial specialization, while + the TREE_PURPOSE is the set of template arguments that must be + substituted into the template pattern in order to generate TARGET. If the choice of partial specialization is ambiguous, a diagnostic is issued, and the error_mark_node is returned. If there are no - partial specializations matching TYPE, then NULL_TREE is + partial specializations matching TARGET, then NULL_TREE is returned, indicating that the primary template should be used. */ static tree -most_specialized_class (tree type, tsubst_flags_t complain) +most_specialized_partial_spec (tree target, tsubst_flags_t complain) { tree list = NULL_TREE; tree t; @@ -19161,10 +19484,29 @@ most_specialized_class (tree type, tsubst_flags_t complain) int fate; bool ambiguous_p; tree outer_args = NULL_TREE; + tree tmpl, args; + + if (TYPE_P (target)) + { + tree tinfo = CLASSTYPE_TEMPLATE_INFO (target); + tmpl = TI_TEMPLATE (tinfo); + args = TI_ARGS (tinfo); + } + else if (TREE_CODE (target) == TEMPLATE_ID_EXPR) + { + tmpl = TREE_OPERAND (target, 0); + args = TREE_OPERAND (target, 1); + } + else if (VAR_P (target)) + { + tree tinfo = DECL_TEMPLATE_INFO (target); + tmpl = TI_TEMPLATE (tinfo); + args = TI_ARGS (tinfo); + } + else + gcc_unreachable (); - tree tmpl = CLASSTYPE_TI_TEMPLATE (type); tree main_tmpl = most_general_template (tmpl); - tree args = CLASSTYPE_TI_ARGS (type); /* For determining which partial specialization to use, only the innermost args are interesting. */ @@ -19179,9 +19521,8 @@ most_specialized_class (tree type, tsubst_flags_t complain) tree partial_spec_args; tree spec_args; tree spec_tmpl = TREE_VALUE (t); - tree orig_parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl); - partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t)); + partial_spec_args = TREE_PURPOSE (t); ++processing_template_decl; @@ -19212,14 +19553,14 @@ most_specialized_class (tree type, tsubst_flags_t complain) return error_mark_node; tree parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl); - spec_args = get_class_bindings (tmpl, parms, + spec_args = get_partial_spec_bindings (tmpl, parms, partial_spec_args, args); if (spec_args) { if (outer_args) spec_args = add_to_template_args (outer_args, spec_args); - list = tree_cons (spec_args, orig_parms, list); + list = tree_cons (spec_args, TREE_VALUE (t), list); TREE_TYPE (list) = TREE_TYPE (t); } } @@ -19233,7 +19574,7 @@ most_specialized_class (tree type, tsubst_flags_t complain) t = TREE_CHAIN (t); for (; t; t = TREE_CHAIN (t)) { - fate = more_specialized_class (tmpl, champ, t); + fate = more_specialized_partial_spec (tmpl, champ, t); if (fate == 1) ; else @@ -19254,7 +19595,7 @@ most_specialized_class (tree type, tsubst_flags_t complain) if (!ambiguous_p) for (t = list; t && t != champ; t = TREE_CHAIN (t)) { - fate = more_specialized_class (tmpl, champ, t); + fate = more_specialized_partial_spec (tmpl, champ, t); if (fate != 1) { ambiguous_p = true; @@ -19268,11 +19609,16 @@ most_specialized_class (tree type, tsubst_flags_t complain) char *spaces = NULL; if (!(complain & tf_error)) return error_mark_node; - error ("ambiguous class template instantiation for %q#T", type); + if (TYPE_P (target)) + error ("ambiguous template instantiation for %q#T", target); + else + error ("ambiguous template instantiation for %q#D", target); str = ngettext ("candidate is:", "candidates are:", list_length (list)); for (t = list; t; t = TREE_CHAIN (t)) { - error ("%s %+#T", spaces ? spaces : str, TREE_TYPE (t)); + tree subst = build_tree_list (TREE_VALUE (t), TREE_PURPOSE (t)); + inform (DECL_SOURCE_LOCATION (TREE_VALUE (t)), + "%s %#S", spaces ? spaces : str, subst); spaces = spaces ? spaces : get_spaces (str); } free (spaces); @@ -20301,7 +20647,8 @@ instantiate_pending_templates (int retries) { tree decl = pending_templates->tinst->decl; - fatal_error ("template instantiation depth exceeds maximum of %d" + fatal_error (input_location, + "template instantiation depth exceeds maximum of %d" " instantiating %q+D, possibly from virtual table generation" " (use -ftemplate-depth= to increase the maximum)", max_tinst_depth, decl); @@ -20554,9 +20901,10 @@ tsubst_enum (tree tag, tree newtag, tree args) /* Give this enumeration constant the correct access. */ set_current_access_from_decl (decl); - /* Actually build the enumerator itself. */ - build_enumerator - (DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl)); + /* Actually build the enumerator itself. Here we're assuming that + enumerators can't have dependent attributes. */ + build_enumerator (DECL_NAME (decl), value, newtag, + DECL_ATTRIBUTES (decl), DECL_SOURCE_LOCATION (decl)); } if (SCOPED_ENUM_P (newtag)) @@ -20577,62 +20925,8 @@ tsubst_enum (tree tag, tree newtag, tree args) tree get_mostly_instantiated_function_type (tree decl) { - tree fn_type; - tree tmpl; - tree targs; - tree tparms; - int parm_depth; - - tmpl = most_general_template (DECL_TI_TEMPLATE (decl)); - targs = DECL_TI_ARGS (decl); - tparms = DECL_TEMPLATE_PARMS (tmpl); - parm_depth = TMPL_PARMS_DEPTH (tparms); - - /* There should be as many levels of arguments as there are levels - of parameters. */ - gcc_assert (parm_depth == TMPL_ARGS_DEPTH (targs)); - - fn_type = TREE_TYPE (tmpl); - - if (parm_depth == 1) - /* No substitution is necessary. */ - ; - else - { - int i; - tree partial_args; - - /* Replace the innermost level of the TARGS with NULL_TREEs to - let tsubst know not to substitute for those parameters. */ - partial_args = make_tree_vec (TREE_VEC_LENGTH (targs)); - for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i) - SET_TMPL_ARGS_LEVEL (partial_args, i, - TMPL_ARGS_LEVEL (targs, i)); - SET_TMPL_ARGS_LEVEL (partial_args, - TMPL_ARGS_DEPTH (targs), - make_tree_vec (DECL_NTPARMS (tmpl))); - - /* Make sure that we can see identifiers, and compute access - correctly. */ - push_access_scope (decl); - - ++processing_template_decl; - /* Now, do the (partial) substitution to figure out the - appropriate function type. */ - fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE); - --processing_template_decl; - - /* Substitute into the template parameters to obtain the real - innermost set of parameters. This step is important if the - innermost set of template parameters contains value - parameters whose types depend on outer template parameters. */ - TREE_VEC_LENGTH (partial_args)--; - tparms = tsubst_template_parms (tparms, partial_args, tf_error); - - pop_access_scope (decl); - } - - return fn_type; + /* For a function, DECL_TI_TEMPLATE is partially instantiated. */ + return TREE_TYPE (DECL_TI_TEMPLATE (decl)); } /* Return truthvalue if we're processing a template different from @@ -20656,6 +20950,16 @@ current_instantiation (void) return current_tinst_level; } +/* Return TRUE if current_function_decl is being instantiated, false + otherwise. */ + +bool +instantiating_current_function_p (void) +{ + return (current_instantiation () + && current_instantiation ()->decl == current_function_decl); +} + /* [temp.param] Check that template non-type parm TYPE is of an allowable type. Return zero for ok, nonzero for disallowed. Issue error and warning messages under control of COMPLAIN. */ @@ -20712,9 +21016,17 @@ dependent_type_p_r (tree type) names a dependent type. */ if (TREE_CODE (type) == TYPENAME_TYPE) return true; + + /* An alias template specialization can be dependent even if the + resulting type is not. */ + if (dependent_alias_template_spec_p (type)) + return true; + /* -- a cv-qualified type where the cv-unqualified type is - dependent. */ - type = TYPE_MAIN_VARIANT (type); + dependent. + No code is necessary for this bullet; the code below handles + cv-qualified types, and we don't want to strip aliases with + TYPE_MAIN_VARIANT because of DR 1558. */ /* -- a compound type constructed from any dependent type. */ if (TYPE_PTRMEM_P (type)) return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type)) @@ -20922,6 +21234,8 @@ value_dependent_expression_p (tree expression) if (DECL_INITIAL (expression) && decl_constant_var_p (expression) && (TREE_CODE (DECL_INITIAL (expression)) == TREE_LIST + /* cp_finish_decl doesn't fold reference initializers. */ + || TREE_CODE (TREE_TYPE (expression)) == REFERENCE_TYPE || value_dependent_expression_p (DECL_INITIAL (expression)))) return true; return false; @@ -21062,6 +21376,8 @@ value_dependent_expression_p (tree expression) { unsigned ix; tree val; + if (dependent_type_p (TREE_TYPE (expression))) + return true; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expression), ix, val) if (value_dependent_expression_p (val)) return true; @@ -21070,7 +21386,7 @@ value_dependent_expression_p (tree expression) case STMT_EXPR: /* Treat a GNU statement expression as dependent to avoid crashing - under fold_non_dependent_expr; it can't be constant. */ + under instantiate_non_dependent_expr; it can't be constant. */ return true; default: @@ -21244,6 +21560,18 @@ type_dependent_expression_p (tree expression) && DECL_INITIAL (expression)) return true; + /* A variable template specialization is type-dependent if it has any + dependent template arguments. */ + if (VAR_P (expression) + && DECL_LANG_SPECIFIC (expression) + && DECL_TEMPLATE_INFO (expression) + && variable_template_p (DECL_TI_TEMPLATE (expression))) + return any_dependent_template_arguments_p (DECL_TI_ARGS (expression)); + + /* Always dependent, on the number of arguments if nothing else. */ + if (TREE_CODE (expression) == EXPR_PACK_EXPANSION) + return true; + if (TREE_TYPE (expression) == unknown_type_node) { if (TREE_CODE (expression) == ADDR_EXPR) @@ -21261,10 +21589,6 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == SCOPE_REF) return false; - /* Always dependent, on the number of arguments if nothing else. */ - if (TREE_CODE (expression) == EXPR_PACK_EXPANSION) - return true; - if (BASELINK_P (expression)) { if (BASELINK_OPTYPE (expression) @@ -21824,7 +22148,7 @@ build_non_dependent_expr (tree expr) /* Try to get a constant value for all non-dependent expressions in order to expose bugs in *_dependent_expression_p and constexpr. */ if (cxx_dialect >= cxx11) - maybe_constant_value (fold_non_dependent_expr_sfinae (expr, tf_none)); + fold_non_dependent_expr (expr); #endif /* Preserve OVERLOADs; the functions must be available to resolve @@ -21996,7 +22320,21 @@ do_auto_deduction (tree type, tree init, tree auto_node) initializer is a braced-init-list (8.5.4), with std::initializer_list. */ if (BRACE_ENCLOSED_INITIALIZER_P (init)) - type = listify_autos (type, auto_node); + { + if (!DIRECT_LIST_INIT_P (init)) + type = listify_autos (type, auto_node); + else if (CONSTRUCTOR_NELTS (init) == 1) + init = CONSTRUCTOR_ELT (init, 0)->value; + else + { + if (permerror (input_location, "direct-list-initialization of " + "% requires exactly one element")) + inform (input_location, + "for deduction to %, use copy-" + "list-initialization (i.e. add %<=%> before the %<{%>)"); + type = listify_autos (type, auto_node); + } + } init = resolve_nondeduced_context (init); @@ -22310,14 +22648,8 @@ convert_generic_types_to_packs (tree parm, int start_idx, int end_idx) void init_template_processing (void) { - decl_specializations = htab_create_ggc (37, - hash_specialization, - eq_specializations, - ggc_free); - type_specializations = htab_create_ggc (37, - hash_specialization, - eq_specializations, - ggc_free); + decl_specializations = hash_table::create_ggc (37); + type_specializations = hash_table::create_ggc (37); } /* Print stats about the template hash tables for -fstats. */ @@ -22326,13 +22658,13 @@ void print_template_statistics (void) { fprintf (stderr, "decl_specializations: size %ld, %ld elements, " - "%f collisions\n", (long) htab_size (decl_specializations), - (long) htab_elements (decl_specializations), - htab_collisions (decl_specializations)); + "%f collisions\n", (long) decl_specializations->size (), + (long) decl_specializations->elements (), + decl_specializations->collisions ()); fprintf (stderr, "type_specializations: size %ld, %ld elements, " - "%f collisions\n", (long) htab_size (type_specializations), - (long) htab_elements (type_specializations), - htab_collisions (type_specializations)); + "%f collisions\n", (long) type_specializations->size (), + (long) type_specializations->elements (), + type_specializations->collisions ()); } #include "gt-cp-pt.h"