static tree add_to_template_args (tree, tree);
static tree add_outermost_template_args (tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
+static int check_non_deducible_conversion (tree, tree, int, int,
+ struct conversion **, bool);
static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
tree);
static int type_unification_real (tree, tree, tree, const tree *,
- unsigned int, int, unification_kind_t, int,
+ unsigned int, int, unification_kind_t,
vec<deferred_access_check, va_gc> **,
bool);
static void note_template_header (int);
return true;
else
{
- permerror (input_location,
- "specialization of %qD in different namespace", tmpl);
- inform (DECL_SOURCE_LOCATION (tmpl),
- " from definition of %q#D", tmpl);
+ auto_diagnostic_group d;
+ if (permerror (input_location,
+ "specialization of %qD in different namespace", tmpl))
+ inform (DECL_SOURCE_LOCATION (tmpl),
+ " from definition of %q#D", tmpl);
return false;
}
}
new_spec_types);
new_type = cp_build_type_attribute_variant (new_type,
TYPE_ATTRIBUTES (old_type));
- new_type = build_exception_variant (new_type,
- TYPE_RAISES_EXCEPTIONS (old_type));
-
- if (TYPE_HAS_LATE_RETURN_TYPE (old_type))
- TYPE_HAS_LATE_RETURN_TYPE (new_type) = 1;
+ new_type = cxx_copy_lang_qualifiers (new_type, old_type);
TREE_TYPE (decl) = new_type;
}
}
if (template_header_count > wanted)
{
+ auto_diagnostic_group d;
bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0,
"too many template headers for %qD "
"(should be %d)",
if (!nattrs)
return;
+ auto_diagnostic_group d;
if (warning_at (DECL_SOURCE_LOCATION (spec), OPT_Wmissing_attributes,
"explicit specialization %q#D may be missing attributes",
spec))
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_HIDDEN_FRIEND_P (tmpl))
{
+ auto_diagnostic_group d;
if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
"friend declaration %qD is not visible to "
"explicit specialization", tmpl))
cap; cap = TREE_CHAIN (cap))
cp_walk_tree (&TREE_VALUE (cap), &find_parameter_packs_r, ppd,
ppd->visited);
- /* Since we defer implicit capture, look in the body as well. */
+ /* Since we defer implicit capture, look in the parms and body. */
tree fn = lambda_function (t);
+ cp_walk_tree (&TREE_TYPE (fn), &find_parameter_packs_r, ppd,
+ ppd->visited);
cp_walk_tree (&DECL_SAVED_TREE (fn), &find_parameter_packs_r, ppd,
ppd->visited);
*walk_subtrees = 0;
return NULL_TREE;
}
+ case IF_STMT:
+ cp_walk_tree (&IF_COND (t), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ cp_walk_tree (&THEN_CLAUSE (t), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ cp_walk_tree (&ELSE_CLAUSE (t), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ /* Don't walk into IF_STMT_EXTRA_ARGS. */
+ *walk_subtrees = 0;
+ return NULL_TREE;
+
default:
return NULL_TREE;
}
if (complain & tf_error)
{
if (TYPE_P (arg))
- error ("expansion pattern %qT contains no argument packs", arg);
+ error ("expansion pattern %qT contains no parameter packs", arg);
else
- error ("expansion pattern %qE contains no argument packs", arg);
+ error ("expansion pattern %qE contains no parameter packs", arg);
}
return error_mark_node;
}
Returns TRUE and emits an error if there were bare parameter packs,
returns FALSE otherwise. */
bool
-check_for_bare_parameter_packs (tree t)
+check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */)
{
tree parameter_packs = NULL_TREE;
struct find_parameter_pack_data ppd;
if (parameter_packs)
{
- location_t loc = EXPR_LOC_OR_LOC (t, input_location);
+ if (loc == UNKNOWN_LOCATION)
+ loc = cp_expr_loc_or_loc (t, input_location);
error_at (loc, "parameter packs not expanded with %<...%>:");
while (parameter_packs)
{
pushdecl (decl);
- if (defval && TREE_CODE (defval) == OVERLOAD)
- lookup_keep (defval, true);
-
/* Build the parameter node linking the parameter declaration,
its default argument (if any), and its constraints (if any). */
parm = build_tree_list (defval, parm);
template PARMS and constraints, CONSTR. If MEMBER_TEMPLATE_P is true,
the new template is a member template. */
-tree
+static tree
build_template_decl (tree decl, tree parms, bool member_template_p)
{
tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
&& TMPL_ARGS_DEPTH (specargs) == 1
&& !get_partial_spec_bindings (maintmpl, maintmpl, specargs))
{
+ auto_diagnostic_group d;
if (permerror (input_location, "partial specialization %qD is not "
"more specialized than", decl))
inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD",
}
accept:
- if (TREE_CODE (type) == REFERENCE_TYPE)
+ if (TYPE_REF_P (type))
{
if (REFERENCE_REF_P (fn))
fn = TREE_OPERAND (fn, 0);
check_valid_ptrmem_cst_expr (tree type, tree expr,
tsubst_flags_t complain)
{
- location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+ location_t loc = cp_expr_loc_or_loc (expr, input_location);
tree orig_expr = expr;
STRIP_NOPS (expr);
if (null_ptr_cst_p (expr))
tree from_type, tree arg)
{
if (explain_p)
- inform (EXPR_LOC_OR_LOC (arg, input_location),
+ inform (cp_expr_loc_or_loc (arg, input_location),
" cannot convert %qE (type %qT) to type %qT",
arg, from_type, to_type);
return unify_invalid (explain_p);
convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
tree expr_type;
- location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+ location_t loc = cp_expr_loc_or_loc (expr, input_location);
tree orig_expr = expr;
/* Detect immediately string literals as invalid non-type argument.
template-parameter. */
expr = build_converted_constant_expr (type, expr, complain);
if (expr == error_mark_node)
- return error_mark_node;
+ /* Make sure we return NULL_TREE only if we have really issued
+ an error, as described above. */
+ return (complain & tf_error) ? NULL_TREE : error_mark_node;
expr = maybe_constant_value (expr);
expr = convert_from_reference (expr);
}
}
}
- if (TREE_CODE (type) == REFERENCE_TYPE)
+ if (TYPE_REF_P (type))
expr = mark_lvalue_use (expr);
else
expr = mark_rvalue_use (expr);
could actually change the type to something more cv-qualified,
and this is not folded by convert_from_reference. */
tree addr = TREE_OPERAND (probe, 0);
- if (TREE_CODE (probe_type) == REFERENCE_TYPE
+ if (TYPE_REF_P (probe_type)
&& TREE_CODE (addr) == ADDR_EXPR
&& TYPE_PTR_P (TREE_TYPE (addr))
&& (same_type_ignoring_top_level_qualifiers_p
"a variable", orig_expr, expr);
return NULL_TREE;
}
- if (POINTER_TYPE_P (expr_type))
+ if (INDIRECT_TYPE_P (expr_type))
{
if (complain & tf_error)
error ("%qE is not a valid template argument for %qT "
tree val;
int is_type, requires_type, is_tmpl_type, requires_tmpl_type;
- if (parm == error_mark_node)
+ if (parm == error_mark_node || error_operand_p (arg))
return error_mark_node;
/* Trivially convert placeholders. */
const_tree inner = TREE_OPERAND (val, 0);
const_tree innertype = TREE_TYPE (inner);
if (innertype
- && TREE_CODE (innertype) == REFERENCE_TYPE
+ && TYPE_REF_P (innertype)
&& TREE_CODE (TREE_TYPE (innertype)) == FUNCTION_TYPE
&& TREE_OPERAND_LENGTH (inner) > 0
&& reject_gcc_builtin (TREE_OPERAND (inner, 0)))
return ret;
}
-/* Increment OBJ's refcount. */
+const unsigned short tinst_level::refcount_infinity;
+
+/* Increment OBJ's refcount unless it is already infinite. */
static tinst_level *
inc_refcount_use (tinst_level *obj)
{
- if (obj)
- {
- ++obj->refcount;
- gcc_assert (obj->refcount != 0);
- }
+ if (obj && obj->refcount != tinst_level::refcount_infinity)
+ ++obj->refcount;
return obj;
}
tinst_level_freelist ().free (obj);
}
-/* Decrement OBJ's refcount. If it reaches zero, release OBJ's DECL
- and OBJ, and start over with the tinst_level object that used to be
- referenced by OBJ's NEXT. */
+/* Decrement OBJ's refcount if not infinite. If it reaches zero, release
+ OBJ's DECL and OBJ, and start over with the tinst_level object that
+ used to be referenced by OBJ's NEXT. */
static void
dec_refcount_use (tinst_level *obj)
{
- while (obj && !--obj->refcount)
+ while (obj
+ && obj->refcount != tinst_level::refcount_infinity
+ && !--obj->refcount)
{
- gcc_assert (obj->refcount+1 != 0);
tinst_level *next = obj->next;
tinst_level::free (obj);
obj = next;
{
if (complain & tf_error)
{
+ auto_diagnostic_group d;
error ("template constraint failure");
diagnose_constraints (input_location, gen_tmpl, arglist);
}
return found;
}
- context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
- complain, in_decl);
+ context = DECL_CONTEXT (gen_tmpl);
+ if (context && TYPE_P (context))
+ {
+ context = tsubst_aggr_type (context, arglist, complain, in_decl, true);
+ context = complete_type (context);
+ }
+ else
+ context = tsubst (context, arglist, complain, in_decl);
+
if (context == error_mark_node)
return error_mark_node;
/* A local class. Make sure the decl gets registered properly. */
if (context == current_function_decl)
- pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current);
+ if (pushtag (DECL_NAME (gen_tmpl), t, /*tag_scope=*/ts_current)
+ == error_mark_node)
+ return error_mark_node;
if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
/* This instantiation is another name for the primary
{
if (complain & tf_error)
{
+ auto_diagnostic_group d;
error ("use of invalid variable template %qE", var);
diagnose_constraints (location_of (var), templ, arglist);
}
break;
case TYPEOF_TYPE:
+ case DECLTYPE_TYPE:
case UNDERLYING_TYPE:
if (pfd->include_nondeduced_p
&& for_each_template_parm (TYPE_VALUES_RAW (t), fn, data,
pfd->include_nondeduced_p,
pfd->any_fn))
return error_mark_node;
+ *walk_subtrees = false;
break;
case FUNCTION_DECL:
new_level->tldcl = tldcl;
new_level->targs = targs;
new_level->locus = loc;
- new_level->errors = errorcount+sorrycount;
- new_level->in_system_header_p = in_system_header_at (input_location);
+ new_level->errors = errorcount + sorrycount;
new_level->next = NULL;
new_level->refcount = 0;
set_refcount_ptr (new_level->next, current_tinst_level);
/* Mark the type as in the process of being defined. */
TYPE_BEING_DEFINED (type) = 1;
+ /* We may be in the middle of deferred access check. Disable
+ it now. */
+ deferring_access_check_sentinel acs (dk_no_deferred);
+
/* Determine what specialization of the original template to
instantiate. */
t = most_specialized_partial_spec (type, tf_warning_or_error);
if (! push_tinst_level (type))
return type;
- /* We may be in the middle of deferred access check. Disable
- 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;
maximum_field_alignment = saved_maximum_field_alignment;
if (!fn_context)
pop_from_top_level ();
- pop_deferring_access_checks ();
pop_tinst_level ();
/* The vtable for a template class can be emitted in any translation
}
else if (builtin_pack_call_p (parm_pack))
{
- /* ??? Support use in other patterns. */
- gcc_assert (parm_pack == pattern);
+ if (parm_pack != pattern)
+ {
+ if (complain & tf_error)
+ sorry ("%qE is not the entire pattern of the pack expansion",
+ parm_pack);
+ return error_mark_node;
+ }
return expand_builtin_pack_call (parm_pack, args,
complain, in_decl);
}
/* Also optimize expression pack expansions if we can tell that the
elements won't have reference type. */
tree type = TREE_TYPE (pattern);
- if (type && TREE_CODE (type) != REFERENCE_TYPE
+ if (type && !TYPE_REF_P (type)
&& !PACK_EXPANSION_P (type)
&& !WILDCARD_TYPE_P (type))
return args;
tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
tsubst_flags_t complain)
{
- tree saved_class_ptr = NULL_TREE;
- tree saved_class_ref = NULL_TREE;
int errs = errorcount + sorrycount;
/* This can happen in invalid code. */
we must be careful to do name lookup in the scope of S<T>,
rather than in the current class. */
+ push_to_top_level ();
push_access_scope (fn);
- /* The "this" pointer is not valid in a default argument. */
- if (cfun)
- {
- saved_class_ptr = current_class_ptr;
- cp_function_chain->x_current_class_ptr = NULL_TREE;
- saved_class_ref = current_class_ref;
- cp_function_chain->x_current_class_ref = NULL_TREE;
- }
-
start_lambda_scope (parm);
- push_deferring_access_checks(dk_no_deferred);
/* The default argument expression may cause implicitly defined
member functions to be synthesized, which will result in garbage
collection. We must treat this situation as if we were within
complain, NULL_TREE,
/*integral_constant_expression_p=*/false);
--function_depth;
- pop_deferring_access_checks();
finish_lambda_scope ();
- /* Restore the "this" pointer. */
- if (cfun)
- {
- cp_function_chain->x_current_class_ptr = saved_class_ptr;
- cp_function_chain->x_current_class_ref = saved_class_ref;
- }
-
if (errorcount+sorrycount > errs
&& (complain & tf_warning_or_error))
inform (input_location,
arg = check_default_argument (type, arg, complain);
pop_access_scope (fn);
+ pop_from_top_level ();
if (arg != error_mark_node && !cp_unevaluated_operand)
{
complain);
}
+/* Hash table mapping a FUNCTION_DECL to its dependent explicit-specifier. */
+static GTY((cache)) tree_cache_map *explicit_specifier_map;
+
+/* Store a pair to EXPLICIT_SPECIFIER_MAP. */
+
+void
+store_explicit_specifier (tree v, tree t)
+{
+ if (!explicit_specifier_map)
+ explicit_specifier_map = tree_cache_map::create_ggc (37);
+ DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (v) = true;
+ explicit_specifier_map->put (v, t);
+}
+
+/* Lookup an element in EXPLICIT_SPECIFIER_MAP. */
+
+static tree
+lookup_explicit_specifier (tree v)
+{
+ return *explicit_specifier_map->get (v);
+}
+
/* Subroutine of tsubst_decl for the case when T is a FUNCTION_DECL. */
static tree
DECL_INITIAL (r) = NULL_TREE;
DECL_CONTEXT (r) = ctx;
+ /* Handle explicit(dependent-expr). */
+ if (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (t))
+ {
+ tree spec = lookup_explicit_specifier (t);
+ spec = tsubst_copy_and_build (spec, args, complain, in_decl,
+ /*function_p=*/false,
+ /*i_c_e_p=*/true);
+ spec = build_explicit_specifier (spec, complain);
+ DECL_NONCONVERTING_P (r) = (spec == boolean_true_node);
+ }
+
/* OpenMP UDRs have the only argument a reference to the declared
type. We want to diagnose if the declared type is a reference,
which is invalid, but as references to references are usually
tree argtype
= TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (t))));
argtype = tsubst (argtype, args, complain, in_decl);
- if (TREE_CODE (argtype) == REFERENCE_TYPE)
+ if (TYPE_REF_P (argtype))
error_at (DECL_SOURCE_LOCATION (t),
"reference type %qT in "
"%<#pragma omp declare reduction%>", argtype);
}
/* Create a new node for the specialization we need. */
- r = copy_decl (t);
if (type == NULL_TREE)
{
if (is_typedef_decl (t))
sub_args = strip_innermost_template_args (args, extra);
}
type = tsubst (type, sub_args, complain, in_decl);
+ /* Substituting the type might have recursively instantiated this
+ same alias (c++/86171). */
+ if (gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl)
+ && (spec = retrieve_specialization (gen_tmpl, argvec, hash)))
+ {
+ r = spec;
+ break;
+ }
}
+ r = copy_decl (t);
if (VAR_P (r))
{
- /* Even if the original location is out of scope, the
- newly substituted one is not. */
- DECL_DEAD_FOR_LOCAL (r) = 0;
DECL_INITIALIZED_P (r) = 0;
DECL_TEMPLATE_INSTANTIATED (r) = 0;
if (type == error_mark_node)
/*constant_expression_p=*/false);
if (REFERENCE_REF_P (ve))
{
- gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
+ gcc_assert (TYPE_REF_P (type));
ve = TREE_OPERAND (ve, 0);
}
SET_DECL_VALUE_EXPR (r, ve);
if (TREE_CODE (t) == FUNCTION_TYPE)
{
fntype = build_function_type (return_type, arg_types);
- fntype = apply_memfn_quals (fntype,
- type_memfn_quals (t),
- type_memfn_rqual (t));
+ fntype = apply_memfn_quals (fntype, type_memfn_quals (t));
}
else
{
fntype = build_method_type_directly (r, return_type,
TREE_CHAIN (arg_types));
- fntype = build_ref_qualified_type (fntype, type_memfn_rqual (t));
}
fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
- if (late_return_type_p)
- TYPE_HAS_LATE_RETURN_TYPE (fntype) = 1;
+ /* See comment above. */
+ tree raises = NULL_TREE;
+ cp_ref_qualifier rqual = type_memfn_rqual (t);
+ fntype = build_cp_fntype_variant (fntype, rqual, raises, late_return_type_p);
return fntype;
}
&& !PLACEHOLDER_TYPE_CONSTRAINTS (r))
/* Break infinite recursion when substituting the constraints
of a constrained placeholder. */;
+ else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
+ && !PLACEHOLDER_TYPE_CONSTRAINTS (t)
+ && !CLASS_PLACEHOLDER_TEMPLATE (t)
+ && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
+ r = TEMPLATE_PARM_DESCENDANTS (arg))
+ && (TEMPLATE_PARM_LEVEL (r)
+ == TEMPLATE_PARM_LEVEL (arg) - levels))
+ /* Cache the simple case of lowering a type parameter. */
+ r = TREE_TYPE (r);
else
{
r = copy_type (t);
Core issue 106 says that creating a reference to a reference
during instantiation is no longer a cause for failure. We
only enforce this check in strict C++98 mode. */
- if ((TREE_CODE (type) == REFERENCE_TYPE
+ if ((TYPE_REF_P (type)
&& (((cxx_dialect == cxx98) && flag_iso) || code != REFERENCE_TYPE))
|| (code == REFERENCE_TYPE && VOID_TYPE_P (type)))
{
if (TREE_CODE (type) == METHOD_TYPE)
r = build_ptrmemfunc_type (r);
}
- else if (TREE_CODE (type) == REFERENCE_TYPE)
+ else if (TYPE_REF_P (type))
/* In C++0x, during template argument substitution, when there is an
attempt to create a reference to a reference type, reference
collapsing is applied as described in [14.3.1/4 temp.arg.type]:
error ("creating pointer to member of non-class type %qT", r);
return error_mark_node;
}
- if (TREE_CODE (type) == REFERENCE_TYPE)
+ if (TYPE_REF_P (type))
{
if (complain & tf_error)
error ("creating pointer to member reference type %qT", type);
|| TREE_CODE (type) == FUNCTION_TYPE
|| (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == NULL_TREE)
- || TREE_CODE (type) == REFERENCE_TYPE)
+ || TYPE_REF_P (type))
{
if (complain & tf_error)
error ("creating array of %qT", type);
r = build_cplus_array_type (type, domain);
+ if (!valid_array_size_p (input_location, r, in_decl,
+ (complain & tf_error)))
+ return error_mark_node;
+
if (TYPE_USER_ALIGN (t))
{
SET_TYPE_ALIGN (r, TYPE_ALIGN (t));
expanded = make_argument_pack (expanded);
if (TYPE_P (expanded))
- return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
+ return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
+ false,
complain & tf_error);
else
return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR,
{
tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
- return build1 (code, type, op0);
+ r = build1 (code, type, op0);
+ if (code == ALIGNOF_EXPR)
+ ALIGNOF_EXPR_STD_P (r) = ALIGNOF_EXPR_STD_P (t);
+ return r;
}
case COMPONENT_REF:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
+ case OMP_CLAUSE_IF_PRESENT:
+ case OMP_CLAUSE_FINALIZE:
break;
default:
gcc_unreachable ();
if (orig_declv && OMP_FOR_ORIG_DECLS (t))
{
tree o = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (t), i);
- TREE_VEC_ELT (orig_declv, i) = RECUR (o);
+ if (TREE_CODE (o) == TREE_LIST)
+ TREE_VEC_ELT (orig_declv, i)
+ = tree_cons (RECUR (TREE_PURPOSE (o)),
+ RECUR (TREE_VALUE (o)), NULL_TREE);
+ else
+ TREE_VEC_ELT (orig_declv, i) = RECUR (o);
}
decl = TREE_OPERAND (init, 0);
return t;
loc = input_location;
- if (EXPR_HAS_LOCATION (t))
- input_location = EXPR_LOCATION (t);
+ if (location_t eloc = cp_expr_location (t))
+ input_location = eloc;
if (STATEMENT_CODE_P (TREE_CODE (t)))
current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
register_local_specialization (inst, decl);
break;
}
+ else if (DECL_PRETTY_FUNCTION_P (decl))
+ decl = make_fname_decl (DECL_SOURCE_LOCATION (decl),
+ DECL_NAME (decl),
+ true/*DECL_PRETTY_FUNCTION_P (decl)*/);
else if (DECL_IMPLICIT_TYPEDEF_P (decl)
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
/* Don't copy the old closure; we'll create a new one in
do. */
if (VAR_P (decl))
DECL_TEMPLATE_INSTANTIATED (decl) = 1;
- if (VAR_P (decl)
+ if (VAR_P (decl) && !DECL_NAME (decl)
&& ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
/* Anonymous aggregates are a special case. */
finish_anon_union (decl);
else
{
int const_init = false;
+ unsigned int cnt = 0;
+ tree first = NULL_TREE, ndecl = error_mark_node;
maybe_push_decl (decl);
+
if (VAR_P (decl)
- && DECL_PRETTY_FUNCTION_P (decl))
- {
- /* For __PRETTY_FUNCTION__ we have to adjust the
- initializer. */
- const char *const name
- = cxx_printable_name (current_function_decl, 2);
- init = cp_fname_init (name, &TREE_TYPE (decl));
- }
- else
- init = tsubst_init (init, decl, args, complain, in_decl);
+ && DECL_DECOMPOSITION_P (decl)
+ && TREE_TYPE (pattern_decl) != error_mark_node)
+ ndecl = tsubst_decomp_names (decl, pattern_decl, args,
+ complain, in_decl, &first,
+ &cnt);
+
+ init = tsubst_init (init, decl, args, complain, in_decl);
if (VAR_P (decl))
const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
(pattern_decl));
- if (VAR_P (decl)
- && DECL_DECOMPOSITION_P (decl)
- && TREE_TYPE (pattern_decl) != error_mark_node)
- {
- unsigned int cnt;
- tree first;
- tree ndecl
- = tsubst_decomp_names (decl, pattern_decl, args,
- complain, in_decl, &first, &cnt);
- if (ndecl != error_mark_node)
- cp_maybe_mangle_decomp (ndecl, first, cnt);
- cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
- if (ndecl != error_mark_node)
- cp_finish_decomp (ndecl, first, cnt);
- }
- else
- cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+
+ if (ndecl != error_mark_node)
+ cp_maybe_mangle_decomp (ndecl, first, cnt);
+
+ cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
+
+ if (ndecl != error_mark_node)
+ cp_finish_decomp (ndecl, first, cnt);
}
}
}
stmt = (processing_template_decl
? begin_range_for_stmt (NULL_TREE, NULL_TREE)
: begin_for_stmt (NULL_TREE, NULL_TREE));
+ RECUR (RANGE_FOR_INIT_STMT (t));
decl = RANGE_FOR_DECL (t);
decl = tsubst (decl, args, complain, in_decl);
maybe_push_decl (decl);
RANGE_FOR_IVDEP (stmt) = RANGE_FOR_IVDEP (t);
RANGE_FOR_UNROLL (stmt) = RANGE_FOR_UNROLL (t);
finish_range_for_decl (stmt, decl, expr);
+ if (decomp_first && decl != error_mark_node)
+ cp_finish_decomp (decl, decomp_first, decomp_cnt);
}
else
{
/* Don't instantiate the THEN_CLAUSE. */;
else
{
- bool inhibit = integer_zerop (fold_non_dependent_expr (tmp));
+ tree folded = fold_non_dependent_expr (tmp, complain);
+ bool inhibit = integer_zerop (folded);
if (inhibit)
++c_inhibit_evaluation_warnings;
RECUR (THEN_CLAUSE (t));
/* Don't instantiate the ELSE_CLAUSE. */;
else if (ELSE_CLAUSE (t))
{
- bool inhibit = integer_nonzerop (fold_non_dependent_expr (tmp));
+ tree folded = fold_non_dependent_expr (tmp, complain);
+ bool inhibit = integer_nonzerop (folded);
begin_else_clause (stmt);
if (inhibit)
++c_inhibit_evaluation_warnings;
LAMBDA_EXPR_MUTABLE_P (r) = LAMBDA_EXPR_MUTABLE_P (t);
if (LAMBDA_EXPR_EXTRA_SCOPE (t) == NULL_TREE)
- LAMBDA_EXPR_EXTRA_SCOPE (r) = NULL_TREE;
+ /* A lambda in a default argument outside a class gets no
+ LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI. But
+ tsubst_default_argument calls start_lambda_scope, so we need to
+ specifically ignore it here, and use the global scope. */
+ record_null_lambda_scope (r);
else
record_lambda_scope (r);
register_parameter_specializations (oldfn, fn);
+ if (oldtmpl)
+ {
+ /* We might not partially instantiate some parts of the function, so
+ copy these flags from the original template. */
+ language_function *ol = DECL_STRUCT_FUNCTION (oldfn)->language;
+ current_function_returns_value = ol->returns_value;
+ current_function_returns_null = ol->returns_null;
+ current_function_returns_abnormally = ol->returns_abnormally;
+ current_function_infinite_loop = ol->infinite_loop;
+ }
+
tsubst_expr (DECL_SAVED_TREE (oldfn), args, complain, r,
/*constexpr*/false);
return t;
loc = input_location;
- if (EXPR_HAS_LOCATION (t))
- input_location = EXPR_LOCATION (t);
+ if (location_t eloc = cp_expr_location (t))
+ input_location = eloc;
/* N3276 decltype magic only applies to calls at the top level or on the
right side of a comma. */
op1 = TREE_OPERAND (t, 0);
if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
op1 = TREE_TYPE (op1);
+ bool std_alignof = (TREE_CODE (t) == ALIGNOF_EXPR
+ && ALIGNOF_EXPR_STD_P (t));
if (!args)
{
/* When there are no ARGS, we are trying to evaluate a
--c_inhibit_evaluation_warnings;
}
if (TYPE_P (op1))
- r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
+ r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), std_alignof,
complain & tf_error);
else
r = cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t),
}
}
+ /* Avoid passing an enclosing decl to valid_array_size_p. */
+ in_decl = NULL_TREE;
+
tree op1 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
tree op2 = RECUR (TREE_OPERAND (t, 2));
ret = build_new (&placement_vec, op1, op2, &init_vec,
bool diag = true;
if (in_lambda)
- error_at (EXPR_LOC_OR_LOC (t, input_location),
+ error_at (cp_expr_loc_or_loc (t, input_location),
msg, function);
else
- diag = permerror (EXPR_LOC_OR_LOC (t, input_location),
+ diag = permerror (cp_expr_loc_or_loc (t, input_location),
msg, function);
if (diag)
{
/* Can't say anything more. */;
else if (DECL_CLASS_SCOPE_P (fn))
{
- location_t loc = EXPR_LOC_OR_LOC (t,
+ location_t loc = cp_expr_loc_or_loc (t,
input_location);
inform (loc,
"declarations in dependent base %qT are "
gcc_assert (nargs == 1);
if (vec_safe_length (call_args) != 1)
{
- error_at (EXPR_LOC_OR_LOC (t, input_location),
+ error_at (cp_expr_loc_or_loc (t, input_location),
"wrong number of arguments to "
"%<__builtin_launder%>");
ret = error_mark_node;
}
else
- ret = finish_builtin_launder (EXPR_LOC_OR_LOC (t,
+ ret = finish_builtin_launder (cp_expr_loc_or_loc (t,
input_location),
(*call_args)[0], complain);
break;
/* Unsupported internal function with arguments. */
gcc_unreachable ();
}
- else if (TREE_CODE (function) == OFFSET_REF)
+ else if (TREE_CODE (function) == OFFSET_REF
+ || TREE_CODE (function) == DOTSTAR_EXPR
+ || TREE_CODE (function) == MEMBER_REF)
ret = build_offset_ref_call_from_tree (function, &call_args,
complain);
else if (TREE_CODE (function) == COMPONENT_REF)
case COND_EXPR:
{
tree cond = RECUR (TREE_OPERAND (t, 0));
- tree folded_cond = fold_non_dependent_expr (cond);
+ cond = mark_rvalue_use (cond);
+ tree folded_cond = fold_non_dependent_expr (cond, complain);
tree exp1, exp2;
if (TREE_CODE (folded_cond) == INTEGER_CST)
else if (outer_automatic_var_p (r))
r = process_outer_var_ref (r, complain);
- if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
+ if (!TYPE_REF_P (TREE_TYPE (t)))
/* If the original type was a reference, we'll be wrapped in
the appropriate INDIRECT_REF. */
r = convert_from_reference (r);
return true;
}
+/* Subroutine of fn_type_unification: check non-dependent parms for
+ convertibility. */
+
+static int
+check_non_deducible_conversions (tree parms, const tree *args, unsigned nargs,
+ tree fn, unification_kind_t strict, int flags,
+ struct conversion **convs, bool explain_p)
+{
+ /* Non-constructor methods need to leave a conversion for 'this', which
+ isn't included in nargs here. */
+ unsigned offset = (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn));
+
+ for (unsigned ia = 0;
+ parms && parms != void_list_node && ia < nargs; )
+ {
+ tree 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;
+
+ if (!uses_template_parms (parm))
+ {
+ tree arg = args[ia];
+ conversion **conv_p = convs ? &convs[ia+offset] : NULL;
+ int lflags = conv_flags (ia, nargs, fn, arg, flags);
+
+ if (check_non_deducible_conversion (parm, arg, strict, lflags,
+ conv_p, explain_p))
+ return 1;
+ }
+
+ ++ia;
+ }
+
+ return 0;
+}
+
/* The FN is a TEMPLATE_DECL for a function. ARGS is an array with
NARGS elements of the arguments that are being used when calling
it. TARGS is a vector into which the deduced template arguments
tree return_type,
unification_kind_t strict,
int flags,
+ struct conversion **convs,
bool explain_p,
bool decltype_p)
{
{
/* We're deducing for a call to the result of a template conversion
function. The parms we really want are in return_type. */
- if (POINTER_TYPE_P (return_type))
+ if (INDIRECT_TYPE_P (return_type))
return_type = TREE_TYPE (return_type);
parms = TYPE_ARG_TYPES (return_type);
}
ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
full_targs, parms, args, nargs, /*subr=*/0,
- strict, flags, &checks, explain_p);
+ strict, &checks, explain_p);
if (!explain_p)
pop_tinst_level ();
if (!ok)
goto fail;
}
+ /* DR 1391: All parameters have args, now check non-dependent parms for
+ convertibility. */
+ if (check_non_deducible_conversions (parms, args, nargs, fn, strict, flags,
+ convs, explain_p))
+ goto fail;
+
/* All is well so far. Now, check:
[temp.deduct]
/* Core issue #873: Do the DR606 thing (see below) for these cases,
too, but here handle it by stripping the reference from PARM
rather than by adding it to ARG. */
- if (TREE_CODE (*parm) == REFERENCE_TYPE
+ if (TYPE_REF_P (*parm)
&& TYPE_REF_IS_RVALUE (*parm)
&& TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
&& cp_type_quals (TREE_TYPE (*parm)) == TYPE_UNQUALIFIED
- && TREE_CODE (*arg) == REFERENCE_TYPE
+ && TYPE_REF_P (*arg)
&& !TYPE_REF_IS_RVALUE (*arg))
*parm = TREE_TYPE (*parm);
/* Nothing else to do in this case. */
gcc_unreachable ();
}
- if (TREE_CODE (*parm) != REFERENCE_TYPE)
+ if (!TYPE_REF_P (*parm))
{
/* [temp.deduct.call]
deduction (13.3.1.8)). If P is a forwarding reference and the argument is
an lvalue, the type "lvalue reference to A" is used in place of A for type
deduction. */
- if (TREE_CODE (*parm) == REFERENCE_TYPE
+ if (TYPE_REF_P (*parm)
&& TYPE_REF_IS_RVALUE (*parm)
&& TREE_CODE (TREE_TYPE (*parm)) == TEMPLATE_TYPE_PARM
&& !TEMPLATE_TYPE_PARM_FOR_CLASS (TREE_TYPE (*parm))
reference type, the type referred to by P is used for
type deduction. */
*parm = TYPE_MAIN_VARIANT (*parm);
- if (TREE_CODE (*parm) == REFERENCE_TYPE)
+ if (TYPE_REF_P (*parm))
{
*parm = TREE_TYPE (*parm);
result |= UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
/* DR 322. For conversion deduction, remove a reference type on parm
too (which has been swapped into ARG). */
- if (strict == DEDUCE_CONV && TREE_CODE (*arg) == REFERENCE_TYPE)
+ if (strict == DEDUCE_CONV && TYPE_REF_P (*arg))
*arg = TREE_TYPE (*arg);
return result;
}
-/* Subroutine of unify_one_argument. PARM is a function parameter of a
- template which does contain any deducible template parameters; check if
+/* Subroutine of fn_type_unification. PARM is a function parameter of a
+ template which doesn't contain any deducible template parameters; check if
ARG is a suitable match for it. STRICT, FLAGS and EXPLAIN_P are as in
unify_one_argument. */
static int
check_non_deducible_conversion (tree parm, tree arg, int strict,
- int flags, bool explain_p)
+ int flags, struct conversion **conv_p,
+ bool explain_p)
{
tree type;
if (same_type_p (parm, type))
return unify_success (explain_p);
+ tsubst_flags_t complain = (explain_p ? tf_warning_or_error : tf_none);
if (strict == DEDUCE_CONV)
{
- if (can_convert_arg (type, parm, NULL_TREE, flags,
- explain_p ? tf_warning_or_error : tf_none))
+ if (can_convert_arg (type, parm, NULL_TREE, flags, complain))
return unify_success (explain_p);
}
else if (strict != DEDUCE_EXACT)
{
- if (can_convert_arg (parm, type,
- TYPE_P (arg) ? NULL_TREE : arg,
- flags, explain_p ? tf_warning_or_error : tf_none))
+ bool ok = false;
+ tree conv_arg = TYPE_P (arg) ? NULL_TREE : arg;
+ if (conv_p)
+ /* Avoid recalculating this in add_function_candidate. */
+ ok = (*conv_p
+ = good_conversion (parm, type, conv_arg, flags, complain));
+ else
+ ok = can_convert_arg (parm, type, conv_arg, flags, complain);
+ if (ok)
return unify_success (explain_p);
}
/* T*
T&
T&& */
- if (POINTER_TYPE_P (type))
+ if (INDIRECT_TYPE_P (type))
return uses_deducible_template_parms (TREE_TYPE (type));
/* T[integer-constant ]
unsigned int xnargs,
int subr,
unification_kind_t strict,
- int flags,
vec<deferred_access_check, va_gc> **checks,
bool explain_p)
{
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++)
{
location_t save_loc = input_location;
if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm);
- if (saw_undeduced == 1)
- ++processing_template_decl;
if (saw_undeduced == 1
&& TREE_CODE (parm) == PARM_DECL
{
/* The type of this non-type parameter depends on undeduced
parameters. Don't try to use its default argument yet,
+ since we might deduce an argument for it on the next pass,
but do check whether the arguments we already have cause
substitution failure, so that that happens before we try
later default arguments (78489). */
+ ++processing_template_decl;
tree type = tsubst (TREE_TYPE (parm), full_targs, complain,
NULL_TREE);
+ --processing_template_decl;
if (type == error_mark_node)
arg = error_mark_node;
else
}
else
{
- arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
+ tree substed = NULL_TREE;
+ if (saw_undeduced == 1 && processing_template_decl == 0)
+ {
+ /* First instatiate in template context, in case we still
+ depend on undeduced template parameters. */
+ ++processing_template_decl;
+ substed = tsubst_template_arg (arg, full_targs, complain,
+ NULL_TREE);
+ --processing_template_decl;
+ if (substed != error_mark_node
+ && !uses_template_parms (substed))
+ /* We replaced all the tparms, substitute again out of
+ template context. */
+ substed = NULL_TREE;
+ }
+ if (!substed)
+ substed = tsubst_template_arg (arg, full_targs, complain,
+ NULL_TREE);
- if (!uses_template_parms (arg))
- arg = convert_template_argument (parm, arg, full_targs,
+ if (!uses_template_parms (substed))
+ arg = convert_template_argument (parm, substed, full_targs,
complain, i, NULL_TREE);
else if (saw_undeduced == 1)
arg = NULL_TREE;
arg = error_mark_node;
}
- if (saw_undeduced == 1)
- --processing_template_decl;
input_location = save_loc;
*checks = get_deferred_access_checks ();
pop_deferring_access_checks ();
types are not of the form "cv-list T" [14.8.2.5 temp.deduct.type].
It is ok when we're allowing additional CV qualifiers
at the outer level [14.8.2.1]/3,1st bullet. */
- if ((TREE_CODE (arg) == REFERENCE_TYPE
+ if ((TYPE_REF_P (arg)
|| TREE_CODE (arg) == FUNCTION_TYPE
|| TREE_CODE (arg) == METHOD_TYPE)
&& (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)))
return 0;
- if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
+ if ((!INDIRECT_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
&& (parm_quals & TYPE_QUAL_RESTRICT))
return 0;
}
return unify_success (explain_p);
}
- FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
- {
- int elt_strict = strict;
+ if (strict != DEDUCE_EXACT
+ && TYPE_P (elttype)
+ && !uses_deducible_template_parms (elttype))
+ /* If ELTTYPE has no deducible template parms, skip deduction from
+ the list elements. */;
+ else
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+ {
+ int elt_strict = strict;
- if (elt == error_mark_node)
- return unify_invalid (explain_p);
+ if (elt == error_mark_node)
+ return unify_invalid (explain_p);
- 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
- (DEDUCE_CALL, &elttype, &type, elt);
- elt = type;
- }
+ 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
+ (DEDUCE_CALL, &elttype, &type, elt);
+ elt = type;
+ }
RECUR_AND_CHECK_FAILURE (tparms, targs, elttype, elt, elt_strict,
explain_p);
}
case REFERENCE_TYPE:
- if (TREE_CODE (arg) != REFERENCE_TYPE)
+ if (!TYPE_REF_P (arg))
return unify_type_mismatch (explain_p, parm, arg);
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
if (type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
args, nargs, 1, DEDUCE_EXACT,
- LOOKUP_NORMAL, NULL, explain_p))
+ NULL, explain_p))
return 1;
if (flag_noexcept_type)
corresponding parameter is type-dependent. Make any necessary
adjustments based on whether arg is a reference. */
if (CONSTANT_CLASS_P (arg))
- parm = fold_non_dependent_expr (parm);
+ parm = fold_non_dependent_expr (parm, complain);
else if (REFERENCE_REF_P (arg))
{
tree sub = TREE_OPERAND (arg, 0);
linkonce sections. */
else if (TREE_PUBLIC (result))
maybe_make_one_only (result);
+ if (TREE_CODE (result) == FUNCTION_DECL
+ && DECL_TEMPLATE_INSTANTIATED (result))
+ /* If the function has already been instantiated, clear DECL_EXTERNAL,
+ since start_preparsed_function wouldn't have if we had an earlier
+ extern explicit instantiation. */
+ DECL_EXTERNAL (result) = 0;
}
/* If EXTERN_P, then this function will not be emitted -- unless
&& !uses_deducible_template_parms (arg2))
goto next;
- if (TREE_CODE (arg1) == REFERENCE_TYPE)
+ if (TYPE_REF_P (arg1))
{
ref1 = TYPE_REF_IS_RVALUE (arg1) + 1;
arg1 = TREE_TYPE (arg1);
quals1 = cp_type_quals (arg1);
}
- if (TREE_CODE (arg2) == REFERENCE_TYPE)
+ if (TYPE_REF_P (arg2))
{
ref2 = TYPE_REF_IS_RVALUE (arg2) + 1;
arg2 = TREE_TYPE (arg2);
args, ix,
(check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE),
- DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false,
+ DEDUCE_EXACT, LOOKUP_NORMAL, NULL,
+ /*explain_p=*/false,
/*decltype*/false)
== error_mark_node)
return NULL_TREE;
error ("explicit instantiation of non-template %q#D", decl);
return;
}
+ else if (DECL_DECLARED_CONCEPT_P (decl))
+ {
+ if (VAR_P (decl))
+ error ("explicit instantiation of variable concept %q#D", decl);
+ else
+ error ("explicit instantiation of function concept %q#D", decl);
+ return;
+ }
bool var_templ = (DECL_TEMPLATE_INFO (decl)
&& variable_template_p (DECL_TI_TEMPLATE (decl)));
else if (!(added = !fns->add (fn)))
{
/* If hash_set::add returns true, the element was already there. */
- location_t loc = EXPR_LOC_OR_LOC (DEFERRED_NOEXCEPT_PATTERN (noex),
+ location_t loc = cp_expr_loc_or_loc (DEFERRED_NOEXCEPT_PATTERN (noex),
DECL_SOURCE_LOCATION (fn));
error_at (loc,
"exception specification of %qD depends on itself",
deleted_p = DECL_DELETED_FN (code_pattern);
pattern_defined = ((DECL_SAVED_TREE (code_pattern) != NULL_TREE
&& DECL_INITIAL (code_pattern) != error_mark_node)
- || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern)
+ || DECL_DEFAULTED_FN (code_pattern)
|| deleted_p);
}
else
push_to_top_level ();
else
{
+ gcc_assert (!processing_template_decl);
push_function_context ();
cp_unevaluated_operand = 0;
c_inhibit_evaluation_warnings = 0;
return false;
else if (TYPE_PTR_P (type))
return false;
- else if (TREE_CODE (type) == REFERENCE_TYPE
+ else if (TYPE_REF_P (type)
&& !TYPE_REF_IS_RVALUE (type))
return false;
else if (TYPE_PTRMEM_P (type))
return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
|| dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
(type)));
- else if (TYPE_PTR_P (type)
- || TREE_CODE (type) == REFERENCE_TYPE)
+ else if (INDIRECT_TYPE_P (type))
return dependent_type_p (TREE_TYPE (type));
else if (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE)
with an expression that is value-dependent. */
if (DECL_DEPENDENT_INIT_P (expression)
/* FIXME cp_finish_decl doesn't fold reference initializers. */
- || TREE_CODE (TREE_TYPE (expression)) == REFERENCE_TYPE)
+ || TYPE_REF_P (TREE_TYPE (expression)))
return true;
if (DECL_HAS_VALUE_EXPR_P (expression))
{
TREE_TYPE. */
case TREE_LIST:
case TREE_VEC:
+ case NONTYPE_ARGUMENT_PACK:
return NULL_TREE;
case TEMPLATE_PARM_INDEX:
[temp.names]: In a qualified-id of a declarator-id, the keyword
template shall not appear at the top level. */
- pedwarn (EXPR_LOC_OR_LOC (fullname, input_location), OPT_Wpedantic,
+ pedwarn (cp_expr_loc_or_loc (fullname, input_location), OPT_Wpedantic,
"keyword %<template%> not allowed in declarator-id");
tmpl = decl;
}
/* Don't do this during concept expansion either and for
the same reason. */
&& !expanding_concept ())
- fold_non_dependent_expr (expr);
+ fold_non_dependent_expr (expr, tf_none);
STRIP_ANY_LOCATION_WRAPPER (expr);
if (is_overloaded_fn (inner_expr)
|| TREE_CODE (inner_expr) == OFFSET_REF)
return orig_expr;
- /* There is no need to return a proxy for a variable. */
- if (VAR_P (expr))
+ /* There is no need to return a proxy for a variable or enumerator. */
+ if (VAR_P (expr) || TREE_CODE (expr) == CONST_DECL)
return orig_expr;
/* Preserve string constants; conversions from string constants to
"char *" are allowed, even though normally a "const char *"
if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
{
gcc_rich_location richloc (input_location);
- maybe_add_include_fixit (&richloc, "<initializer_list>");
+ maybe_add_include_fixit (&richloc, "<initializer_list>", false);
error_at (&richloc,
"deducing from brace-enclosed initializer list"
" requires %<#include <initializer_list>%>");
inline hashval_t
auto_hash::hash (tree t)
{
- if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
+ if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
/* Matching constrained-type-specifiers denote the same template
parameter, so hash the constraint. */
return hash_placeholder_constraint (c);
if (TYPE_P (ctor))
{
type = ctor;
- bool copy_p = TREE_CODE (type) == REFERENCE_TYPE;
+ bool copy_p = TYPE_REF_P (type);
if (copy_p)
{
type = TREE_TYPE (type);
targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
int val = type_unification_real (tparms, targs, parms, &init, 1, 0,
- DEDUCE_CALL, LOOKUP_NORMAL,
+ DEDUCE_CALL,
NULL, /*explain_p=*/false);
if (val > 0)
{
else
error ("unable to deduce %qT from %qE", type, init);
type_unification_real (tparms, targs, parms, &init, 1, 0,
- DEDUCE_CALL, LOOKUP_NORMAL,
+ DEDUCE_CALL,
NULL, /*explain_p=*/true);
}
return error_mark_node;
/* Check any placeholder constraints against the deduced type. */
if (flag_concepts && !processing_template_decl)
- if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))
+ if (tree constr = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (auto_node)))
{
/* Use the deduced type to check the associated constraints. If we
have a partial-concept-id, rebuild the argument list so that
{
if (complain & tf_warning_or_error)
{
+ auto_diagnostic_group d;
switch (context)
{
case adc_unspecified:
them. */
if (uses_template_parms (type))
return for_each_template_parm (type, is_auto_r, /*data*/NULL,
- /*visited*/NULL, /*nondeduced*/true);
+ /*visited*/NULL, /*nondeduced*/false);
else
return NULL_TREE;
}
NULL_TREE, ECF_CONST);
DECL_DECLARED_CONSTEXPR_P (ipfn) = true;
DECL_BUILT_IN_CLASS (ipfn) = BUILT_IN_FRONTEND;
+ DECL_FUNCTION_CODE (ipfn)
+ = (enum built_in_function) (int) CP_BUILT_IN_INTEGER_PACK;
}
/* Set up the hash tables for template instantiations. */