[PATCH] string: Use __restrict__ according to ISO/IEC 9899:TC3

Guilhem Massol posted 1 patch 1 month, 1 week ago
include/linux/string.h | 12 ++++++------
lib/string.c           | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
[PATCH] string: Use __restrict__ according to ISO/IEC 9899:TC3
Posted by Guilhem Massol 1 month, 1 week ago
Source: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
Some functions in lib/string.c needs to use restrict according to sections:
* 7.21.2.1: memcpy
* 7.21.2.3: strcpy
* 7.21.2.4: strncpy
* 7.21.3.1: strcat
* 7.21.3.2: strncat

Signed-off-by: Guilhem Massol <guilhem.massol85@gmail.com>
---
 include/linux/string.h | 12 ++++++------
 lib/string.c           | 12 ++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index b850bd91b3d8..07679485104b 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -65,12 +65,12 @@ void *vmemdup_array_user(const void __user *src, size_t n, size_t size)
 #include <asm/string.h>
 
 #ifndef __HAVE_ARCH_STRCPY
-extern char * strcpy(char *,const char *);
+extern char * strcpy(char *__restrict__, const char *__restrict__);
 #endif
 #ifndef __HAVE_ARCH_STRNCPY
-extern char * strncpy(char *,const char *, __kernel_size_t);
+extern char * strncpy(char *__restrict__, const char *__restrict__, __kernel_size_t);
 #endif
-ssize_t sized_strscpy(char *, const char *, size_t);
+ssize_t sized_strscpy(char *__restrict__, const char *__restrict__, size_t);
 
 /*
  * The 2 argument style can only be used when dst is an array with a
@@ -149,10 +149,10 @@ ssize_t sized_strscpy(char *, const char *, size_t);
 	CONCATENATE(__strscpy_pad, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__)
 
 #ifndef __HAVE_ARCH_STRCAT
-extern char * strcat(char *, const char *);
+extern char * strcat(char *__restrict__, const char *__restrict__);
 #endif
 #ifndef __HAVE_ARCH_STRNCAT
-extern char * strncat(char *, const char *, __kernel_size_t);
+extern char * strncat(char *__restrict__, const char *__restrict__, __kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_STRLCAT
 extern size_t strlcat(char *, const char *, __kernel_size_t);
@@ -257,7 +257,7 @@ extern void **__memcat_p(void **a, void **b);
 })
 
 #ifndef __HAVE_ARCH_MEMCPY
-extern void * memcpy(void *,const void *,__kernel_size_t);
+extern void * memcpy(void *__restrict__, const void *__restrict__, __kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_MEMMOVE
 extern void * memmove(void *,const void *,__kernel_size_t);
diff --git a/lib/string.c b/lib/string.c
index b632c71df1a5..9b492402ad04 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -77,7 +77,7 @@ EXPORT_SYMBOL(strcasecmp);
 #endif
 
 #ifndef __HAVE_ARCH_STRCPY
-char *strcpy(char *dest, const char *src)
+char *strcpy(char *__restrict__ dest, const char *__restrict__ src)
 {
 	char *tmp = dest;
 
@@ -89,7 +89,7 @@ EXPORT_SYMBOL(strcpy);
 #endif
 
 #ifndef __HAVE_ARCH_STRNCPY
-char *strncpy(char *dest, const char *src, size_t count)
+char *strncpy(char *__restrict__ dest, const char *__restrict__ src, size_t count)
 {
 	char *tmp = dest;
 
@@ -110,7 +110,7 @@ EXPORT_SYMBOL(strncpy);
 # define ALLBUTLAST_BYTE_MASK (~0ul >> 8)
 #endif
 
-ssize_t sized_strscpy(char *dest, const char *src, size_t count)
+ssize_t sized_strscpy(char *__restrict__ dest, const char *__restrict__ src, size_t count)
 {
 	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
 	size_t max = count;
@@ -215,7 +215,7 @@ char *stpcpy(char *__restrict__ dest, const char *__restrict__ src)
 EXPORT_SYMBOL(stpcpy);
 
 #ifndef __HAVE_ARCH_STRCAT
-char *strcat(char *dest, const char *src)
+char *strcat(char *__restrict__ dest, const char *__restrict__ src)
 {
 	char *tmp = dest;
 
@@ -229,7 +229,7 @@ EXPORT_SYMBOL(strcat);
 #endif
 
 #ifndef __HAVE_ARCH_STRNCAT
-char *strncat(char *dest, const char *src, size_t count)
+char *strncat(char *__restrict__ dest, const char *__restrict__ src, size_t count)
 {
 	char *tmp = dest;
 
@@ -618,7 +618,7 @@ EXPORT_SYMBOL(memset64);
  * You should not use this function to access IO space, use memcpy_toio()
  * or memcpy_fromio() instead.
  */
-void *memcpy(void *dest, const void *src, size_t count)
+void *memcpy(void *__restrict__ dest, const void *__restrict__ src, size_t count)
 {
 	char *tmp = dest;
 	const char *s = src;
-- 
2.54.0
Re: [PATCH] string: Use __restrict__ according to ISO/IEC 9899:TC3
Posted by kernel test robot 1 month ago
Hi Guilhem,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on linus/master v7.1-rc2 next-20260508]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Guilhem-Massol/string-Use-__restrict__-according-to-ISO-IEC-9899-TC3/20260505-025614
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
patch link:    https://lore.kernel.org/r/20260503131245.13868-1-guilhem.massol85%40gmail.com
patch subject: [PATCH] string: Use __restrict__ according to ISO/IEC 9899:TC3
config: microblaze-randconfig-r123-20260509 (https://download.01.org/0day-ci/archive/20260509/202605091039.FFdxv5Qe-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 12.5.0
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260509/202605091039.FFdxv5Qe-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605091039.FFdxv5Qe-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   kernel/fork.c:1051:19: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *owner @@     got struct task_struct *p @@
   kernel/fork.c:1051:19: sparse:     expected struct task_struct [noderef] __rcu *owner
   kernel/fork.c:1051:19: sparse:     got struct task_struct *p
   kernel/fork.c:1650:38: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:1650:38: sparse:     expected struct refcount_struct [usertype] *r
   kernel/fork.c:1650:38: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:1659:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1659:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1659:31: sparse:     got struct spinlock [noderef] __rcu *
>> kernel/fork.c:1660:36: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const *restrict @@     got struct k_sigaction [noderef] __rcu * @@
   kernel/fork.c:1660:36: sparse:     expected void const *restrict
   kernel/fork.c:1660:36: sparse:     got struct k_sigaction [noderef] __rcu *
   kernel/fork.c:1661:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:1661:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:1661:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2041:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2041:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2041:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2045:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2045:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2045:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2381:32: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *real_parent @@     got struct task_struct *register [addressable] [toplevel] current @@
   kernel/fork.c:2381:32: sparse:     expected struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:2381:32: sparse:     got struct task_struct *register [addressable] [toplevel] current
   kernel/fork.c:2390:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2390:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2390:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2439:54: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct list_head *head @@     got struct list_head [noderef] __rcu * @@
   kernel/fork.c:2439:54: sparse:     expected struct list_head *head
   kernel/fork.c:2439:54: sparse:     got struct list_head [noderef] __rcu *
   kernel/fork.c:2459:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2459:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2459:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2481:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2481:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2481:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2510:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sighand @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/fork.c:2510:28: sparse:     expected struct sighand_struct *sighand
   kernel/fork.c:2510:28: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/fork.c:2543:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2543:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2543:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2545:33: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/fork.c:2545:33: sparse:     expected struct spinlock [usertype] *lock
   kernel/fork.c:2545:33: sparse:     got struct spinlock [noderef] __rcu *
   kernel/fork.c:2984:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct *[assigned] parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/fork.c:2984:24: sparse:     expected struct task_struct *[assigned] parent
   kernel/fork.c:2984:24: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/fork.c:3067:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct refcount_struct const [usertype] *r @@     got struct refcount_struct [noderef] __rcu * @@
   kernel/fork.c:3067:43: sparse:     expected struct refcount_struct const [usertype] *r
   kernel/fork.c:3067:43: sparse:     got struct refcount_struct [noderef] __rcu *
   kernel/fork.c:1759:9: sparse: sparse: dereference of noderef expression
   kernel/fork.c:2091:22: sparse: sparse: dereference of noderef expression
   kernel/fork.c: note: in included file (through include/uapi/asm-generic/bpf_perf_event.h, arch/microblaze/include/generated/uapi/asm/bpf_perf_event.h, include/uapi/linux/bpf_perf_event.h, ...):
   include/linux/ptrace.h:210:45: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *parent @@
   include/linux/ptrace.h:210:45: sparse:     expected struct task_struct *new_parent
   include/linux/ptrace.h:210:45: sparse:     got struct task_struct [noderef] __rcu *parent
   include/linux/ptrace.h:210:62: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected struct cred const *ptracer_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
   include/linux/ptrace.h:210:62: sparse:     expected struct cred const *ptracer_cred
   include/linux/ptrace.h:210:62: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
   kernel/fork.c:2437:59: sparse: sparse: dereference of noderef expression
   kernel/fork.c:2438:59: sparse: sparse: dereference of noderef expression
   kernel/fork.c:1043:23: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/fork.c:1043:23: sparse:    struct task_struct [noderef] __rcu *
   kernel/fork.c:1043:23: sparse:    struct task_struct *
--
>> drivers/mtd/nand/onenand/onenand_base.c:779:34: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const *restrict @@     got void [noderef] __iomem * @@
   drivers/mtd/nand/onenand/onenand_base.c:779:34: sparse:     expected void const *restrict
   drivers/mtd/nand/onenand/onenand_base.c:779:34: sparse:     got void [noderef] __iomem *
   drivers/mtd/nand/onenand/onenand_base.c:817:34: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void const *restrict @@     got void [noderef] __iomem * @@
   drivers/mtd/nand/onenand/onenand_base.c:817:34: sparse:     expected void const *restrict
   drivers/mtd/nand/onenand/onenand_base.c:817:34: sparse:     got void [noderef] __iomem *
>> drivers/mtd/nand/onenand/onenand_base.c:860:26: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void *restrict @@     got void [noderef] __iomem * @@
   drivers/mtd/nand/onenand/onenand_base.c:860:26: sparse:     expected void *restrict
   drivers/mtd/nand/onenand/onenand_base.c:860:26: sparse:     got void [noderef] __iomem *

vim +1660 kernel/fork.c

a016f3389c0660 JANAK DESAI        2006-02-07  1644  
04ff48239f46e8 Simon Schuster     2025-09-01  1645  static int copy_sighand(u64 clone_flags, struct task_struct *tsk)
^1da177e4c3f41 Linus Torvalds     2005-04-16  1646  {
^1da177e4c3f41 Linus Torvalds     2005-04-16  1647  	struct sighand_struct *sig;
^1da177e4c3f41 Linus Torvalds     2005-04-16  1648  
60348802e9cb13 Zhaolei            2009-01-06  1649  	if (clone_flags & CLONE_SIGHAND) {
d036bda7d0e726 Elena Reshetova    2019-01-18  1650  		refcount_inc(&current->sighand->count);
^1da177e4c3f41 Linus Torvalds     2005-04-16  1651  		return 0;
^1da177e4c3f41 Linus Torvalds     2005-04-16  1652  	}
^1da177e4c3f41 Linus Torvalds     2005-04-16  1653  	sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
0c282b068eb26d Madhuparna Bhowmik 2020-01-27  1654  	RCU_INIT_POINTER(tsk->sighand, sig);
^1da177e4c3f41 Linus Torvalds     2005-04-16  1655  	if (!sig)
^1da177e4c3f41 Linus Torvalds     2005-04-16  1656  		return -ENOMEM;
9d7fb04276481c Peter Zijlstra     2015-06-30  1657  
d036bda7d0e726 Elena Reshetova    2019-01-18  1658  	refcount_set(&sig->count, 1);
06e62a46bbba20 Jann Horn          2018-08-21  1659  	spin_lock_irq(&current->sighand->siglock);
^1da177e4c3f41 Linus Torvalds     2005-04-16 @1660  	memcpy(sig->action, current->sighand->action, sizeof(sig->action));
06e62a46bbba20 Jann Horn          2018-08-21  1661  	spin_unlock_irq(&current->sighand->siglock);
b612e5df4587c9 Christian Brauner  2019-10-14  1662  
b612e5df4587c9 Christian Brauner  2019-10-14  1663  	/* Reset all signal handler not set to SIG_IGN to SIG_DFL. */
b612e5df4587c9 Christian Brauner  2019-10-14  1664  	if (clone_flags & CLONE_CLEAR_SIGHAND)
b612e5df4587c9 Christian Brauner  2019-10-14  1665  		flush_signal_handlers(tsk, 0);
b612e5df4587c9 Christian Brauner  2019-10-14  1666  
^1da177e4c3f41 Linus Torvalds     2005-04-16  1667  	return 0;
^1da177e4c3f41 Linus Torvalds     2005-04-16  1668  }
^1da177e4c3f41 Linus Torvalds     2005-04-16  1669  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki