[C-safe-secure-studygroup] reframing rule 11.6 to focus on undefined behavior

Fulvio Baccaglini fbaccaglini at perforce.com
Tue Oct 9 12:12:18 BST 2018


On Mon, 2018-10-08 at 17:21 -0600, Martin Sebor wrote:
> On 10/08/2018 04:22 AM, Fulvio Baccaglini wrote:
> > 
> > On Sat, 2018-10-06 at 11:26 -0600, Martin Sebor wrote:
> > > 
> > > Besides the above, I note that by using the term "cast" the rule
> > > excludes implicit conversions from the set of diagnosable cases.
> > > For example:
> > > 
> > >    extern void *p;
> > >    int i = p;         // compliant (no cast here)
> > >    ++i;
> > >    p = i;             // undefined yet compliant
> > >    i = *(int*)p;      // ditto
> > > 
> > > This is almost certainly unintended and simply the result of
> > > sloppy wording, but it needs to be corrected if the rule is
> > > to impose meaningful binding requirements on analyzers.
> > My understanding is that ISO C definitions apply to MISRA C terms,
> > unless otherwise specified, and in particular the term "cast" in
> > Rule
> > 11.6 "A cast shall not be performed between pointer to void and an
> > arithmetic type" is intended, because:
> > 
> > (1) both 'int i = p;' and 'p = i;' are constraint violations, and
> > therefore already captured by Rule 1.1
> Unfortunately, there is no constraint in C that pointers cannot
> be implicitly converted to integers or vice versa.  In fact, C
> is explicit in 6.3.2.3 that:
> 
>    -5-  An integer may be converted to any pointer type. ...
>    -6-  Any pointer type may be converted to an integer type. ...
> 
> The result in both cases is implementation-defined and using
> it may be undefined.

I think that the following paragraphs apply:

[C99-6.5.4] Cast operators - Constraints: "Conversions that involve
pointers, other than where permitted by the constraints of 6.5.16.1,
shall be specified by means of an explicit cast."

[C99-6.5.16.1-1] Simple assignment - Constraints: "One of the following
shall hold:
- the left operand has qualified or unqualified arithmetic type and the
right has arithmetic type;
- the left operand has a qualified or unqualified version of a
structure or union type compatible with the type of the right;
- both operands are pointers to qualified or unqualified versions of
compatible types, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;
- one operand is a pointer to an object or incomplete type and the
other is a pointer to a qualified or unqualified version of void, and
the type pointed to by the left has all the qualifiers of the type
pointed to by the right;
- the left operand is a pointer and the right is a null pointer
constant; or
- the left operand has type _Bool and the right is a pointer."

[C99-5.1.1.3-1] "A conforming implementation shall produce at least one
diagnostic message (identified in an implementation-defined manner) if
a preprocessing translation unit or translation unit contains a
violation of any syntax rule or constraint, even if the behavior is
also explicitly specified as undefined or implementation-defined."

With regards to:

[C99-6.3.2.3-3] Pointers - "An integer constant expression with the
value 0, or such an expression cast to type void *, is called a null
pointer constant.

[C99-6.3.2.3-5] Pointers - "An integer may be converted to any pointer
type. Except as previously specified, the result is implementation-
defined, might not be correctly aligned, might not point to an entity
of the referenced type, and might be a trap representation."

[C99-6.3.2.3-6] Pointers - "Any pointer type may be converted to an
integer type. Except as previously specified, the result is
implementation-defined, might not be correctly aligned, might not point
to an entity of the referenced type, and might be a trap
representation."

I wonder why the term "converted" is used instead of the term "cast"?

Maybe because these implicit conversions between integers and pointers,
which do not violate constraint [C99-6.5.16.1-1], may apply:
- the left operand is a pointer and the right is a null pointer
constant
- the left operand has type _Bool and the right is a pointer

However my understanding is that they do not result in implementation-
defined behaviour, so that the only way an implicit conversion may be
affected by implementation-defined behaviour is to violate a constraint
(and therefore MISRA C Rule 1.1).




More information about the C-safe-secure-studygroup mailing list