Commit 4af9e878 by Jason Merrill Committed by Jason Merrill

re PR c++/36334 (typedef to function type leads to problems)

        PR c++/36334
        PR c++/37646
        * tree.c (lvalue_p_1): Handle BASELINK.  A COMPONENT_REF to
        a function isn't necessarily an lvalue. Take tree, not const_tree.
        (lvalue_p, real_lvalue_p): Take tree, not const_tree.
        * typeck.c (lvalue_or_else): Likewise.
        * cp-tree.h: Adjust prototypes.

From-SVN: r143404
parent f1253e7e
2009-01-15 Jason Merrill <jason@redhat.com>
PR c++/36334
PR c++/37646
* tree.c (lvalue_p_1): Handle BASELINK. A COMPONENT_REF to
a function isn't necessarily an lvalue. Take tree, not const_tree.
(lvalue_p, real_lvalue_p): Take tree, not const_tree.
* typeck.c (lvalue_or_else): Likewise.
* cp-tree.h: Adjust prototypes.
2009-01-15 Steve Ellcey <sje@cup.hp.com>
PR c++/38357
......
......@@ -4836,7 +4836,7 @@ extern tree canonical_type_variant (tree);
extern tree copy_binfo (tree, tree, tree,
tree *, int);
extern int member_p (const_tree);
extern cp_lvalue_kind real_lvalue_p (const_tree);
extern cp_lvalue_kind real_lvalue_p (tree);
extern bool builtin_valid_in_constant_expr_p (const_tree);
extern tree build_min (enum tree_code, tree, ...);
extern tree build_min_nt (enum tree_code, ...);
......@@ -4984,9 +4984,9 @@ extern tree lookup_anon_field (tree, tree);
extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t);
extern tree convert_member_func_to_ptr (tree, tree);
extern tree convert_ptrmem (tree, tree, bool, bool);
extern int lvalue_or_else (const_tree, enum lvalue_use,
extern int lvalue_or_else (tree, enum lvalue_use,
tsubst_flags_t);
extern int lvalue_p (const_tree);
extern int lvalue_p (tree);
/* in typeck2.c */
extern void require_complete_eh_spec_types (tree, tree);
......
......@@ -44,7 +44,7 @@ static tree build_cplus_array_type_1 (tree, tree);
static int list_hash_eq (const void *, const void *);
static hashval_t list_hash_pieces (tree, tree, tree);
static hashval_t list_hash (const void *);
static cp_lvalue_kind lvalue_p_1 (const_tree, int);
static cp_lvalue_kind lvalue_p_1 (tree, int);
static tree build_target_expr (tree, tree);
static tree count_trees_r (tree *, int *, void *);
static tree verify_stmt_tree_r (tree *, int *, void *);
......@@ -59,7 +59,7 @@ static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
nonzero, rvalues of class type are considered lvalues. */
static cp_lvalue_kind
lvalue_p_1 (const_tree ref,
lvalue_p_1 (tree ref,
int treat_class_rvalues_as_lvalues)
{
cp_lvalue_kind op1_lvalue_kind = clk_none;
......@@ -110,11 +110,13 @@ lvalue_p_1 (const_tree ref,
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues);
/* Look at the member designator. */
if (!op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
|| TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
if (!op1_lvalue_kind)
;
else if (is_overloaded_fn (TREE_OPERAND (ref, 1)))
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
treat_class_rvalues_as_lvalues);
else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
{
/* Clear the ordinary bit. If this object was a class
......@@ -195,6 +197,12 @@ lvalue_p_1 (const_tree ref,
return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
? clk_none : clk_ordinary);
case BASELINK:
/* We now represent a reference to a single static member function
with a BASELINK. */
return lvalue_p_1 (BASELINK_FUNCTIONS (ref),
treat_class_rvalues_as_lvalues);
case NON_DEPENDENT_EXPR:
/* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
things like "&E" where "E" is an expression with a
......@@ -227,7 +235,7 @@ lvalue_p_1 (const_tree ref,
computes the C++ definition of lvalue. */
cp_lvalue_kind
real_lvalue_p (const_tree ref)
real_lvalue_p (tree ref)
{
return lvalue_p_1 (ref,
/*treat_class_rvalues_as_lvalues=*/0);
......@@ -237,7 +245,7 @@ real_lvalue_p (const_tree ref)
considered lvalues. */
int
lvalue_p (const_tree ref)
lvalue_p (tree ref)
{
return
(lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
......
......@@ -7339,7 +7339,7 @@ non_reference (tree t)
how the lvalue is being used and so selects the error message. */
int
lvalue_or_else (const_tree ref, enum lvalue_use use, tsubst_flags_t complain)
lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
{
int win = lvalue_p (ref);
......
2009-01-15 Jason Merrill <jason@redhat.com>
PR c++/36334
* g++.dg/conversion/memfn1.C: New test.
PR c++/37646
* g++.dg/conversion/memfn2.C: New test.
2008-01-15 Steve Ellcey <sje@cup.hp.com>
PR c++/38357
......
// PR c++/36334
struct X
{
typedef int* foobar();
static void foo(foobar&);
};
void X::foo(foobar&)
{
}
struct Y : public X
{
static foobar bar;
static void foo();
};
void Y::foo()
{
X::foo(bar);
}
int* Y::bar()
{
return 0;
}
// PR c++/37646
struct A
{
void foo();
void bar(int i)
{
void (*p)() = i ? foo : foo; // { dg-error "invalid use of member" }
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment