Diagnose decimal integer constants too large for intmax_t
Joseph S. Myers
joseph@codesourcery.com
Sat Apr 25 18:56:00 GMT 2009
This patch fixes PR preprocessor/39559 by making decimal integer
constants within the range of uintmax_t but not that of intmax_t,
without a "u" or "U" suffix, result in a pedwarn in C99 mode. See the
comment added for further discussion.
Bootstrapped with no regressions on i686-pc-linux-gnu and
x86_64-unknown-linux-gnu. Applied to mainline.
libcpp:
2009-04-25 Joseph Myers <joseph@codesourcery.com>
PR preprocessor/39559
* expr.c (cpp_interpret_integer): Use a pedwarn for decimal
constants larger than intmax_t in C99 mode.
gcc/testsuite:
2009-04-25 Joseph Myers <joseph@codesourcery.com>
PR preprocessor/39559
* gcc.dg/c99-intconst-2.c: New test.
Index: gcc/testsuite/gcc.dg/c99-intconst-2.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-intconst-2.c (revision 0)
+++ gcc/testsuite/gcc.dg/c99-intconst-2.c (revision 0)
@@ -0,0 +1,8 @@
+/* Test for integer constant types: diagnostics for constants outside
+ range of intmax_t must be pedwarns. PR 39559. */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+#if 9223372036854775808LL /* { dg-error "integer constant is so large that it is unsigned" } */
+unsigned long long l = 9223372036854775808LL; /* { dg-error "integer constant is so large that it is unsigned" } */
+#endif
Index: libcpp/expr.c
===================================================================
--- libcpp/expr.c (revision 146747)
+++ libcpp/expr.c (working copy)
@@ -538,8 +538,27 @@ cpp_interpret_integer (cpp_reader *pfile
&& pfile->state.in_directive)
&& !num_positive (result, precision))
{
+ /* This is for constants within the range of uintmax_t but
+ not that or intmax_t. For such decimal constants, a
+ diagnostic is required for C99 as the selected type must
+ be signed and not having a type is a constraint violation
+ (DR#298, TC3), so this must be a pedwarn. For C90,
+ unsigned long is specified to be used for a constant that
+ does not fit in signed long; if uintmax_t has the same
+ range as unsigned long this means only a warning is
+ appropriate here. C90 permits the preprocessor to use a
+ wider range than unsigned long in the compiler, so if
+ uintmax_t is wider than unsigned long no diagnostic is
+ required for such constants in preprocessor #if
+ expressions and the compiler will pedwarn for such
+ constants outside the range of unsigned long that reach
+ the compiler so a diagnostic is not required there
+ either; thus, pedwarn for C99 but use a plain warning for
+ C90. */
if (base == 10)
- cpp_error (pfile, CPP_DL_WARNING,
+ cpp_error (pfile, (CPP_OPTION (pfile, c99)
+ ? CPP_DL_PEDWARN
+ : CPP_DL_WARNING),
"integer constant is so large that it is unsigned");
result.unsignedp = true;
}
--
Joseph S. Myers
joseph@codesourcery.com
More information about the Gcc-patches
mailing list