tm.texi (INTMAX_TYPE, [...]): Define.
authorJoseph Myers <jsm28@cam.ac.uk>
Sun, 8 Oct 2000 21:20:45 +0000 (22:20 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Sun, 8 Oct 2000 21:20:45 +0000 (22:20 +0100)
* tm.texi (INTMAX_TYPE, UINTMAX_TYPE): Define.
* c-common.h (enum c_tree_index): Add CTI_INTMAX_TYPE and
CTI_UINTMAX_TYPE.
(intmax_type_node, uintmax_type_node): Define.
* c-common.c (decl_attributes): If pedantic, warn if `mode'
attributes create a type wider than intmax_t.
(T_IM, T_UIM): Define properly.
* c-decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
defined.
(init_decl_processing): Initialize intmax_type_node and
uintmax_type_node.
* c-lex.c (lex_number): When pedantic and warning for integer
constants that are too large, in C99 mode warn for those that have
a type wider than long long.

cp:
* decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
defined.
(init_decl_processing): Initialize intmax_type_node and
uintmax_type_node.

testsuite:
* gcc.dg/c99-printf-1.c, gcc.dg/c99-scanf-1.c,
gcc.dg/c90-printf-2.c, gcc.dg/c90-scanf-2.c: Define intmax_t and
uintmax_t using <limits.h> to emulate the compiler's internal
logic.  No longer XFAIL %j tests.

From-SVN: r36791

13 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/c-lex.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/c90-printf-2.c
gcc/testsuite/gcc.dg/c90-scanf-2.c
gcc/testsuite/gcc.dg/c99-printf-1.c
gcc/testsuite/gcc.dg/c99-scanf-1.c
gcc/tm.texi

index 6f1718fbe5adebe984552ba22ba3a8124e28e669..2109191eb078c42d0ca5b65e15638c1f9ecd4067 100644 (file)
@@ -1,3 +1,20 @@
+2000-10-08  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * tm.texi (INTMAX_TYPE, UINTMAX_TYPE): Define.
+       * c-common.h (enum c_tree_index): Add CTI_INTMAX_TYPE and
+       CTI_UINTMAX_TYPE.
+       (intmax_type_node, uintmax_type_node): Define.
+       * c-common.c (decl_attributes): If pedantic, warn if `mode'
+       attributes create a type wider than intmax_t.
+       (T_IM, T_UIM): Define properly.
+       * c-decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
+       defined.
+       (init_decl_processing): Initialize intmax_type_node and
+       uintmax_type_node.
+       * c-lex.c (lex_number): When pedantic and warning for integer
+       constants that are too large, in C99 mode warn for those that have
+       a type wider than long long.
+
 2000-10-08  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * c-common.c (FMT_FLAG_ARG_CONVERT, FMT_FLAG_SCANF_A_KLUDGE,
index 6ad83f78d77d05dafe9864b4ba6231a212cf2266..7ae71c9a95005af6fd242024c87599fd8f4a6584 100644 (file)
@@ -761,6 +761,12 @@ decl_attributes (node, attributes, prefix_attributes)
                error ("no data type for mode `%s'", p);
              else
                {
+                 if (TYPE_PRECISION (typefm) > (TREE_UNSIGNED (type)
+                                                ? TYPE_PRECISION(uintmax_type_node)
+                                                : TYPE_PRECISION(intmax_type_node))
+                     && pedantic)
+                   pedwarn ("type with more precision than %s",
+                            TREE_UNSIGNED (type) ? "uintmax_t" : "intmax_t");
                  TREE_TYPE (decl) = type = typefm;
                  DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0;
                  layout_decl (decl, 0);
@@ -1589,9 +1595,9 @@ static const format_flag_pair strftime_flag_pairs[] =
 #define T99_PD { STD_C99, "ptrdiff_t", T_PD }
 #define T_UPD   &unsigned_ptrdiff_type_node
 #define T99_UPD        { STD_C99, "unsigned ptrdiff_t", T_UPD }
-#define T_IM    NULL /* intmax_t not yet implemented.  */
+#define T_IM    &intmax_type_node
 #define T99_IM { STD_C99, "intmax_t", T_IM }
-#define T_UIM   NULL /* uintmax_t not yet implemented.  */
+#define T_UIM   &uintmax_type_node
 #define T99_UIM        { STD_C99, "uintmax_t", T_UIM }
 
 static const format_char_info print_char_table[] =
index 24db762fc6544d529259ce33c7280456de3b5bf7..18eb5fb54f74f794cd37341a6378ba03240b3f6b 100644 (file)
@@ -119,6 +119,8 @@ enum c_tree_index
     CTI_C_SIZE_TYPE, /* For format checking only.  */
     CTI_SIGNED_SIZE_TYPE, /* For format checking only.  */
     CTI_UNSIGNED_PTRDIFF_TYPE, /* For format checking only.  */
+    CTI_INTMAX_TYPE,
+    CTI_UINTMAX_TYPE,
     CTI_WIDEST_INT_LIT_TYPE,
     CTI_WIDEST_UINT_LIT_TYPE,
 
@@ -161,6 +163,8 @@ enum c_tree_index
 #define c_size_type_node               c_global_trees[CTI_C_SIZE_TYPE]
 #define signed_size_type_node          c_global_trees[CTI_SIGNED_SIZE_TYPE]
 #define unsigned_ptrdiff_type_node     c_global_trees[CTI_UNSIGNED_PTRDIFF_TYPE]
+#define intmax_type_node               c_global_trees[CTI_INTMAX_TYPE]
+#define uintmax_type_node              c_global_trees[CTI_UINTMAX_TYPE]
 #define widest_integer_literal_type_node c_global_trees[CTI_WIDEST_INT_LIT_TYPE]
 #define widest_unsigned_literal_type_node c_global_trees[CTI_WIDEST_UINT_LIT_TYPE]
 
index 9dbaa2846857c9d16cfc951ac437ff9f0bb4099a..39e0b4a978c46971ecf443a1a9d6df26ab746b27 100644 (file)
@@ -77,6 +77,22 @@ enum decl_context
 #ifndef WINT_TYPE
 #define WINT_TYPE "unsigned int"
 #endif
+
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
+                    ? "int"                                    \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long int"                            \
+                       : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
+                    ? "unsigned int"                           \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long unsigned int"                   \
+                       : "long long unsigned int"))
+#endif
 \f
 /* Do GC.  */
 int ggc_p = 1;
@@ -3078,6 +3094,11 @@ init_decl_processing ()
   wint_type_node =
     TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
 
+  intmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
+  uintmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
+
   boolean_type_node = integer_type_node;
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_node;
index 693615361fc9afc41a90ad38430d9653816bad6a..343c9ccc6595ff47914c10a420a3772416b05b1a 100644 (file)
@@ -2287,11 +2287,19 @@ lex_number (str, len)
            warning ("width of integer constant may change on other systems with -traditional");
        }
 
-      if (pedantic && !flag_traditional && !spec_long_long && !warn
-         && (TYPE_PRECISION (long_integer_type_node) < TYPE_PRECISION (type)))
+      if (pedantic && !flag_traditional && (flag_isoc99 || !spec_long_long)
+         && !warn
+         && ((flag_isoc99
+              ? TYPE_PRECISION (long_long_integer_type_node)
+              : TYPE_PRECISION (long_integer_type_node)) < TYPE_PRECISION (type)))
        {
          warn = 1;
-         pedwarn ("integer constant larger than the maximum value of an unsigned long int");
+         pedwarn ("integer constant larger than the maximum value of %s",
+                  (flag_isoc99
+                   ? (TREE_UNSIGNED (type)
+                      ? "an unsigned long long int"
+                      : "a long long int")
+                   : "an unsigned long int"));
        }
 
       if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
index e7fdacea4027a9e66eddc46eed1ebd31499c501e..f0e2d4eab924e2793acc220dca938c0d66195c7c 100644 (file)
@@ -1,3 +1,10 @@
+2000-10-08  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
+       defined.
+       (init_decl_processing): Initialize intmax_type_node and
+       uintmax_type_node.
+
 2000-10-06  Richard Henderson  <rth@cygnus.com>
 
        * cp-tree.h (struct cp_language_function): Remove x_result_rtx.
index 82ebc36af0ed4672bb6e6633f3b1675bebf065fe..16d6ebd37c9e0ecf6593e9cc0054240111caf2b4 100644 (file)
@@ -83,6 +83,22 @@ int ggc_p = 1;
 #define WCHAR_TYPE "int"
 #endif
 
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
+                    ? "int"                                    \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long int"                            \
+                       : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
+                    ? "unsigned int"                           \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long unsigned int"                   \
+                       : "long long unsigned int"))
+#endif
+
 static tree grokparms                          PARAMS ((tree, int));
 static const char *redeclaration_error_message PARAMS ((tree, tree));
 
@@ -6542,6 +6558,11 @@ init_decl_processing ()
   wchar_array_type_node
     = build_array_type (wchar_type_node, array_domain_type);
 
+  intmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
+  uintmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
+
   if (flag_vtable_thunks)
     {
       /* Make sure we get a unique function type, so we can give
index 990a4df578819a09e6034876b33951e0bb6c806c..9c48023ad07222b09141185ab663449d412b5cdc 100644 (file)
@@ -1,3 +1,10 @@
+2000-10-08  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * gcc.dg/c99-printf-1.c, gcc.dg/c99-scanf-1.c,
+       gcc.dg/c90-printf-2.c, gcc.dg/c90-scanf-2.c: Define intmax_t and
+       uintmax_t using <limits.h> to emulate the compiler's internal
+       logic.  No longer XFAIL %j tests.
+
 2000-10-08  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * gcc.dg/c90-printf-1.c, gcc.dg/c90-scanf-1.c,
index 729ccd0f1dcdab798ab13e956818b95408c8cdfc..16082bee63d777f68d3d9e37aef4a96abb9d5532 100644 (file)
@@ -10,12 +10,17 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
 
 __extension__ typedef long long int llong;
 
-/* This next definition is broken.  When GCC has a <stdint.h> and
-   an internal understanding of intmax_t, it should be
-   replaced by an include of <stdint.h> or by a definition for internal
-   macros or typedefs.
+/* This next definition is a kludge.  When GCC has a <stdint.h> it
+   should be used.
 */
-__extension__ typedef long long int intmax_t;
+#include <limits.h>
+#if INT_MAX == LLONG_MAX
+typedef int intmax_t;
+#elif LONG_MAX == LLONG_MAX
+typedef long intmax_t;
+#else
+__extension__ typedef long long intmax_t;
+#endif
 
 extern int printf (const char *, ...);
 
index 1b8636db6ed5391dfb2fe34fb82357e61fae9d9e..7e3a8c55d525aff45bf5e17533daf4989d2fadec 100644 (file)
@@ -10,12 +10,17 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
 
 __extension__ typedef long long int llong;
 
-/* This next definition is broken.  When GCC has a <stdint.h> and
-   an internal understanding of intmax_t, it should be
-   replaced by an include of <stdint.h> or by a definition for internal
-   macros or typedefs.
+/* This next definition is a kludge.  When GCC has a <stdint.h> it
+   should be used.
 */
-__extension__ typedef long long int intmax_t;
+#include <limits.h>
+#if INT_MAX == LLONG_MAX
+typedef int intmax_t;
+#elif LONG_MAX == LLONG_MAX
+typedef long intmax_t;
+#else
+__extension__ typedef long long intmax_t;
+#endif
 
 extern int scanf (const char *, ...);
 
index 304be531657466e2424e9563efdf80a996c3cc08..179ea6e5516c22698fc07439e6868469e338fa78 100644 (file)
@@ -16,13 +16,24 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
 typedef __SIZE_TYPE__ signed_size_t;
 #undef unsigned
 
-/* These next definitions are broken.  When GCC has a <stdint.h> and
-   an internal understanding of intmax_t and uintmax_t, they should be
-   replaced by an include of <stdint.h> or by definitions for internal
-   macros or typedefs, and the corresponding xfails removed.
+/* These next definitions are kludges.  When GCC has a <stdint.h> it
+   should be used.
 */
-typedef long long int intmax_t;
-typedef unsigned long long int uintmax_t;
+#include <limits.h>
+#if INT_MAX == LLONG_MAX
+typedef int intmax_t;
+#elif LONG_MAX == LLONG_MAX
+typedef long intmax_t;
+#else
+typedef long long intmax_t;
+#endif
+#if UINT_MAX == ULLONG_MAX
+typedef unsigned int uintmax_t;
+#elif ULONG_MAX == ULLONG_MAX
+typedef unsigned long uintmax_t;
+#else
+typedef unsigned long long uintmax_t;
+#endif
 
 extern int printf (const char *, ...);
 
@@ -82,8 +93,8 @@ foo (int i, unsigned int u, double d, char *s, void *p, int *n,
   printf ("%llc", i); /* { dg-warning "length" "bad use of %ll" } */
   printf ("%lls", s); /* { dg-warning "length" "bad use of %ll" } */
   printf ("%llp", p); /* { dg-warning "length" "bad use of %ll" } */
-  printf ("%jd%ji%jo%ju%jx%jX", j, j, uj, uj, uj, uj); /* { dg-bogus "length" "bogus %j warning" { xfail *-*-* } } */
-  printf ("%jn", jn); /* { dg-bogus "length" "bogus %j warning" { xfail *-*-* } } */
+  printf ("%jd%ji%jo%ju%jx%jX", j, j, uj, uj, uj, uj); /* { dg-bogus "length" "bogus %j warning" { target *-*-* } } */
+  printf ("%jn", jn); /* { dg-bogus "length" "bogus %j warning" { target *-*-* } } */
   printf ("%jf", d); /* { dg-warning "length" "bad use of %j" } */
   printf ("%jF", d); /* { dg-warning "length" "bad use of %j" } */
   printf ("%je", d); /* { dg-warning "length" "bad use of %j" } */
index 447d51eaed80d622e933e65dcb0ae9213c05fc0f..369f02e667bd277847ddb1f5f8f0a657a74555b5 100644 (file)
@@ -18,13 +18,24 @@ typedef __SIZE_TYPE__ signed_size_t;
 typedef unsigned __PTRDIFF_TYPE__ unsigned_ptrdiff_t;
 #undef signed
 
-/* These next definitions are broken.  When GCC has a <stdint.h> and
-   an internal understanding of intmax_t and uintmax_t, they should be
-   replaced by an include of <stdint.h> or by definitions for internal
-   macros or typedefs, and the corresponding xfails removed.
+/* These next definitions are kludges.  When GCC has a <stdint.h> it
+   should be used.
 */
-typedef long long int intmax_t;
-typedef unsigned long long int uintmax_t;
+#include <limits.h>
+#if INT_MAX == LLONG_MAX
+typedef int intmax_t;
+#elif LONG_MAX == LLONG_MAX
+typedef long intmax_t;
+#else
+typedef long long intmax_t;
+#endif
+#if UINT_MAX == ULLONG_MAX
+typedef unsigned int uintmax_t;
+#elif ULONG_MAX == ULLONG_MAX
+typedef unsigned long uintmax_t;
+#else
+typedef unsigned long long uintmax_t;
+#endif
 
 extern int scanf (const char *, ...);
 
@@ -102,7 +113,7 @@ foo (int *ip, unsigned int *uip, short int *hp, unsigned short int *uhp,
   scanf ("%ll[ac]", s); /* { dg-warning "length" "bad use of %ll" } */
   scanf ("%llc", s); /* { dg-warning "length" "bad use of %ll" } */
   scanf ("%llp", pp); /* { dg-warning "length" "bad use of %ll" } */
-  scanf ("%jd%ji%jo%ju%jx%jX%jn", jp, jp, ujp, ujp, ujp, ujp, jn); /* { dg-bogus "length" "bogus %j warning" { xfail *-*-* } } */
+  scanf ("%jd%ji%jo%ju%jx%jX%jn", jp, jp, ujp, ujp, ujp, ujp, jn); /* { dg-bogus "length" "bogus %j warning" { target *-*-* } } */
   scanf ("%ja", fp); /* { dg-warning "length" "bad use of %j" } */
   scanf ("%jA", fp); /* { dg-warning "length" "bad use of %j" } */
   scanf ("%je", fp); /* { dg-warning "length" "bad use of %j" } */
index 198b7fb833599dfd2fc319992783df725e09e04e..784943849a24a0c8a8e96a3e3b031565abe7361d 100644 (file)
@@ -1331,6 +1331,29 @@ information.
 
 If you don't define this macro, the default is @code{"unsigned int"}.
 
+@findex INTMAX_TYPE
+@item INTMAX_TYPE
+A C expression for a string describing the name of the data type that
+can represent any value of any standard or extended signed integer type.
+The typedef name @code{intmax_t} is defined using the contents of the
+string.  See @code{SIZE_TYPE} above for more information.
+
+If you don't define this macro, the default is the first of
+@code{"int"}, @code{"long int"}, or @code{"long long int"} that has as
+much precision as @code{long long int}.
+
+@findex UINTMAX_TYPE
+@item UINTMAX_TYPE
+A C expression for a string describing the name of the data type that
+can represent any value of any standard or extended unsigned integer
+type.  The typedef name @code{uintmax_t} is defined using the contents
+of the string.  See @code{SIZE_TYPE} above for more information.
+
+If you don't define this macro, the default is the first of
+@code{"unsigned int"}, @code{"long unsigned int"}, or @code{"long long
+unsigned int"} that has as much precision as @code{long long unsigned
+int}.
+
 @findex OBJC_INT_SELECTORS
 @item OBJC_INT_SELECTORS
 Define this macro if the type of Objective C selectors should be