aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <jsm28@cam.ac.uk>2000-10-08 22:20:45 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2000-10-08 22:20:45 +0100
commitb15ad712574a975b0ba2a333bff74db3f19c17d4 (patch)
tree15af4058397b150088ce3bdbb721fc90ed1842f9
parent2588e44e0019aac9b55c974efd69885eea663f54 (diff)
downloadgcc-b15ad712574a975b0ba2a333bff74db3f19c17d4.zip
gcc-b15ad712574a975b0ba2a333bff74db3f19c17d4.tar.gz
gcc-b15ad712574a975b0ba2a333bff74db3f19c17d4.tar.bz2
tm.texi (INTMAX_TYPE, [...]): Define.
* 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
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/c-common.c10
-rw-r--r--gcc/c-common.h4
-rw-r--r--gcc/c-decl.c21
-rw-r--r--gcc/c-lex.c14
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c21
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/c90-printf-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/c90-scanf-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/c99-printf-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/c99-scanf-1.c25
-rw-r--r--gcc/tm.texi23
13 files changed, 176 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6f1718f..2109191 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,22 @@
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,
FMT_FLAG_FANCY_PERCENT_OK): Define.
(format_char_info): Add flag "4" to comment.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 6ad83f7..7ae71c9 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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[] =
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 24db762..18eb5fb 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -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]
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 9dbaa28..39e0b4a 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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
/* 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;
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index 6936153..343c9cc 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -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))
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e7fdace..f0e2d4e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 82ebc36..16d6ebd 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 990a4df..9c48023 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
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,
gcc.dg/c99-printf-1.c, gcc.dg/c99-scanf-1.c,
gcc.dg/c99-strftime-1.c, gcc.dg/format-ext-3.c: Adjust error
diff --git a/gcc/testsuite/gcc.dg/c90-printf-2.c b/gcc/testsuite/gcc.dg/c90-printf-2.c
index 729ccd0..16082be 100644
--- a/gcc/testsuite/gcc.dg/c90-printf-2.c
+++ b/gcc/testsuite/gcc.dg/c90-printf-2.c
@@ -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 *, ...);
diff --git a/gcc/testsuite/gcc.dg/c90-scanf-2.c b/gcc/testsuite/gcc.dg/c90-scanf-2.c
index 1b8636d..7e3a8c55 100644
--- a/gcc/testsuite/gcc.dg/c90-scanf-2.c
+++ b/gcc/testsuite/gcc.dg/c90-scanf-2.c
@@ -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 *, ...);
diff --git a/gcc/testsuite/gcc.dg/c99-printf-1.c b/gcc/testsuite/gcc.dg/c99-printf-1.c
index 304be53..179ea6e 100644
--- a/gcc/testsuite/gcc.dg/c99-printf-1.c
+++ b/gcc/testsuite/gcc.dg/c99-printf-1.c
@@ -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" } */
diff --git a/gcc/testsuite/gcc.dg/c99-scanf-1.c b/gcc/testsuite/gcc.dg/c99-scanf-1.c
index 447d51e..369f02e 100644
--- a/gcc/testsuite/gcc.dg/c99-scanf-1.c
+++ b/gcc/testsuite/gcc.dg/c99-scanf-1.c
@@ -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" } */
diff --git a/gcc/tm.texi b/gcc/tm.texi
index 198b7fb..7849438 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -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