summaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r--gcc/cp/pt.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ee4e6b11334..bf1f75de1e7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6879,7 +6879,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
}
else if (NULLPTR_TYPE_P (type))
{
- if (expr != nullptr_node)
+ if (!NULLPTR_TYPE_P (TREE_TYPE (expr)))
{
if (complain & tf_error)
error ("%qE is not a valid template argument for type %qT "
@@ -12875,7 +12875,15 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
&& VAR_HAD_UNKNOWN_BOUND (t)
&& type != error_mark_node)
type = strip_array_domain (type);
+ tree auto_node = type_uses_auto (type);
+ int len = TREE_VEC_LENGTH (args);
+ if (auto_node)
+ /* Mask off any template args past the variable's context so we
+ don't replace the auto with an unrelated argument. */
+ TREE_VEC_LENGTH (args) = TEMPLATE_TYPE_LEVEL (auto_node) - 1;
type = tsubst (type, args, complain, in_decl);
+ if (auto_node)
+ TREE_VEC_LENGTH (args) = len;
}
if (VAR_P (r))
{
@@ -14656,6 +14664,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
= TREE_CONSTANT (r) = true;
DECL_INITIAL (r) = init;
+ if (tree auto_node = type_uses_auto (TREE_TYPE (r)))
+ TREE_TYPE (r)
+ = do_auto_deduction (TREE_TYPE (r), init, auto_node,
+ complain, adc_variable_type);
}
gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
|| decl_constant_var_p (r)
@@ -22493,16 +22505,17 @@ always_instantiate_p (tree decl)
}
/* If FN has a noexcept-specifier that hasn't been instantiated yet,
- instantiate it now, modifying TREE_TYPE (fn). */
+ instantiate it now, modifying TREE_TYPE (fn). Returns false on
+ error, true otherwise. */
-void
-maybe_instantiate_noexcept (tree fn)
+bool
+maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
{
tree fntype, spec, noex, clone;
/* Don't instantiate a noexcept-specification from template context. */
if (processing_template_decl)
- return;
+ return true;
if (DECL_CLONED_FUNCTION_P (fn))
fn = DECL_CLONED_FUNCTION (fn);
@@ -22510,7 +22523,7 @@ maybe_instantiate_noexcept (tree fn)
spec = TYPE_RAISES_EXCEPTIONS (fntype);
if (!spec || !TREE_PURPOSE (spec))
- return;
+ return true;
noex = TREE_PURPOSE (spec);
@@ -22519,7 +22532,7 @@ maybe_instantiate_noexcept (tree fn)
static hash_set<tree>* fns = new hash_set<tree>;
bool added = false;
if (DEFERRED_NOEXCEPT_PATTERN (noex) == NULL_TREE)
- spec = get_defaulted_eh_spec (fn);
+ spec = get_defaulted_eh_spec (fn, complain);
else if (!(added = !fns->add (fn)))
{
/* If hash_set::add returns true, the element was already there. */
@@ -22553,6 +22566,9 @@ maybe_instantiate_noexcept (tree fn)
if (added)
fns->remove (fn);
+ if (spec == error_mark_node)
+ return false;
+
TREE_TYPE (fn) = build_exception_variant (fntype, spec);
}
@@ -22563,6 +22579,8 @@ maybe_instantiate_noexcept (tree fn)
else
TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
}
+
+ return true;
}
/* Produce the definition of D, a _DECL generated from a template. If
@@ -25452,11 +25470,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
if (gtype)
{
tree guide = build_deduction_guide (gtype, outer_args, complain);
- if ((flags & LOOKUP_ONLYCONVERTING)
- && DECL_NONCONVERTING_P (STRIP_TEMPLATE (guide)))
- elided = true;
- else
- cands = lookup_add (guide, cands);
+ cands = lookup_add (guide, cands);
}
}
@@ -25467,6 +25481,12 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags,
"user-declared constructors", type);
return error_mark_node;
}
+ else if (!cands && call == error_mark_node)
+ {
+ error ("cannot deduce template arguments of %qT, as it has no viable "
+ "deduction guides", type);
+ return error_mark_node;
+ }
if (call == error_mark_node)
{