summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-25 04:57:16 +0000
committershebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-25 04:57:16 +0000
commit3e5d979595c5dd72ad98fdffb3deae78547b939b (patch)
tree7bb6f3b26e6d15d4a769a03c44e1525a5daa0f24
parentfbb76a77a493ef347474beaab73bc49ec92bcff3 (diff)
downloadgcc-3e5d979595c5dd72ad98fdffb3deae78547b939b.tar.gz
2002-08-24 Matt Austern <austern@apple.com>
* tree.c (lvalue_p_1): Add argument for whether casts of lvalues are allowable. (real_lvalue_p): Update caller. (lvalue_p): Ditto. (non_cast_lvalue_or_else): New. * tree.h: Declare it. * typeck.c (build_unary_op): Use non_cast_lvalue_or_else. 2002-08-24 Matt Austern <austern@apple.com> * g++.dg/ext/lvaddr.C: New test. * g++.dg/ext/lvcast.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56560 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/tree.c63
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/lvaddr.C10
-rw-r--r--gcc/testsuite/g++.dg/ext/lvcast.C11
7 files changed, 85 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cb95b6d33b7..def395ea126 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2002-08-24 Matt Austern <austern@apple.com>
+
+ * tree.c (lvalue_p_1): Add argument for whether casts of lvalues
+ are allowable.
+ (real_lvalue_p): Update caller.
+ (lvalue_p): Ditto.
+ (non_cast_lvalue_or_else): New.
+ * tree.h: Declare it.
+ * typeck.c (build_unary_op): Use non_cast_lvalue_or_else.
+
2002-08-22 Mark Mitchell <mark@codesourcery.com>
* typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 44a52fc8e78..ef4f171829b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4184,6 +4184,7 @@ extern tree canonical_type_variant PARAMS ((tree));
extern void unshare_base_binfos PARAMS ((tree));
extern int member_p PARAMS ((tree));
extern cp_lvalue_kind real_lvalue_p PARAMS ((tree));
+extern int non_cast_lvalue_or_else PARAMS ((tree, const char *));
extern tree build_min PARAMS ((enum tree_code, tree,
...));
extern tree build_min_nt PARAMS ((enum tree_code, ...));
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 36305660372..6e092850762 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -39,7 +39,7 @@ static tree build_cplus_array_type_1 PARAMS ((tree, tree));
static int list_hash_eq PARAMS ((const void *, const void *));
static hashval_t list_hash_pieces PARAMS ((tree, tree, tree));
static hashval_t list_hash PARAMS ((const void *));
-static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int));
+static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int, int));
static tree no_linkage_helper PARAMS ((tree *, int *, void *));
static tree build_srcloc PARAMS ((const char *, int));
static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
@@ -59,9 +59,10 @@ static tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, boo
non-zero, rvalues of class type are considered lvalues. */
static cp_lvalue_kind
-lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
+lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
tree ref;
int treat_class_rvalues_as_lvalues;
+ int allow_cast_as_lvalue;
{
cp_lvalue_kind op1_lvalue_kind = clk_none;
cp_lvalue_kind op2_lvalue_kind = clk_none;
@@ -84,16 +85,28 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
case WITH_CLEANUP_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
- /* This shouldn't be here, but there are lots of places in the compiler
- that are sloppy about tacking on NOP_EXPRs to the same type when
- no actual conversion is happening. */
- case NOP_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
+
+ case NOP_EXPR:
+ /* If expression doesn't change the type, we consider it as an
+ lvalue even when cast_as_lvalue extension isn't selected.
+ That's because parts of the compiler are alleged to be sloppy
+ about sticking in NOP_EXPR node for no good reason. */
+ if (allow_cast_as_lvalue ||
+ same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)),
+ TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0)))))
+ return lvalue_p_1 (TREE_OPERAND (ref, 0),
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
+ else
+ return clk_none;
case COMPONENT_REF:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
if (op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
@@ -134,16 +147,20 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
case MAX_EXPR:
case MIN_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
break;
case COND_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
break;
case MODIFY_EXPR:
@@ -151,7 +168,8 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
case COMPOUND_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues);
+ treat_class_rvalues_as_lvalues,
+ allow_cast_as_lvalue);
case TARGET_EXPR:
return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
@@ -196,7 +214,7 @@ cp_lvalue_kind
real_lvalue_p (ref)
tree ref;
{
- return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/0);
+ return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1);
}
/* This differs from real_lvalue_p in that class rvalues are
@@ -207,7 +225,7 @@ lvalue_p (ref)
tree ref;
{
return
- (lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1) != clk_none);
+ (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none);
}
/* Return nonzero if REF is an lvalue valid for this language;
@@ -218,7 +236,20 @@ lvalue_or_else (ref, string)
tree ref;
const char *string;
{
- int win = lvalue_p (ref);
+ int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 1);
+ int win = (ret != clk_none);
+ if (! win)
+ error ("non-lvalue in %s", string);
+ return win;
+}
+
+int
+non_cast_lvalue_or_else (ref, string)
+ tree ref;
+ const char *string;
+{
+ int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 0);
+ int win = (ret != clk_none);
if (! win)
error ("non-lvalue in %s", string);
return win;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 624b379cf71..8535cde4ae7 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4268,7 +4268,7 @@ build_unary_op (code, xarg, noconvert)
is an error. */
else if (TREE_CODE (argtype) != FUNCTION_TYPE
&& TREE_CODE (argtype) != METHOD_TYPE
- && !lvalue_or_else (arg, "unary `&'"))
+ && !non_cast_lvalue_or_else (arg, "unary `&'"))
return error_mark_node;
if (argtype != error_mark_node)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 00a92134d45..f509299f6e5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2002-08-24 Matt Austern <austern@apple.com>
+
+ * g++.dg/ext/lvaddr.C: New test.
+ * g++.dg/ext/lvcast.C: New test.
+
2002-08-22 Mark Mitchell <mark@codesourcery.com>
* testsuite/g++.dg/inherit/cond1.C: New test.
diff --git a/gcc/testsuite/g++.dg/ext/lvaddr.C b/gcc/testsuite/g++.dg/ext/lvaddr.C
new file mode 100644
index 00000000000..184afce900b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/lvaddr.C
@@ -0,0 +1,10 @@
+// Copyright (C) 2002 Free Software Foundation
+// Contributed by Matt Austern <austern@apple.com>
+
+// { dg-do compile }
+
+void f()
+{
+ int n;
+ char* p = &(char) n; // { dg-error "non-lvalue" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/lvcast.C b/gcc/testsuite/g++.dg/ext/lvcast.C
new file mode 100644
index 00000000000..efff04ec089
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/lvcast.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2002 Free Software Foundation
+// Contributed by Matt Austern <austern@apple.com>
+
+// { dg-do compile }
+// { dg-options -fpermissive }
+
+void f ()
+{
+ int n;
+ (char) n = 1;
+}