(610) 584-4261 sales@gimpel.com
Request Evaluation Online Demo
Gimpel Software LLC Logo   Gimpel Software Evaluate Order Support News About

PC-lint Plus Support for MISRA C 2012

Gimpel Software has supported the MISRA community for nearly 20 years and is dedicated to providing reliable, best-in-class support for MISRA C 2012.

PC-lint Plus 1.3 provides support for almost all of the statically enforceable guidelines comprising MISRA C 2012, and the vast majority of these are comprehensively supported. Checking for MISRA C 2012 compliance is easily accomplished by adding a reference to the au-misra3.lnt file (distributed with PC-lint Plus) to your existing configuration. This file enables the messages which correspond to MISRA C 2012 guidelines and adds text to the issued messages specifying the specific rule(s) associated with each applicable message. The au-misra3.lnt file is a plain text, human-readable configuration file using standard PC-lint Plus option syntax that can easily be modified to meet the needs of any individual project.

The Reference Manual that ships with PC-lint Plus includes a support matrix detailing the level of support for each guideline as well as the mechanisms by which each guideline is supported.

Violation Analysis and Presentation

Consider the following example which contains many MISRA C 2012 violations:

    typedef short int16_t;
    typedef int int32_t;
    typedef unsigned short uint16_t;

    int32_t calc(uint16_t id_1, uint16_t id_2, int16_t *idl, uint16_t idl_size);
    int32_t calc(uint16_t id_1, uint16_t id_2, int16_t *idl, uint16_t idl_size) {
        if (idl_size && id_1 < idl_size && id_2 < idl_size)
            return idl[id_1] * idl[id_2] + idl[id_1];
        return 0;
    }

When analyzing this example with PC-lint Plus, the reported MISRA C 2012 violations include (among others):

    9046: 'idl' is typographically ambiguous with respect to 'id_1' when ignoring underscores,
        treating '1' as 'I', and treating 'l' as 'I' [MISRA 2012 Directive 4.5, advisory]
    int32_t calc(uint16_t id_1, uint16_t id_2, int16_t *idl, uint16_t idl_size);
                                                        ^
    891: previous declaration is here
    int32_t calc(uint16_t id_1, uint16_t id_2, int16_t *idl, uint16_t idl_size);
                          ^

    904: return statement before end of function 'calc' [MISRA 2012 Rule 15.5, advisory]
            return idl[id_1] * idl[id_2] + idl[id_1];
            ^

    9012: body should be a compound statement [MISRA 2012 Rule 15.6, required]
            return idl[id_1] * idl[id_2] + idl[id_1];
            ^

    9050: dependence placed on operator precedence (operators '&&' and '<') [MISRA 
        2012 Rule 12.1, advisory]
        if (idl_size && id_1 < idl_size && id_2 < idl_size)
                                        ^  ~~~~

    9027: an unsigned value is not an appropriate left operand to && [MISRA 2012 
        Rule 10.1, required]
        if (idl_size && id_1 < idl_size && id_2 < idl_size)
            ~~~~~~~~ ^

    9031: cannot assign a composite expression of type 'signed16' to an object of 
        wider type 'signed32' [MISRA 2012 Rule 10.6, required]
            return idl[id_1] * idl[id_2] + idl[id_1];
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    9050: dependence placed on operator precedence (operators '+' and '*') [MISRA 
        2012 Rule 12.1, advisory]
            return idl[id_1] * idl[id_2] + idl[id_1];
                             ~           ^

    818: parameter 'idl' of function 'calc(uint16_t, uint16_t, int16_t *, uint16_t)'
        could be pointer to const [MISRA 2012 Rule 8.13, advisory]
    int32_t calc(uint16_t id_1, uint16_t id_2, int16_t *idl,

Each violation reported includes the location where the violation occurred, a message number and textual description of the underlying issue, and the MISRA C 2012 Rule that was violated. For example, in the message:

    904: return statement before end of function 'calc' [MISRA 2012 Rule 15.5, advisory]
            return idl[id_1] * idl[id_2] + idl[id_1];
            ^

904 is the PC-lint Plus message number associated with the message that is issued when a return statement appears before the end of a function. The actual text of the message in this case is “return statement before end of function ‘calc’” which identifies the offending function. The MISRA Rule or Directive violated is included in square brackets at the end of the message text. The subsequent two lines show the context and position associated with the message.

Resolving Violations

The PC-lint Plus Reference Manual contains descriptions of each message and often provides additional guidance that can be used to correct the issue. This information can also be displayed on the command line. For example, to display the description of message 904, run PC-lint Plus with the option -help=904 to have PC-lint Plus display the following commentary:

    A return statement was found before the end of a function definition.
    Many programming standards require that functions contain a single exit
    point located at the end of the function. This can enhance readability
    and may make subsequent modification less error prone.

The MISRA C 2012 guidelines document can be consulted for information about the specified Rule or Directive.

One way to rewrite the calc function above to address the reported violations is:

    int32_t calc(uint16_t id_1, uint16_t id_2, const int16_t *id_list, uint16_t idl_size);
    int32_t calc(uint16_t id_1, uint16_t id_2, const int16_t *id_list, uint16_t idl_size) {
        int32_t result = 0;
        if ((idl_size > 0U) && (id_1 < idl_size) && (id_2 < idl_size)) {
            result = ((int32_t)id_list[id_1] * id_list[id_2]) + id_list[id_1];
        }
        return result;
    }

Handling Deviations

Deviations are instances in the source code where a violation of a Rule or Directive has been reviewed and deemed acceptable. The MISRA C 2012 document contains advisory, required, and mandatory guidelines. A compliant project may not deviate from mandatory guidelines but may contain approved deviations for required and advisory guidelines. While the deviation process will vary from project to project, deviations can be configured in PC-lint Plus using a very flexible suppression mechanism. Most messages can be suppressed in a variety of ways such as within a file, function, or statement, when referring to a particular symbol or type, or on a particular line. Some types of suppressions require a comment be added to the source code but most do not.

For example, MISRA 2012 Rule 15.5 (reported above by message 904) is an advisory rule recommending a single point of exit for every function. This message could be suppressed for the function calc using the option -efunc(904, calc) which can be placed either in the project configuration file or in your source code as a lint comment. The other messages from within this function could be suppressed in the same manner. Commentary can follow a suppression option which may include a rationale or formal deviation information.

Library Code

PC-lint Plus distinguishes between library code (which by default includes foreign and system headers but can be customized to include any subset of headers and modules) and project code. By default, PC-lint Plus will check both library code and project code for compliance with MISRA C 2012. It is often desired to limit checking to project code and this is easily accomplished by resetting the library warning level using the options -wlib=4 -wlib=1 after referencing the au-misra3.lnt file. Individual messages can also be enabled or disabled for library code just as easily using the -elib and +elib options.

Essential Type Calculation

PC-lint Plus can explain the steps involved in calculating the final essential type of a compound expression using the +f12 option. Message 9903 will be issued after full expressions to illustrate the MISRA C 2012 essential types involved in the expression and how they combine to form new essential types.

For example, given:

    int32_t f(int32_t a, int16_t b) {
        return (b + b) + (a + b);
    }

PC-lint Plus emits:

    note 9032: left operand to + is a composite expression of type 'signed16'
               which is smaller than the right operand of type 'signed32'
               [MISRA 2012 Rule 10.7, required]
        return (b + b) + (a + b);
               ~~~~~~~ ^

Why is the left side signed16 and the right side signed32?

Processing the example with +f12 and +e9903 yields the step by step evaluation of the expression with the corresponding essential types involved at each step:
    info 9903: (signed16 + signed16) + (signed32 + signed16)
    info 9903: (signed16) + (signed32)
    info 9903: signed32
illustrating that in the right operand, signed32 + signed16 yielded the signed32 with which the left operand conflicted.

See Also