re PR c++/48594 (Rejects valid with pointer-to-member in template)

PR c++/48594
	* decl2.c (build_offset_ref_call_from_tree): Fix calling a functor
	or pointer to (non-member) function.

From-SVN: r172804
This commit is contained in:
Jason Merrill 2011-04-20 22:57:28 -04:00 committed by Jason Merrill
parent 3766c7e508
commit 21e89bed26
6 changed files with 47 additions and 6 deletions

View File

@ -1,3 +1,9 @@
2011-04-20 Jason Merrill <jason@redhat.com>
PR c++/48594
* decl2.c (build_offset_ref_call_from_tree): Fix calling a functor
or pointer to (non-member) function.
2011-04-16 Release Manager
* GCC 4.4.6 released.

View File

@ -145,7 +145,6 @@ static tree convert_like_real (conversion *, tree, tree, int, int, bool,
bool, tsubst_flags_t);
static void op_error (enum tree_code, enum tree_code, tree, tree,
tree, const char *);
static tree build_object_call (tree, tree, tsubst_flags_t);
static tree resolve_args (tree);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
static void print_z_candidate (const char *, struct z_candidate *);
@ -3194,7 +3193,7 @@ build_operator_new_call (tree fnname, tree args,
return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
}
static tree
tree
build_object_call (tree obj, tree args, tsubst_flags_t complain)
{
struct z_candidate *candidates = 0, *cand;

View File

@ -4193,6 +4193,7 @@ extern tree build_new_function_call (tree, tree, bool,
tsubst_flags_t);
extern tree build_operator_new_call (tree, tree, tree *, tree *,
tree *);
extern tree build_object_call (tree, tree, tsubst_flags_t);
extern tree build_new_method_call (tree, tree, tree, tree, int,
tree *, tsubst_flags_t);
extern tree build_special_member_call (tree, tree, tree, tree, int,

View File

@ -3725,9 +3725,12 @@ build_offset_ref_call_from_tree (tree fn, tree args)
because we depend on the form of FN. */
args = build_non_dependent_args (args);
object = build_non_dependent_expr (object);
if (TREE_CODE (fn) == DOTSTAR_EXPR)
object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
args = tree_cons (NULL_TREE, object, args);
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
{
if (TREE_CODE (fn) == DOTSTAR_EXPR)
object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
args = tree_cons (NULL_TREE, object, args);
}
/* Now that the arguments are done, transform FN. */
fn = build_non_dependent_expr (fn);
}
@ -3747,7 +3750,10 @@ build_offset_ref_call_from_tree (tree fn, tree args)
args = tree_cons (NULL_TREE, object_addr, args);
}
expr = cp_build_function_call (fn, args, tf_warning_or_error);
if (CLASS_TYPE_P (TREE_TYPE (fn)))
expr = build_object_call (fn, args, tf_warning_or_error);
else
expr = cp_build_function_call (fn, args, tf_warning_or_error);
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep_call_list (expr, orig_fn, orig_args);
return expr;

View File

@ -1,3 +1,7 @@
2011-04-20 Jason Merrill <jason@redhat.com>
* g++.dg/template/operator11.C: New.
2011-04-16 Jakub Jelinek <jakub@redhat.com>
Backported from 4.6 branch

View File

@ -0,0 +1,25 @@
// PR c++/48594
// Test for uses of (X->*Y)() that don't actually involve a
// pointer to member function.
struct A { } a;
struct B { } b;
struct C * cp;
struct Func { void operator()(); };
Func operator->* (A, int);
typedef void (*pfn)();
pfn operator->* (B, int);
pfn C::*cpfn;
Func C::*cfunc;
template <class T>
void f()
{
(a->*1)();
(b->*1)();
(cp->*cpfn)();
(cp->*cfunc)();
}