* [FFmpeg-devel] [PR] configure: Enable -Wunterminated-string-initialization warning (PR #21387)
@ 2026-01-05 22:49 mkver via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: mkver via ffmpeg-devel @ 2026-01-05 22:49 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: mkver
PR #21387 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21387
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21387.patch
>From 77d51affd0ae2bddb84f962793e6cc676bd879de Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 5 Jan 2026 21:31:28 +0100
Subject: [PATCH 1/4] configure: Use per-language unknown-warnings-flags
E.g. when CC is clang, the unknown warnings flags
are -Werror=unused-command-line-argument and
-Werror=unknown-warning-option. These flags are currently
also used for testing the C++ and ObjC compilers, yet
g++ does not recognize these flags and errors out because
of them, so that the tests fail and the parentheses,
switch etc. warnings are not disabled for C++.
Fix this by using per-language flags.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
configure | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/configure b/configure
index 38cbfd3d1b..0ea64fc039 100755
--- a/configure
+++ b/configure
@@ -7705,6 +7705,13 @@ fi
enabled debug && add_allcflags -g"$debuglevel" && add_asflags -g"$debuglevel"
+for lang in c cxx objc; do
+ test_${lang}flags -Werror=unused-command-line-argument &&
+ append unknown_warning_${lang}flags "-Werror=unused-command-line-argument"
+ test_${lang}flags -Werror=unknown-warning-option &&
+ append unknown_warning_${lang}flags "-Werror=unknown-warning-option"
+done
+
# add some useful compiler flags if supported
check_allcflags -Wall
check_allcflags -Wdisabled-optimization
@@ -7725,16 +7732,11 @@ fi
check_disable_warning(){
warning_flag=-W${1#-Wno-}
- test_cflags $unknown_warning_flags $warning_flag && add_cflags $1
- test_cxxflags -Werror $unknown_warning_flags $warning_flag && add_cxxflags $1
- test_objcflags $unknown_warning_flags $warning_flag && add_objcflags $1
+ test_cflags $unknown_warning_cflags $warning_flag && add_cflags $1
+ test_cxxflags -Werror $unknown_warning_cxxflags $warning_flag && add_cxxflags $1
+ test_objcflags $unknown_warning_objcflags $warning_flag && add_objcflags $1
}
-test_cflags -Werror=unused-command-line-argument &&
- append unknown_warning_flags "-Werror=unused-command-line-argument"
-test_cflags -Werror=unknown-warning-option &&
- append unknown_warning_flags "-Werror=unknown-warning-option"
-
check_disable_warning -Wno-parentheses
check_disable_warning -Wno-switch
check_disable_warning -Wno-format-zero-length
--
2.49.1
>From 8c10ab8f7d841758f712bdd125931bccbb8f2e5e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 5 Jan 2026 18:54:42 +0100
Subject: [PATCH 2/4] configure: Make check for accepting warnings stricter
Clang by default allows unknown warnings and merely emits
a Wunknown-warning-option warning which is non-fatal by default,
making it appear as if Clang supported any warning. This patch
rewrites the tests to always add the arguments to error out
in case an unrecognized option is encountered.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
configure | 53 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 32 insertions(+), 21 deletions(-)
diff --git a/configure b/configure
index 0ea64fc039..6833997621 100755
--- a/configure
+++ b/configure
@@ -7712,31 +7712,42 @@ for lang in c cxx objc; do
append unknown_warning_${lang}flags "-Werror=unknown-warning-option"
done
-# add some useful compiler flags if supported
-check_allcflags -Wall
-check_allcflags -Wdisabled-optimization
-check_allcflags -Wpointer-arith
-check_allcflags -Wredundant-decls
-check_allcflags -Wwrite-strings
-check_allcflags -Wtype-limits
-check_allcflags -Wundef
-check_allcflags -Wempty-body
-check_cflags -Wmissing-prototypes
-check_cflags -Wstrict-prototypes
-
-if enabled extra_warnings; then
- check_allcflags -Wcast-qual
- check_allcflags -Wextra
- check_allcflags -Wpedantic
-fi
+check_warning(){
+ warning_flag=$1
+ flag_to_add=${2:-$1}
+ test_cflags $unknown_warning_cflags $warning_flag && add_cflags $flag_to_add
+ test_cxxflags -Werror $unknown_warning_cxxflags $warning_flag && add_cxxflags $flag_to_add
+ test_objcflags $unknown_warning_objcflags $warning_flag && add_objcflags $flag_to_add
+}
check_disable_warning(){
warning_flag=-W${1#-Wno-}
- test_cflags $unknown_warning_cflags $warning_flag && add_cflags $1
- test_cxxflags -Werror $unknown_warning_cxxflags $warning_flag && add_cxxflags $1
- test_objcflags $unknown_warning_objcflags $warning_flag && add_objcflags $1
+ check_warning $warning_flag $1
}
+check_c_warning(){
+ warning_flag=$1
+ test_cflags $unknown_warning_cflags $warning_flag && add_cflags $warning_flag
+}
+
+# add some useful compiler flags if supported
+check_warning -Wall
+check_warning -Wdisabled-optimization
+check_warning -Wpointer-arith
+check_warning -Wredundant-decls
+check_warning -Wwrite-strings
+check_warning -Wtype-limits
+check_warning -Wundef
+check_warning -Wempty-body
+check_c_warning -Wmissing-prototypes
+check_c_warning -Wstrict-prototypes
+
+if enabled extra_warnings; then
+ check_warning -Wcast-qual
+ check_warning -Wextra
+ check_warning -Wpedantic
+fi
+
check_disable_warning -Wno-parentheses
check_disable_warning -Wno-switch
check_disable_warning -Wno-format-zero-length
@@ -7749,7 +7760,7 @@ check_disable_warning -Wno-microsoft-enum-forward-reference
check_disable_warning_headers(){
warning_flag=-W${1#-Wno-}
- test_cflags $warning_flag && add_cflags_headers $1
+ test_cflags $unknown_warning_cflags $warning_flag && add_cflags_headers $1
}
check_disable_warning_headers -Wno-deprecated-declarations
--
2.49.1
>From f4ba0f457978f70666c24fbc5601a95d68e244e9 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 5 Jan 2026 17:24:44 +0100
Subject: [PATCH 3/4] avutil/attributes_internal: Add attribute_nonstring
This attribute is used to signal to the compiler
that an array object initialized via a string literal
is not a real string and may lack the space for
the trailing zero, as in char fourcc[4]="FOUR".
This is in preparation for enabling
the -Wunterminated-string-initialization warning.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/gif.h | 6 ++++--
libavformat/amr.c | 9 +++++----
libavformat/concatdec.c | 3 ++-
libavformat/id3v2.c | 7 ++++---
libavformat/mccdec.c | 3 ++-
libavutil/attributes_internal.h | 19 +++++++++++++++++++
libavutil/error.c | 3 ++-
libavutil/uuid.c | 3 ++-
8 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/libavcodec/gif.h b/libavcodec/gif.h
index 7fb61495bc..7848b8876e 100644
--- a/libavcodec/gif.h
+++ b/libavcodec/gif.h
@@ -31,8 +31,10 @@
#include <stdint.h>
-static const uint8_t gif87a_sig[6] = "GIF87a";
-static const uint8_t gif89a_sig[6] = "GIF89a";
+#include "libavutil/attributes_internal.h"
+
+static attribute_nonstring const uint8_t gif87a_sig[6] = "GIF87a";
+static attribute_nonstring const uint8_t gif89a_sig[6] = "GIF89a";
#define GCE_DISPOSAL_NONE 0
#define GCE_DISPOSAL_INPLACE 1
diff --git a/libavformat/amr.c b/libavformat/amr.c
index 9cc61baf55..e825121af3 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -25,6 +25,7 @@ Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.tx
#include "config_components.h"
+#include "libavutil/attributes_internal.h"
#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
@@ -39,10 +40,10 @@ typedef struct AMRContext {
FFRawDemuxerContext rawctx;
} AMRContext;
-static const uint8_t AMR_header[6] = "#!AMR\x0a";
-static const uint8_t AMRMC_header[12] = "#!AMR_MC1.0\x0a";
-static const uint8_t AMRWB_header[9] = "#!AMR-WB\x0a";
-static const uint8_t AMRWBMC_header[15] = "#!AMR-WB_MC1.0\x0a";
+static attribute_nonstring const uint8_t AMR_header[6] = "#!AMR\x0a";
+static attribute_nonstring const uint8_t AMRMC_header[12] = "#!AMR_MC1.0\x0a";
+static attribute_nonstring const uint8_t AMRWB_header[9] = "#!AMR-WB\x0a";
+static attribute_nonstring const uint8_t AMRWBMC_header[15] = "#!AMR-WB_MC1.0\x0a";
static const uint8_t amrnb_packed_size[16] = {
13, 14, 16, 18, 20, 21, 27, 32, 6, 1, 1, 1, 1, 1, 1, 1
diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index e0c2c87248..c57d1b649a 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -18,6 +18,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "libavutil/attributes_internal.h"
#include "libavutil/avstring.h"
#include "libavutil/avassert.h"
#include "libavutil/bprint.h"
@@ -419,7 +420,7 @@ static int concat_read_close(AVFormatContext *avf)
typedef struct ParseSyntax {
const char *keyword;
- char args[MAX_ARGS];
+ attribute_nonstring char args[MAX_ARGS];
uint8_t flags;
} ParseSyntax;
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 98969c67a0..5fc82ad9dc 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -32,6 +32,7 @@
#include <zlib.h>
#endif
+#include "libavutil/attributes_internal.h"
#include "libavutil/avstring.h"
#include "libavutil/bprint.h"
#include "libavutil/dict.h"
@@ -87,7 +88,7 @@ static const AVMetadataConv id3v2_2_metadata_conv[] = {
{ 0 }
};
-const char ff_id3v2_tags[][4] = {
+attribute_nonstring const char ff_id3v2_tags[][4] = {
"TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
"TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
"TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
@@ -95,13 +96,13 @@ const char ff_id3v2_tags[][4] = {
{ 0 },
};
-const char ff_id3v2_4_tags[][4] = {
+attribute_nonstring const char ff_id3v2_4_tags[][4] = {
"TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
"TPRO", "TSOA", "TSOP", "TSOT", "TSST",
{ 0 },
};
-const char ff_id3v2_3_tags[][4] = {
+attribute_nonstring const char ff_id3v2_3_tags[][4] = {
"TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
{ 0 },
};
diff --git a/libavformat/mccdec.c b/libavformat/mccdec.c
index e9b6fa14b4..4384704f32 100644
--- a/libavformat/mccdec.c
+++ b/libavformat/mccdec.c
@@ -26,6 +26,7 @@
#include "libavcodec/bytestream.h"
#include "libavcodec/codec_id.h"
#include "libavcodec/smpte_436m.h"
+#include "libavutil/attributes_internal.h"
#include "libavutil/avstring.h"
#include "libavutil/avutil.h"
#include "libavutil/error.h"
@@ -84,7 +85,7 @@ typedef struct alias {
#define CCPAD "\xFA\x0\x0"
#define CCPAD3 CCPAD CCPAD CCPAD
-static const char cc_pad[27] = CCPAD3 CCPAD3 CCPAD3;
+static attribute_nonstring const char cc_pad[27] = CCPAD3 CCPAD3 CCPAD3;
static const alias aliases[20] = {
// clang-format off
diff --git a/libavutil/attributes_internal.h b/libavutil/attributes_internal.h
index bc85ce77ff..5b480112f9 100644
--- a/libavutil/attributes_internal.h
+++ b/libavutil/attributes_internal.h
@@ -33,4 +33,23 @@
#define EXTERN extern attribute_visibility_hidden
+#if (AV_HAS_ATTRIBUTE(nonstring) && (AV_GCC_VERSION_AT_LEAST(15,1) || defined(__clang__)))
+// Attribute to mark a variable initialized via a string literal as not
+// containing string data to suppress warnings about unterminated strings
+// in situations like char fourcc[4] = "TALB".
+#define attribute_nonstring __attribute__((nonstring))
+// The behavior of GCC and Clang differs when a string literal is terminated
+// by a \0 included in the string literal like char foo[4] = "bar\0":
+// GCC warns about it, Clang does not, so we use attribute_internal_trailing_zero
+// to silence the GCC warning while still benefiting from the Clang check.
+#if AV_GCC_VERSION_AT_LEAST(15,1)
+#define attribute_internal_trailing_zero __attribute__((nonstring))
+#else
+#define attribute_internal_trailing_zero
+#endif
+#else
+#define attribute_nonstring
+#define attribute_internal_trailing_zero
+#endif
+
#endif /* AVUTIL_ATTRIBUTES_INTERNAL_H */
diff --git a/libavutil/error.c b/libavutil/error.c
index 23a2a0a53a..7855efbefd 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <string.h>
#include "config.h"
+#include "attributes_internal.h"
#include "avstring.h"
#include "error.h"
#include "macros.h"
@@ -111,7 +112,7 @@ enum {
};
#define STRING(CODE, DESC) DESC "\0"
-static const char error_stringtable[ERROR_LIST_SIZE] =
+static attribute_internal_trailing_zero const char error_stringtable[ERROR_LIST_SIZE] =
AVERROR_LIST(STRING, NOTHING)
#if !HAVE_STRERROR_R
STRERROR_LIST(STRING)
diff --git a/libavutil/uuid.c b/libavutil/uuid.c
index 062e28736b..3f5075c066 100644
--- a/libavutil/uuid.c
+++ b/libavutil/uuid.c
@@ -60,6 +60,7 @@
* @author Zane van Iperen <zane@zanevaniperen.com>
*/
+#include "attributes_internal.h"
#include "uuid.h"
#include "error.h"
#include "avstring.h"
@@ -112,7 +113,7 @@ int av_uuid_parse_range(const char *in_start, const char *in_end, AVUUID uu)
return 0;
}
-static const char hexdigits_lower[16] = "0123456789abcdef";
+static attribute_nonstring const char hexdigits_lower[16] = "0123456789abcdef";
void av_uuid_unparse(const AVUUID uuid, char *out)
{
--
2.49.1
>From 01d0e0a563133eb5cdd33a8369a511b28ec05938 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 5 Jan 2026 21:55:21 +0100
Subject: [PATCH 4/4] configure: Enable -Wunterminated-string-initialization
warning
When an array of pointers to strings is converted into
an array of constant-length strings, one has to find out
the maximum size of the strings. Currently no warning will
be emitted If one forgets to account for the trailing zero,
making this optimization dangerous (think of the scenario
where the array will be modified without adjusting the maximum
size of the strings).
The -Wunterminated-string-initialization warning catches these cases.
It is supported by GCC 15.1 and Clang 21. It only requires to mark
the few instances of arrays initialized via string literals that
are not supposed to be strings with the nonstring attribute; this
has already been done in the previous commit.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
configure | 1 +
1 file changed, 1 insertion(+)
diff --git a/configure b/configure
index 6833997621..4f88c3abe0 100755
--- a/configure
+++ b/configure
@@ -7741,6 +7741,7 @@ check_warning -Wundef
check_warning -Wempty-body
check_c_warning -Wmissing-prototypes
check_c_warning -Wstrict-prototypes
+check_c_warning -Wunterminated-string-initialization
if enabled extra_warnings; then
check_warning -Wcast-qual
--
2.49.1
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-01-05 22:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-05 22:49 [FFmpeg-devel] [PR] configure: Enable -Wunterminated-string-initialization warning (PR #21387) mkver via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git