[C-safe-secure-studygroup] Tentative analysis of MISRA C:2012 Rule 11.7 for TS-17961 purposes

Fulvio Baccaglini fbaccaglini at perforce.com
Wed Oct 10 18:55:18 BST 2018


MISRA:C 2012 Rule 11.7 states: "A cast shall not be performed between
pointer to object and a non-integer arithmetic type"

Its Amplification indicates that in the context of this rule only, the
term "non-integer arithmetic type" is to be given a MISRA-specifc
meaning rather than a C standard meaning, i.e. a non-integer arithmetic
type is one of:

* Essentially Boolean
* Essentially character
* Essentially enum
* Essentially floating

These references to the C99 standard apply:

* [C99-J.3.7-1] - Implementation defined behaviour: "The result of
converting a pointer to an integer or vice versa"
* [C99-J.2-21] - Undefined behaviour: "Conversion of a pointer to an
integer type produces a value outside the range that can be
represented"
* [C99-J.2-41] - Undefined behaviour: "A pointer is converted to other
than an integer or pointer type"

Given the different severities of the associated implementation defined
behaviour, I think that it is worth decomposing [C99-J.3.7-1] into:
* [IDB-1] The result of converting a pointer to an integer
* [IDB-2] The result of converting an integer to a pointer

Here is a streamlined example, to try and highlight how behaviours and
MISRA C guideline violations may apply to 4 x 2 basic cases: 

~~~~~~~~>
#include <stdbool.h>

void f (void)
{
  extern int * x;

  //~~~~  Essentially Boolean  ~~~~

  bool b;

  b = (bool)  x;    // [IDB-1] [UB-21]  <==  R-11.4, R-11.7
  x = (int *) b;    // [IDB-2]          <==  R-11.4, R-11.7

  //~~~~  Essentially character  ~~~~

  char c;

  c = (char)  x;    // [IDB-1] [UB-21]  <==  R-11.4, R-11.7
  x = (int *) c;    // [IDB-2]          <==  R-11.4, R-11.7

  //~~~~  Essentially enum  ~~~~

  enum E { E1, E2 };

  enum E e;

  e = (enum E) x;   // [IDB-1] [UB-21]  <==  R-11.4, R-11.7
  x = (int *)  e;   // [IDB-2]          <==  R-11.4, R-11.7

  //~~~~  Essentially floating  ~~~~

  double d;

  d = (double) x;   // [UB-41]          <==  R-11.7
  x = (int *)  d;   // [?????]          <==  R-11.7
}
<~~~~~~~~

There is a significant overlap with Rule 11.4 "A conversion should not
be performed between a pointer to object and an integer type".

This is because in the context of Rule 11.4 the types '_Bool', 'char'
and the enumerated types are all integer types, as per ISO C99
definition.

Moreover, none of the referenced behaviours apply to the cast from
essentially Floating to pointer to object.

The ISO C99 standard does not define what the outcome of this cast
should be, and therefore I believe that it should be considered
implicitly undefined behaviour.

As of ISO C11 however, a new paragraph was added:
[C11-6.5.4-4] Cast operators - Constraints - "A pointer type shall not
be converted to any floating type. A floating type shall not be
converted to any pointer type."

This would then turn undefined behaviour into constraint violation and
make the essentially floating casts redundant with Rule 1.1.

Once those are taken off, it appears that the rest of Rule 11.7 may
become fully redundant with Rule 11.4.

So the tentative conclusion would be that Rule 11.7 may be ignored with
regards to TS-17961, unless I am missing something?

Fulvio





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