* pt.c (do_class_deduction): Handle list-initialization.
(do_auto_deduction): Call it sooner.
(build_deduction_guide): Use tsubst_arg_types.
(rewrite_template_parm): Don't copy_type.
From-SVN: r240765
+2016-10-04 Jason Merrill <jason@redhat.com>
+
+ * c-common.c (make_tree_vector_from_ctor): New.
+ * c-common.h: Declare it.
+
2016-10-04 Jakub Jelinek <jakub@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Don't define
return ret;
}
+/* Get a new tree vector of the values of a CONSTRUCTOR. */
+
+vec<tree, va_gc> *
+make_tree_vector_from_ctor (tree ctor)
+{
+ vec<tree,va_gc> *ret = make_tree_vector ();
+ vec_safe_reserve (ret, CONSTRUCTOR_NELTS (ctor));
+ for (unsigned i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i)
+ ret->quick_push (CONSTRUCTOR_ELT (ctor, i)->value);
+ return ret;
+}
+
/* Get a new tree vector which is a copy of an existing one. */
vec<tree, va_gc> *
extern void release_tree_vector (vec<tree, va_gc> *);
extern vec<tree, va_gc> *make_tree_vector_single (tree);
extern vec<tree, va_gc> *make_tree_vector_from_list (tree);
+extern vec<tree, va_gc> *make_tree_vector_from_ctor (tree);
extern vec<tree, va_gc> *make_tree_vector_copy (const vec<tree, va_gc> *);
/* Used for communication between c_common_type_for_mode and
-2016-09-30 Jason Merrill <jason@redhat.com>
+2016-10-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/77852
+ * pt.c (do_class_deduction): Handle list-initialization.
+ (do_auto_deduction): Call it sooner.
+ (build_deduction_guide): Use tsubst_arg_types.
+ (rewrite_template_parm): Don't copy_type.
PR c++/77775
* constexpr.c (cxx_eval_component_reference): Use name matching
for PMFs.
-2016-10-04 Jason Merrill <jason@redhat.com>
-
Implement P0091R2, Template argument deduction for class templates.
* parser.c (cp_parser_simple_type_specifier): Parse class placeholder.
Use the location of the beginning of the type-specifier.
if (TREE_CODE (olddecl) == TYPE_DECL
|| TREE_CODE (olddecl) == TEMPLATE_DECL)
{
- newtype = copy_type (TREE_TYPE (olddecl));
+ newtype = cxx_make_type (TREE_CODE (TREE_TYPE (olddecl)));
TYPE_MAIN_VARIANT (newtype) = newtype;
}
else
/* Now we have a final set of template parms to substitute into the
function signature. */
targs = template_parms_to_args (tparms);
- fparms = tsubst (fparms, tsubst_args, complain, ctor);
+ fparms = tsubst_arg_types (fparms, tsubst_args, NULL_TREE,
+ complain, ctor);
fargs = tsubst (fargs, tsubst_args, complain, ctor);
if (ci)
ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor);
vec<tree,va_gc> *args;
if (TREE_CODE (init) == TREE_LIST)
args = make_tree_vector_from_list (init);
+ else if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ args = make_tree_vector_from_ctor (init);
else
args = make_tree_vector_single (init);
from ahead of time isn't worth the trouble. */
return type;
+ if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
+ /* C++17 class template argument deduction. */
+ return do_class_deduction (tmpl, init, complain);
+
/* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
with either a new invented type template parameter U or, if the
initializer is a braced-init-list (8.5.4), with
return error_mark_node;
}
}
- else if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
- /* C++17 class template argument deduction. */
- return do_class_deduction (tmpl, init, complain);
else
{
tree parms = build_tree_list (NULL_TREE, type);
--- /dev/null
+// { dg-options -std=c++1z }
+
+#include <vector>
+
+template<class T> struct container {
+ container(T t) {}
+ template<class Iter> container(Iter beg, Iter end);
+};
+template<class Iter>
+container(Iter b, Iter e) // { dg-message "iterator_traits.int" }
+ -> container<typename std::iterator_traits<Iter>::value_type>;
+std::vector<double> v = { /* ... */ };
+container c(7); // OK, deduces int for T
+auto d = container(v.begin(), v.end()); // OK, deduces double for T
+container e{5, 6}; // { dg-error "" } int is not an iterator
--- /dev/null
+// { dg-options -std=c++1z }
+
+#include <utility>
+
+int main()
+{
+ std::pair x{42, 666};
+}
+
--- /dev/null
+// { dg-options -std=c++1z }
+
+template <class... T>
+struct A
+{
+ template <class...Us> A(Us&&...);
+};
+
+A a(1,2);