commit d84445fd99912ad25589975f3d5f2fadb08ff9f6
Author: Jason Merrill <jason@redhat.com>
Date: Thu Mar 28 11:21:47 2013 -0400
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.
@@ -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,
@@ -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;
@@ -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);
@@ -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;
@@ -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;
new file mode 100644
@@ -0,0 +1,7 @@
+// PR c++/52748
+// We don't want to instantiate A<T> here.
+// { dg-require-effective-target c++11 }
+
+template <class T> struct A: T { };
+template <class T> A<T> f(T);
+decltype(f(42)) *p;