automation/eclair_analysis/ECLAIR/deviations.ecl | 9 +++++++++ docs/misra/deviations.rst | 9 +++++++++ docs/misra/rules.rst | 5 ++++- 3 files changed, 22 insertions(+), 1 deletion(-)
bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() and
strstr() all accept a const pointer/object but return a non-const pointer
to the matched element or byte, matching their standard C library
interfaces. The const qualifier is deliberately stripped so that callers
searching a non-const object get back a mutable pointer to it. Fixing
this would require changing the public API, so document these uses as
deviations instead.
Update docs/misra/rules.rst to note that this class of double-use
library functions is deviated on a per-function basis.
Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
---
Test CI pipeline: https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/2892411430
---
automation/eclair_analysis/ECLAIR/deviations.ecl | 9 +++++++++
docs/misra/deviations.rst | 9 +++++++++
docs/misra/rules.rst | 5 ++++-
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/automation/eclair_analysis/ECLAIR/deviations.ecl b/automation/eclair_analysis/ECLAIR/deviations.ecl
index 33d508a2fb..0b87bd1d6f 100644
--- a/automation/eclair_analysis/ECLAIR/deviations.ecl
+++ b/automation/eclair_analysis/ECLAIR/deviations.ecl
@@ -445,6 +445,15 @@ write or not"
-config=MC3A2.R11.8,reports+={safe,"any_area(any_loc(text(^.*__hvm_copy.*HVMCOPY_to_guest doesn't modify.*$)))"}
-doc_end
+-doc_begin="Functions bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(),
+strrchr() and strstr() accept a const pointer/object and return a non-const
+pointer to the matched element or byte, matching their standard C library
+interfaces. The const qualifier is deliberately stripped so that callers
+searching a non-const object get back a mutable pointer. This use is deemed
+safe."
+-config=MC3A2.R11.8,reports+={safe,"any_area(any_loc(file(^xen/include/xen/bsearch\\.h|xen/lib/memchr\\.c|xen/lib/memchr_inv\\.c|xen/lib/strchr\\.c|xen/lib/strpbrk\\.c|xen/lib/strrchr\\.c|xen/lib/strstr\\.c$)))"}
+-doc_end
+
-doc_begin="This construct is used to check if the type is scalar, and for this purpose the use of 0 as a null pointer constant is deliberate."
-config=MC3A2.R11.9,reports+={deliberate, "any_area(any_loc(any_exp(macro(^__ACCESS_ONCE$))))"
}
diff --git a/docs/misra/deviations.rst b/docs/misra/deviations.rst
index b048309596..e3ad3545bc 100644
--- a/docs/misra/deviations.rst
+++ b/docs/misra/deviations.rst
@@ -427,6 +427,15 @@ Deviations related to MISRA C:2012 Rules:
readability.
- Tagged as `safe` for ECLAIR.
+ * - R11.8
+ - Functions bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(),
+ strrchr() and strstr() accept a const pointer/object and return a
+ non-const pointer to the matched element or byte, matching their
+ standard C library interfaces. The const qualifier is deliberately
+ stripped so that callers searching a non-const object get back a
+ mutable pointer. This use is deemed safe.
+ - Tagged as `safe` for ECLAIR.
+
* - R11.9
- __ACCESS_ONCE uses an integer, which happens to be zero, as a
compile time check. The typecheck uses a cast. The usage of zero or other
diff --git a/docs/misra/rules.rst b/docs/misra/rules.rst
index c9bbab6c08..644e897558 100644
--- a/docs/misra/rules.rst
+++ b/docs/misra/rules.rst
@@ -469,7 +469,10 @@ maintainers if you want to suggest a change.
* - `Rule 11.8 <https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_11_08.c>`_
- Required
- A cast shall not remove any const or volatile qualification from the type pointed to by a pointer
- -
+ - Some standard C library-style functions are inherently double-use,
+ accepting a const argument and returning a non-const pointer into
+ it so that callers searching a non-const object get back a
+ mutable pointer. Such uses are deviated on a per-function basis.
* - `Rule 11.9 <https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_11_09.c>`_
- Required
--
2.43.0
On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote: > bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() and > strstr() all accept a const pointer/object but return a non-const pointer > to the matched element or byte, matching their standard C library > interfaces. The const qualifier is deliberately stripped so that callers > searching a non-const object get back a mutable pointer to it. Fixing > this would require changing the public API, so document these uses as > deviations instead. > > Update docs/misra/rules.rst to note that this class of double-use > library functions is deviated on a per-function basis. > > Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com> When I prepared my 11.8 series [1], I was wondering whether we need to go as far as deviating these. Since we now uniformly take gcc5 as minimum baseline, there is (at least in theory) the option of using _Generic to cover the dual-use. One question there is whether Eclair would recognize such - Nicola? After all, looking at e.g. glibc's implementation, the functions themselves remain "unsafe" there; it's a macro wrapping them which puts the lost qualifier back. Another question is about memchr_inv(): That's not a standard function, and hence it also doesn't need to strictly follow the pattern of those other functions. In no case should it, imo, be mixed with the standard functions without mentioning the difference. Jan [1] https://lists.xen.org/archives/html/xen-devel/2026-09/msg00036.html
On 2026-09-29 15:40, Jan Beulich wrote: > On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote: >> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() and >> strstr() all accept a const pointer/object but return a non-const >> pointer >> to the matched element or byte, matching their standard C library >> interfaces. The const qualifier is deliberately stripped so that >> callers >> searching a non-const object get back a mutable pointer to it. Fixing >> this would require changing the public API, so document these uses as >> deviations instead. >> >> Update docs/misra/rules.rst to note that this class of double-use >> library functions is deviated on a per-function basis. >> >> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com> > > When I prepared my 11.8 series [1], I was wondering whether we need to > go > as far as deviating these. Since we now uniformly take gcc5 as minimum > baseline, there is (at least in theory) the option of using _Generic to > cover the dual-use. One question there is whether Eclair would > recognize > such - Nicola? After all, looking at e.g. glibc's implementation, the > functions themselves remain "unsafe" there; it's a macro wrapping them > which puts the lost qualifier back. > Could you provide a concrete example? In passing, for stronger guarantees w.r.t. _Generic it would be better to switch to MISRA C:2012 Amendment 3, which has specific support for that feature. Keeping AMD2 and using _Generic weakens a bit the safety argument (though one can do an analysis himself, of course). > Another question is about memchr_inv(): That's not a standard function, > and hence it also doesn't need to strictly follow the pattern of those > other functions. In no case should it, imo, be mixed with the standard > functions without mentioning the difference. > > Jan > > [1] https://lists.xen.org/archives/html/xen-devel/2026-09/msg00036.html -- Nicola Vetrini, B.Sc. Software Engineer BUGSENG (https://bugseng.com) LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On 29.09.2026 16:56, Nicola Vetrini wrote:
> On 2026-09-29 15:40, Jan Beulich wrote:
>> On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote:
>>> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() and
>>> strstr() all accept a const pointer/object but return a non-const
>>> pointer
>>> to the matched element or byte, matching their standard C library
>>> interfaces. The const qualifier is deliberately stripped so that
>>> callers
>>> searching a non-const object get back a mutable pointer to it. Fixing
>>> this would require changing the public API, so document these uses as
>>> deviations instead.
>>>
>>> Update docs/misra/rules.rst to note that this class of double-use
>>> library functions is deviated on a per-function basis.
>>>
>>> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
>>
>> When I prepared my 11.8 series [1], I was wondering whether we need to
>> go
>> as far as deviating these. Since we now uniformly take gcc5 as minimum
>> baseline, there is (at least in theory) the option of using _Generic to
>> cover the dual-use. One question there is whether Eclair would
>> recognize
>> such - Nicola? After all, looking at e.g. glibc's implementation, the
>> functions themselves remain "unsafe" there; it's a macro wrapping them
>> which puts the lost qualifier back.
>
> Could you provide a concrete example?
From glibc 2.43:
# define __glibc_const_generic(PTR, CTYPE, CALL) \
_Generic (0 ? (PTR) : (void *) 1, \
const void *: (CTYPE) (CALL), \
default: CALL)
while the declarations still are e.g.
extern void *memchr (const void *__s, int __c, size_t __n)
__THROW __attribute_pure__ __nonnull ((1));
(and hence the implementation still - necessarily - casts away
const-ness).
> In passing, for stronger
> guarantees w.r.t. _Generic it would be better to switch to MISRA C:2012
> Amendment 3, which has specific support for that feature. Keeping AMD2
> and using _Generic weakens a bit the safety argument (though one can do
> an analysis himself, of course).
As this keeps coming up, we surely want to discuss / progress this move.
Jan
On 2026-09-29 17:11, Jan Beulich wrote: > On 29.09.2026 16:56, Nicola Vetrini wrote: >> On 2026-09-29 15:40, Jan Beulich wrote: >>> On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote: >>>> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() >>>> and >>>> strstr() all accept a const pointer/object but return a non-const >>>> pointer >>>> to the matched element or byte, matching their standard C library >>>> interfaces. The const qualifier is deliberately stripped so that >>>> callers >>>> searching a non-const object get back a mutable pointer to it. >>>> Fixing >>>> this would require changing the public API, so document these uses >>>> as >>>> deviations instead. >>>> >>>> Update docs/misra/rules.rst to note that this class of double-use >>>> library functions is deviated on a per-function basis. >>>> >>>> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com> >>> >>> When I prepared my 11.8 series [1], I was wondering whether we need >>> to >>> go >>> as far as deviating these. Since we now uniformly take gcc5 as >>> minimum >>> baseline, there is (at least in theory) the option of using _Generic >>> to >>> cover the dual-use. One question there is whether Eclair would >>> recognize >>> such - Nicola? After all, looking at e.g. glibc's implementation, the >>> functions themselves remain "unsafe" there; it's a macro wrapping >>> them >>> which puts the lost qualifier back. >> >> Could you provide a concrete example? > > From glibc 2.43: > > # define __glibc_const_generic(PTR, CTYPE, CALL) \ > _Generic (0 ? (PTR) : (void *) 1, \ > const void *: (CTYPE) (CALL), \ > default: CALL) > > while the declarations still are e.g. > > extern void *memchr (const void *__s, int __c, size_t __n) > __THROW __attribute_pure__ __nonnull ((1)); > > (and hence the implementation still - necessarily - casts away > const-ness). > Ok, will look into that >> In passing, for stronger >> guarantees w.r.t. _Generic it would be better to switch to MISRA >> C:2012 >> Amendment 3, which has specific support for that feature. Keeping AMD2 >> and using _Generic weakens a bit the safety argument (though one can >> do >> an analysis himself, of course). > > As this keeps coming up, we surely want to discuss / progress this > move. > > Jan That makes a lot of sense. We could add to the next community call or maintainers/committers call to present the problem and propose a way forward so that all stakeholders are aware. From my side, I can explain what moving from one to the other can entail in terms of static analysis, while others (e.g. Andrew Cooper) may expand a bit on specific C11/C18 features is desirable aside from safety. -- Nicola Vetrini, B.Sc. Software Engineer BUGSENG (https://bugseng.com) LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On 29/09/2026 6:52 pm, Nicola Vetrini wrote: > On 2026-09-29 17:11, Jan Beulich wrote: >> On 29.09.2026 16:56, Nicola Vetrini wrote: >>> On 2026-09-29 15:40, Jan Beulich wrote: >>>> On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote: >>>>> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() and >>>>> strstr() all accept a const pointer/object but return a non-const >>>>> pointer >>>>> to the matched element or byte, matching their standard C library >>>>> interfaces. The const qualifier is deliberately stripped so that >>>>> callers >>>>> searching a non-const object get back a mutable pointer to it. Fixing >>>>> this would require changing the public API, so document these uses as >>>>> deviations instead. >>>>> >>>>> Update docs/misra/rules.rst to note that this class of double-use >>>>> library functions is deviated on a per-function basis. >>>>> >>>>> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com> >>>> >>>> When I prepared my 11.8 series [1], I was wondering whether we need to >>>> go >>>> as far as deviating these. Since we now uniformly take gcc5 as minimum >>>> baseline, there is (at least in theory) the option of using >>>> _Generic to >>>> cover the dual-use. One question there is whether Eclair would >>>> recognize >>>> such - Nicola? After all, looking at e.g. glibc's implementation, the >>>> functions themselves remain "unsafe" there; it's a macro wrapping them >>>> which puts the lost qualifier back. >>> >>> Could you provide a concrete example? >> >> From glibc 2.43: >> >> # define __glibc_const_generic(PTR, CTYPE, CALL) \ >> _Generic (0 ? (PTR) : (void *) 1, \ >> const void *: (CTYPE) (CALL), \ >> default: CALL) >> >> while the declarations still are e.g. >> >> extern void *memchr (const void *__s, int __c, size_t __n) >> __THROW __attribute_pure__ __nonnull ((1)); >> >> (and hence the implementation still - necessarily - casts away >> const-ness). >> > > Ok, will look into that We are going to have to deviate the implementation, even if we are using _Generic() to force const-correct behaviour from the callers. We could duplicate the functions, but there's a different rule about that. We can't use ELF aliasing tricks because that breaks software type-hashing techniques for control-flow integrity. > >>> In passing, for stronger >>> guarantees w.r.t. _Generic it would be better to switch to MISRA C:2012 >>> Amendment 3, which has specific support for that feature. Keeping AMD2 >>> and using _Generic weakens a bit the safety argument (though one can do >>> an analysis himself, of course). >> >> As this keeps coming up, we surely want to discuss / progress this move. >> >> Jan > > That makes a lot of sense. We could add to the next community call or > maintainers/committers call to present the problem and propose a way > forward so that all stakeholders are aware. From my side, I can > explain what moving from one to the other can entail in terms of > static analysis, while others (e.g. Andrew Cooper) may expand a bit on > specific C11/C18 features is desirable aside from safety. > What I've got for now is all in https://gitlab.com/xen-project/xen/-/work_items/201 We want _Generic() for const-correctness reasons only. (And possibly API transition work - this has mixed results but can substantially reduce churn in a series if done well). This depends on moving to C11, which we need to at some point anyway even if weren't for _Generic(). The other area was the use of auto, but that's sorted now and will continue to be an implementation extension until we get to the point of considering C23. ~Andrew
On 2026-10-01 14:39, Andrew Cooper wrote:
> On 29/09/2026 6:52 pm, Nicola Vetrini wrote:
>> On 2026-09-29 17:11, Jan Beulich wrote:
>>> On 29.09.2026 16:56, Nicola Vetrini wrote:
>>>> On 2026-09-29 15:40, Jan Beulich wrote:
>>>>> On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote:
>>>>>> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr()
>>>>>> and
>>>>>> strstr() all accept a const pointer/object but return a non-const
>>>>>> pointer
>>>>>> to the matched element or byte, matching their standard C library
>>>>>> interfaces. The const qualifier is deliberately stripped so that
>>>>>> callers
>>>>>> searching a non-const object get back a mutable pointer to it.
>>>>>> Fixing
>>>>>> this would require changing the public API, so document these uses
>>>>>> as
>>>>>> deviations instead.
>>>>>>
>>>>>> Update docs/misra/rules.rst to note that this class of double-use
>>>>>> library functions is deviated on a per-function basis.
>>>>>>
>>>>>> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
>>>>>
>>>>> When I prepared my 11.8 series [1], I was wondering whether we need
>>>>> to
>>>>> go
>>>>> as far as deviating these. Since we now uniformly take gcc5 as
>>>>> minimum
>>>>> baseline, there is (at least in theory) the option of using
>>>>> _Generic to
>>>>> cover the dual-use. One question there is whether Eclair would
>>>>> recognize
>>>>> such - Nicola? After all, looking at e.g. glibc's implementation,
>>>>> the
>>>>> functions themselves remain "unsafe" there; it's a macro wrapping
>>>>> them
>>>>> which puts the lost qualifier back.
>>>>
>>>> Could you provide a concrete example?
>>>
>>> From glibc 2.43:
>>>
>>> # define __glibc_const_generic(PTR, CTYPE, CALL) \
>>> _Generic (0 ? (PTR) : (void *) 1, \
>>> const void *: (CTYPE) (CALL), \
>>> default: CALL)
>>>
>>> while the declarations still are e.g.
>>>
>>> extern void *memchr (const void *__s, int __c, size_t __n)
>>> __THROW __attribute_pure__ __nonnull ((1));
>>>
>>> (and hence the implementation still - necessarily - casts away
>>> const-ness).
>>>
>>
>> Ok, will look into that
>
> We are going to have to deviate the implementation, even if we are
> using
> _Generic() to force const-correct behaviour from the callers.
>
> We could duplicate the functions, but there's a different rule about
> that. We can't use ELF aliasing tricks because that breaks software
> type-hashing techniques for control-flow integrity.
>
Yeah. The internal cast is clearly still signaled by ECLAIR, regardless
of the surrounding context. That being said, the trick is quite nice and
it would actually be a stronger argument for a deviation in my opinion:
it mitigates the risk pointed out by the MISRA rule at the callsites. It
is also true that the C23 signature is a lot nicer in terms of typing
[1].
There's a slight friction with MISRA C Rule 23.5 ("A generic selection
should not depend on implicit pointer type conversion") from MISRA
C:2012 Amendment 3 for the non-const input case, because the type of the
controlling expression could match either alternative depending on the
context, but that's not a strong concern (Advisory rule, no associated
UB).
[1] https://en.cppreference.com/c/string/byte/memchr
--
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On 10/5/26 00:05, Nicola Vetrini wrote:
> On 2026-10-01 14:39, Andrew Cooper wrote:
>> On 29/09/2026 6:52 pm, Nicola Vetrini wrote:
>>> On 2026-09-29 17:11, Jan Beulich wrote:
>>>> On 29.09.2026 16:56, Nicola Vetrini wrote:
>>>>> On 2026-09-29 15:40, Jan Beulich wrote:
>>>>>> On 29.09.2026 11:03, Dmytro Prokopchuk1 wrote:
>>>>>>> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr()
>>>>>>> and
>>>>>>> strstr() all accept a const pointer/object but return a non-const
>>>>>>> pointer
>>>>>>> to the matched element or byte, matching their standard C library
>>>>>>> interfaces. The const qualifier is deliberately stripped so that
>>>>>>> callers
>>>>>>> searching a non-const object get back a mutable pointer to it.
>>>>>>> Fixing
>>>>>>> this would require changing the public API, so document these
>>>>>>> uses as
>>>>>>> deviations instead.
>>>>>>>
>>>>>>> Update docs/misra/rules.rst to note that this class of double-use
>>>>>>> library functions is deviated on a per-function basis.
>>>>>>>
>>>>>>> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
>>>>>>
>>>>>> When I prepared my 11.8 series [1], I was wondering whether we
>>>>>> need to
>>>>>> go
>>>>>> as far as deviating these. Since we now uniformly take gcc5 as
>>>>>> minimum
>>>>>> baseline, there is (at least in theory) the option of using
>>>>>> _Generic to
>>>>>> cover the dual-use. One question there is whether Eclair would
>>>>>> recognize
>>>>>> such - Nicola? After all, looking at e.g. glibc's implementation, the
>>>>>> functions themselves remain "unsafe" there; it's a macro wrapping
>>>>>> them
>>>>>> which puts the lost qualifier back.
>>>>>
>>>>> Could you provide a concrete example?
>>>>
>>>> From glibc 2.43:
>>>>
>>>> # define __glibc_const_generic(PTR, CTYPE, CALL) \
>>>> _Generic (0 ? (PTR) : (void *) 1, \
>>>> const void *: (CTYPE) (CALL), \
>>>> default: CALL)
>>>>
>>>> while the declarations still are e.g.
>>>>
>>>> extern void *memchr (const void *__s, int __c, size_t __n)
>>>> __THROW __attribute_pure__ __nonnull ((1));
>>>>
>>>> (and hence the implementation still - necessarily - casts away
>>>> const-ness).
>>>>
>>>
>>> Ok, will look into that
>>
>> We are going to have to deviate the implementation, even if we are using
>> _Generic() to force const-correct behaviour from the callers.
>>
>> We could duplicate the functions, but there's a different rule about
>> that. We can't use ELF aliasing tricks because that breaks software
>> type-hashing techniques for control-flow integrity.
>>
>
> Yeah. The internal cast is clearly still signaled by ECLAIR, regardless
> of the surrounding context. That being said, the trick is quite nice and
> it would actually be a stronger argument for a deviation in my opinion:
> it mitigates the risk pointed out by the MISRA rule at the callsites. It
> is also true that the C23 signature is a lot nicer in terms of typing [1].
>
> There's a slight friction with MISRA C Rule 23.5 ("A generic selection
> should not depend on implicit pointer type conversion") from MISRA
> C:2012 Amendment 3 for the non-const input case, because the type of the
> controlling expression could match either alternative depending on the
> context, but that's not a strong concern (Advisory rule, no associated UB).
>
> [1] https://eur01.safelinks.protection.outlook.com/?
> url=https%3A%2F%2Fen.cppreference.com%2Fc%2Fstring%2Fbyte%2Fmemchr&data=05%7C02%7Cdmytro_prokopchuk1%40epam.com%7C3402c71c34a844fdfaed08df225b3d77%7Cb41b72d04e9f4c268a69f949f367c91d%7C1%7C0%7C639267447530756053%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=0NM2ftsbEg98wGci7zbNyy%2BoESvP%2BqfU7%2Bz5OQKnNcc%3D&reserved=0
>
Combining all comments and answers I see the next steps to this patch:
- drop memchr_inv() from the deviation
- anchor the file patterns as ^...$||^...$
- group the xen/lib files together
- narrow the justification to the casts in the function bodies.
Any suggestions?
BR, Dmytro.
On 01.10.2026 14:39, Andrew Cooper wrote: > We want _Generic() for const-correctness reasons only. (And possibly > API transition work - this has mixed results but can substantially > reduce churn in a series if done well). > > This depends on moving to C11, which we need to at some point anyway > even if weren't for _Generic(). Why is this? Can't we use _Generic() as a compiler extension, i.e. without fully going to C11? Jan
On 01/10/2026 1:43 pm, Jan Beulich wrote: > On 01.10.2026 14:39, Andrew Cooper wrote: >> We want _Generic() for const-correctness reasons only. (And possibly >> API transition work - this has mixed results but can substantially >> reduce churn in a series if done well). >> >> This depends on moving to C11, which we need to at some point anyway >> even if weren't for _Generic(). > Why is this? Can't we use _Generic() as a compiler extension, i.e. without > fully going to C11? AIUI, the parsing rules had to change in C11 to support _Generic()'s syntax, and IIRC Eclair can't parse it without specifying C11 or later. ~Andrew
On 2026-10-01 15:16, Andrew Cooper wrote:
> On 01/10/2026 1:43 pm, Jan Beulich wrote:
>> On 01.10.2026 14:39, Andrew Cooper wrote:
>>> We want _Generic() for const-correctness reasons only. (And possibly
>>> API transition work - this has mixed results but can substantially
>>> reduce churn in a series if done well).
>>>
>>> This depends on moving to C11, which we need to at some point anyway
>>> even if weren't for _Generic().
>> Why is this? Can't we use _Generic() as a compiler extension, i.e.
>> without
>> fully going to C11?
>
> AIUI, the parsing rules had to change in C11 to support _Generic()'s
> syntax, and IIRC Eclair can't parse it without specifying C11 or later.
>
That's not true, ECLAIR copes just fine with _Generic regardless of the
-std:
0|$ cat p.c
void f(void) {
int x;
_Generic(x, int: 0, unsigned: 1);
}
nicola@nico:~
0|$ eclair_env -- gcc -std=c99 -c p.c
--
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On 2026-09-29 11:03, Dmytro Prokopchuk1 wrote:
> bsearch(), memchr(), memchr_inv(), strchr(), strpbrk(), strrchr() and
> strstr() all accept a const pointer/object but return a non-const
> pointer
> to the matched element or byte, matching their standard C library
> interfaces. The const qualifier is deliberately stripped so that
> callers
> searching a non-const object get back a mutable pointer to it. Fixing
> this would require changing the public API, so document these uses as
> deviations instead.
>
> Update docs/misra/rules.rst to note that this class of double-use
> library functions is deviated on a per-function basis.
>
> Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
> ---
> Test CI pipeline:
> https://gitlab.com/xen-project/people/dimaprkp4k/xen/-/pipelines/2892411430
> ---
> automation/eclair_analysis/ECLAIR/deviations.ecl | 9 +++++++++
> docs/misra/deviations.rst | 9 +++++++++
> docs/misra/rules.rst | 5 ++++-
> 3 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/automation/eclair_analysis/ECLAIR/deviations.ecl
> b/automation/eclair_analysis/ECLAIR/deviations.ecl
> index 33d508a2fb..0b87bd1d6f 100644
> --- a/automation/eclair_analysis/ECLAIR/deviations.ecl
> +++ b/automation/eclair_analysis/ECLAIR/deviations.ecl
> @@ -445,6 +445,15 @@ write or not"
>
> -config=MC3A2.R11.8,reports+={safe,"any_area(any_loc(text(^.*__hvm_copy.*HVMCOPY_to_guest
> doesn't modify.*$)))"}
> -doc_end
>
> +-doc_begin="Functions bsearch(), memchr(), memchr_inv(), strchr(),
> strpbrk(),
> +strrchr() and strstr() accept a const pointer/object and return a
> non-const
> +pointer to the matched element or byte, matching their standard C
> library
> +interfaces. The const qualifier is deliberately stripped so that
> callers
> +searching a non-const object get back a mutable pointer. This use is
> deemed
> +safe."
> +-config=MC3A2.R11.8,reports+={safe,"any_area(any_loc(file(^xen/include/xen/bsearch\\.h|xen/lib/memchr\\.c|xen/lib/memchr_inv\\.c|xen/lib/strchr\\.c|xen/lib/strpbrk\\.c|xen/lib/strrchr\\.c|xen/lib/strstr\\.c$)))"}
> +-doc_end
> +
I would say that the regex can be more compact than this. (e.g.
file(^xen/include/bsearch\\.h$||^xen/lib/(memchr|memchr_inv|strchr|strpbrk|strrchr|strstr)\\.c$)
)
> -doc_begin="This construct is used to check if the type is scalar, and
> for this purpose the use of 0 as a null pointer constant is
> deliberate."
> -config=MC3A2.R11.9,reports+={deliberate,
> "any_area(any_loc(any_exp(macro(^__ACCESS_ONCE$))))"
> }
> diff --git a/docs/misra/deviations.rst b/docs/misra/deviations.rst
> index b048309596..e3ad3545bc 100644
> --- a/docs/misra/deviations.rst
> +++ b/docs/misra/deviations.rst
> @@ -427,6 +427,15 @@ Deviations related to MISRA C:2012 Rules:
> readability.
> - Tagged as `safe` for ECLAIR.
>
> + * - R11.8
> + - Functions bsearch(), memchr(), memchr_inv(), strchr(),
> strpbrk(),
> + strrchr() and strstr() accept a const pointer/object and return
> a
> + non-const pointer to the matched element or byte, matching
> their
> + standard C library interfaces. The const qualifier is
> deliberately
> + stripped so that callers searching a non-const object get back
> a
> + mutable pointer. This use is deemed safe.
> + - Tagged as `safe` for ECLAIR.
> +
> * - R11.9
> - __ACCESS_ONCE uses an integer, which happens to be zero, as a
> compile time check. The typecheck uses a cast. The usage of
> zero or other
> diff --git a/docs/misra/rules.rst b/docs/misra/rules.rst
> index c9bbab6c08..644e897558 100644
> --- a/docs/misra/rules.rst
> +++ b/docs/misra/rules.rst
> @@ -469,7 +469,10 @@ maintainers if you want to suggest a change.
> * - `Rule 11.8
> <https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_11_08.c>`_
> - Required
> - A cast shall not remove any const or volatile qualification
> from the type pointed to by a pointer
> - -
> + - Some standard C library-style functions are inherently
> double-use,
> + accepting a const argument and returning a non-const pointer
> into
> + it so that callers searching a non-const object get back a
> + mutable pointer. Such uses are deviated on a per-function
> basis.
>
> * - `Rule 11.9
> <https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_11_09.c>`_
> - Required
--
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
© 2016 - 2026 Red Hat, Inc.