incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Scott Zhong" <Scott.Zh...@roguewave.com>
Subject [PATCH] STDCXX-423 LIMITS.cpp assumes integers with no padding bits
Date Thu, 03 Apr 2008 21:59:46 GMT
Changes made:

* fix a bug (not filed) that would potentially access an array using
negative index
* add function compute_type_bits to calculate the number of bits in the
value representation of type T.
* add a check that would only define exact width integer type if the
system supports two's complement
* add a check to ensure that the number of bits in the value
representation and the number of bits in the object representation are
the same before defining exact integer width types. 

Index: LIMITS.cpp
===================================================================
--- LIMITS.cpp  (revision 639462)
+++ LIMITS.cpp  (working copy)
@@ -80,7 +80,7 @@
         '0','1','2','3','4','5','6','7','8','9', 'a', 'b', 'c', 'd',
'e', 'f'
     };
 
-    if (is_max || n >= zero) {
+    if (n >= zero) {
 
         T tnstr = n;
 
@@ -224,6 +224,19 @@
 }
 
 
+template <class T>
+unsigned compute_type_bits()
+{
+    T max = T (one);
+    T current = T(one);
+    int bits = 1;
+ 
+    for (; T (current * 2) > max; current *=2, max *= 2, bits++) { }
+
+    return bits;
+}
+
+
 // used to compute the size of a pointer to a member function
 struct EmptyStruct { };
 
@@ -397,6 +410,12 @@
     // 1 for a 16-bit integer, etc)
     int width_bits = 0;
 
+    // store exact bit size of each type
+    int ushort_bits = compute_type_bits<unsigned short> ();
+    int uint_bits = compute_type_bits<unsigned int> ();
+    int ulong_bits = compute_type_bits<unsigned long> ();
+    int ullong_bits = compute_type_bits<unsigned LLong> ();
+
#define PRINT_SPECIFIC(width, least, type)
\
     do {
\
         /* avoid warnings about expression being constant */
\
@@ -406,7 +425,7 @@
                     "#define _RWSTD_UINT_LEAST%d_T %s  _RWSTD_U%s_T\n",
\
                     width, width < 10 ? " " : "", type,
\
                     width, width < 10 ? " " : "", type);
\
-        else
\
+        else if (!no_twos_complement)
\
             printf ("#define _RWSTD_INT%d_T %s          signed %s\n"
\
                     "#define _RWSTD_UINT%d_T %s         unsigned %s\n",
\
                     width, width < 10 ? " " : "", type,
\
@@ -430,59 +449,59 @@
         PRINT_SPECIFIC (64, "", "char");
     }
 
-    if (16 == char_bits * sizeof (short) && !(width_bits & 2)) {
+    if (16 == char_bits * sizeof (short) && 16 == ushort_bits &&
!(width_bits & 2)) {
         width_bits |= 2;
         PRINT_SPECIFIC (16, "", "short");
     }
-    else if (32 == char_bits * sizeof (short) && !(width_bits & 4)) {
+    else if (32 == char_bits * sizeof (short) && 32 == ushort_bits &&
!(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", "short");
     }
-    else if (64 == char_bits * sizeof (short) && !(width_bits & 8)) {
+    else if (64 == char_bits * sizeof (short) && 64 == ushort_bits &&
!(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", "short");
     }
-    else if (128 == char_bits * sizeof (short) && !(width_bits & 16)) {
+    else if (128 == char_bits * sizeof (short) && 128 == ushort_bits &&
!(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", "short");
     }
 
-    if (32 == char_bits * sizeof (int) && !(width_bits & 4)) {
+    if (32 == char_bits * sizeof (int) && 32 == uint_bits &&
!(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", "int");
     }
-    else if (64 == char_bits * sizeof (int) && !(width_bits & 8)) {
+    else if (64 == char_bits * sizeof (int) && 64 == uint_bits &&
!(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", "int");
     }
-    else if (128 == char_bits * sizeof (int) && !(width_bits & 16)) {
+    else if (128 == char_bits * sizeof (int) && 128 == uint_bits &&
!(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", "int");
     }
 
-    if (32 == char_bits * sizeof (long) && !(width_bits & 4)) {
+    if (32 == char_bits * sizeof (long) && 32 == ulong_bits &&
!(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", "long");
     }
-    else if (64 == char_bits * sizeof (long) && !(width_bits & 8)) {
+    else if (64 == char_bits * sizeof (long) && 64 == ulong_bits &&
!(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", "long");
     }
-    else if (128 == char_bits * sizeof (long) && !(width_bits & 16)) {
+    else if (128 == char_bits * sizeof (long) && 128 == ulong_bits &&
!(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", "long");
     }
 
-    if (32 == char_bits * sizeof (LLong) && !(width_bits & 4)) {
+    if (32 == char_bits * sizeof (LLong) && 32 == ullong_bits &&
!(width_bits & 4)) {
         width_bits |= 4;
         PRINT_SPECIFIC (32, "", llong_name);
     }
-    else if (64 == char_bits * sizeof (LLong) && !(width_bits & 8)) {
+    else if (64 == char_bits * sizeof (LLong) && 64 == ullong_bits &&
!(width_bits & 8)) {
         width_bits |= 8;
         PRINT_SPECIFIC (64, "", llong_name);
 
     }
-    else if (128 == char_bits * sizeof (LLong) && !(width_bits & 16)) {
+    else if (128 == char_bits * sizeof (LLong) && 128 == ullong_bits &&
!(width_bits & 16)) {
         width_bits |= 16;
         PRINT_SPECIFIC (128, "", llong_name);
     }

Mime
View raw message