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