[C-safe-secure-studygroup] MISRA C:2012 Rule 11.6 - can undefined behaviour on conversion from intptr_t/uintptr_t to void * occur?

Fulvio Baccaglini fulvio_baccaglini at prqa.com
Thu May 31 13:54:12 BST 2018


During the last meeting Aaron raised an interesting query about this
first line in the rationale of Rule 11.6:
"Conversion of an integer into a pointer to void may result in a pointer
that is not correctly aligned, resulting in undefined behaviour."

Tentative argument:

Looking at the list of undefined behaviours in the C99 standard, this
entry looks applicable:
[C99-J.2.22] "Conversion between two pointer types produces a result
that is incorrectly aligned (6.3.2.3)."

In its most direct form:

~~~~~~~~>
short *  x;
long *   y;
y = (long *) x; // violates Rule 11.3 & possible incorrect alignment
<~~~~~~~~

However the conversion may also occur indirectly:

~~~~~~~~>
short *    x;
long *     y;
uintptr_t  i;

i = (uintptr_t) x;  // violates Rule 11.4
y = (long *) i;     // violates Rule 11.4 & possible incorrect alignment
<~~~~~~~~

I cannot find in the undefined behaviour list of the standard an entry
of the type: "conversion from an integer to a pointer type produces a
result that is incorrectly aligned", but I suppose that in this case
this would still fall under implicitly undefined behaviour.

Considering this example:

~~~~>
void *     v;
uintptr_t  i;

i = (uintptr_t) v;  // violates Rule 11.6
++ i;
v = (void *) i;     // violates Rule 11.6 - is incorrect alignment
possible here?
<~~~~

The standard says:

[C99-7.18.1.4] "The following type designates an unsigned integer type
with the property that any valid pointer to void can be converted to
this type, then converted back to pointer to void, and the result will
compare equal to the original pointer: uintptr_t"

[C99-6.2.5-27]: "A pointer to void shall have the same representation
and alignment requirements as a pointer to a character type".

[C99-3.2] "alignment - requirement that objects of a particular type be
located on storage boundaries with addresses that are particular
multiples of a byte address"

At the moment I cannot find anything in the standard that could prevent
an implementation from using 16 bits of physical memory for representing
a character type and a scale of 8 bits of physical memory for
representing an object of type uintptr_t.

In this situation incrementing an object of type uintptr_t would result
in incorrect alignment and the implicitly undefined behaviour
corresponding to [C99-J.2.22] would come into play.

Would this be possible, or am I missing something?

Another possible undefined behaviour could perhaps arise from an
implicit variant of:
[C99-J.2.15] "Conversion to or from an integer type produces a value
outside the range that can be represented (6.3.1.4)."

While uintptr_t and intptr_t would be required to represent all possible
values of void *, I believe that the reverse may not apply, and
arithmetic manipulation of an object of these types could lead to an out
of range condition when converting back to void *.

Fulvio
---------------------------------------------------------------------------------------
 This email has been scanned for email related threats and delivered safely by Mimecast.
 For more information please visit http://www.mimecast.com
---------------------------------------------------------------------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.trustable.io/pipermail/c-safe-secure-studygroup/attachments/20180531/3fd0ad47/attachment.html>


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