From f9395a766f8eb1b9428539b3c41ff2f86197b2f8 Mon Sep 17 00:00:00 2001
From: William Horvath <[EMAIL REDACTED]>
Date: Thu, 15 Jan 2026 17:11:55 -0800
Subject: [PATCH] thread: Use a flexible array member for "array" in
SDL_TLSData.
Avoids UBSan warning (among other similar ones in SDL_thread.c):
src/thread/SDL_thread.c:109:13: runtime error: index 1 out of bounds for type 'struct (unnamed struct at src/thread/SDL_thread_c.h:70:5)[1]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/thread/SDL_thread.c:109:13
---
src/thread/SDL_thread.c | 2 +-
src/thread/SDL_thread_c.h | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c
index cf89f958cf8f3..04b0573920449 100644
--- a/src/thread/SDL_thread.c
+++ b/src/thread/SDL_thread.c
@@ -99,7 +99,7 @@ bool SDL_SetTLS(SDL_TLSID *id, const void *value, SDL_TLSDestructorCallback dest
oldlimit = storage ? storage->limit : 0;
newlimit = (storage_index + TLS_ALLOC_CHUNKSIZE);
- new_storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0]));
+ new_storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + newlimit * sizeof(storage->array[0]));
if (!new_storage) {
return false;
}
diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h
index df73aeb6447de..3659b85cc4af3 100644
--- a/src/thread/SDL_thread_c.h
+++ b/src/thread/SDL_thread_c.h
@@ -67,11 +67,18 @@ extern void SDL_RunThread(SDL_Thread *thread);
typedef struct
{
int limit;
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4200) // Flexible array members (C99)
+#endif
struct
{
void *data;
void(SDLCALL *destructor)(void *);
- } array[1];
+ } array[];
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
} SDL_TLSData;
// This is how many TLS entries we allocate at once