mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
f1253e7e69
commit
4af9e878d9
|
@ -1,3 +1,13 @@
|
|||
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
|
||||
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. */
|
||||
|| TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
|
||||
;
|
||||
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);
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// 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;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// PR c++/37646
|
||||
|
||||
struct A
|
||||
{
|
||||
void foo();
|
||||
|
||||
void bar(int i)
|
||||
{
|
||||
void (*p)() = i ? foo : foo; // { dg-error "invalid use of member" }
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue