From 1d73cf20031765d263b03873c7ad781e140c7db1 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Tue, 3 Dec 2024 14:45:50 +0100 Subject: [PATCH] Prevent false warnings in memcpy (GCC 12) GCC 12 tree-loop-distribute-patterns generates false warnings of -Warray-bounds, -Wstringop-overflow, or -Wstringop-overread in memcpy() and memcpy_cpu() in static/inline cases for code that obviously prevents its execution by invariant checking. On -O3, even more warnings are produced. --- repos/base/include/cpu/string.h | 3 +++ repos/base/include/util/string.h | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/repos/base/include/cpu/string.h b/repos/base/include/cpu/string.h index 898b0a9b57..ea6b100227 100644 --- a/repos/base/include/cpu/string.h +++ b/repos/base/include/cpu/string.h @@ -25,7 +25,10 @@ namespace Genode { * \param size number of bytes to copy * * \return number of bytes not copied + * + * The compiler attribute prevents array-bounds warnings with gcc 12.3. */ + __attribute((optimize("no-tree-loop-distribute-patterns"))) inline size_t memcpy_cpu(void * dst, const void * src, size_t size) { using word_t = unsigned long; diff --git a/repos/base/include/util/string.h b/repos/base/include/util/string.h index af2a438d2b..8022266322 100644 --- a/repos/base/include/util/string.h +++ b/repos/base/include/util/string.h @@ -130,7 +130,7 @@ namespace Genode { /** * Return length of null-terminated string in bytes */ - __attribute((optimize("no-tree-loop-distribute-patterns"))) + __attribute((optimize("no-tree-loop-distribute-patterns"))) inline size_t strlen(const char *s) { size_t res = 0; @@ -190,6 +190,9 @@ namespace Genode { */ inline void *memcpy(void *dst, const void *src, size_t size) { + if (!size) + return dst; + char *d = (char *)dst, *s = (char *)src; size_t i; @@ -281,7 +284,7 @@ namespace Genode { * generation of a 'memset()' call in the 'while' loop * with gcc 10. */ - __attribute((optimize("no-tree-loop-distribute-patterns"))) + __attribute((optimize("no-tree-loop-distribute-patterns"))) inline void *memset(void *dst, uint8_t i, size_t size) { using word_t = unsigned long;