PR c++/77852 - class deduction from list-init

* 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
This commit is contained in:
Jason Merrill 2016-10-04 21:24:38 -04:00 committed by Jason Merrill
parent 1c84b79889
commit f1644724b5
8 changed files with 67 additions and 8 deletions

View File

@ -1,3 +1,8 @@
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

View File

@ -12612,6 +12612,18 @@ make_tree_vector_from_list (tree list)
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> *

View File

@ -1111,6 +1111,7 @@ extern vec<tree, va_gc> *make_tree_vector (void);
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

View File

@ -1,11 +1,15 @@
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.

View File

@ -24178,7 +24178,7 @@ rewrite_template_parm (tree olddecl, unsigned index, unsigned level,
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
@ -24340,7 +24340,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain)
/* 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);
@ -24376,6 +24377,8 @@ do_class_deduction (tree tmpl, tree init, tsubst_flags_t complain)
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);
@ -24465,6 +24468,10 @@ do_auto_deduction (tree type, tree init, tree auto_node,
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
@ -24510,9 +24517,6 @@ do_auto_deduction (tree type, tree init, tree auto_node,
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);

View File

@ -0,0 +1,15 @@
// { 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

View File

@ -0,0 +1,9 @@
// { dg-options -std=c++1z }
#include <utility>
int main()
{
std::pair x{42, 666};
}

View File

@ -0,0 +1,9 @@
// { dg-options -std=c++1z }
template <class... T>
struct A
{
template <class...Us> A(Us&&...);
};
A a(1,2);