https://gcc.gnu.org/g:44c9403ed1833ae71a59e84f9e37af3182be0df5

commit r15-2026-g44c9403ed1833ae71a59e84f9e37af3182be0df5
Author: Alejandro Colomar <a...@kernel.org>
Date:   Sat Jun 29 15:10:43 2024 +0200

    c, objc: Add -Wunterminated-string-initialization
    
    Warn about the following:
    
        char  s[3] = "foo";
    
    Initializing a char array with a string literal of the same length as
    the size of the array is usually a mistake.  Rarely is the case where
    one wants to create a non-terminated character sequence from a string
    literal.
    
    In some cases, for writing faster code, one may want to use arrays
    instead of pointers, since that removes the need for storing an array of
    pointers apart from the strings themselves.
    
        char  *log_levels[]   = { "info", "warning", "err" };
    vs.
        char  log_levels[][7] = { "info", "warning", "err" };
    
    This forces the programmer to specify a size, which might change if a
    new entry is later added.  Having no way to enforce null termination is
    very dangerous, however, so it is useful to have a warning for this, so
    that the compiler can make sure that the programmer didn't make any
    mistakes.  This warning catches the bug above, so that the programmer
    will be able to fix it and write:
    
        char  log_levels[][8] = { "info", "warning", "err" };
    
    This warning already existed as part of -Wc++-compat, but this patch
    allows enabling it separately.  It is also included in -Wextra, since
    it may not always be desired (when unterminated character sequences are
    wanted), but it's likely to be desired in most cases.
    
    Since Wc++-compat now includes this warning, the test has to be modified
    to expect the text of the new warning too, in <gcc.dg/Wcxx-compat-14.c>.
    
    Link: https://lists.gnu.org/archive/html/groff/2022-11/msg00059.html
    Link: https://lists.gnu.org/archive/html/groff/2022-11/msg00063.html
    Link: 
https://inbox.sourceware.org/gcc/36da94eb-1cac-5ae8-7fea-ec66160cf...@gmail.com/T/
    
            PR c/115185
    
    gcc/c-family/ChangeLog:
    
            * c.opt: Add -Wunterminated-string-initialization.
    
    gcc/c/ChangeLog:
    
            * c-typeck.cc (digest_init): Separate warnings about character
            arrays being initialized as unterminated character sequences
            with string literals, from -Wc++-compat, into a new warning,
            -Wunterminated-string-initialization.
    
    gcc/ChangeLog:
    
            * doc/invoke.texi: Document the new
            -Wunterminated-string-initialization.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/Wcxx-compat-14.c: Adapt the test to match the new text
            of the warning, which doesn't say anything about C++ anymore.
            * gcc.dg/Wunterminated-string-initialization.c: New test.
    
    Acked-by: Doug McIlroy <douglas.mcil...@dartmouth.edu>
    Acked-by: Mike Stump <mikest...@comcast.net>
    Reviewed-by: Sandra Loosemore <sloosem...@baylibre.com>
    Reviewed-by: Martin Uecker <uec...@tugraz.at>
    Signed-off-by: Alejandro Colomar <a...@kernel.org>
    Reviewed-by: Marek Polacek <pola...@redhat.com>

Diff:
---
 gcc/c-family/c.opt                                   |  4 ++++
 gcc/c/c-typeck.cc                                    |  6 +++---
 gcc/doc/invoke.texi                                  | 20 +++++++++++++++++++-
 gcc/testsuite/gcc.dg/Wcxx-compat-14.c                |  2 +-
 .../gcc.dg/Wunterminated-string-initialization.c     |  6 ++++++
 5 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 5c1006ff321f..a52682d835ce 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1464,6 +1464,10 @@ Wunsuffixed-float-constants
 C ObjC Var(warn_unsuffixed_float_constants) Warning
 Warn about unsuffixed float constants.
 
+Wunterminated-string-initialization
+C ObjC Var(warn_unterminated_string_initialization) Warning LangEnabledBy(C 
ObjC,Wextra || Wc++-compat)
+Warn about character arrays initialized as unterminated character sequences 
with a string literal.
+
 Wunused
 C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall)
 ; documented in common.opt
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 574114d541fd..7e0f01ed22b9 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8878,11 +8878,11 @@ digest_init (location_t init_loc, tree type, tree init, 
tree origtype,
                pedwarn_init (init_loc, 0,
                              ("initializer-string for array of %qT "
                               "is too long"), typ1);
-             else if (warn_cxx_compat
+             else if (warn_unterminated_string_initialization
                       && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
-               warning_at (init_loc, OPT_Wc___compat,
+               warning_at (init_loc, OPT_Wunterminated_string_initialization,
                            ("initializer-string for array of %qT "
-                            "is too long for C++"), typ1);
+                            "is too long"), typ1);
              if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
                {
                  unsigned HOST_WIDE_INT size
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d544984ce7cf..403ea9da1abd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -415,7 +415,9 @@ Objective-C and Objective-C++ Dialects}.
 -Wsystem-headers  -Wtautological-compare  -Wtrampolines  -Wtrigraphs
 -Wtrivial-auto-var-init  -Wno-tsan  -Wtype-limits  -Wundef
 -Wuninitialized  -Wunknown-pragmas
--Wunsuffixed-float-constants  -Wunused
+-Wunsuffixed-float-constants
+-Wunterminated-string-initialization
+-Wunused
 -Wunused-but-set-parameter  -Wunused-but-set-variable
 -Wunused-const-variable  -Wunused-const-variable=@var{n}
 -Wunused-function  -Wunused-label  -Wunused-local-typedefs
@@ -6496,6 +6498,7 @@ name is still supported, but the newer name is more 
descriptive.)
 -Wstring-compare
 -Wtype-limits
 -Wuninitialized
+-Wunterminated-string-initialization
 -Wunused-parameter @r{(only with} @option{-Wunused} @r{or} @option{-Wall}@r{)}
 -Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} 
@option{-Wall}@r{)}}
 
@@ -8664,6 +8667,21 @@ arithmetic that may yield out of bounds values. This 
warning level may
 give a larger number of false positives and is deactivated by default.
 @end table
 
+@opindex Wunterminated-string-initialization
+@opindex Wno-unterminated-string-initialization
+@item -Wunterminated-string-initialization @r{(C and Objective-C only)}
+Warn about character arrays
+initialized as unterminated character sequences
+with a string literal.
+For example:
+
+@smallexample
+char arr[3] = "foo";
+@end smallexample
+
+This warning is enabled by @option{-Wextra} and @option{-Wc++-compat}.
+In C++, such initializations are an error.
+
 @opindex Warray-compare
 @opindex Wno-array-compare
 @item -Warray-compare
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c 
b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
index 23783711be66..6df0ee197cca 100644
--- a/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-14.c
@@ -2,5 +2,5 @@
 /* { dg-options "-Wc++-compat" } */
 
 char a1[] = "a";
-char a2[1] = "a";      /* { dg-warning "C\[+\]\[+\]" } */
+char a2[1] = "a";      /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
 char a3[2] = "a";
diff --git a/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c 
b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
new file mode 100644
index 000000000000..13d5dbc66400
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunterminated-string-initialization" } */
+
+char a1[] = "a";
+char a2[1] = "a";      /* { dg-warning "initializer-string for array of 'char' 
is too long" } */
+char a3[2] = "a";

Reply via email to