From b15ad712574a975b0ba2a333bff74db3f19c17d4 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Sun, 8 Oct 2000 22:20:45 +0100 Subject: [PATCH] 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 to emulate the compiler's internal logic. No longer XFAIL %j tests. From-SVN: r36791 --- gcc/ChangeLog | 17 +++++++++++++++++ gcc/c-common.c | 10 ++++++++-- gcc/c-common.h | 4 ++++ gcc/c-decl.c | 21 +++++++++++++++++++++ gcc/c-lex.c | 14 +++++++++++--- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 21 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/c90-printf-2.c | 15 ++++++++++----- gcc/testsuite/gcc.dg/c90-scanf-2.c | 15 ++++++++++----- gcc/testsuite/gcc.dg/c99-printf-1.c | 27 +++++++++++++++++++-------- gcc/testsuite/gcc.dg/c99-scanf-1.c | 25 ++++++++++++++++++------- gcc/tm.texi | 23 +++++++++++++++++++++++ 13 files changed, 176 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6f1718fbe5a..2109191eb07 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2000-10-08 Joseph S. Myers + + * 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 * c-common.c (FMT_FLAG_ARG_CONVERT, FMT_FLAG_SCANF_A_KLUDGE, diff --git a/gcc/c-common.c b/gcc/c-common.c index 6ad83f78d77..7ae71c9a950 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 24db762fc65..18eb5fb54f7 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 9dbaa284685..39e0b4a978c 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 693615361fc..343c9ccc659 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 e7fdacea402..f0e2d4eab92 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2000-10-08 Joseph S. Myers + + * 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 * cp-tree.h (struct cp_language_function): Remove x_result_rtx. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 82ebc36af0e..16d6ebd37c9 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 990a4df5788..9c48023ad07 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2000-10-08 Joseph S. Myers + + * 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 to emulate the compiler's internal + logic. No longer XFAIL %j tests. + 2000-10-08 Joseph S. Myers * gcc.dg/c90-printf-1.c, gcc.dg/c90-scanf-1.c, diff --git a/gcc/testsuite/gcc.dg/c90-printf-2.c b/gcc/testsuite/gcc.dg/c90-printf-2.c index 729ccd0f1dc..16082bee63d 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 and - an internal understanding of intmax_t, it should be - replaced by an include of or by a definition for internal - macros or typedefs. +/* This next definition is a kludge. When GCC has a it + should be used. */ -__extension__ typedef long long int intmax_t; +#include +#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 1b8636db6ed..7e3a8c55d52 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 and - an internal understanding of intmax_t, it should be - replaced by an include of or by a definition for internal - macros or typedefs. +/* This next definition is a kludge. When GCC has a it + should be used. */ -__extension__ typedef long long int intmax_t; +#include +#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 304be531657..179ea6e5516 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 and - an internal understanding of intmax_t and uintmax_t, they should be - replaced by an include of or by definitions for internal - macros or typedefs, and the corresponding xfails removed. +/* These next definitions are kludges. When GCC has a it + should be used. */ -typedef long long int intmax_t; -typedef unsigned long long int uintmax_t; +#include +#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 447d51eaed8..369f02e667b 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 and - an internal understanding of intmax_t and uintmax_t, they should be - replaced by an include of or by definitions for internal - macros or typedefs, and the corresponding xfails removed. +/* These next definitions are kludges. When GCC has a it + should be used. */ -typedef long long int intmax_t; -typedef unsigned long long int uintmax_t; +#include +#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 198b7fb8335..784943849a2 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 -- 2.30.2