This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch to separate lvalue_or_else for C and C++


Stopping the C front end from depending on NON_LVALUE_EXPR requires
that it determine information about whether an expression is an lvalue
from internal structures (additional flags in c_expr) rather than from
the tree for the expression.  Thus lvalue_or_else needs to become
local to each of the C and C++ front ends again, although the code
printing diagnostics can remain shared.  This patch makes it local to
the front ends, with a shared lvalue_error function to deal with the
diagnostics.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
commit?

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-03-20  Joseph S. Myers  <joseph@codesourcery.com>

	* c-common.c (lvalue_or_else): Replace by lvalue_error; only give
	diagnostic without checking whether an lvalue.
	* c-common.h (lvalue_p): Remove.
	(enum lvalue_use): Update comment.
	(lvalue_or_else): Replace by lvalue_error.
	* c-typeck.c (lvalue_p): Make static.
	(lvalue_or_else): New.  Call lvalue_error.

cp:
2005-03-20  Joseph S. Myers  <joseph@codesourcery.com>

	* cp-tree.h (lvalue_or_else, lvalue_p): New.
	* typeck.c (lvalue_or_else): New.  Call lvalue_error.

diff -rupN GCC.orig/gcc/c-common.c GCC/gcc/c-common.c
--- GCC.orig/gcc/c-common.c	2005-03-18 20:45:08.000000000 +0000
+++ GCC/gcc/c-common.c	2005-03-20 14:11:59.000000000 +0000
@@ -5742,40 +5742,32 @@ fold_offsetof (tree expr)
   return convert (size_type_node, fold_offsetof_1 (expr));
 }
 
-/* Return nonzero if REF is an lvalue valid for this language;
-   otherwise, print an error message and return zero.  USE says
+/* Print an error message for an invalid lvalue.  USE says
    how the lvalue is being used and so selects the error message.  */
 
-int
-lvalue_or_else (tree ref, enum lvalue_use use)
+void
+lvalue_error (enum lvalue_use use)
 {
-  int win = lvalue_p (ref);
-
-  if (!win)
+  switch (use)
     {
-      switch (use)
-	{
-	case lv_assign:
-	  error ("invalid lvalue in assignment");
-	  break;
-	case lv_increment:
-	  error ("invalid lvalue in increment");
-	  break;
-	case lv_decrement:
-	  error ("invalid lvalue in decrement");
-	  break;
-	case lv_addressof:
-	  error ("invalid lvalue in unary %<&%>");
-	  break;
-	case lv_asm:
-	  error ("invalid lvalue in asm statement");
-	  break;
-	default:
-	  gcc_unreachable ();
-	}
+    case lv_assign:
+      error ("invalid lvalue in assignment");
+      break;
+    case lv_increment:
+      error ("invalid lvalue in increment");
+      break;
+    case lv_decrement:
+      error ("invalid lvalue in decrement");
+      break;
+    case lv_addressof:
+      error ("invalid lvalue in unary %<&%>");
+      break;
+    case lv_asm:
+      error ("invalid lvalue in asm statement");
+      break;
+    default:
+      gcc_unreachable ();
     }
-
-  return win;
 }
 
 #include "gt-c-common.h"
diff -rupN GCC.orig/gcc/c-common.h GCC/gcc/c-common.h
--- GCC.orig/gcc/c-common.h	2005-02-23 23:43:17.000000000 +0000
+++ GCC/gcc/c-common.h	2005-03-20 14:24:47.000000000 +0000
@@ -808,7 +808,6 @@ extern tree build_break_stmt (void);
 
 extern tree build_unary_op (enum tree_code, tree, int);
 extern tree build_binary_op (enum tree_code, tree, tree, int);
-extern int lvalue_p (tree);
 extern tree default_conversion (tree);
 
 /* Given two integer or real types, return the type for their sum.
@@ -877,7 +876,7 @@ extern void verify_sequence_points (tree
 extern tree fold_offsetof (tree);
 
 /* Places where an lvalue, or modifiable lvalue, may be required.
-   Used to select diagnostic messages in lvalue_or_else and
+   Used to select diagnostic messages in lvalue_error and
    readonly_error.  */
 enum lvalue_use {
   lv_assign,
@@ -887,7 +886,7 @@ enum lvalue_use {
   lv_asm
 };
 
-extern int lvalue_or_else (tree, enum lvalue_use);
+extern void lvalue_error (enum lvalue_use);
 
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-03-18 20:45:08.000000000 +0000
+++ GCC/gcc/c-typeck.c	2005-03-20 14:25:14.000000000 +0000
@@ -100,6 +100,8 @@ static void set_nonincremental_init (voi
 static void set_nonincremental_init_from_string (tree);
 static tree find_init_member (tree);
 static void readonly_error (tree, enum lvalue_use);
+static int lvalue_or_else (tree, enum lvalue_use);
+static int lvalue_p (tree);
 static void record_maybe_used_decl (tree);
 
 /* Do `exp = require_complete_type (exp);' to make sure exp
@@ -2758,7 +2760,7 @@ build_unary_op (enum tree_code code, tre
    Lvalues can be assigned, unless their type has TYPE_READONLY.
    Lvalues can have their address taken, unless they have C_DECL_REGISTER.  */
 
-int
+static int
 lvalue_p (tree ref)
 {
   enum tree_code code = TREE_CODE (ref);
@@ -2823,6 +2825,22 @@ readonly_error (tree arg, enum lvalue_us
 			 N_("increment of read-only location"),
 			 N_("decrement of read-only location")));
 }
+
+
+/* Return nonzero if REF is an lvalue valid for this language;
+   otherwise, print an error message and return zero.  USE says
+   how the lvalue is being used and so selects the error message.  */
+
+static int
+lvalue_or_else (tree ref, enum lvalue_use use)
+{
+  int win = lvalue_p (ref);
+
+  if (!win)
+    lvalue_error (use);
+
+  return win;
+}
 
 /* Mark EXP saying that we need to be able to take the
    address of it; it should not be allocated in a register.
diff -rupN GCC.orig/gcc/cp/cp-tree.h GCC/gcc/cp/cp-tree.h
--- GCC.orig/gcc/cp/cp-tree.h	2005-03-17 16:46:16.000000000 +0000
+++ GCC/gcc/cp/cp-tree.h	2005-03-20 14:25:27.000000000 +0000
@@ -4332,6 +4332,8 @@ extern tree lookup_anon_field           
 extern bool invalid_nonstatic_memfn_p           (tree);
 extern tree convert_member_func_to_ptr          (tree, tree);
 extern tree convert_ptrmem                      (tree, tree, bool, bool);
+extern int lvalue_or_else                       (tree, enum lvalue_use);
+extern int lvalue_p                             (tree);
 
 /* in typeck2.c */
 extern void require_complete_eh_spec_types	(tree, tree);
diff -rupN GCC.orig/gcc/cp/typeck.c GCC/gcc/cp/typeck.c
--- GCC.orig/gcc/cp/typeck.c	2005-03-11 00:37:14.000000000 +0000
+++ GCC/gcc/cp/typeck.c	2005-03-20 14:13:27.000000000 +0000
@@ -6513,3 +6513,19 @@ non_reference (tree t)
     t = TREE_TYPE (t);
   return t;
 }
+
+
+/* Return nonzero if REF is an lvalue valid for this language;
+   otherwise, print an error message and return zero.  USE says
+   how the lvalue is being used and so selects the error message.  */
+
+int
+lvalue_or_else (tree ref, enum lvalue_use use)
+{
+  int win = lvalue_p (ref);
+
+  if (!win)
+    lvalue_error (use);
+
+  return win;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]