+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
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, ...);
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);
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 *);
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;
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
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
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);
considered lvalues. */
int
-lvalue_p (const_tree ref)
+lvalue_p (tree ref)
{
return
(lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);