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
This commit is contained in:
Jason Merrill 2013-03-28 14:21:06 -04:00 committed by Jason Merrill
parent f5e44182eb
commit 2b24855e1e
7 changed files with 32 additions and 9 deletions

View File

@ -1,5 +1,15 @@
2013-03-28 Jason Merrill <jason@redhat.com>
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).

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;