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 v2:
- Updated subject line;
- Updated commit message based on reviewers feedback.
Link to v1: https://patchew.org/Xen/8989bf6d8d245537628912a00f5ba4731b292fb1.1753738107.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 29.07.2025 14:21, Dmytro Prokopchuk1 wrote:
> --- 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
As I understand it, this is about any function, not just void (void *) ones.
Hence throughout anything textual in this patch, may I ask that this be made
explicit by inserting e.g. "e.g." everywhere?
I'm also on the edge of complaining again about the patch subject, as that's
still not quite accurate: It's only one direction in which things are safe.
Jan
On 2025-07-29 14:39, Jan Beulich wrote:
> On 29.07.2025 14:21, Dmytro Prokopchuk1 wrote:
>> --- 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
>
> As I understand it, this is about any function, not just void (void *)
> ones.
> Hence throughout anything textual in this patch, may I ask that this be
> made
> explicit by inserting e.g. "e.g." everywhere?
>
Technically yes, in practice other implicit function pointer conversions
would be caught by -Wincompatible-pointer-types and similar flags so
they don't even come into play. However I agree that adding that is
clearer.
> I'm also on the edge of complaining again about the patch subject, as
> that's
> still not quite accurate: It's only one direction in which things are
> safe.
>
> Jan
--
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On 29.07.2025 15:02, Nicola Vetrini wrote:
> On 2025-07-29 14:39, Jan Beulich wrote:
>> On 29.07.2025 14:21, Dmytro Prokopchuk1 wrote:
>>> --- 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
>>
>> As I understand it, this is about any function, not just void (void *)
>> ones.
>> Hence throughout anything textual in this patch, may I ask that this be
>> made
>> explicit by inserting e.g. "e.g." everywhere?
>
> Technically yes, in practice other implicit function pointer conversions
> would be caught by -Wincompatible-pointer-types and similar flags so
> they don't even come into play. However I agree that adding that is
> clearer.
Perhaps a misunderstanding: With "any" I meant any which has a noreturn
attribute, when converted to one with otherwise the same signature. But
irrespective of the particular return type or parameter types (i.e.
specifically not just void (void *) ones).
Jan
On 2025-07-29 15:09, Jan Beulich wrote:
> On 29.07.2025 15:02, Nicola Vetrini wrote:
>> On 2025-07-29 14:39, Jan Beulich wrote:
>>> On 29.07.2025 14:21, Dmytro Prokopchuk1 wrote:
>>>> --- 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
>>>
>>> As I understand it, this is about any function, not just void (void
>>> *)
>>> ones.
>>> Hence throughout anything textual in this patch, may I ask that this
>>> be
>>> made
>>> explicit by inserting e.g. "e.g." everywhere?
>>
>> Technically yes, in practice other implicit function pointer
>> conversions
>> would be caught by -Wincompatible-pointer-types and similar flags so
>> they don't even come into play. However I agree that adding that is
>> clearer.
>
> Perhaps a misunderstanding: With "any" I meant any which has a noreturn
> attribute, when converted to one with otherwise the same signature. But
> irrespective of the particular return type or parameter types (i.e.
> specifically not just void (void *) ones).
>
Ah, sorry, I misunderstood. We check the destination type of the
conversion with
"to(type(pointer(inner(return(builtin(void))&&all_param(1,
pointer(builtin(void)))))))". In principle it could be avoided but I
think that at the moment it's ok as it is, then if it needs to be
extended when more cases emerge I can do that.
--
Nicola Vetrini, B.Sc.
Software Engineer
BUGSENG (https://bugseng.com)
LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On 29.07.2025 15:16, Nicola Vetrini wrote:
> On 2025-07-29 15:09, Jan Beulich wrote:
>> On 29.07.2025 15:02, Nicola Vetrini wrote:
>>> On 2025-07-29 14:39, Jan Beulich wrote:
>>>> On 29.07.2025 14:21, Dmytro Prokopchuk1 wrote:
>>>>> --- 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
>>>>
>>>> As I understand it, this is about any function, not just void (void
>>>> *)
>>>> ones.
>>>> Hence throughout anything textual in this patch, may I ask that this
>>>> be
>>>> made
>>>> explicit by inserting e.g. "e.g." everywhere?
>>>
>>> Technically yes, in practice other implicit function pointer
>>> conversions
>>> would be caught by -Wincompatible-pointer-types and similar flags so
>>> they don't even come into play. However I agree that adding that is
>>> clearer.
>>
>> Perhaps a misunderstanding: With "any" I meant any which has a noreturn
>> attribute, when converted to one with otherwise the same signature. But
>> irrespective of the particular return type or parameter types (i.e.
>> specifically not just void (void *) ones).
>
> Ah, sorry, I misunderstood. We check the destination type of the
> conversion with
> "to(type(pointer(inner(return(builtin(void))&&all_param(1,
> pointer(builtin(void)))))))". In principle it could be avoided but I
> think that at the moment it's ok as it is, then if it needs to be
> extended when more cases emerge I can do that.
Oh, then my comment to Dmytro (still in context above) was wrong. But
why would we limit things as much? For noreturn functions a return type
of other than void is surely not to be expected, so that part is fine.
Yet any kinds of parameters would want to be permitted.
Jan
On 7/29/25 16:26, Jan Beulich wrote:
> On 29.07.2025 15:16, Nicola Vetrini wrote:
>> On 2025-07-29 15:09, Jan Beulich wrote:
>>> On 29.07.2025 15:02, Nicola Vetrini wrote:
>>>> On 2025-07-29 14:39, Jan Beulich wrote:
>>>>> On 29.07.2025 14:21, Dmytro Prokopchuk1 wrote:
>>>>>> --- 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
>>>>>
>>>>> As I understand it, this is about any function, not just void (void
>>>>> *)
>>>>> ones.
>>>>> Hence throughout anything textual in this patch, may I ask that this
>>>>> be
>>>>> made
>>>>> explicit by inserting e.g. "e.g." everywhere?
>>>>
>>>> Technically yes, in practice other implicit function pointer
>>>> conversions
>>>> would be caught by -Wincompatible-pointer-types and similar flags so
>>>> they don't even come into play. However I agree that adding that is
>>>> clearer.
>>>
>>> Perhaps a misunderstanding: With "any" I meant any which has a noreturn
>>> attribute, when converted to one with otherwise the same signature. But
>>> irrespective of the particular return type or parameter types (i.e.
>>> specifically not just void (void *) ones).
>>
>> Ah, sorry, I misunderstood. We check the destination type of the
>> conversion with
>> "to(type(pointer(inner(return(builtin(void))&&all_param(1,
>> pointer(builtin(void)))))))". In principle it could be avoided but I
>> think that at the moment it's ok as it is, then if it needs to be
>> extended when more cases emerge I can do that.
>
> Oh, then my comment to Dmytro (still in context above) was wrong. But
> why would we limit things as much? For noreturn functions a return type
> of other than void is surely not to be expected, so that part is fine.
> Yet any kinds of parameters would want to be permitted.
>
> Jan
As the Eclair tries to check the exact function prototype, deviation
wording is acceptable, per my understanding.
Regarding the patch subject, I may to change it to this:
"misra: allow discarding 'noreturn' during function pointer conversions".
Dmytro
© 2016 - 2025 Red Hat, Inc.