This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

-Woverlength-strings redux (committed now)


This is a slightly revised patch incorporating the suggestions from the
previous thread.  Also, the test cases all actually pass (shame on me for
posting the original patch before running the testsuite) and I dropped out
the attempt to squelch warnings for gengtype-lex.c as it seems this is more
complicated than I had thought.

I went ahead and checked this in per Bernd's preapproval.

zw

gcc:
	* c.opt: Add -W(no-)overlength-strings.
	* doc/invoke.texi: Document it.
	* c-opts.c (c_common_handle_option): -pedantic implies
	-Woverlength-strings, if not explicitly disabled already.
	(c_common_post_options): -Woverlength-strings defaults to off, and
	is always off for C++.
	* c-common.c (fix_string_type): Issue warning about strings longer
	than is portable only if warn_overlength_strings.  Rearrange code
	a little for clarity.
	* configure.in: Check for -Wno-overlength-strings as well before
	enabling -pedantic in stage 1.
	* Makefile.in (STRICT2_WARN): Add -Wno-overlength-strings.
	(gcc.o-warn, insn-automata.o-warn, build/gencondmd.o-warn): Delete.

	* genconditions.c (write_header, write_one_condition)
	(write_conditions, write_writer): Consolidate very long strings
	that were broken up to fit in C89 portable limit.  Don't use
	printf when fputs will do.

gcc/testsuite:
	* gcc.dg/Woverlength-strings.c
	* gcc.dg/Woverlength-strings-pedantic-c89.c
	* gcc.dg/Woverlength-strings-pedantic-c89-no.c
	* gcc.dg/Woverlength-strings-pedantic-c99.c
	* gcc.dg/Woverlength-strings-pedantic-c99-no.c: New tests.

==================================================================
--- Makefile.in	(revision 110396)
+++ Makefile.in	(local)
@@ -177,7 +177,8 @@ LOOSE_WARN = -W -Wall -Wwrite-strings -W
 STRICT_WARN = @strict1_warn@
 WERROR_FLAGS = @WERROR@
 STRICT2_WARN = -pedantic -Wno-long-long -Wno-variadic-macros \
-  -Wold-style-definition -Wmissing-format-attribute $(WERROR_FLAGS)
+  -Wno-overlength-strings -Wold-style-definition -Wmissing-format-attribute \
+  $(WERROR_FLAGS)
 
 # This is set by --enable-checking.  The idea is to catch forgotten
 # "extern" tags in header files.
@@ -195,11 +196,8 @@ VALGRIND_DRIVER_DEFINES = @valgrind_path
 build-warn = $(STRICT_WARN)
 GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn)
 
-# These files are to have -Werror bypassed in stage2:
-# These are very hard to completely clean due to target complexities.
-gcc.o-warn = -Wno-error
-insn-automata.o-warn = -Wno-error
-build/gencondmd.o-warn = -Wno-error
+# These files are to have specific diagnostics suppressed, or are not to
+# be subject to -Werror:
 # Bison-1.75 output often yields (harmless) -Wtraditional warnings
 build/gengtype-yacc.o-warn = -Wno-error
 # flex output may yield harmless "no previous prototype" warnings
==================================================================
--- c-common.c	(revision 110396)
+++ c-common.c	(local)
@@ -844,7 +844,6 @@ fix_string_type (tree value)
 {
   const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
   const int wide_flag = TREE_TYPE (value) == wchar_array_type_node;
-  const int nchars_max = flag_isoc99 ? 4095 : 509;
   int length = TREE_STRING_LENGTH (value);
   int nchars;
   tree e_type, i_type, a_type;
@@ -852,11 +851,24 @@ fix_string_type (tree value)
   /* Compute the number of elements, for the array type.  */
   nchars = wide_flag ? length / wchar_bytes : length;
 
-  if (pedantic && nchars - 1 > nchars_max && !c_dialect_cxx ())
-    pedwarn ("string length %qd is greater than the length %qd ISO C%d compilers are required to support",
-	     nchars - 1, nchars_max, flag_isoc99 ? 99 : 89);
+  /* C89 2.2.4.1, C99 5.2.4.1 (Translation limits).  The analogous
+     limit in C++98 Annex B is very large (65536) and is not normative,
+     so we do not diagnose it (warn_overlength_strings is forced off
+     in c_common_post_options).  */
+  if (warn_overlength_strings)
+    {
+      const int nchars_max = flag_isoc99 ? 4095 : 509;
+      const int relevant_std = flag_isoc99 ? 99 : 90;
+      if (nchars - 1 > nchars_max)
+	/* Translators: The %d after 'ISO C' will be 90 or 99.  Do not
+	   separate the %d from the 'C'.  'ISO' should not be
+	   translated, but it may be moved after 'C%d' in languages
+	   where modifiers follow nouns.  */
+	pedwarn ("string length %qd is greater than the length %qd "
+		 "ISO C%d compilers are required to support",
+		 nchars - 1, nchars_max, relevant_std);
+    }
 
-  e_type = wide_flag ? wchar_type_node : char_type_node;
   /* Create the array type for the string constant.  flag_const_strings
      says make the string constant an array of const char so that
      copying it to a non-const pointer will get a warning.  For C++,
@@ -868,6 +880,7 @@ fix_string_type (tree value)
      construct the matching unqualified array type first.  The C front
      end does not require this, but it does no harm, so we do it
      unconditionally.  */
+  e_type = wide_flag ? wchar_type_node : char_type_node;
   i_type = build_index_type (build_int_cst (NULL_TREE, nchars - 1));
   a_type = build_array_type (e_type, i_type);
   if (flag_const_strings)
==================================================================
--- c-opts.c	(revision 110396)
+++ c-opts.c	(local)
@@ -893,6 +893,8 @@ c_common_handle_option (size_t scode, co
       cpp_opts->warn_endif_labels = 1;
       if (warn_pointer_sign == -1)
 	warn_pointer_sign = 1;
+      if (warn_overlength_strings == -1)
+	warn_overlength_strings = 1;
       break;
 
     case OPT_print_objc_runtime_info:
@@ -1018,6 +1020,12 @@ c_common_post_options (const char **pfil
   if (warn_pointer_sign == -1)
     warn_pointer_sign = 0;
 
+  /* -Woverlength-strings is off by default, but is enabled by -pedantic.
+     It is never enabled in C++, as the minimum limit is not normative
+     in that standard.  */
+  if (warn_overlength_strings == -1 || c_dialect_cxx ())
+    warn_overlength_strings = 0;
+
   /* Special format checking options don't work without -Wformat; warn if
      they are used.  */
   if (!warn_format)
==================================================================
--- c.opt	(revision 110396)
+++ c.opt	(local)
@@ -311,6 +311,10 @@ Wold-style-definition
 C ObjC Var(warn_old_style_definition)
 Warn if an old-style parameter definition is used
 
+Woverlength-strings
+C ObjC C++ ObjC++ Var(warn_overlength_strings) Init(-1)
+Warn if a string is longer than the maximum portable length specified by the standard
+
 Woverloaded-virtual
 C++ ObjC++ Var(warn_overloaded_virtual)
 Warn about overloaded virtual function names
==================================================================
--- configure.ac	(revision 110396)
+++ configure.ac	(local)
@@ -301,6 +301,7 @@ AC_CHECK_TYPES([__int64], [AC_CHECK_SIZE
 # We want to use -pedantic, but we don't want warnings about
 # * 'long long'
 # * variadic macros
+# * overlong strings
 # So, we only use -pedantic if we can disable those warnings.
 
 AC_CACHE_CHECK(
@@ -325,10 +326,22 @@ AC_CACHE_CHECK(
   CFLAGS="$save_CFLAGS"
   ])
 
+AC_CACHE_CHECK(
+  [whether ${CC} accepts -Wno-overlength-strings],
+  [ac_cv_prog_cc_w_no_overlength_strings],
+  [save_CFLAGS="$CFLAGS"
+  CFLAGS="-Wno-overlength-strings"
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])],
+                    [ac_cv_prog_cc_w_no_overlength_strings=yes],
+                    [ac_cv_prog_cc_w_no_overlength_strings=no])
+  CFLAGS="$save_CFLAGS"
+  ])
+
 strict1_warn=
 if test $ac_cv_prog_cc_w_no_long_long = yes \
-   && test $ac_cv_prog_cc_w_no_variadic_macros = yes ; then
-  strict1_warn="-pedantic -Wno-long-long -Wno-variadic-macros"
+   && test $ac_cv_prog_cc_w_no_variadic_macros = yes \
+   && test $ac_cv_prog_cc_w_no_overlength_strings = yes ; then
+  strict1_warn="-pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings"
 fi
 
 # Add -Wold-style-definition if it's accepted
==================================================================
--- doc/invoke.texi	(revision 110396)
+++ doc/invoke.texi	(local)
@@ -238,7 +238,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wmain  -Wmissing-braces  -Wmissing-field-initializers @gol
 -Wmissing-format-attribute  -Wmissing-include-dirs @gol
 -Wmissing-noreturn @gol
--Wno-multichar  -Wnonnull  -Wpacked  -Wpadded @gol
+-Wno-multichar  -Wnonnull  -Woverlength-strings  -Wpacked  -Wpadded @gol
 -Wparentheses  -Wpointer-arith  -Wno-pointer-to-int-cast @gol
 -Wredundant-decls @gol
 -Wreturn-type  -Wsequence-point  -Wshadow @gol
@@ -3444,6 +3444,21 @@ even when intentional, result in unspeci
 Usually these warnings alert that the programmer intended to use
 @code{strcmp}.  This warning is enabled by @option{-Wall}.
 
+@item -Woverlength-strings
+@opindex Woverlength-strings
+Warn about string constants which are longer than the ``minimum
+maximum'' length specified in the C standard.  Modern compilers
+generally allow string constants which are much longer than the
+standard's minimum limit, but very portable programs should avoid
+using longer strings.
+
+The limit applies @emph{after} string constant concatenation, and does
+not count the trailing NUL@.  In C89, the limit was 509 characters; in
+C99, it was raised to 4095.  C++98 does not specify a normative
+minimum maximum, so we do not diagnose overlength strings in C++@.
+
+This option is implied by @option{-pedantic}, and can be disabled with
+@option{-Wno-overlength-strings}.
 @end table
 
 @node Debugging Options
==================================================================
--- genconditions.c	(revision 110396)
+++ genconditions.c	(local)
@@ -52,9 +52,8 @@ write_header (void)
    machine description file.  */\n\
 \n\
 #include \"bconfig.h\"\n\
-#include \"system.h\"\n");
-
-  puts ("\
+#include \"system.h\"\n\
+\n\
 /* It is necessary, but not entirely safe, to include the headers below\n\
    in a generator program.  As a defensive measure, don't do so when the\n\
    table isn't going to have anything in it.  */\n\
@@ -66,23 +65,20 @@ write_header (void)
 #undef ENABLE_RTL_CHECKING\n\
 #undef ENABLE_RTL_FLAG_CHECKING\n\
 #undef ENABLE_GC_CHECKING\n\
-#undef ENABLE_GC_ALWAYS_COLLECT\n");
-
-  puts ("\
+#undef ENABLE_GC_ALWAYS_COLLECT\n\
+\n\
 #include \"coretypes.h\"\n\
 #include \"tm.h\"\n\
 #include \"insn-constants.h\"\n\
 #include \"rtl.h\"\n\
 #include \"tm_p.h\"\n\
-#include \"function.h\"\n");
-
-  puts ("\
+#include \"function.h\"\n\
+\n\
 /* Fake - insn-config.h doesn't exist yet.  */\n\
 #define MAX_RECOG_OPERANDS 10\n\
 #define MAX_DUP_OPERANDS 10\n\
-#define MAX_INSNS_PER_SPLIT 5\n");
-
-  puts ("\
+#define MAX_INSNS_PER_SPLIT 5\n\
+\n\
 #include \"regs.h\"\n\
 #include \"recog.h\"\n\
 #include \"real.h\"\n\
@@ -134,11 +130,11 @@ write_one_condition (void **slot, void *
       putchar (*p);
     }
 
-  printf ("\",\n    __builtin_constant_p ");
+  fputs ("\",\n    __builtin_constant_p ", stdout);
   print_c_condition (test->expr);
-  printf ("\n    ? (int) ");
+  fputs ("\n    ? (int) ", stdout);
   print_c_condition (test->expr);
-  printf ("\n    : -1 },\n");
+  fputs ("\n    : -1 },\n", stdout);
   return 1;
 }
 
@@ -154,9 +150,8 @@ struct c_test\n\
 {\n\
   const char *expr;\n\
   int value;\n\
-};\n");
-
-  puts ("\
+};\n\
+\n\
 /* This table lists each condition found in the machine description.\n\
    Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
    cannot be calculated at compile time.\n\
@@ -200,8 +195,8 @@ write_writer (void)
 	"          putchar (*p);\n"
 	"        }\n"
         "      puts (\"\\\")\");\n"
-        "    }");
-  puts ("  puts (\"])\");\n"
+        "    }\n"
+	"  puts (\"])\");\n"
         "  fflush (stdout);\n"
         "return ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;\n"
 	"}");
==================================================================
--- testsuite/gcc.dg/Woverlength-strings-pedantic-c89-no.c	(revision 110396)
+++ testsuite/gcc.dg/Woverlength-strings-pedantic-c89-no.c	(local)
@@ -0,0 +1,19 @@
+/* -Woverlength-strings complains about string constants which are too long
+   for the C standard's "minimum maximum" limits.  It is off by default,
+   but implied by -pedantic.  */
+
+/* { dg-options "-std=c89 -pedantic -Wno-overlength-strings" } */
+
+#define TEN "xxxxxxxxxx"
+#define HUN TEN TEN TEN TEN TEN  TEN TEN TEN TEN TEN
+#define THO HUN HUN HUN HUN HUN  HUN HUN HUN HUN HUN
+
+/* C89's minimum-maximum is 509. */
+const char x510[] = HUN HUN HUN HUN HUN TEN;
+
+/* C99's minimum-maximum is 4095.  */
+const char x4096[] =
+  THO THO THO THO     /* 4000 */
+  TEN TEN TEN TEN TEN /* 4050 */
+  TEN TEN TEN TEN     /* 4090 */
+  "123456";
==================================================================
--- testsuite/gcc.dg/Woverlength-strings-pedantic-c89.c	(revision 110396)
+++ testsuite/gcc.dg/Woverlength-strings-pedantic-c89.c	(local)
@@ -0,0 +1,19 @@
+/* -Woverlength-strings complains about string constants which are too long
+   for the C standard's "minimum maximum" limits.  It is off by default,
+   but implied by -pedantic.  */
+
+/* { dg-options "-std=c89 -pedantic" } */
+
+#define TEN "xxxxxxxxxx"
+#define HUN TEN TEN TEN TEN TEN  TEN TEN TEN TEN TEN
+#define THO HUN HUN HUN HUN HUN  HUN HUN HUN HUN HUN
+
+/* C89's minimum-maximum is 509. */
+const char x510[] = HUN HUN HUN HUN HUN TEN; /* { dg-warning "greater than" } */
+
+/* C99's minimum-maximum is 4095.  */
+const char x4096[] =
+  THO THO THO THO     /* 4000 */
+  TEN TEN TEN TEN TEN /* 4050 */
+  TEN TEN TEN TEN     /* 4090 */
+  "123456";  /* { dg-warning "greater than" } */
==================================================================
--- testsuite/gcc.dg/Woverlength-strings-pedantic-c99-no.c	(revision 110396)
+++ testsuite/gcc.dg/Woverlength-strings-pedantic-c99-no.c	(local)
@@ -0,0 +1,19 @@
+/* -Woverlength-strings complains about string constants which are too long
+   for the C standard's "minimum maximum" limits.  It is off by default,
+   but implied by -pedantic.  */
+
+/* { dg-options "-std=c99 -pedantic -Wno-overlength-strings" } */
+
+#define TEN "xxxxxxxxxx"
+#define HUN TEN TEN TEN TEN TEN  TEN TEN TEN TEN TEN
+#define THO HUN HUN HUN HUN HUN  HUN HUN HUN HUN HUN
+
+/* C89's minimum-maximum is 509. */
+const char x510[] = HUN HUN HUN HUN HUN TEN;
+
+/* C99's minimum-maximum is 4095.  */
+const char x4096[] =
+  THO THO THO THO     /* 4000 */
+  TEN TEN TEN TEN TEN /* 4050 */
+  TEN TEN TEN TEN     /* 4090 */
+  "123456";
==================================================================
--- testsuite/gcc.dg/Woverlength-strings-pedantic-c99.c	(revision 110396)
+++ testsuite/gcc.dg/Woverlength-strings-pedantic-c99.c	(local)
@@ -0,0 +1,19 @@
+/* -Woverlength-strings complains about string constants which are too long
+   for the C standard's "minimum maximum" limits.  It is off by default,
+   but implied by -pedantic.  */
+
+/* { dg-options "-std=c99 -pedantic" } */
+
+#define TEN "xxxxxxxxxx"
+#define HUN TEN TEN TEN TEN TEN  TEN TEN TEN TEN TEN
+#define THO HUN HUN HUN HUN HUN  HUN HUN HUN HUN HUN
+
+/* C89's minimum-maximum is 509. */
+const char x510[] = HUN HUN HUN HUN HUN TEN;
+
+/* C99's minimum-maximum is 4095.  */
+const char x4096[] =
+  THO THO THO THO     /* 4000 */
+  TEN TEN TEN TEN TEN /* 4050 */
+  TEN TEN TEN TEN     /* 4090 */
+  "123456";  /* { dg-warning "greater than" } */
==================================================================
--- testsuite/gcc.dg/Woverlength-strings.c	(revision 110396)
+++ testsuite/gcc.dg/Woverlength-strings.c	(local)
@@ -0,0 +1,19 @@
+/* -Woverlength-strings complains about string constants which are too long
+   for the C standard's "minimum maximum" limits.  It is off by default,
+   but implied by -pedantic.  */
+
+/* { dg-options "" } */
+
+#define TEN "xxxxxxxxxx"
+#define HUN TEN TEN TEN TEN TEN  TEN TEN TEN TEN TEN
+#define THO HUN HUN HUN HUN HUN  HUN HUN HUN HUN HUN
+
+/* C89's minimum-maximum is 509. */
+const char x510[] = HUN HUN HUN HUN HUN TEN;
+
+/* C99's minimum-maximum is 4095.  */
+const char x4096[] =
+  THO THO THO THO     /* 4000 */
+  TEN TEN TEN TEN TEN /* 4050 */
+  TEN TEN TEN TEN     /* 4090 */
+  "123456";


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]