[PATCH v4 6/6] test/soring: fix stringop-overflow warning with LTO

Stephen Hemminger
2026-01-19T22:46:39Z

When LTO is enabled, GCC inlines through the soring dequeue path into
__rte_ring_dequeue_elems_128(), which copies 32 bytes per element for
128-bit ring elements. The compiler cannot prove at compile time that
this code path is unreachable when elem_size is 4 bytes, resulting in
warnings like:

warning: writing 32 bytes into a region of size 0 [-Wstringop-overflow=]
note: at offset 128 into destination object 'dequeued_objs' of size 128

The test allocates uint32_t arrays of 32 elements (128 bytes), which is
correct for 32 elements of 4 bytes each. However, the 128-bit path
would require 512 bytes for 32 elements.

Using __rte_assume or RTE_ASSERT in this case is not enough to
resolve the problem because the condition does not propogate
through the compiler inlining so the compiler still can't
prove the 128-bit path won't be taken.

Increase the array sizes in test_soring_stages() to 128 uint32_t
elements (512 bytes) to accommodate the worst-case 128-bit element
path that the compiler cannot eliminate.

Bugzilla ID: 1726
Fixes: 70581c355d69 ("test/ring: add unit tests for soring API")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_soring.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/app/test/test_soring.c b/app/test/test_soring.c
index 52852692d4..9e8e1e5fae 100644
--- a/app/test/test_soring.c
+++ b/app/test/test_soring.c
@@ -149,12 +149,18 @@ test_soring_stages(void)
{
struct rte_soring *sor = NULL;
struct rte_soring_param prm;
- uint32_t objs[32];
- uint32_t rcs[32];
- uint32_t acquired_objs[32];
- uint32_t acquired_rcs[32];
- uint32_t dequeued_rcs[32];
- uint32_t dequeued_objs[32];
+ /*
+ * The soring/ring code has paths for 4/8/16-byte elements.
+ * With LTO, GCC cannot eliminate the 16-byte path and warns
+ * about potential buffer overflow. Size arrays for worst case:
+ * 32 elements * 16 bytes = 512 bytes = 128 uint32_t.
+ */
+ uint32_t objs[128];
+ uint32_t rcs[128];
+ uint32_t acquired_objs[128];
+ uint32_t acquired_rcs[128];
+ uint32_t dequeued_rcs[128];
+ uint32_t dequeued_objs[128];
size_t ssz;
uint32_t stage, enqueued, dequeued, acquired;
uint32_t i, ftoken;
--
2.51.0