From 2b24855e1efd2caad72bf7b6132a3be0981cdfe3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 28 Mar 2013 14:21:06 -0400 Subject: [PATCH] re PR c++/17232 ([DR 1640] classes and class template specializations treated differently w.r.t. core issue #337) PR c++/17232 PR c++/52748 * typeck2.c (abstract_virtuals_error_sfinae): Don't complete the type if tf_decltype is set. * pt.c (fn_type_unification): Add decltype_p parm. (get_bindings): Adjust. * cp-tree.h: Adjust. * class.c (resolve_address_of_overloaded_function): Adjust. * call.c (add_template_candidate_real, print_z_candidate): Adjust. From-SVN: r197214 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/call.c | 5 +++-- gcc/cp/class.c | 2 +- gcc/cp/cp-tree.h | 2 +- gcc/cp/pt.c | 9 +++++++-- gcc/cp/typeck2.c | 6 +++--- gcc/testsuite/g++.dg/cpp0x/decltype-call2.C | 7 +++++++ 7 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype-call2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0709b66966f..5375f01dda5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 2013-03-28 Jason Merrill + PR c++/17232 + PR c++/52748 + * typeck2.c (abstract_virtuals_error_sfinae): Don't complete + the type if tf_decltype is set. + * pt.c (fn_type_unification): Add decltype_p parm. + (get_bindings): Adjust. + * cp-tree.h: Adjust. + * class.c (resolve_address_of_overloaded_function): Adjust. + * call.c (add_template_candidate_real, print_z_candidate): Adjust. + PR c++/56679 * parser.c (cp_parser_sizeof_pack): Split out from... (cp_parser_sizeof_operand): ...here. Require (id). diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d39124ddcab..4542500315f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2905,7 +2905,8 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, fn = fn_type_unification (tmpl, explicit_targs, targs, args_without_in_chrg, nargs_without_in_chrg, - return_type, strict, flags, false); + return_type, strict, flags, false, + complain & tf_decltype); if (fn == error_mark_node) { @@ -3221,7 +3222,7 @@ print_z_candidate (location_t loc, const char *msgstr, r->u.template_unification.return_type, r->u.template_unification.strict, r->u.template_unification.flags, - true); + true, false); break; case rr_invalid_copy: inform (cloc, diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b48b353d596..956d5aa9e27 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -7253,7 +7253,7 @@ resolve_address_of_overloaded_function (tree target_type, instantiation = fn_type_unification (fn, explicit_targs, targs, args, nargs, target_ret_type, DEDUCE_EXACT, LOOKUP_NORMAL, - false); + false, false); if (instantiation == error_mark_node) /* Instantiation failed. */ continue; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e8e40ec4e05..e1677160ff9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5419,7 +5419,7 @@ extern tree instantiate_template (tree, tree, tsubst_flags_t); extern tree fn_type_unification (tree, tree, tree, const tree *, unsigned int, tree, unification_kind_t, int, - bool); + bool, bool); extern void mark_decl_instantiated (tree, int); extern int more_specialized_fn (tree, tree, int); extern void do_decl_instantiation (tree, tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 59ecdcb82b1..27e3ff87204 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14935,7 +14935,8 @@ fn_type_unification (tree fn, tree return_type, unification_kind_t strict, int flags, - bool explain_p) + bool explain_p, + bool decltype_p) { tree parms; tree fntype; @@ -14949,6 +14950,9 @@ fn_type_unification (tree fn, tree tinst; tree r = error_mark_node; + if (decltype_p) + complain |= tf_decltype; + /* In C++0x, it's possible to have a function template whose type depends on itself recursively. This is most obvious with decltype, but can also occur with enumeration scope (c++/48969). So we need to catch infinite @@ -17626,7 +17630,8 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) 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, /*explain_p=*/false, + /*decltype*/false) == error_mark_node) return NULL_TREE; diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 52bc4ec3b7f..cf42958193a 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -265,15 +265,15 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use, return 0; type = TYPE_MAIN_VARIANT (type); - /* In SFINAE context, force instantiation. */ - if (!(complain & tf_error)) + /* In SFINAE, non-N3276 context, force instantiation. */ + if (!(complain & (tf_error|tf_decltype))) complete_type (type); /* If the type is incomplete, we register it within a hash table, so that we can check again once it is completed. This makes sense only for objects for which we have a declaration or at least a name. */ - if (!COMPLETE_TYPE_P (type)) + if (!COMPLETE_TYPE_P (type) && (complain & tf_error)) { void **slot; struct pending_abstract_type *pat; diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call2.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call2.C new file mode 100644 index 00000000000..ad2322090e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-call2.C @@ -0,0 +1,7 @@ +// PR c++/52748 +// We don't want to instantiate A here. +// { dg-require-effective-target c++11 } + +template struct A: T { }; +template A f(T); +decltype(f(42)) *p;