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]

Additional checking for varrays used as stacks


This patch adds ENABLE_CHECKING logic to VARRAY_TOP and VARRAY_POP,
which used to happily return garbage and wrap elements_used around to
SIZE_MAX, respectively, if called on an empty varray.  I suppose that
the check done in VARRAY_TOP is stronger than it needs to be, but I
don't think that's a big deal.

The other sort of checking that varrays completely lack is
verification that you are reading elements with the appropriate type.
This, I think, we should work out a way to do statically.

Bootstrapped i686-linux.

zw

        * varray.h (VARRAY_POP): Add checking variant, aborts on underflow.
        (VARRAY_TOP): Use VARRAY_CHECK so the access is bounds-checked.
        * varray.c: No need to prototype error.
        (varray_check_failed): Wrap long string onto two lines.
        (varray_underflow): New function.

===================================================================
Index: varray.c
--- varray.c	12 Jan 2004 11:15:33 -0000	1.22
+++ varray.c	13 Jan 2004 02:40:25 -0000
@@ -118,15 +118,22 @@ varray_clear (varray_type va)
 
 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
 
-extern void error (const char *, ...)	ATTRIBUTE_PRINTF_1;
-
 void
 varray_check_failed (varray_type va, size_t n, const char *file, int line,
 		     const char *function)
 {
-  internal_error ("virtual array %s[%lu]: element %lu out of bounds in %s, at %s:%d",
+  internal_error ("virtual array %s[%lu]: element %lu out of bounds "
+		  "in %s, at %s:%d",
 		  va->name, (unsigned long) va->num_elements, (unsigned long) n,
 		  function, trim_filename (file), line);
+}
+
+void
+varray_underflow (varray_type va, const char *file, int line,
+		  const char *function)
+{
+  internal_error ("underflowed virtual array %s in %s, at %s:%d",
+		  va->name, function, trim_filename (file), line);
 }
 
 #endif
===================================================================
Index: varray.h
--- varray.h	10 Jul 2003 11:38:18 -0000	1.32
+++ varray.h	13 Jan 2004 02:40:25 -0000
@@ -227,14 +227,27 @@ extern void varray_clear (varray_type);
 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
 extern void varray_check_failed (varray_type, size_t, const char *, int,
 				 const char *) ATTRIBUTE_NORETURN;
+extern void varray_underflow (varray_type, const char *, int, const char *)
+     ATTRIBUTE_NORETURN;
 #define VARRAY_CHECK(VA, N, T) __extension__			\
 (*({ varray_type const _va = (VA);				\
      const size_t _n = (N);					\
      if (_n >= _va->num_elements)				\
        varray_check_failed (_va, _n, __FILE__, __LINE__, __FUNCTION__);	\
      &_va->data.T[_n]; }))
+
+#define VARRAY_POP(VA) do {					\
+  varray_type const _va = (VA);					\
+  if (_va->elements_used == 0)					\
+    varray_underflow (_va, __FILE__, __LINE__, __FUNCTION__);	\
+  else								\
+    _va->elements_used--;					\
+} while (0)
+
 #else
 #define VARRAY_CHECK(VA, N, T) ((VA)->data.T[N])
+/* Pop the top element of VA.  */
+#define VARRAY_POP(VA) do { ((VA)->elements_used--); } while (0)
 #endif
 
 /* Push X onto VA.  T is the name of the field in varray_data
@@ -248,14 +261,6 @@ extern void varray_check_failed (varray_
     }							\
   while (0)
 
-/* Pop the top element of VA.  */
-#define VARRAY_POP(VA) \
-  ((VA)->elements_used--)
-
-/* Return the top element of VA.  */
-#define VARRAY_TOP(VA, T) \
-  ((VA)->data.T[(VA)->elements_used - 1])
-
 #define VARRAY_CHAR(VA, N)		VARRAY_CHECK (VA, N, c)
 #define VARRAY_UCHAR(VA, N)		VARRAY_CHECK (VA, N, uc)
 #define VARRAY_SHORT(VA, N)		VARRAY_CHECK (VA, N, s)
@@ -299,6 +304,8 @@ extern void varray_check_failed (varray_
 #define VARRAY_PUSH_BB(VA, X)		VARRAY_PUSH (VA, bb, X)
 
 /* Return the last element of VA.  */
+#define VARRAY_TOP(VA, T) VARRAY_CHECK(VA, (VA)->elements_used - 1, T)
+
 #define VARRAY_TOP_CHAR(VA)		VARRAY_TOP (VA, c)
 #define VARRAY_TOP_UCHAR(VA)	        VARRAY_TOP (VA, uc)
 #define VARRAY_TOP_SHORT(VA)	        VARRAY_TOP (VA, s)


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