c.opt: Add -fno-deduce-init-list.
* c.opt: Add -fno-deduce-init-list. * pt.c (get_pattern_parm): New. (listify): Split out from... (listify_autos): ...here. (unify): Deduce std::initializer_list for T. * call.c (build_over_call): Warn about it. From-SVN: r151867
This commit is contained in:
parent
172d0c8683
commit
5f5babf18b
9 changed files with 161 additions and 16 deletions
|
@ -1,3 +1,7 @@
|
|||
2009-09-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* c.opt: Add -fno-deduce-init-list.
|
||||
|
||||
2009-09-18 Neil Vachharajani <nvachhar@google.com>
|
||||
|
||||
* value-prof.c (interesting_stringop_to_profile_p): Added output
|
||||
|
|
|
@ -558,6 +558,10 @@ fconstant-string-class=
|
|||
ObjC ObjC++ Joined
|
||||
-fconst-string-class=<name> Use class <name> for constant strings
|
||||
|
||||
fdeduce-init-list
|
||||
C++ ObjC++ Var(flag_deduce_init_list) Init(1)
|
||||
-fno-deduce-init-list disable deduction of std::initializer_list for a template type parameter from a brace-enclosed initializer-list
|
||||
|
||||
fdefault-inline
|
||||
C++ ObjC++
|
||||
Inline member functions by default
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2009-09-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* pt.c (get_pattern_parm): New.
|
||||
(listify): Split out from...
|
||||
(listify_autos): ...here.
|
||||
(unify): Deduce std::initializer_list for T.
|
||||
* call.c (build_over_call): Warn about it.
|
||||
|
||||
2009-09-17 Andrew Pinski <pinskia@gcc.gnu.org>
|
||||
|
||||
PR c++/39365
|
||||
|
@ -67,7 +75,7 @@
|
|||
* decl.c (build_init_list_var_init): Check return value of
|
||||
perform_implicit_conversion.
|
||||
|
||||
2009-09-03 Jason Merrill <jason@redhat.com>
|
||||
2009-09-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* class.c (currently_open_class): Make sure we're dealing with the
|
||||
main variant.
|
||||
|
|
|
@ -5568,6 +5568,28 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
|||
&& !TREE_ADDRESSABLE (type))
|
||||
conv = conv->u.next;
|
||||
|
||||
/* Warn about initializer_list deduction that isn't currently in the
|
||||
working draft. */
|
||||
if (cxx_dialect > cxx98
|
||||
&& flag_deduce_init_list
|
||||
&& cand->template_decl
|
||||
&& is_std_init_list (non_reference (type)))
|
||||
{
|
||||
tree tmpl = TI_TEMPLATE (cand->template_decl);
|
||||
tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
|
||||
tree patparm = get_pattern_parm (realparm, tmpl);
|
||||
|
||||
if (!is_std_init_list (non_reference (TREE_TYPE (patparm))))
|
||||
{
|
||||
pedwarn (input_location, 0, "deducing %qT as %qT",
|
||||
non_reference (TREE_TYPE (patparm)),
|
||||
non_reference (type));
|
||||
pedwarn (input_location, 0, " in call to %q+D", cand->fn);
|
||||
pedwarn (input_location, 0,
|
||||
" (you can disable this with -fno-deduce-init-list)");
|
||||
}
|
||||
}
|
||||
|
||||
val = convert_like_with_context
|
||||
(conv, VEC_index (tree, args, arg_index), fn, i - is_method,
|
||||
complain);
|
||||
|
|
|
@ -4646,6 +4646,7 @@ extern tree get_types_needing_access_check (tree);
|
|||
extern int template_class_depth (tree);
|
||||
extern int is_specialization_of (tree, tree);
|
||||
extern bool is_specialization_of_friend (tree, tree);
|
||||
extern tree get_pattern_parm (tree, tree);
|
||||
extern int comp_template_args (tree, tree);
|
||||
extern tree maybe_process_partial_specialization (tree);
|
||||
extern tree most_specialized_instantiation (tree);
|
||||
|
|
85
gcc/cp/pt.c
85
gcc/cp/pt.c
|
@ -192,6 +192,8 @@ static void perform_typedefs_access_check (tree tmpl, tree targs);
|
|||
static void append_type_to_template_for_access_check_1 (tree, tree, tree);
|
||||
static hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
|
||||
static bool primary_template_instantiation_p (const_tree);
|
||||
static tree listify (tree);
|
||||
static tree listify_autos (tree, tree);
|
||||
|
||||
/* Make the current scope suitable for access checking when we are
|
||||
processing T. T can be FUNCTION_DECL for instantiated function
|
||||
|
@ -8033,6 +8035,36 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Given PARM_DECL PARM, find the corresponding PARM_DECL in the template
|
||||
TMPL. We do this using DECL_PARM_INDEX, which should work even with
|
||||
parameter packs; all parms generated from a function parameter pack will
|
||||
have the same DECL_PARM_INDEX. */
|
||||
|
||||
tree
|
||||
get_pattern_parm (tree parm, tree tmpl)
|
||||
{
|
||||
tree pattern = DECL_TEMPLATE_RESULT (tmpl);
|
||||
tree patparm;
|
||||
|
||||
if (DECL_ARTIFICIAL (parm))
|
||||
{
|
||||
for (patparm = DECL_ARGUMENTS (pattern);
|
||||
patparm; patparm = TREE_CHAIN (patparm))
|
||||
if (DECL_ARTIFICIAL (patparm)
|
||||
&& DECL_NAME (parm) == DECL_NAME (patparm))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
patparm = FUNCTION_FIRST_USER_PARM (DECL_TEMPLATE_RESULT (tmpl));
|
||||
patparm = chain_index (DECL_PARM_INDEX (parm)-1, patparm);
|
||||
gcc_assert (DECL_PARM_INDEX (patparm)
|
||||
== DECL_PARM_INDEX (parm));
|
||||
}
|
||||
|
||||
return patparm;
|
||||
}
|
||||
|
||||
/* Substitute ARGS into the vector or list of template arguments T. */
|
||||
|
||||
static tree
|
||||
|
@ -13727,6 +13759,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
|
|||
{
|
||||
tree elt, elttype;
|
||||
unsigned i;
|
||||
tree orig_parm = parm;
|
||||
|
||||
/* Replace T with std::initializer_list<T> for deduction. */
|
||||
if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
|
||||
&& flag_deduce_init_list)
|
||||
parm = listify (parm);
|
||||
|
||||
if (!is_std_init_list (parm))
|
||||
/* We can only deduce from an initializer list argument if the
|
||||
|
@ -13752,6 +13790,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
|
|||
if (unify (tparms, targs, elttype, elt, elt_strict))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the std::initializer_list<T> deduction worked, replace the
|
||||
deduced A with std::initializer_list<A>. */
|
||||
if (orig_parm != parm)
|
||||
{
|
||||
idx = TEMPLATE_TYPE_IDX (orig_parm);
|
||||
targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
|
||||
targ = listify (targ);
|
||||
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = targ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -17446,26 +17494,33 @@ make_auto (void)
|
|||
return au;
|
||||
}
|
||||
|
||||
/* Given type ARG, return std::initializer_list<ARG>. */
|
||||
|
||||
static tree
|
||||
listify (tree arg)
|
||||
{
|
||||
tree std_init_list = namespace_binding
|
||||
(get_identifier ("initializer_list"), std_node);
|
||||
tree argvec;
|
||||
if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
|
||||
{
|
||||
error ("deducing from brace-enclosed initializer list requires "
|
||||
"#include <initializer_list>");
|
||||
return error_mark_node;
|
||||
}
|
||||
argvec = make_tree_vec (1);
|
||||
TREE_VEC_ELT (argvec, 0) = arg;
|
||||
return lookup_template_class (std_init_list, argvec, NULL_TREE,
|
||||
NULL_TREE, 0, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Replace auto in TYPE with std::initializer_list<auto>. */
|
||||
|
||||
static tree
|
||||
listify_autos (tree type, tree auto_node)
|
||||
{
|
||||
tree std_init_list = namespace_binding
|
||||
(get_identifier ("initializer_list"), std_node);
|
||||
tree argvec;
|
||||
tree init_auto;
|
||||
if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
|
||||
{
|
||||
error ("deducing auto from brace-enclosed initializer list requires "
|
||||
"#include <initializer_list>");
|
||||
return error_mark_node;
|
||||
}
|
||||
argvec = make_tree_vec (1);
|
||||
TREE_VEC_ELT (argvec, 0) = auto_node;
|
||||
init_auto = lookup_template_class (std_init_list, argvec, NULL_TREE,
|
||||
NULL_TREE, 0, tf_warning_or_error);
|
||||
|
||||
tree init_auto = listify (auto_node);
|
||||
tree argvec = make_tree_vec (1);
|
||||
TREE_VEC_ELT (argvec, 0) = init_auto;
|
||||
if (processing_template_decl)
|
||||
argvec = add_to_template_args (current_template_args (), argvec);
|
||||
|
|
|
@ -1785,6 +1785,27 @@ two definitions were merged.
|
|||
This option is no longer useful on most targets, now that support has
|
||||
been added for putting variables into BSS without making them common.
|
||||
|
||||
@item -fno-deduce-init-list
|
||||
@opindex fno-deduce-init-list
|
||||
Disable deduction of a template type parameter as
|
||||
std::initializer_list from a brace-enclosed initializer list, i.e.
|
||||
|
||||
@smallexample
|
||||
template <class T> auto forward(T t) -> decltype (realfn (t))
|
||||
@{
|
||||
return realfn (t);
|
||||
@}
|
||||
|
||||
void f()
|
||||
@{
|
||||
forward(@{1,2@}); // call forward<std::initializer_list<int>>
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
This option is present because this deduction is an extension to the
|
||||
current specification in the C++0x working draft, and there was
|
||||
some concern about potential overload resolution problems.
|
||||
|
||||
@item -ffriend-injection
|
||||
@opindex ffriend-injection
|
||||
Inject friend functions into the enclosing namespace, so that they are
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2009-09-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/initlist-deduce.C: New.
|
||||
|
||||
2009-09-18 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
* gcc.dg/dfp/dfp.exp: Also run tests in c-c++-common/dfp.
|
||||
|
|
26
gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C
Normal file
26
gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Test for deduction of T as std::initializer_list. This isn't currently
|
||||
// supported by the working draft, but is necessary for perfect forwarding
|
||||
// of initializer-lists to things that can take a std::initializer_list.
|
||||
|
||||
// { dg-options -std=c++0x }
|
||||
// { dg-do run }
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
struct A
|
||||
{
|
||||
A(std::initializer_list<int>) { }
|
||||
};
|
||||
|
||||
void f (A a) { }
|
||||
|
||||
template <class T>
|
||||
auto g (T&& t) -> decltype (f(t)) // { dg-warning "call" }
|
||||
{
|
||||
return f(t);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
g({1}); // { dg-warning "deduc" }
|
||||
}
|
Loading…
Add table
Reference in a new issue