diff options
author | Jason Merrill <jason@redhat.com> | 2009-01-15 13:14:32 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-01-15 13:14:32 -0500 |
commit | 4af9e878d91689da977b1e31fbb3248b5ad677b9 (patch) | |
tree | 813a681559b4e930c5f836452d80f24baae41519 /gcc | |
parent | f1253e7e69d20a489bb734ea66d0702e9eaa4b76 (diff) | |
download | gcc-4af9e878d91689da977b1e31fbb3248b5ad677b9.zip gcc-4af9e878d91689da977b1e31fbb3248b5ad677b9.tar.gz gcc-4af9e878d91689da977b1e31fbb3248b5ad677b9.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/tree.c | 24 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/memfn1.C | 26 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/memfn2.C | 11 |
7 files changed, 75 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index af7f0c0..4b23d31 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 718167f..186ec9a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 8ac2720..3347bfb 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 3c7787c..415b8a2 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f7c4833..198ba97 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/conversion/memfn1.C b/gcc/testsuite/g++.dg/conversion/memfn1.C new file mode 100644 index 0000000..da2fb0f --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/memfn1.C @@ -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; +} diff --git a/gcc/testsuite/g++.dg/conversion/memfn2.C b/gcc/testsuite/g++.dg/conversion/memfn2.C new file mode 100644 index 0000000..c3d7613 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/memfn2.C @@ -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" } + } +}; |