Devicetree
 help / color / mirror / Atom feed
* [PATCH v3 0/5] Add strprefix() and fix a bug with it
@ 2026-11-10 15:33 Alejandro Colomar
  2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
                   ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 15:33 UTC (permalink / raw)
  To: linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Alejandro Colomar, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio

[-- Attachment #1: Type: text/plain, Size: 6762 bytes --]

Hi!

str_has_prefix() is based on sizes and lengths, which means it must
overload the valid length 0 to mean not found.  This is a typical
consequence of choosing to design an API around sizes and lengths, and
vanishes when moving to pointer-based similar APIs.

According to its author (Steven R.), str_has_prefix() was never meant to
accept an empty prefix, but that's not documented, and there's no
obvious reason why that would be acceptable for a generic string
function (as opposed to a function very specific to its original use).
Users of strings need a function whose behavior extends naturally to the
empty string, and we can do better, by returning a pointer.  And indeed,
users have ended up using str_has_prefix() with empty prefix, expecting
it to work (as is natural of a generic string API).

This patch set adds strprefix(), deprecates str_has_prefix(), and uses
strprefix() in one place to fix a bug reported by Bartosz.

We can later work on replacing the other uses of str_has_prefix(), which
might hide similar bugs.

This patch set also adds infrastructure to make string functions return
a pointer that is as qualified as the input pointer.

Changes in v2
~~~~~~~~~~~~~

-  Copy the description from str_has_prefix().  [Steve]
-  Add links for the Reported-by tags.
-  Make these APIs const-generic.  [Geert]

I didn't apply some changes requested by reviewers:

-  I didn't remove the deprecation of str_has_prefix(), because I think
   it should not be used in new code.  It remains useful for code that
   is already using it, because rewriting all the surrounding code to
   use pointers instead of offsets might be too risky.  However, for new
   code, strprefix() produces simpler code, and is safer, so I don't see
   why str_has_prefix() would be good in any new code.

-  I didn't rename strprefix() to strsuffix(), because that name would
   be worse (strsuffix() is widely implemented with other semantics, and
   having it different here would lead to confusion and bugs).  Andy
   agreed.

See range-diff below.

Testing
~~~~~~~

I haven't changed the implementation of the function, so haven't re-run
tests.  Since the changes since v2 are only about type safety, with a
new wrapper macro, I have built again with 'allmodconfig', just to make
sure it still compiles.


Have a lovely day!
Alex

v1: <https://lore.kernel.org/linux-hardening/cover.1793876837.git.alx@kernel.org/>
v2: <https://lore.kernel.org/linux-hardening/cover.1793882260.git.alx@kernel.org/>

Alejandro Colomar (5):
  string: Add strprefix(), and deprecate str_has_prefix()
  device property: Fix fwnode_name_eq() for empty node names
  stddef: Add const_cast()
  string: Add [C]QChar_of() and QVoid_of()
  string: Make strprefix() const-qualifier-generic

 drivers/base/property.c  |  5 +---
 include/linux/stddef.h   | 12 ++++++++
 include/linux/string.h   | 63 +++++++++++++++++++++++++++++++++++++---
 lib/tests/string_kunit.c |  9 ++++++
 4 files changed, 81 insertions(+), 8 deletions(-)

Range-diff against v2:
1:  d3b325ecefd1 ! 1:  556766412884 string: Add strprefix(), and deprecate str_has_prefix()
    @@ Commit message
     
         We'll slowly migrate existing code from str_has_prefix() to strprefix().
     
    +    Copy the description from str_has_prefix().
    +
         Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    +    Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
         Cc: Andy Shevchenko <andy@kernel.org>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## include/linux/string.h ##
     @@ include/linux/string.h: void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
    - 	       sizeof(*(obj)) - offsetof(typeof(*(obj)), member));	\
      })
      
    -+/**
    + /**
    +- * str_has_prefix - Test if a string has a given prefix
    +- * @str: The string to test
    +- * @prefix: The string to see if @str starts with
     + * strprefix - string prefix
     + * @s: The string to be tested
     + * @prefix: The string to see if @s starts with
    -+ *
    -+ * Returns:
    -+ * *  @s+strlen(@prefix) if @s starts with @prefix
    -+ * *  NULL if @s does not start with @prefix
    -+ */
    -+static __always_inline char *strprefix(const char *s, const char *prefix)
    -+{
    -+	size_t len = strlen(prefix);
    -+	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
    -+}
    -+
    - /**
    -  * str_has_prefix - Test if a string has a given prefix
    -  * @str: The string to test
    -  * @prefix: The string to see if @str starts with
       *
    -+ * DEPRECATED: Use strprefix()
    -+ *
       * A common way to test a prefix of a string is to do:
       *  strncmp(str, prefix, sizeof(prefix) - 1)
       *
       * But this can lead to bugs due to typos, or if prefix is a pointer
     - * and not a constant. Instead use str_has_prefix().
    ++ * and not a constant. Instead use strprefix().
    ++ *
    ++ * Returns:
    ++ * *  @s+strlen(@prefix) if @s starts with @prefix
    ++ * *  NULL if @s does not start with @prefix
    ++ */
    ++static inline char *strprefix(const char *s, const char *prefix)
    ++{
    ++	size_t len = strlen(prefix);
    ++	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
    ++}
    ++
    ++/**
    ++ * str_has_prefix - Test if a string has a given prefix
    ++ * @str: The string to test
    ++ * @prefix: The string to see if @str starts with
    ++ *
    ++ * DEPRECATED: Use strprefix()
    ++ *
    ++ * A common way to test a prefix of a string is to do:
    ++ *  strncmp(str, prefix, sizeof(prefix) - 1)
    ++ *
    ++ * But this can lead to bugs due to typos, or if prefix is a pointer
     + * and not a constant. Instead use strprefix().
       *
       * Returns:
2:  ac9728afa027 ! 2:  eed085c85f36 device property: Fix fwnode_name_eq() for empty node names
    @@ Commit message
     
         Fixes: a9c8c738066b7 ("device property: Add fwnode_name_eq()")
         Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    +    Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
         Cc: Andy Shevchenko <andy@kernel.org>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
-:  ------------ > 3:  2bf5cf7baad8 stddef: Add const_cast()
-:  ------------ > 4:  415453a31ebf string: Add [C]QChar_of() and QVoid_of()
-:  ------------ > 5:  35bf6672f84f string: Make strprefix() const-qualifier-generic
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix()
  2026-11-10 15:33 [PATCH v3 0/5] Add strprefix() and fix a bug with it Alejandro Colomar
@ 2026-11-10 15:33 ` Alejandro Colomar
  2026-11-10 15:47   ` Joe Perches
  2026-11-11  8:43   ` Steven Rostedt
  2026-11-10 15:33 ` [PATCH v3 2/5] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 15:33 UTC (permalink / raw)
  To: linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Alejandro Colomar, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 3877 bytes --]

As Bartosz reported, str_has_prefix() has a bug: it can't differentiate
between an empty prefix matching an empty string from a non-matching
prefix.  This is a fundamental design flaw in this API, and not
something that can be fixed.

As always, this is a consequence of choosing sizes instead of pointers.
Sizes are often the wrong choice.  In this specific case, pointers are
more capable of differentiating these cases, as NULL is a special
sentinel value that doesn't need to overload a valid value.

Let's implement strprefix(), a function that returns a pointer
right after the prefix if found, and a null pointer if not found.

We'll slowly migrate existing code from str_has_prefix() to strprefix().

Copy the description from str_has_prefix().

Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
Cc: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 include/linux/string.h   | 31 +++++++++++++++++++++++++++----
 lib/tests/string_kunit.c |  9 +++++++++
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index 6cb5cdd01158..12e31c17f0d3 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -546,15 +546,38 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
 })
 
 /**
- * str_has_prefix - Test if a string has a given prefix
- * @str: The string to test
- * @prefix: The string to see if @str starts with
+ * strprefix - string prefix
+ * @s: The string to be tested
+ * @prefix: The string to see if @s starts with
  *
  * A common way to test a prefix of a string is to do:
  *  strncmp(str, prefix, sizeof(prefix) - 1)
  *
  * But this can lead to bugs due to typos, or if prefix is a pointer
- * and not a constant. Instead use str_has_prefix().
+ * and not a constant. Instead use strprefix().
+ *
+ * Returns:
+ * *  @s+strlen(@prefix) if @s starts with @prefix
+ * *  NULL if @s does not start with @prefix
+ */
+static inline char *strprefix(const char *s, const char *prefix)
+{
+	size_t len = strlen(prefix);
+	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
+}
+
+/**
+ * str_has_prefix - Test if a string has a given prefix
+ * @str: The string to test
+ * @prefix: The string to see if @str starts with
+ *
+ * DEPRECATED: Use strprefix()
+ *
+ * A common way to test a prefix of a string is to do:
+ *  strncmp(str, prefix, sizeof(prefix) - 1)
+ *
+ * But this can lead to bugs due to typos, or if prefix is a pointer
+ * and not a constant. Instead use strprefix().
  *
  * Returns:
  * * strlen(@prefix) if @str starts with @prefix
diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
index 0819ace5b027..73d2614b1474 100644
--- a/lib/tests/string_kunit.c
+++ b/lib/tests/string_kunit.c
@@ -287,6 +287,14 @@ static void string_test_strspn(struct kunit *test)
 	}
 }
 
+static void string_test_strprefix(struct kunit *test)
+{
+	KUNIT_ASSERT_EQ(test, 0, strcmp(strprefix("foobar", "foo"), "bar"));
+	KUNIT_ASSERT_EQ(test, 0, strcmp(strprefix("foobar", ""), "foobar"));
+	KUNIT_ASSERT_EQ(test, 0, strcmp(strprefix("foobar", "foobar"), ""));
+	KUNIT_ASSERT_NULL(test, strprefix("foobar", "bar"));
+}
+
 static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN];
 static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN];
 
@@ -891,6 +899,7 @@ static struct kunit_case string_test_cases[] = {
 	KUNIT_CASE(string_test_strnchr),
 	KUNIT_CASE(string_test_strrchr),
 	KUNIT_CASE(string_test_strspn),
+	KUNIT_CASE(string_test_strprefix),
 	KUNIT_CASE(string_test_strcmp),
 	KUNIT_CASE(string_test_strcmp_long_strings),
 	KUNIT_CASE(string_test_strncmp),
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 2/5] device property: Fix fwnode_name_eq() for empty node names
  2026-11-10 15:33 [PATCH v3 0/5] Add strprefix() and fix a bug with it Alejandro Colomar
  2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
@ 2026-11-10 15:33 ` Alejandro Colomar
  2026-11-10 15:33 ` [PATCH v3 3/5] stddef: Add const_cast() Alejandro Colomar
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 15:33 UTC (permalink / raw)
  To: linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Alejandro Colomar, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 1549 bytes --]

str_has_prefix() returns the prefix length on match and 0 on mismatch,
so the mistmatch case can't be told from "empty prefix matched an empty
string".

For instance: the OF root node's name as returned by
fwnode_get_name() is "" and will return 0 for any name matched against
it and since len is 0 too, fwnode_name_eq() will return true.

Let's use strprefix() instead, which also makes this function simpler.

Fixes: a9c8c738066b7 ("device property: Add fwnode_name_eq()")
Reported-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Link: https://lore.kernel.org/linux-hardening/20261104-fwnode-for-each-prop-v1-1-6e28fe1c72c4@oss.qualcomm.com/
Cc: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 drivers/base/property.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index 51109794d727..7728116e2968 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -692,15 +692,12 @@ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
 bool fwnode_name_eq(const struct fwnode_handle *fwnode, const char *name)
 {
 	const char *node_name;
-	ptrdiff_t len;
 
 	node_name = fwnode_get_name(fwnode);
 	if (!node_name)
 		return false;
 
-	len = strchrnul(node_name, '@') - node_name;
-
-	return str_has_prefix(node_name, name) == len;
+	return strprefix(node_name, name) == strchrnul(node_name, '@');
 }
 EXPORT_SYMBOL_GPL(fwnode_name_eq);
 
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 3/5] stddef: Add const_cast()
  2026-11-10 15:33 [PATCH v3 0/5] Add strprefix() and fix a bug with it Alejandro Colomar
  2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
  2026-11-10 15:33 ` [PATCH v3 2/5] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
@ 2026-11-10 15:33 ` Alejandro Colomar
  2026-11-11 10:25   ` David Laight
  2026-11-10 15:33 ` [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
  2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
  4 siblings, 1 reply; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 15:33 UTC (permalink / raw)
  To: linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Alejandro Colomar, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio

[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]

This macro serves to cast const away without risking unwanted
conversions due to mistakes in the cast.

It's similar to C++'s const_cast(), but it is more restrictive: it can
only cast away 'const', and not arbitrary qualifiers.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 include/linux/stddef.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index e1851c50c89b..d79a81406b78 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -194,4 +194,16 @@ enum {
 #define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS)				\
 	__TRAILING_OVERLAP(TYPE, NAME, FAM, /* no attrs */, MEMBERS)
 
