automation/eclair_analysis/ECLAIR/deviations.ecl | 7 +++++++ docs/misra/deviations.rst | 6 ++++++ docs/misra/rules.rst | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-)
The conversion from a function pointer with the 'noreturn' attribute
('void noreturn (*)(void *)') to a function pointer type ('void (*)(void *)'
causes type incompatibility according to MISRA C Rule 11.1, which forbids
conversions between incompatible function pointer types.
The violation occurs at the call site:
smp_call_function(halt_this_cpu, NULL, 0);
where 'halt_this_cpu' with type 'void noreturn (*)(void *)' is passed to
'smp_call_function' expecting a function pointer of type 'void (*)(void *)'.
The 'noreturn' attribute does not change the function calling convention
or parameter handling at runtime, making the conversion safe.
Configure ECLAIR to treat implicit conversions that lose the "noreturn"
attribute on a function 'void (*)(void*)' as safe. This is because the
deviation actually just deviates 'void noreturn (*)(void*)' -> 'void (*)(void*)'.
Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
---
Changes in v3:
- updated commit subject
Link to v2: https://patchew.org/Xen/3b821bc506b04bf7ff8bf5a3712449d45429dc90.1753791398.git.dmytro._5Fprokopchuk1@epam.com/
---
automation/eclair_analysis/ECLAIR/deviations.ecl | 7 +++++++
docs/misra/deviations.rst | 6 ++++++
docs/misra/rules.rst | 3 ++-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/automation/eclair_analysis/ECLAIR/deviations.ecl b/automation/eclair_analysis/ECLAIR/deviations.ecl
index 483507e7b9..0e04681c4c 100644
--- a/automation/eclair_analysis/ECLAIR/deviations.ecl
+++ b/automation/eclair_analysis/ECLAIR/deviations.ecl
@@ -367,6 +367,13 @@ constant expressions are required.\""
}
-doc_end
+-doc_begin="The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)' is safe
+because the semantics of the 'noreturn' attribute do not alter the calling convention or behavior of the resulting code."
+-config=MC3A2.R11.1,casts+={safe,
+ "kind(bitcast)&&to(type(pointer(inner(return(builtin(void))&&all_param(1, pointer(builtin(void)))))))&&from(expr(skip(!syntactic(),
+ ref(property(noreturn)))))"}
+-doc_end
+
-doc_begin="The conversion from a pointer to an incomplete type to unsigned long does not lose any information, provided that the target type has enough bits to store it."
-config=MC3A2.R11.2,casts+={safe,
"from(type(any()))
diff --git a/docs/misra/deviations.rst b/docs/misra/deviations.rst
index e78179fcb8..4e430bb17e 100644
--- a/docs/misra/deviations.rst
+++ b/docs/misra/deviations.rst
@@ -342,6 +342,12 @@ Deviations related to MISRA C:2012 Rules:
semantics that do not lead to unexpected behaviour.
- Tagged as `safe` for ECLAIR.
+ * - R11.1
+ - The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)'
+ is safe because the semantics of the 'noreturn' attribute do not alter
+ the calling convention or behavior of the resulting code.
+ - Tagged as `safe` for ECLAIR.
+
* - R11.2
- The conversion from a pointer to an incomplete type to unsigned long
does not lose any information, provided that the target type has enough
diff --git a/docs/misra/rules.rst b/docs/misra/rules.rst
index 3e014a6298..82a26162a9 100644
--- a/docs/misra/rules.rst
+++ b/docs/misra/rules.rst
@@ -404,7 +404,8 @@ maintainers if you want to suggest a change.
function and any other type
- All conversions to integer types are permitted if the destination
type has enough bits to hold the entire value. Conversions to
- bool and void* are permitted.
+ bool and void* are permitted. Conversions from 'void noreturn (*)(void *)'
+ to 'void (*)(void *)' are permitted.
* - `Rule 11.2 <https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_11_02.c>`_
- Required
--
2.43.0
On 30.07.2025 23:47, Dmytro Prokopchuk1 wrote: > --- a/docs/misra/deviations.rst > +++ b/docs/misra/deviations.rst > @@ -342,6 +342,12 @@ Deviations related to MISRA C:2012 Rules: > semantics that do not lead to unexpected behaviour. > - Tagged as `safe` for ECLAIR. > > + * - R11.1 > + - The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)' > + is safe because the semantics of the 'noreturn' attribute do not alter > + the calling convention or behavior of the resulting code. > + - Tagged as `safe` for ECLAIR. As before, imo such a deviation should be generic, i.e. here independent of what parameters a function takes. If that can't be easily expressed to Eclair, then that wants stating as a justification for the deviations.ecl change to not fully cover the deviation we put in place. Having the textual deviation generic means later possible needs can be easily addressed by just a deviations.ecl change, without any adjustment to the deviations themselves. Jan
On 7/31/25 10:20, Jan Beulich wrote: > On 30.07.2025 23:47, Dmytro Prokopchuk1 wrote: >> --- a/docs/misra/deviations.rst >> +++ b/docs/misra/deviations.rst >> @@ -342,6 +342,12 @@ Deviations related to MISRA C:2012 Rules: >> semantics that do not lead to unexpected behaviour. >> - Tagged as `safe` for ECLAIR. >> >> + * - R11.1 >> + - The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)' >> + is safe because the semantics of the 'noreturn' attribute do not alter >> + the calling convention or behavior of the resulting code. >> + - Tagged as `safe` for ECLAIR. > > As before, imo such a deviation should be generic, i.e. here independent > of what parameters a function takes. If that can't be easily expressed > to Eclair, then that wants stating as a justification for the > deviations.ecl change to not fully cover the deviation we put in place. > Having the textual deviation generic means later possible needs can be > easily addressed by just a deviations.ecl change, without any adjustment > to the deviations themselves. > > Jan Hi, Jan Currently Eclair checks exact pointer type 'void (*)(void *)', as described in the configuration: to(type(pointer(inner(return(builtin(void))&&all_param(1, pointer(builtin(void))))))) Nicola wrote: "then if it needs to be extended when more cases emerge I can do that". So, for clarification. 1. In the file "deviations.ecl" I leave exist description and config: "The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)' is safe because the semantics of the 'noreturn' attribute do not alter the calling convention or behavior of the resulting code." 2. In the file "deviations.rst" I change the description to: "The conversion from `void noreturn (*)(...)` to `void (*)(...)` is safe because the semantics of the 'noreturn' attribute do not alter the calling convention or behavior of the resulting code, parameter handling remain consistent." 3. In the file "rules.rst" I change the description to: "Conversions from 'void noreturn (*)(...)' to 'void (*)(...)' are permitted." It means that only "deviations.ecl" needs to be updated if a new deviation needs to be addressed. Is it OK? Dmytro
On 31.07.2025 18:48, Dmytro Prokopchuk1 wrote: > > > On 7/31/25 10:20, Jan Beulich wrote: >> On 30.07.2025 23:47, Dmytro Prokopchuk1 wrote: >>> --- a/docs/misra/deviations.rst >>> +++ b/docs/misra/deviations.rst >>> @@ -342,6 +342,12 @@ Deviations related to MISRA C:2012 Rules: >>> semantics that do not lead to unexpected behaviour. >>> - Tagged as `safe` for ECLAIR. >>> >>> + * - R11.1 >>> + - The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)' >>> + is safe because the semantics of the 'noreturn' attribute do not alter >>> + the calling convention or behavior of the resulting code. >>> + - Tagged as `safe` for ECLAIR. >> >> As before, imo such a deviation should be generic, i.e. here independent >> of what parameters a function takes. If that can't be easily expressed >> to Eclair, then that wants stating as a justification for the >> deviations.ecl change to not fully cover the deviation we put in place. >> Having the textual deviation generic means later possible needs can be >> easily addressed by just a deviations.ecl change, without any adjustment >> to the deviations themselves. >> >> Jan > > Hi, Jan > > Currently Eclair checks exact pointer type 'void (*)(void *)', as > described in the configuration: > > to(type(pointer(inner(return(builtin(void))&&all_param(1, > pointer(builtin(void))))))) > > Nicola wrote: "then if it needs to be extended when more cases emerge I > can do that". > > So, for clarification. > > 1. In the file "deviations.ecl" I leave exist description and config: > "The conversion from 'void noreturn (*)(void *)' to 'void (*)(void *)' > is safe because the semantics of the 'noreturn' attribute do not alter > the calling convention or behavior of the resulting code." > > 2. In the file "deviations.rst" I change the description to: > "The conversion from `void noreturn (*)(...)` to `void (*)(...)` > is safe because the semantics of the 'noreturn' attribute do not alter > the calling convention or behavior of the resulting code, parameter > handling remain consistent." > > 3. In the file "rules.rst" I change the description to: > "Conversions from 'void noreturn (*)(...)' to 'void (*)(...)' are > permitted." > > It means that only "deviations.ecl" needs to be updated if a new > deviation needs to be addressed. > > > Is it OK? Yes, with the patch description also suitably adjusted. Jan
© 2016 - 2025 Red Hat, Inc.