PR c++/14267
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Mar 2004 02:25:06 +0000 (02:25 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Mar 2004 02:25:06 +0000 (02:25 +0000)
* typeck.c (build_modify_expr): Remove more of the cast-as-lvalue
extension.

PR c++/14267
* g++.dg/expr/crash2.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@78689 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/crash2.C [new file with mode: 0644]

index 979f578..82de3a9 100644 (file)
@@ -1,5 +1,9 @@
 2004-02-29  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/14267
+       * typeck.c (build_modify_expr): Remove more of the cast-as-lvalue
+       extension.
+
        PR debug/12103
        * class.c (update_vtable_entry_for_fn): Do not go through
        covariance machinery if the type returned by an overrider is the
index aa85df5..d5d832b 100644 (file)
@@ -5098,52 +5098,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
                          20011220);
     }
 
-  /* Handle a cast used as an "lvalue".
-     We have already performed any binary operator using the value as cast.
-     Now convert the result to the cast type of the lhs,
-     and then true type of the lhs and store it there;
-     then convert result back to the cast type to be the value
-     of the assignment.  */
-
-  switch (TREE_CODE (lhs))
-    {
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-    case FLOAT_EXPR:
-    case FIX_TRUNC_EXPR:
-    case FIX_FLOOR_EXPR:
-    case FIX_ROUND_EXPR:
-    case FIX_CEIL_EXPR:
-      {
-       tree inner_lhs = TREE_OPERAND (lhs, 0);
-       tree result;
-
-       if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
-           || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE
-           || TREE_CODE (TREE_TYPE (newrhs)) == METHOD_TYPE
-           || TREE_CODE (TREE_TYPE (newrhs)) == OFFSET_TYPE)
-         newrhs = decay_conversion (newrhs);
-       
-       /* ISO C++ 5.4/1: The result is an lvalue if T is a reference
-          type, otherwise the result is an rvalue.  */
-       if (! lvalue_p (lhs))
-         pedwarn ("ISO C++ forbids cast to non-reference type used as lvalue");
-
-       result = build_modify_expr (inner_lhs, NOP_EXPR,
-                                   cp_convert (TREE_TYPE (inner_lhs),
-                                               cp_convert (lhstype, newrhs)));
-       if (result == error_mark_node)
-         return result;
-       return cp_convert (TREE_TYPE (lhs), result);
-      }
-
-    default:
-      break;
-    }
-
-  /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
-     Reject anything strange now.  */
-
+  /* The left-hand side must be an lvalue.  */
   if (!lvalue_or_else (lhs, "assignment"))
     return error_mark_node;
 
index 74be633..c6dbd88 100644 (file)
@@ -1,5 +1,8 @@
 2004-02-29  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/14267
+       * g++.dg/expr/crash2.C: New test.
+
        PR middle-end/13448
        * gcc.dg/inline-5.c: New test.
        * gcc.dg/always-inline.c: Split out tests into ...
diff --git a/gcc/testsuite/g++.dg/expr/crash2.C b/gcc/testsuite/g++.dg/expr/crash2.C
new file mode 100644 (file)
index 0000000..5379bb1
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/14267
+class foo {
+public: static int& x;
+};
+int temp;
+int& foo::x=temp;
+
+int main() {
+  int x = 3;
+  &foo::x = x; // { dg-error "" }
+  return 0;
+}
+