+/**
+ * const_cast() - Drop const in the left-most derivation of a pointer
+ *
+ * @T: Type for the cast.
+ * @p: Pointer to be casted.
+ *
+ * If @p is of type const @T, then it is casted to @T.
+ * Otherwise, @p is returned without any casts.
+ * This avoids mistakes that change anything other than 'const' in a cast.
+ */
+#define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))
+
 #endif
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of()
  2026-11-10 15:33 [PATCH v3 0/5] Add strprefix() and fix a bug with it Alejandro Colomar
                   ` (2 preceding siblings ...)
  2026-11-10 15:33 ` [PATCH v3 3/5] stddef: Add const_cast() Alejandro Colomar
@ 2026-11-10 15:33 ` Alejandro Colomar
  2026-11-10 15:45   ` sashiko-bot
  2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
  4 siblings, 1 reply; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 15:33 UTC (permalink / raw)
  To: linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Alejandro Colomar, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio

[-- Attachment #1: Type: text/plain, Size: 1784 bytes --]

These macros serve to implement qualifier-generic macros as those
specified in ISO C23.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 include/linux/string.h | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 12e31c17f0d3..9e59f9697c9e 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -14,6 +14,36 @@
 #include <linux/stdarg.h>
 #include <uapi/linux/string.h>
 
+/**
+ * QVoid_of - qualified void of
+ *
+ * @p: Pointer to test for qualifiers
+ *
+ * This macro produces the type name 'void',
+ * qualified with any qualifiers present in the element of @p.
+ */
+#define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
+#define __QVoidptr_of(p)  typeof(1?(p):(void*){0})
+
+/**
+ * QChar_of - qualified char of
+ *
+ * @Q: Qualifier to test.
+ * @p: Pointer to test for the @Q qualifier
+ *
+ * This macro produces the type name 'char',
+ * @Q-qualified iff the input pointer points to a @Q-qualified element.
+ */
+#define QChar_of(Q, p)  typeof                                        \
+(                                                                     \
+	_Generic((QVoid_of(p) *){0},                                  \
+		Q void *:  (Q char){0},                               \
+		void *:    (  char){0}                                \
+	)                                                             \
+)
+// CQChar_of - const qualified char of
+#define CQChar_of(p)  QChar_of(const, p)
+
 extern char *strndup_user(const char __user *, long);
 extern void *memdup_user(const void __user *, size_t) __realloc_size(2);
 extern void *vmemdup_user(const void __user *, size_t) __realloc_size(2);
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 15:33 [PATCH v3 0/5] Add strprefix() and fix a bug with it Alejandro Colomar
                   ` (3 preceding siblings ...)
  2026-11-10 15:33 ` [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
@ 2026-11-10 15:33 ` Alejandro Colomar
  2026-11-10 15:44   ` sashiko-bot
                     ` (2 more replies)
  4 siblings, 3 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 15:33 UTC (permalink / raw)
  To: linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Alejandro Colomar, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio

[-- Attachment #1: Type: text/plain, Size: 899 bytes --]

Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 include/linux/string.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/string.h b/include/linux/string.h
index 9e59f9697c9e..55ca4cb5122c 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -590,7 +590,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
  * *  @s+strlen(@prefix) if @s starts with @prefix
  * *  NULL if @s does not start with @prefix
  */
-static inline char *strprefix(const char *s, const char *prefix)
+#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
+
+static inline char *(strprefix)(const char *s, const char *prefix)
 {
 	size_t len = strlen(prefix);
 	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
-- 
2.55.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
@ 2026-11-10 15:44   ` sashiko-bot
  2026-11-11  0:27     ` Alejandro Colomar
  2026-11-10 16:32   ` Joe Perches
  2026-11-11 10:34   ` David Laight
  2 siblings, 1 reply; 21+ messages in thread
From: sashiko-bot @ 2026-11-10 15:44 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: devicetree, linux-gpio, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [High] string: strprefix() breaks Clang builds via void * subscript in
  QVoid_of()
- [Medium] string: strprefix() always returns char * due to non-const
  (strprefix)()
- [Low] string: strprefix() macro parameter pfx mismatches @prefix
  kernel-doc
--

commit f882ec908122ee0c3f780648b859ed41700664d0
Author: Alejandro Colomar <alx@kernel.org>

string: Make strprefix() const-qualifier-generic

This commit wraps strprefix() in a const_cast(CQChar_of(s) *, ...) macro so
that its return type preserves the const qualifier of its first argument.

> diff --git a/include/linux/string.h b/include/linux/string.h
> index cb096e9eb9835..3e8a0537b86bb 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -577,7 +577,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
>   * *  @s+strlen(@prefix) if @s starts with @prefix
>   * *  NULL if @s does not start with @prefix
>   */
> -static inline char *strprefix(const char *s, const char *prefix)
> +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))

[Severity: High]
Does expanding CQChar_of(s) here break Clang builds (make LLVM=1)?

CQChar_of(s) expands to QChar_of(const, s), which expands QVoid_of(s):

include/linux/string.h:
#define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
#define __QVoidptr_of(p)  typeof(1?(p):(void*){0})

Because __QVoidptr_of(p) is void * or const void *, applying the [0] array
subscript operator to it fails to compile under Clang ("error: subscript of a
pointer to void") in every translation unit that calls strprefix(), such as
drivers/base/property.c, and triggers -Wpointer-arith under W=3 in GCC.

[Severity: Low]
Does naming the macro parameter pfx instead of prefix cause scripts/kernel-doc
warnings?  The kernel-doc comment immediately above documents @prefix, and
scripts/kernel-doc binds that comment to the macro definition that follows it.

> +
> +static inline char *(strprefix)(const char *s, const char *prefix)
>  {
>  	size_t len = strlen(prefix);
>  	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;

[Severity: Medium]
Does strprefix(s, pfx) still unconditionally return char * even when s is
const char *?

include/linux/stddef.h:
#define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))

In const_cast(CQChar_of(s) *, strprefix(s, pfx)), the first _Generic
association is const CQChar_of(s) *, which is const char *.  Because the
underlying (strprefix)() function returns char *, the controlling expression
never matches const char * and always selects the default branch, returning
an unqualified char * and stripping const from read-only strings.  Should
(strprefix)() return const char * and avoid casting s to char *?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794323750.git.alx@kernel.org?part=5

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of()
  2026-11-10 15:33 ` [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
@ 2026-11-10 15:45   ` sashiko-bot
  2026-11-11  0:03     ` Alejandro Colomar
  0 siblings, 1 reply; 21+ messages in thread
From: sashiko-bot @ 2026-11-10 15:45 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: devicetree, linux-gpio, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] string: void pointer subscript in QVoid_of() breaks Clang
  builds
- [Medium] string: QChar_of() fails to compile when pointee has
  qualifiers other than Q
--

commit cea37634307d89ede7b6ca6128f006d50a90391c
Author: Alejandro Colomar <alx@kernel.org>

string: Add [C]QChar_of() and QVoid_of()

This commit introduces the QVoid_of(), QChar_of(), and CQChar_of() helper
macros in include/linux/string.h to support qualifier-generic string macros.

> diff --git a/include/linux/string.h b/include/linux/string.h
> index 3a70ba9ed3021..cb096e9eb9835 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -14,6 +14,36 @@
>  #include <linux/stdarg.h>
>  #include <uapi/linux/string.h>
>  
> +/**
> + * QVoid_of - qualified void of
> + *
> + * @p: Pointer to test for qualifiers
> + *
> + * This macro produces the type name 'void',
> + * qualified with any qualifiers present in the element of @p.
> + */
> +#define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
> +#define __QVoidptr_of(p)  typeof(1?(p):(void*){0})

[Severity: High]
Does applying the array subscript [0] to a void pointer in QVoid_of()
break Clang builds?

__QVoidptr_of(p) produces a pointer to (qualified) void.  Because array
subscripting requires a pointer to a complete object type, Clang rejects
(__QVoidptr_of(p)){0}[0] even inside typeof() with an incomplete type
error, and GCC emits a -Wpointer-arith warning when pointer arithmetic
warnings are enabled.  Using unary * instead of [0], such as
typeof(*(__QVoidptr_of(p)){0}), avoids both issues.

> +
> +/**
> + * QChar_of - qualified char of
> + *
> + * @Q: Qualifier to test.
> + * @p: Pointer to test for the @Q qualifier
> + *
> + * This macro produces the type name 'char',
> + * @Q-qualified iff the input pointer points to a @Q-qualified element.
> + */
> +#define QChar_of(Q, p)  typeof                                        \
> +(                                                                     \
> +	_Generic((QVoid_of(p) *){0},                                  \
> +		Q void *:  (Q char){0},                               \
> +		void *:    (  char){0}                                \
> +	)                                                             \
> +)

[Severity: Medium]
Can QChar_of() fail to compile when the pointed-to type of p carries a
qualifier other than Q?

QVoid_of(p) preserves all qualifiers on the target of p, but the _Generic
selection only matches exact Q void * and unqualified void *.  Passing a
volatile char * or const volatile char * to CQChar_of(p) produces a
volatile void * or const volatile void * controlling expression, which
matches neither association and fails at compile time.  Matching against
Q QVoid_of(p) *: (Q char){0} and default: (char){0} would test specifically
for Q regardless of other qualifiers.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794323750.git.alx@kernel.org?part=4

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix()
  2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
@ 2026-11-10 15:47   ` Joe Perches
  2026-11-10 16:14     ` Alejandro Colomar
  2026-11-11  8:43   ` Steven Rostedt
  1 sibling, 1 reply; 21+ messages in thread
From: Joe Perches @ 2026-11-10 15:47 UTC (permalink / raw)
  To: Alejandro Colomar, linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Andreas Schwab, Andy Shevchenko, Bartosz Golaszewski,
	Daniel Scally, Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
	Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
	Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
	Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
	linux-kernel, devicetree, linux-gpio, Bartosz Golaszewski

On Tue, 2026-11-10 at 16:33 +0100, Alejandro Colomar wrote:
> As Bartosz reported, str_has_prefix() has a bug: it can't differentiate
> between an empty prefix matching an empty string from a non-matching
> prefix.  This is a fundamental design flaw in this API, and not
> something that can be fixed.
> 
> As always, this is a consequence of choosing sizes instead of pointers.
> Sizes are often the wrong choice.  In this specific case, pointers are
> more capable of differentiating these cases, as NULL is a special
> sentinel value that doesn't need to overload a valid value.
> 
> Let's implement strprefix(), a function that returns a pointer
> right after the prefix if found, and a null pointer if not found.
> 
> We'll slowly migrate existing code from str_has_prefix() to strprefix().

Most uses of str_has_prefix could use the existing strstarts.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix()
  2026-11-10 15:47   ` Joe Perches
@ 2026-11-10 16:14     ` Alejandro Colomar
  0 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 16:14 UTC (permalink / raw)
  To: Joe Perches
  Cc: Alejandro Colomar, linux-hardening, Krzysztof Kozlowski,
	Maciej W. Rozycki, Geert Uytterhoeven, Andreas Schwab,
	Andy Shevchenko, Bartosz Golaszewski, Daniel Scally,
	Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
	Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
	Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
	Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
	linux-kernel, devicetree, linux-gpio, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 1322 bytes --]

Hi Joe,

> Date: 2026-11-10 07:47:55-0800
> From: Joe Perches <joe@perches.com>
>
> On Tue, 2026-11-10 at 16:33 +0100, Alejandro Colomar wrote:
> > As Bartosz reported, str_has_prefix() has a bug: it can't differentiate
> > between an empty prefix matching an empty string from a non-matching
> > prefix.  This is a fundamental design flaw in this API, and not
> > something that can be fixed.
> > 
> > As always, this is a consequence of choosing sizes instead of pointers.
> > Sizes are often the wrong choice.  In this specific case, pointers are
> > more capable of differentiating these cases, as NULL is a special
> > sentinel value that doesn't need to overload a valid value.
> > 
> > Let's implement strprefix(), a function that returns a pointer
> > right after the prefix if found, and a null pointer if not found.
> > 
> > We'll slowly migrate existing code from str_has_prefix() to strprefix().
> 
> Most uses of str_has_prefix could use the existing strstarts.

Hmmm, actually, both str_has_prefix() and strstarts() can be replaced by
strprefix(), which provides functionality for both use cases.  It's the
more generic API for this.  And I expect compilers can optimize the
unused parts if actually unused.


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
  2026-11-10 15:44   ` sashiko-bot
@ 2026-11-10 16:32   ` Joe Perches
  2026-11-10 23:27     ` Alejandro Colomar
  2026-11-11 10:34   ` David Laight
  2 siblings, 1 reply; 21+ messages in thread
From: Joe Perches @ 2026-11-10 16:32 UTC (permalink / raw)
  To: Alejandro Colomar, linux-hardening
  Cc: Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Andreas Schwab, Andy Shevchenko, Bartosz Golaszewski,
	Daniel Scally, Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
	Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
	Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
	Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
	linux-kernel, devicetree, linux-gpio

On Tue, 2026-11-10 at 16:33 +0100, Alejandro Colomar wrote:

no commit description on proposed patch

> Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>  include/linux/string.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/string.h b/include/linux/string.h
> index 9e59f9697c9e..55ca4cb5122c 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -590,7 +590,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
>   * *  @s+strlen(@prefix) if @s starts with @prefix
>   * *  NULL if @s does not start with @prefix
>   */
> -static inline char *strprefix(const char *s, const char *prefix)
> +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
> +
> +static inline char *(strprefix)(const char *s, const char *prefix)

Why introduce a new coding style?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 16:32   ` Joe Perches
@ 2026-11-10 23:27     ` Alejandro Colomar
  2026-11-11 10:28       ` David Laight
  0 siblings, 1 reply; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-10 23:27 UTC (permalink / raw)
  To: Joe Perches
  Cc: Alejandro Colomar, linux-hardening, Krzysztof Kozlowski,
	Maciej W. Rozycki, Geert Uytterhoeven, Andreas Schwab,
	Andy Shevchenko, Bartosz Golaszewski, Daniel Scally,
	Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
	Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
	Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
	Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
	linux-kernel, devicetree, linux-gpio

[-- Attachment #1: Type: text/plain, Size: 1512 bytes --]

Hi Joe,

> Date: 2026-11-10 08:32:41-0800
> From: Joe Perches <joe@perches.com>
>
> On Tue, 2026-11-10 at 16:33 +0100, Alejandro Colomar wrote:
> 
> no commit description on proposed patch

There isn't much to say, but I'll add something (the explanation of why
the parentheses are needed around the function name, for example).

> > Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
> > Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > ---
> >  include/linux/string.h | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/string.h b/include/linux/string.h
> > index 9e59f9697c9e..55ca4cb5122c 100644
> > --- a/include/linux/string.h
> > +++ b/include/linux/string.h
> > @@ -590,7 +590,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
> >   * *  @s+strlen(@prefix) if @s starts with @prefix
> >   * *  NULL if @s does not start with @prefix
> >   */
> > -static inline char *strprefix(const char *s, const char *prefix)
> > +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
> > +
> > +static inline char *(strprefix)(const char *s, const char *prefix)
> 
> Why introduce a new coding style?

It's not style; the parentheses are technically needed to avoid macro
expansion, since the macro has the same name as the function.

Alternatively, I could rename the function to __strprefix().


Have a lovely night!
Alex

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of()
  2026-11-10 15:45   ` sashiko-bot
@ 2026-11-11  0:03     ` Alejandro Colomar
  0 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-11  0:03 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: devicetree, linux-gpio, robh, conor+dt, linux-hardening

[-- Attachment #1: Type: text/plain, Size: 3680 bytes --]

> Date: 2026-11-10 15:45:13+0000
> From: sashiko-bot@kernel.org
>
> Thank you for your contribution! Sashiko AI review found 2 potential
> issues to consider:
> - [High] string: void pointer subscript in QVoid_of() breaks Clang
>   builds

It seems I can't build with LLVM in the way that sashiko suggested in
the other mail, so I can't reproduce this:

	$ make LLVM=1
	  SYNC    include/config/auto.conf
	  HOSTCC  scripts/basic/fixdep
	clang: error: invalid linker name in argument '-fuse-ld=lld'
	make[3]: *** [scripts/Makefile.host:114: scripts/basic/fixdep] Error 1
	make[2]: *** [Makefile:682: scripts_basic] Error 2
	make[1]: *** [/srv/alx/src/linux/linux/llvm/Makefile:912: include/config/auto.conf] Error 2
	make[1]: *** [include/config/auto.conf] Deleting file 'include/generated/rustc_cfg'
	make[1]: *** [include/config/auto.conf] Deleting file 'include/generated/autoconf.h'
	make: *** [Makefile:248: __sub-make] Error 2

But I see no reason why Clang shouldn't build this.  I've written
a small test program just to see, and Clang seems to just work well:

	alx@devuan:~/tmp$ cat const.c 
	#include <stddef.h>

	#define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
	#define __QVoidptr_of(p)  typeof(1?(p):(void*){0})

	int
	main(void)
	{
		const void  *p;
		QVoid_of(p) *q;  // const void *
	}
	alx@devuan:~/tmp$ gcc -Wall -Wextra -Wno-unused const.c 
	alx@devuan:~/tmp$ clang -Wall -Wextra -Wno-unused const.c 
	alx@devuan:~/tmp$ 

Unless anyone can actually reproduce the build issue, I'll assume this
report is nonsense.

> - [Medium] string: QChar_of() fails to compile when pointee has
>   qualifiers other than Q

That's actually desirable.  You don't want to call strchr(3) with
a pointer to volatile.

> --
> 
> commit cea37634307d89ede7b6ca6128f006d50a90391c
> Author: Alejandro Colomar <alx@kernel.org>
> 
> string: Add [C]QChar_of() and QVoid_of()
> 
> This commit introduces the QVoid_of(), QChar_of(), and CQChar_of() helper
> macros in include/linux/string.h to support qualifier-generic string macros.
> 
> > diff --git a/include/linux/string.h b/include/linux/string.h
[...]
> 
> [Severity: High]
> Does applying the array subscript [0] to a void pointer in QVoid_of()
> break Clang builds?

I don't see why it would.  I can't use LLVM myself, so can't reproduce,
but a small test program shows that Clang works just fine with it.

> __QVoidptr_of(p) produces a pointer to (qualified) void.  Because array
> subscripting requires a pointer to a complete object type, Clang rejects
> (__QVoidptr_of(p)){0}[0] even inside typeof() with an incomplete type
> error, and GCC emits a -Wpointer-arith warning when pointer arithmetic
> warnings are enabled.  Using unary * instead of [0], such as
> typeof(*(__QVoidptr_of(p)){0}), avoids both issues.

This is a lie, unless anyone can confirm.

[...]
> [Severity: Medium]
> Can QChar_of() fail to compile when the pointed-to type of p carries a
> qualifier other than Q?

Indeed, a desirable property.

> QVoid_of(p) preserves all qualifiers on the target of p, but the _Generic
> selection only matches exact Q void * and unqualified void *.  Passing a
> volatile char * or const volatile char * to CQChar_of(p) produces a
> volatile void * or const volatile void * controlling expression, which
> matches neither association and fails at compile time.  Matching against
> Q QVoid_of(p) *: (Q char){0} and default: (char){0} would test specifically
> for Q regardless of other qualifiers.

You certainly don't want to pass a volatile char* to strchr(3).


Alex

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 15:44   ` sashiko-bot
@ 2026-11-11  0:27     ` Alejandro Colomar
  0 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-11  0:27 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: devicetree, linux-gpio, robh, conor+dt, linux-hardening

[-- Attachment #1: Type: text/plain, Size: 4480 bytes --]

> Date: 2026-11-10 15:44:36+0000
> From: sashiko-bot@kernel.org
>
> Thank you for your contribution! Sashiko AI review found 3 potential
> issues to consider:
> - [High] string: strprefix() breaks Clang builds via void * subscript in
>   QVoid_of()

This seems nonsense; already replied to in the review of 4/5.

> - [Medium] string: strprefix() always returns char * due to non-const
>   (strprefix)()

Hmmm.  Fixed for v4.

> - [Low] string: strprefix() macro parameter pfx mismatches @prefix
>   kernel-doc

Hmmm.  Fixed for v4.

> --
> 
> commit f882ec908122ee0c3f780648b859ed41700664d0
> Author: Alejandro Colomar <alx@kernel.org>
> 
> string: Make strprefix() const-qualifier-generic
> 
> This commit wraps strprefix() in a const_cast(CQChar_of(s) *, ...) macro so
> that its return type preserves the const qualifier of its first argument.
> 
> > diff --git a/include/linux/string.h b/include/linux/string.h
> > index cb096e9eb9835..3e8a0537b86bb 100644
> > --- a/include/linux/string.h
> > +++ b/include/linux/string.h
> > @@ -577,7 +577,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
> >   * *  @s+strlen(@prefix) if @s starts with @prefix
> >   * *  NULL if @s does not start with @prefix
> >   */
> > -static inline char *strprefix(const char *s, const char *prefix)
> > +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
> 
> [Severity: High]
> Does expanding CQChar_of(s) here break Clang builds (make LLVM=1)?

I can't even seem to build with LLVM=1, so can't reproduce, but as said
in the other subthread (4/5), this makes no sense.  Clang accepts this
code just fine.

> CQChar_of(s) expands to QChar_of(const, s), which expands QVoid_of(s):
> 
> include/linux/string.h:
> #define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
> #define __QVoidptr_of(p)  typeof(1?(p):(void*){0})
> 
> Because __QVoidptr_of(p) is void * or const void *, applying the [0] array
> subscript operator to it fails to compile under Clang ("error: subscript of a
> pointer to void") in every translation unit that calls strprefix(), such as
> drivers/base/property.c, and triggers -Wpointer-arith under W=3 in GCC.

Hmmmm, I see why it says Clang may not compile.  For that to happen, one
needs to enable non-usual diagnostics.

	alx@devuan:~/tmp$ cat const.c 
	#include <stddef.h>

	#define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
	#define __QVoidptr_of(p)  typeof(1?(p):(void*){0})

	int
	main(void)
	{
		const void  *p;
		QVoid_of(p) *q;  // const void *
	}
	alx@devuan:~/tmp$ gcc -Wall -Wextra -Wpointer-arith -Wno-unused const.c 
	const.c: In function ‘main’:
	const.c:3:55: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
	    3 | #define QVoid_of(p)       typeof((__QVoidptr_of(p)){0}[0])
	      |                                                       ^
	const.c:10:9: note: in expansion of macro ‘QVoid_of’
	   10 |         QVoid_of(p) *q;  // const void *
	      |         ^~~~~~~~

I think this diagnostic isn't very useful, which is why it isn't in
-Wall -Wextra.

> [Severity: Low]
> Does naming the macro parameter pfx instead of prefix cause scripts/kernel-doc
> warnings?  The kernel-doc comment immediately above documents @prefix, and
> scripts/kernel-doc binds that comment to the macro definition that follows it.

Solved.

> > +
> > +static inline char *(strprefix)(const char *s, const char *prefix)
> >  {
> >  	size_t len = strlen(prefix);
> >  	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;
> 
> [Severity: Medium]
> Does strprefix(s, pfx) still unconditionally return char * even when s is
> const char *?
> 
> include/linux/stddef.h:
> #define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))
> 
> In const_cast(CQChar_of(s) *, strprefix(s, pfx)), the first _Generic
> association is const CQChar_of(s) *, which is const char *.  Because the
> underlying (strprefix)() function returns char *, the controlling expression
> never matches const char * and always selects the default branch, returning
> an unqualified char * and stripping const from read-only strings.  Should
> (strprefix)() return const char * and avoid casting s to char *?

Solved.

> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794323750.git.alx@kernel.org?part=5

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix()
  2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
  2026-11-10 15:47   ` Joe Perches
@ 2026-11-11  8:43   ` Steven Rostedt
  1 sibling, 0 replies; 21+ messages in thread
From: Steven Rostedt @ 2026-11-11  8:43 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-hardening, Krzysztof Kozlowski, Maciej W. Rozycki,
	Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Tom Zanussi,
	linux-acpi, driver-core, linux-kernel, devicetree, linux-gpio,
	Bartosz Golaszewski

On Tue, 10 Nov 2026 16:33:23 +0100
Alejandro Colomar <alx@kernel.org> wrote:

> +/**
> + * str_has_prefix - Test if a string has a given prefix
> + * @str: The string to test
> + * @prefix: The string to see if @str starts with
> + *
> + * DEPRECATED: Use strprefix()

I'm still not convinced, so NAK on this part.

-- Steve


> + *
> + * A common way to test a prefix of a string is to do:
> + *  strncmp(str, prefix, sizeof(prefix) - 1)
> + *
> + * But this can lead to bugs due to typos, or if prefix is a pointer
> + * and not a constant. Instead use strprefix().
>   *

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 3/5] stddef: Add const_cast()
  2026-11-10 15:33 ` [PATCH v3 3/5] stddef: Add const_cast() Alejandro Colomar
@ 2026-11-11 10:25   ` David Laight
  2026-11-11 10:51     ` Alejandro Colomar
  0 siblings, 1 reply; 21+ messages in thread
From: David Laight @ 2026-11-11 10:25 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-hardening, Krzysztof Kozlowski, Maciej W. Rozycki,
	Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio

On Tue, 10 Nov 2026 16:33:40 +0100
Alejandro Colomar <alx@kernel.org> wrote:

> This macro serves to cast const away without risking unwanted
> conversions due to mistakes in the cast.
> 
> It's similar to C++'s const_cast(), but it is more restrictive: it can
> only cast away 'const', and not arbitrary qualifiers.
> 
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>  include/linux/stddef.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> index e1851c50c89b..d79a81406b78 100644
> --- a/include/linux/stddef.h
> +++ b/include/linux/stddef.h
> @@ -194,4 +194,16 @@ enum {
>  #define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS)				\
>  	__TRAILING_OVERLAP(TYPE, NAME, FAM, /* no attrs */, MEMBERS)
>  
> +/**
> + * const_cast() - Drop const in the left-most derivation of a pointer
> + *
> + * @T: Type for the cast.
> + * @p: Pointer to be casted.
> + *
> + * If @p is of type const @T, then it is casted to @T.
> + * Otherwise, @p is returned without any casts.
> + * This avoids mistakes that change anything other than 'const' in a cast.
> + */
> +#define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))

Should it be de_const_cast(), or just de_const().
It is a shame you need to specify the type, but why not:
	_Generic(p, T: p, const T: (T)(p))
so that you get a compile time error from the _Generic() if the type
is wrong.

David


> +
>  #endif


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 23:27     ` Alejandro Colomar
@ 2026-11-11 10:28       ` David Laight
  2026-11-11 10:59         ` Alejandro Colomar
  0 siblings, 1 reply; 21+ messages in thread
From: David Laight @ 2026-11-11 10:28 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Joe Perches, Alejandro Colomar, linux-hardening,
	Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Andreas Schwab, Andy Shevchenko, Bartosz Golaszewski,
	Daniel Scally, Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
	Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
	Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
	Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
	linux-kernel, devicetree, linux-gpio

On Wed, 11 Nov 2026 00:27:28 +0100
Alejandro Colomar <alx+linux-hardening@kernel.org> wrote:

> Hi Joe,
> 
> > Date: 2026-11-10 08:32:41-0800
> > From: Joe Perches <joe@perches.com>
> >
> > On Tue, 2026-11-10 at 16:33 +0100, Alejandro Colomar wrote:
> > 
> > no commit description on proposed patch  
> 
> There isn't much to say, but I'll add something (the explanation of why
> the parentheses are needed around the function name, for example).
> 
> > > Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
> > > Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > > ---
> > >  include/linux/string.h | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/include/linux/string.h b/include/linux/string.h
> > > index 9e59f9697c9e..55ca4cb5122c 100644
> > > --- a/include/linux/string.h
> > > +++ b/include/linux/string.h
> > > @@ -590,7 +590,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
> > >   * *  @s+strlen(@prefix) if @s starts with @prefix
> > >   * *  NULL if @s does not start with @prefix
> > >   */
> > > -static inline char *strprefix(const char *s, const char *prefix)
> > > +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
> > > +
> > > +static inline char *(strprefix)(const char *s, const char *prefix)  
> > 
> > Why introduce a new coding style?  
> 
> It's not style; the parentheses are technically needed to avoid macro
> expansion, since the macro has the same name as the function.
> 
> Alternatively, I could rename the function to __strprefix().

Or put the #define after the function definition.

David

> 
> 
> Have a lovely night!
> Alex
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
  2026-11-10 15:44   ` sashiko-bot
  2026-11-10 16:32   ` Joe Perches
@ 2026-11-11 10:34   ` David Laight
  2026-11-11 11:28     ` Alejandro Colomar
  2 siblings, 1 reply; 21+ messages in thread
From: David Laight @ 2026-11-11 10:34 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-hardening, Krzysztof Kozlowski, Maciej W. Rozycki,
	Geert Uytterhoeven, Andreas Schwab, Andy Shevchenko,
	Bartosz Golaszewski, Daniel Scally, Danilo Krummrich,
	Greg Kroah-Hartman, Hans Verkuil, Heikki Krogerus, Joe Perches,
	Johan Hovold, Kees Cook, Laurent Pinchart, Len Brown,
	Linus Torvalds, Linus Walleij, Namhyung Kim, Rafael J. Wysocki,
	Rob Herring, Sakari Ailus, Saravana Kannan, Steven Rostedt,
	Tom Zanussi, linux-acpi, driver-core, linux-kernel, devicetree,
	linux-gpio

On Tue, 10 Nov 2026 16:33:56 +0100
Alejandro Colomar <alx@kernel.org> wrote:

> Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>  include/linux/string.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/string.h b/include/linux/string.h
> index 9e59f9697c9e..55ca4cb5122c 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -590,7 +590,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
>   * *  @s+strlen(@prefix) if @s starts with @prefix
>   * *  NULL if @s does not start with @prefix
>   */
> -static inline char *strprefix(const char *s, const char *prefix)
> +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))

Isn't in enough to do:
#define strprefix(s, pfx) ((typeof(s))strprefix(s, pfx))

which correctly preserves all qualifiers.

David

> +
> +static inline char *(strprefix)(const char *s, const char *prefix)
>  {
>  	size_t len = strlen(prefix);
>  	return strncmp(s, prefix, len) == 0 ? (char *) s + len : NULL;


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 3/5] stddef: Add const_cast()
  2026-11-11 10:25   ` David Laight
@ 2026-11-11 10:51     ` Alejandro Colomar
  0 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-11 10:51 UTC (permalink / raw)
  To: David Laight
  Cc: Alejandro Colomar, linux-hardening, Krzysztof Kozlowski,
	Maciej W. Rozycki, Geert Uytterhoeven, Andreas Schwab,
	Andy Shevchenko, Bartosz Golaszewski, Daniel Scally,
	Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Joe Perches, Johan Hovold, Kees Cook,
	Laurent Pinchart, Len Brown, Linus Torvalds, Linus Walleij,
	Namhyung Kim, Rafael J. Wysocki, Rob Herring, Sakari Ailus,
	Saravana Kannan, Steven Rostedt, Tom Zanussi, linux-acpi,
	driver-core, linux-kernel, devicetree, linux-gpio

[-- Attachment #1: Type: text/plain, Size: 2709 bytes --]

Hi David,

> Date: 2026-11-11 10:25:35+0000
> From: David Laight <david.laight.linux@gmail.com>
>
> On Tue, 10 Nov 2026 16:33:40 +0100
> Alejandro Colomar <alx@kernel.org> wrote:
> 
> > This macro serves to cast const away without risking unwanted
> > conversions due to mistakes in the cast.
> > 
> > It's similar to C++'s const_cast(), but it is more restrictive: it can
> > only cast away 'const', and not arbitrary qualifiers.
> > 
> > Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > ---
> >  include/linux/stddef.h | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> > index e1851c50c89b..d79a81406b78 100644
> > --- a/include/linux/stddef.h
> > +++ b/include/linux/stddef.h
> > @@ -194,4 +194,16 @@ enum {
> >  #define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS)				\
> >  	__TRAILING_OVERLAP(TYPE, NAME, FAM, /* no attrs */, MEMBERS)
> >  
> > +/**
> > + * const_cast() - Drop const in the left-most derivation of a pointer
> > + *
> > + * @T: Type for the cast.
> > + * @p: Pointer to be casted.
> > + *
> > + * If @p is of type const @T, then it is casted to @T.
> > + * Otherwise, @p is returned without any casts.
> > + * This avoids mistakes that change anything other than 'const' in a cast.
> > + */
> > +#define const_cast(T, p)  _Generic(p, const T: (T) (p), default: (p))
> 
> Should it be de_const_cast(), or just de_const().

If we want to be explicit about it being for dropping, perhaps
drop_const() or cast_drop_const() feels more readable to me than
de_const().  I had been calling this const_cast() for following C++'s
name.

> It is a shame you need to specify the type,

In some cases we don't want to drop const; it's a "maybe drop const",
actually.  Perhaps for this reason, cast_drop_const() might be
misleading, in that it tells you that it dropped const, but sometimes
it didn't.  On the other hand, if you thougt you had dropped const and
haven't, you'll get build errors, so it's not a big problem.

The reason why we may want to not drop const is that since we do:

	const_cast(CQChar_of(s) *, strprefix(s, pfx))

'CQChar_of() *' expands to either 'const char *' or 'char *', depending
on the qualification of 's'.  In case it expands to 'const char *', we
want to retain const, and not drop it.  The most accurate name would be
cast_at_most_drop_const_but_maybe_not().  :)

> but why not:
> 	_Generic(p, T: p, const T: (T)(p))
> so that you get a compile time error from the _Generic() if the type
> is wrong.

Thanks!  I like that being more robust.


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-11 10:28       ` David Laight
@ 2026-11-11 10:59         ` Alejandro Colomar
  0 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-11 10:59 UTC (permalink / raw)
  To: David Laight
  Cc: Joe Perches, Alejandro Colomar, linux-hardening,
	Krzysztof Kozlowski, Maciej W. Rozycki, Geert Uytterhoeven,
	Andreas Schwab, Andy Shevchenko, Bartosz Golaszewski,
	Daniel Scally, Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Johan Hovold, Kees Cook, Laurent Pinchart,
	Len Brown, Linus Torvalds, Linus Walleij, Namhyung Kim,
	Rafael J. Wysocki, Rob Herring, Sakari Ailus, Saravana Kannan,
	Steven Rostedt, Tom Zanussi, linux-acpi, driver-core,
	linux-kernel, devicetree, linux-gpio

[-- Attachment #1: Type: text/plain, Size: 2013 bytes --]

Hi David,

> Date: 2026-11-11 10:28:36+0000
> From: David Laight <david.laight.linux@gmail.com>
>
> On Wed, 11 Nov 2026 00:27:28 +0100
> Alejandro Colomar <alx+linux-hardening@kernel.org> wrote:
> 
> > Hi Joe,
> > 
> > > Date: 2026-11-10 08:32:41-0800
> > > From: Joe Perches <joe@perches.com>
> > >
> > > On Tue, 2026-11-10 at 16:33 +0100, Alejandro Colomar wrote:
> > > 
> > > no commit description on proposed patch  
> > 
> > There isn't much to say, but I'll add something (the explanation of why
> > the parentheses are needed around the function name, for example).
> > 
> > > > Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org>
> > > > Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > > > ---
> > > >  include/linux/string.h | 4 +++-
> > > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/include/linux/string.h b/include/linux/string.h
> > > > index 9e59f9697c9e..55ca4cb5122c 100644
> > > > --- a/include/linux/string.h
> > > > +++ b/include/linux/string.h
> > > > @@ -590,7 +590,9 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
> > > >   * *  @s+strlen(@prefix) if @s starts with @prefix
> > > >   * *  NULL if @s does not start with @prefix
> > > >   */
> > > > -static inline char *strprefix(const char *s, const char *prefix)
> > > > +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
> > > > +
> > > > +static inline char *(strprefix)(const char *s, const char *prefix)  
> > > 
> > > Why introduce a new coding style?  
> > 
> > It's not style; the parentheses are technically needed to avoid macro
> > expansion, since the macro has the same name as the function.
> > 
> > Alternatively, I could rename the function to __strprefix().
> 
> Or put the #define after the function definition.

Done for v4.


Cheers,
Alex

> 
> David
> 
> > 
> > 
> > Have a lovely night!
> > Alex
> > 
> 
> 

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic
  2026-11-11 10:34   ` David Laight
@ 2026-11-11 11:28     ` Alejandro Colomar
  0 siblings, 0 replies; 21+ messages in thread
From: Alejandro Colomar @ 2026-11-11 11:28 UTC (permalink / raw)
  To: David Laight
  Cc: Alejandro Colomar, linux-hardening, Krzysztof Kozlowski,
	Maciej W. Rozycki, Geert Uytterhoeven, Andreas Schwab,
	Andy Shevchenko, Bartosz Golaszewski, Daniel Scally,
	Danilo Krummrich, Greg Kroah-Hartman, Hans Verkuil,
	Heikki Krogerus, Joe Perches, Johan Hovold, Kees Cook,
	Laurent Pinchart, Len Brown, Linus Torvalds, Linus Walleij,
	Namhyung Kim, Rafael J. Wysocki, Rob Herring, Sakari Ailus,
	Saravana Kannan, Steven Rostedt, Tom Zanussi, linux-acpi,
	driver-core, linux-kernel, devicetree, linux-gpio

[-- Attachment #1: Type: text/plain, Size: 774 bytes --]

Hi David,

> Date: 2026-11-11 10:34:38+0000
> From: David Laight <david.laight.linux@gmail.com>
>
[...]
> > -static inline char *strprefix(const char *s, const char *prefix)
> > +#define strprefix(s, pfx)  const_cast(CQChar_of(s) *, strprefix(s, pfx))
> 
> Isn't in enough to do:
> #define strprefix(s, pfx) ((typeof(s))strprefix(s, pfx))
> 
> which correctly preserves all qualifiers.

This would return a const void* if you pass a const void*.  In general,
we shouldn't be passing a void* to a string function, but C allows this.
With CQChar_of(), you coerce a 'const void *' into a 'const char *'.

See also: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3998.pdf#subsection.0.7.28.5>


Cheers,
Alex

-- 
<https://www.alejandro-colomar.es>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2026-11-11 11:28 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-10 15:33 [PATCH v3 0/5] Add strprefix() and fix a bug with it Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 1/5] string: Add strprefix(), and deprecate str_has_prefix() Alejandro Colomar
2026-11-10 15:47   ` Joe Perches
2026-11-10 16:14     ` Alejandro Colomar
2026-11-11  8:43   ` Steven Rostedt
2026-11-10 15:33 ` [PATCH v3 2/5] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 3/5] stddef: Add const_cast() Alejandro Colomar
2026-11-11 10:25   ` David Laight
2026-11-11 10:51     ` Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 4/5] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
2026-11-10 15:45   ` sashiko-bot
2026-11-11  0:03     ` Alejandro Colomar
2026-11-10 15:33 ` [PATCH v3 5/5] string: Make strprefix() const-qualifier-generic Alejandro Colomar
2026-11-10 15:44   ` sashiko-bot
2026-11-11  0:27     ` Alejandro Colomar
2026-11-10 16:32   ` Joe Perches
2026-11-10 23:27     ` Alejandro Colomar
2026-11-11 10:28       ` David Laight
2026-11-11 10:59         ` Alejandro Colomar
2026-11-11 10:34   ` David Laight
2026-11-11 11:28     ` Alejandro Colomar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox