bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

rewrote DECIMAL_DIGIT_ACCUMULATE to no longer need typeof


From: Paul Eggert
Subject: rewrote DECIMAL_DIGIT_ACCUMULATE to no longer need typeof
Date: Mon, 04 Jul 2005 23:37:47 -0700
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

While looking into the problems with typeof on Sun's C compiler, I
noticed a bug in DECIMAL_DIGIT_ACCUMULATE: it assumed that the type of
the accumulator never promoted to int.  While fixing this, I noticed
that I could rewrite DECIMAL_DIGIT_ACCUMULATE so that it didn't need
typeof at all.  This simplifies configuration, and it improves checking
on compilers that don't have typeof.  I installed this:

2005-07-04  Paul Eggert  <address@hidden>

        * m4/prereq.m4 (gl_PREREQ): Don't require gl_TYPEOF; no longer needed.
        * m4/typeof.m4: Remove; no longer needed.
        * src/system.h (VERIFY_W_TYPEOF): Remove; no longer needed.
        (DECIMAL_DIGIT_ACCUMULATE): Change last arg from T's maximum value
        to T itself.  All callers changed.  Check that T is unsigned, and
        that Accum is of type T.  This fixes a bug in the unlikely case
        where SIZE_MAX <= INT_MAX, and it no longer requires typeof to do
        the proper validity checks.

Index: m4/prereq.m4
===================================================================
RCS file: /fetish/cu/m4/prereq.m4,v
retrieving revision 1.117
diff -p -u -r1.117 prereq.m4
--- m4/prereq.m4        4 Jul 2005 05:05:55 -0000       1.117
+++ m4/prereq.m4        5 Jul 2005 06:26:44 -0000
@@ -1,4 +1,4 @@
-#serial 59
+#serial 60
 
 dnl We use gl_ for non Autoconf macros.
 m4_pattern_forbid([^gl_[ABCDEFGHIJKLMNOPQRSTUVXYZ]])dnl
@@ -171,5 +171,4 @@ AC_DEFUN([gl_PREREQ],
   AC_REQUIRE([gl_LINEBUFFER])
   AC_REQUIRE([gl_ARGMATCH])
   AC_REQUIRE([gl_CYCLE_CHECK])
-  AC_REQUIRE([gl_TYPEOF])
 ])
Index: src/cut.c
===================================================================
RCS file: /fetish/cu/src/cut.c,v
retrieving revision 1.123
diff -p -u -r1.123 cut.c
--- src/cut.c   14 May 2005 07:58:37 -0000      1.123
+++ src/cut.c   5 Jul 2005 06:26:45 -0000
@@ -455,7 +455,7 @@ set_fields (const char *fieldstr)
          in_digits = true;
 
          /* Detect overflow.  */
-         if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', SIZE_MAX))
+         if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t))
            {
              /* In case the user specified -c4294967296,22,
                 complain only about the first number.  */
Index: src/expand.c
===================================================================
RCS file: /fetish/cu/src/expand.c,v
retrieving revision 1.85
diff -p -u -r1.85 expand.c
--- src/expand.c        14 May 2005 07:58:37 -0000      1.85
+++ src/expand.c        5 Jul 2005 06:26:45 -0000
@@ -172,7 +172,7 @@ parse_tab_stops (char const *stops)
              num_start = stops;
            }
 
-         if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', UINTMAX_MAX))
+         if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t))
            {
              size_t len = strspn (num_start, "0123456789");
              char *bad_num = xstrndup (num_start, len);
Index: src/split.c
===================================================================
RCS file: /fetish/cu/src/split.c,v
retrieving revision 1.110
diff -p -u -r1.110 split.c
--- src/split.c 3 Jul 2005 07:20:33 -0000       1.110
+++ src/split.c 5 Jul 2005 06:26:45 -0000
@@ -481,7 +481,7 @@ main (int argc, char **argv)
          if (digits_optind != 0 && digits_optind != this_optind)
            n_units = 0;        /* More than one number given; ignore other. */
          digits_optind = this_optind;
-         if (!DECIMAL_DIGIT_ACCUMULATE (n_units, c - '0', UINTMAX_MAX))
+         if (!DECIMAL_DIGIT_ACCUMULATE (n_units, c - '0', uintmax_t))
            {
              char buffer[INT_BUFSIZE_BOUND (uintmax_t)];
              error (EXIT_FAILURE, 0,
Index: src/system.h
===================================================================
RCS file: /fetish/cu/src/system.h,v
retrieving revision 1.129
diff -p -u -r1.129 system.h
--- src/system.h        5 Jul 2005 05:16:57 -0000       1.129
+++ src/system.h        5 Jul 2005 06:26:45 -0000
@@ -807,25 +807,18 @@ ptr_align (void const *ptr, size_t align
   return (void *) (p1 - (size_t) p1 % alignment);
 }
 
-/* With a compiler that supports the __typeof__ operator, ensure that
-   TYPEOF_REQUIREMENT is nonzero at compile time.  If the compiler does
-   not support __typeof__, do nothing.  */
-#if HAVE_TYPEOF
-# define VERIFY_W_TYPEOF(typeof_requirement) verify_expr (typeof_requirement)
-#else
-# define VERIFY_W_TYPEOF(typeof_requirement) ((void) 0)
-#endif
+/* If 10*Accum + Digit_val is larger than the maximum value for Type,
+   then don't update Accum and return false to indicate it would
+   overflow.  Otherwise, set Accum to that new value and return true.
+   Verify at compile-time that Type is Accum's type, and that Type is
+   unsigned.  Accum must be an object, so that we can take its address.
+   Accum and Digit_val may be evaluated multiple times.  */
 
-/* If 10*Accum+Digit_val is larger than Type_max, then don't update Accum
-   and return zero to indicate it would overflow.  Otherwise, set Accum to
-   that new value and return nonzero.  With a compiler that provides the
-   __typeof__ operator, perform a compile-time check to verify that the
-   specified Type_max value is the same as the constant derived from the
-   type of Accum.  */
-#define DECIMAL_DIGIT_ACCUMULATE(Accum, Digit_val, Type_max)           \
+#define DECIMAL_DIGIT_ACCUMULATE(Accum, Digit_val, Type)               \
   (                                                                    \
-   /* Ensure that Type_max is the maximum value of Accum.  */          \
-   VERIFY_W_TYPEOF (TYPE_MAXIMUM (__typeof__ (Accum)) == (Type_max)),  \
-   ((Type_max) / 10 < Accum || Accum * 10 + (Digit_val) < Accum                
\
-              ? 0 : ((Accum = Accum * 10 + (Digit_val)), 1))           \
+   (void) (&(Accum) == (Type *) NULL),  /* The type matches.  */       \
+   verify_expr (! TYPE_SIGNED (Type)),  /* The type is unsigned.  */   \
+   (((Type) -1 / 10 < (Accum)                                          \
+     || (Type) ((Accum) * 10 + (Digit_val)) < (Accum))                 \
+    ? false : (((Accum) = (Accum) * 10 + (Digit_val)), true))          \
   )
Index: src/unexpand.c
===================================================================
RCS file: /fetish/cu/src/unexpand.c,v
retrieving revision 1.92
diff -p -u -r1.92 unexpand.c
--- src/unexpand.c      14 May 2005 07:58:37 -0000      1.92
+++ src/unexpand.c      5 Jul 2005 06:26:45 -0000
@@ -192,7 +192,7 @@ parse_tab_stops (char const *stops)
            }
          {
            /* Detect overflow.  */
-           if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', UINTMAX_MAX))
+           if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t))
              {
                size_t len = strspn (num_start, "0123456789");
                char *bad_num = xstrndup (num_start, len);
@@ -512,7 +512,7 @@ main (int argc, char **argv)
              tabval = 0;
              have_tabval = true;
            }
-         if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', UINTMAX_MAX))
+         if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', uintmax_t))
            error (EXIT_FAILURE, 0, _("tab stop value is too large"));
          break;
        }
Index: src/uniq.c
===================================================================
RCS file: /fetish/cu/src/uniq.c,v
retrieving revision 1.125
diff -p -u -r1.125 uniq.c
--- src/uniq.c  3 Jul 2005 06:26:15 -0000       1.125
+++ src/uniq.c  5 Jul 2005 06:26:45 -0000
@@ -471,7 +471,7 @@ main (int argc, char **argv)
            if (skip_field_option_type == SFO_NEW)
              skip_fields = 0;
 
-           if (!DECIMAL_DIGIT_ACCUMULATE (skip_fields, optc - '0', SIZE_MAX))
+           if (!DECIMAL_DIGIT_ACCUMULATE (skip_fields, optc - '0', size_t))
              error (EXIT_FAILURE, 0, "%s",
                     _("invalid number of fields to skip"));
            skip_field_option_type = SFO_OBSOLETE;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]