Hi again,

Thank you for your remarks. This is indeed a sensible subject that should be 
dealt with care.

Today we had a very productive meeting with ESA static analysis expert and 
Sebastian. I learned quite a bit and would like to share some information with 
you. Let me just summarize the main points:

 - manual verifications are laborious (very) and miss a lot of rule violations. 
We don't say that manual verifications cannot be done, but manually verified 
rules should be instead referred as software coding guidelines (that is, it is 
not mandatory to verify them).

 - Coverity tool is very good (advertisement aside). At least I got this 
impression. It gives fewer false-positive violations, has "models" which has 
models which allow to address false positives in a central and very efficient 
manner (e.g. see 
https://github.com/qemu/qemu/blob/master/scripts/coverity-model.c). In the 
Linux kernel, it has identified 526 issues in the 4.x series alone - if nothing 
else, this is quite a testimonial. allow to configure the tool much faster.

 - GCC does indeed provide some rules, but the output is not stable (the 
error/warning message changes from time to time)

 - Clang static analyzer and Cppcheck are more or less similar. That is, they 
are "moving in the right direction" but provide more false-positive cases, 
don't offer a functionality like Coverity's "models" to automatically 
mass-address false positives, and they also have far fewer static analysis 
checks.

 - FramaC is good for "sound static analysis", that is, it depends on 
painstaking writing of contracts in ACSL inside special comments in the code. 
Because of that, the effort involved far exceeds that of addressing bug reports 
from tools like Coverity. It is indeed the way to go to build "bulletproof" 
code; but it isn't the 1st step.

My general impression (I think ESA and Sebastian agreed) is that Coverity is 
"the way to go". It really beats the competition and we have a chance to use 
it, since ESA can automatically execute the tool on a regular basis. I can't 
commit to periodicity of the reports but I think it is reasonable to expect 
daily.

Coverity has a set of rules (MISRA and more) and we should select which ones to 
use for RTEMS. For example, Sebastian did not want to use the "single return 
per function" MISRA rule. Coverity rules are public 
(https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html,
 search for for MISRA or ISO 26262) so we can check them and pick up what we 
like.

Sounds like a good approach?

Thank you,
Manuel










From: Joel Sherrill [mailto:j...@rtems.org]
Sent: quarta-feira, 24 de julho de 2019 18:24
To: Manuel Coutinho
Cc: rtems-de...@rtems.org
Subject: Re: RTEMS Software Coding Standard



On Wed, Jul 24, 2019 at 11:39 AM Manuel Coutinho <manuel.couti...@edisoft.pt> 
wrote:
Regarding MISRA, we are not suggesting to have all the rules. Only the ones 
that are automatically verified by a tool that we can use and only those that 
make sense for the community.
MISRA is not open, that is understood. But there are some sources 
(https://www.synopsys.com/content/dam/synopsys/sig-assets/datasheets/coverity-misra-standards-ds-ul.pdf)
 that give a good insight about the rules. I would say that for the rules that 
are doubtful of their meaning, just leave them out.
Anyway, I suggest to look at cppcheck rules. I send below. They are not exactly 
written with a "proper rule phrasing" but we can more or less understand their 
meaning.

The Excel file (proprietary file warning) was inlined and not attached. But 
which MISRA rules do those correspond to?

Looking through what I can see of the inlined XML, some/many of these are 
checked by GCC. Why isn't GCC the first order tool? We have been fairly 
aggressive in enabling warnings and if gcc is already checking for something, 
that should be the first order tool. If there is value in enabling another 
warning, that's OK.

What about clang/llvm? Has Gaisler upstreamed their SPARC work? They are 
usually considered to have good static checking. See 
http://clang-analyzer.llvm.org/


The code standard should be applicable, at least in the context of the 
pre-qualification project, to a subset of the RTEMS which we called "space 
profile" (we don't have the effort to pre-qualify all the RTEMS code). I don't 
think third party code is inside the space profile.

But any checks need to be consistently integrated into the build mechanics. 
Perhaps code error checks can be separately defined from more style oriented 
things that we don't want to apply everywhere.


We are thinking about Coverity or Coverity Scan. Coverity Scan, as I was told, 
is not a great tool because we don't know which are the rules that are covered 
and there are no guarantees that one month from now they will remain the same. 
Coverity might be an issue (or not).

If you have a Coverity license, they may answer questions about what Scan does 
in comparison.

But ultimately, it is a proprietary tool and even Scan's reports are a pain 
from an open project perspective.They really can't be depended on for a random 
submitter to use or even look at. They can only be a back up -- not the primary 
enforcer of any rule.


We could start with the current RTEMS verifiable rules, but if you look at the 
excel file, most of the rules that can be automatically verified... I don't 
know of a tool that verifies them. There are 6 rules that I know that Coverity 
can check (since they are equivalent to MISRA rules, like the use of /* and */ 
for comments).

Then we need a table that says we have a rule and no way to automatically 
verify it so is checked by hand. Or we can verify it with X.

Just checking whatever rules a random tool can check seems like box checking 
for a contract. Lets try to do the right thing. Just because a rule is checked 
by hand, doesn't mean the rule doesn't have value and doesn't mean that the 
rule will never be automatically checked.

I think it would be a very big effort to look at all the rules and cross-check 
with the tools to find if any tool can verify them. Normally we do the other 
way around (that is, first we select the tool(s) and derive the rules from it).

Doing this to an open source code base in an open way is not the usual way 
either. This is new territory.

I think picking a tool and just using a subset of the rules it implements is 
really backwards. You should know the rules you want to enforce and look for a 
tool (or tool combination) that covers those rules. Why wouldn't we want an 
objective set of rules we want to follow?


Random question: Does Frama-C offer anything here?


Anyway, we welcome suggestions or corrections.

I'm not trying to be argumentative. We have rules just not all are enforced by 
tools. Let's try to change that where possible and if we add rules, try to 
ensure they are enforced by FLOSS tools.


Thanks,
Manuel


<?xml version="1.0" encoding="UTF-8"?>
<results>    <error id="toomanyconfigs" severity="style" msg="Too many #ifdef 
configurations - cppcheck only checks 12 configurations. Use --force to check 
all configurations. For more details, use --enable=information."/>
    <error id="AssignmentAddressToInteger" severity="style" msg="Assigning a 
pointer to an integer is not portable."/>
    <error id="AssignmentIntegerToAddress" severity="style" msg="Assigning an 
integer to a pointer is not portable."/>
    <error id="CastIntegerToAddressAtReturn" severity="style" msg="Returning an 
integer in a function with pointer return type is not portable."/>
    <error id="CastAddressToIntegerAtReturn" severity="style" msg="Returning an 
address value in a function with integer return type is not portable."/>
    <error id="assertWithSideEffect" severity="style" msg="Assert statement 
calls a function which may have desired side effects: &apos;function&apos;."/>
    <error id="assignmentInAssert" severity="style" msg="Assert statement 
modifies &apos;var&apos;."/>
    <error id="autoVariables" severity="error" msg="Address of local 
auto-variable assigned to a function parameter."/>
    <error id="returnAddressOfAutoVariable" severity="error" msg="Address of an 
auto-variable returned."/>
    <error id="returnLocalVariable" severity="error" msg="Pointer to local 
array variable returned."/>
    <error id="returnReference" severity="error" msg="Reference to auto 
variable returned."/>
    <error id="returnTempReference" severity="error" msg="Reference to 
temporary returned."/>
    <error id="autovarInvalidDeallocation" severity="error" msg="Deallocation 
of an auto-variable results in undefined behaviour."/>
    <error id="returnAddressOfFunctionParameter" severity="error" msg="Address 
of function parameter &apos;parameter&apos; returned."/>
    <error id="uselessAssignmentArg" severity="style" msg="Assignment of 
function parameter has no effect outside the function."/>
    <error id="uselessAssignmentPtrArg" severity="style" msg="Assignment of 
function parameter has no effect outside the function. Did you forget 
dereferencing it?"/>
    <error id="assignBoolToPointer" severity="error" msg="Boolean value 
assigned to pointer."/>
    <error id="assignBoolToFloat" severity="style" msg="Boolean value assigned 
to floating point variable."/>
    <error id="comparisonOfFuncReturningBoolError" severity="style" 
msg="Comparison of a function returning boolean value using relational (&lt;, 
&gt;, &lt;= or &gt;=) operator."/>
    <error id="comparisonOfTwoFuncsReturningBoolError" severity="style" 
msg="Comparison of two functions returning boolean value using relational 
(&lt;, &gt;, &lt;= or &gt;=) operator."/>
    <error id="comparisonOfBoolWithBoolError" severity="style" msg="Comparison 
of a variable having boolean value using relational (&lt;, &gt;, &lt;= or 
&gt;=) operator."/>
    <error id="incrementboolean" severity="style" msg="Incrementing a variable 
of type &apos;bool&apos; with postfix operator++ is deprecated by the C++ 
Standard. You should assign it the value &apos;true&apos; instead."/>

    <error id="compareBoolExpressionWithInt" severity="style" msg="Comparison 
of a boolean expression with an integer other than 0 or 1."/>
    <error id="pointerArithBool" severity="error" msg="Converting pointer 
arithmetic result to bool. The bool is always true unless there is undefined 
behaviour."/>
    <error id="boostForeachError" severity="error" msg="BOOST_FOREACH caches 
the end() iterator. It&apos;s undefined behavior if you modify the container 
inside."/>
    <error id="arrayIndexOutOfBounds" severity="error" msg="Array 
&apos;array[2]&apos; index array[1][1] out of bounds."/>
    <error id="bufferAccessOutOfBounds" severity="error" msg="Buffer is 
accessed out of bounds: buffer"/>
    <error id="strncatUsage" severity="style" msg="Dangerous usage of strncat - 
3rd parameter is the maximum number of characters to append."/>
    <error id="outOfBounds" severity="error" msg="index is out of bounds: 
Supplied size 2 is larger than actual size 1."/>
    <error id="sizeArgumentAsChar" severity="style" msg="The size argument is 
given as a char constant."/>


    <error id="negativeIndex" severity="error" msg="Array index -1 is out of 
bounds."/>
    <error id="insecureCmdLineArgs" severity="error" msg="Buffer overrun 
possible for long command line arguments."/>
    <error id="pointerOutOfBounds" severity="style" msg="Undefined behaviour, 
pointer arithmetic &apos;&apos; is out of bounds."/>
    <error id="arrayIndexThenCheck" severity="style" msg="Array index 
&apos;index&apos; is used before limits check."/>
    <error id="possibleBufferAccessOutOfBounds" severity="style" msg="Possible 
buffer overflow if strlen(source) is larger than or equal to 
sizeof(destination)."/>
    <error id="argumentSize" severity="style" msg="The array &apos;array&apos; 
is too small, the function &apos;function&apos; expects a bigger one."/>
    <error id="negativeMemoryAllocationSize" severity="error" msg="Memory 
allocation size is negative."/>
    <error id="negativeArraySize" severity="error" msg="Declaration of array 
&apos;&apos; with negative size is undefined behaviour"/>
    <error id="arrayIndexOutOfBoundsCond" severity="style" msg="Array 
&apos;x[10]&apos; accessed at index 20, which is out of bounds. Otherwise 
condition &apos;y==20&apos; is redundant."/>
    <error id="invalidFunctionArg" severity="error" msg="Invalid func_name() 
argument nr 1"/>
    <error id="invalidFunctionArgBool" severity="error" msg="Invalid 
func_name() argument nr 1. A non-boolean value is required."/>
    <error id="ignoredReturnValue" severity="style" msg="Return value of 
function malloc() is not used."/>
    <error id="wrongmathcall" severity="style" msg="Passing value &apos;#&apos; 
to #() leads to implementation-defined result."/>
    <error id="unpreciseMathCall" severity="style" msg="Expression &apos;1 - 
erf(x)&apos; can be replaced by &apos;erfc(x)&apos; to avoid loss of 
precision."/>
    <error id="noConstructor" severity="style" msg="The class 
&apos;classname&apos; does not have a constructor."/>
    <error id="noExplicitConstructor" severity="style" msg="Class 
&apos;classname&apos; has a constructor with 1 argument that is not explicit."/>
    <error id="copyCtorPointerCopying" severity="style" msg="Value of pointer 
&apos;var&apos;, which points to allocated memory, is copied in copy 
constructor instead of allocating new memory."/>
    <error id="noCopyConstructor" severity="style" msg="&apos;class class&apos; 
does not have a copy constructor which is recommended since the class contains 
a pointer to allocated memory."/>
    <error id="uninitMemberVar" severity="style" msg="Member variable 
&apos;classname::varname&apos; is not initialized in the constructor."/>
    <error id="operatorEqVarError" severity="style" msg="Member variable 
&apos;classname::&apos; is not assigned a value in 
&apos;classname::operator=&apos;."/>
    <error id="unusedPrivateFunction" severity="style" msg="Unused private 
function: &apos;classname::funcname&apos;"/>
    <error id="memsetClass" severity="error" msg="Using &apos;memfunc&apos; on 
class that contains a classname."/>
    <error id="memsetClassReference" severity="error" msg="Using 
&apos;memfunc&apos; on class that contains a reference."/>
    <error id="memsetClassFloat" severity="style" msg="Using memset() on class 
which contains a floating point number."/>
    <error id="mallocOnClassWarning" severity="style" msg="Memory for class 
instance allocated with malloc(), but class provides constructors."/>
    <error id="mallocOnClassError" severity="error" msg="Memory for class 
instance allocated with malloc(), but class contains a std::string."/>
    <error id="operatorEq" severity="style" msg="&apos;class::operator=&apos; 
should return &apos;class &amp;&apos;."/>
    <error id="virtualDestructor" severity="error" msg="Class &apos;Base&apos; 
which is inherited by class &apos;Derived&apos; does not have a virtual 
destructor."/>
    <error id="thisSubtraction" severity="style" msg="Suspicious pointer 
subtraction. Did you intend to write &apos;-&gt;&apos;?"/>
    <error id="operatorEqRetRefThis" severity="style" 
msg="&apos;operator=&apos; should return reference to &apos;this&apos; 
instance."/>
    <error id="operatorEqMissingReturnStatement" severity="error" msg="No 
&apos;return&apos; statement in non-void function causes undefined behavior."/>
    <error id="operatorEqShouldBeLeftUnimplemented" severity="style" 
msg="&apos;operator=&apos; should either return reference to &apos;this&apos; 
instance or be declared private and left unimplemented."/>
    <error id="operatorEqToSelf" severity="style" msg="&apos;operator=&apos; 
should check for assignment to self to avoid problems with dynamic memory."/>



    <error id="useInitializationList" severity="style" msg="Variable 
&apos;variable&apos; is assigned in constructor body. Consider performing 
initialization in initialization list."/>
    <error id="selfInitialization" severity="error" msg="Member variable 
&apos;var&apos; is initialized by itself."/>
    <error id="duplInheritedMember" severity="style" msg="The class 
&apos;class&apos; defines member variable with name &apos;variable&apos; also 
defined in its parent class &apos;class&apos;."/>
    <error id="assignIfError" severity="style" msg="Mismatching assignment and 
comparison, comparison &apos;&apos; is always false."/>
    <error id="badBitmaskCheck" severity="style" msg="Result of operator 
&apos;|&apos; is always true if one operand is non-zero. Did you intend to use 
&apos;&amp;&apos;?"/>
    <error id="comparisonError" severity="style" msg="Expression &apos;(X &amp; 
0x6) == 0x1&apos; is always false."/>
    <error id="multiCondition" severity="style" msg="Expression is always false 
because &apos;else if&apos; condition matches previous condition at line 1."/>
    <error id="mismatchingBitAnd" severity="style" msg="Mismatching bitmasks. 
Result is always 0 (X = Y &amp; 0xf0; Z = X &amp; 0x1; =&gt; Z=0)."/>
    <error id="oppositeInnerCondition" severity="style" msg="Opposite 
conditions in nested &apos;if&apos; blocks lead to a dead code block."/>
    <error id="incorrectLogicOperator" severity="style" msg="Logical 
disjunction always evaluates to true: foo &gt; 3 &amp;&amp; foo &lt; 4."/>
    <error id="redundantCondition" severity="style" msg="Redundant condition: 
If x &gt; 11 the condition x &gt; 10 is always true."/>
    <error id="moduloAlwaysTrueFalse" severity="style" msg="Comparison of 
modulo result is predetermined, because it is always less than 1."/>
    <error id="clarifyCondition" severity="style" msg="Suspicious condition 
(assignment + comparison); Clarify expression with parentheses."/>
    <error id="knownConditionTrueFalse" severity="style" msg="Condition 
&apos;x&apos; is always true"/>
    <error id="invalidTestForOverflow" severity="style" msg="Invalid test for 
overflow &apos;x + u &lt; x&apos;. Condition is always false unless there is 
overflow, and overflow is UB."/>
    <error id="exceptThrowInDestructor" severity="style" msg="Class Class is 
not safe, destructor throws exception"/>
    <error id="exceptDeallocThrow" severity="style" msg="Exception thrown in 
invalid state, &apos;p&apos; points at deallocated memory."/>
    <error id="exceptRethrowCopy" severity="style" msg="Throwing a copy of the 
caught exception instead of rethrowing the original exception."/>
    <error id="catchExceptionByValue" severity="style" msg="Exception should be 
caught by reference."/>
    <error id="throwInNoexceptFunction" severity="error" msg="Exception thrown 
in function declared not to throw exceptions."/>

    <error id="coutCerrMisusage" severity="error" msg="Invalid usage of output 
stream: &apos;&lt;&lt; std::cout&apos;."/>
    <error id="fflushOnInputStream" severity="style" msg="fflush() called on 
input stream &apos;stdin&apos; may result in undefined behaviour on non-linux 
systems."/>
    <error id="IOWithoutPositioning" severity="error" msg="Read and write 
operations without a call to a positioning function (fseek, fsetpos or rewind) 
or fflush in between result in undefined behaviour."/>
    <error id="readWriteOnlyFile" severity="error" msg="Read operation on a 
file that was opened only for writing."/>
    <error id="writeReadOnlyFile" severity="error" msg="Write operation on a 
file that was opened only for reading."/>
    <error id="useClosedFile" severity="error" msg="Used file that is not 
opened."/>
    <error id="seekOnAppendedFile" severity="style" msg="Repositioning 
operation performed on a file opened in append mode has no effect."/>
    <error id="invalidscanf" severity="style" msg="scanf() without field width 
limits can crash with huge input data."/>
    <error id="wrongPrintfScanfArgNum" severity="error" msg="printf format 
string requires 3 parameters but only 2 are given."/>
    <error id="invalidScanfArgType_s" severity="style" msg="%s in format string 
(no. 1) requires a &apos;char *&apos; but the argument type is Unknown."/>
    <error id="invalidScanfArgType_int" severity="style" msg="%d in format 
string (no. 1) requires &apos;int *&apos; but the argument type is Unknown."/>
    <error id="invalidScanfArgType_float" severity="style" msg="%f in format 
string (no. 1) requires &apos;float *&apos; but the argument type is Unknown."/>
    <error id="invalidPrintfArgType_s" severity="style" msg="%s in format 
string (no. 1) requires &apos;char *&apos; but the argument type is Unknown."/>
    <error id="invalidPrintfArgType_n" severity="style" msg="%n in format 
string (no. 1) requires &apos;int *&apos; but the argument type is Unknown."/>
    <error id="invalidPrintfArgType_p" severity="style" msg="%p in format 
string (no. 1) requires an address but the argument type is Unknown."/>
    <error id="invalidPrintfArgType_int" severity="style" msg="%X in format 
string (no. 1) requires &apos;unsigned int&apos; but the argument type is 
Unknown."/>
    <error id="invalidPrintfArgType_uint" severity="style" msg="%u in format 
string (no. 1) requires &apos;unsigned int&apos; but the argument type is 
Unknown."/>
    <error id="invalidPrintfArgType_sint" severity="style" msg="%i in format 
string (no. 1) requires &apos;int&apos; but the argument type is Unknown."/>
    <error id="invalidPrintfArgType_float" severity="style" msg="%f in format 
string (no. 1) requires &apos;double&apos; but the argument type is Unknown."/>
    <error id="invalidLengthModifierError" severity="style" msg="&apos;I&apos; 
in format string (no. 1) is a length modifier and cannot be used without a 
conversion specifier."/>
    <error id="invalidScanfFormatWidth" severity="error" msg="Width 5 given in 
format string (no. 10) is larger than destination buffer &apos;[0]&apos;, use 
%-1s to prevent overflowing it."/>
    <error id="wrongPrintfScanfParameterPositionError" severity="style" 
msg="printf: referencing parameter 2 while 1 arguments given"/>
    <error id="deallocret" severity="error" msg="Returning/dereferencing 
&apos;p&apos; after it is deallocated / released"/>
    <error id="doubleFree" severity="error" msg="Memory pointed to by 
&apos;varname&apos; is freed twice."/>
    <error id="leakNoVarFunctionCall" severity="error" msg="Allocation with 
funcName, funcName doesn&apos;t release it."/>
    <error id="leakReturnValNotUsed" severity="error" msg="Return value of 
allocation function &apos;funcName&apos; is not stored."/>

    <error id="publicAllocationError" severity="style" msg="Possible leak in 
public function. The pointer &apos;varname&apos; is not deallocated before it 
is allocated."/>
    <error id="unsafeClassCanLeak" severity="style" msg="Class 
&apos;class&apos; is unsafe, &apos;class::varname&apos; can leak by wrong 
usage."/>
    <error id="memleak" severity="error" msg="Memory leak: varname"/>
    <error id="resourceLeak" severity="error" msg="Resource leak: varname"/>
    <error id="deallocDealloc" severity="error" msg="Deallocating a deallocated 
pointer: varname"/>
    <error id="deallocuse" severity="error" msg="Dereferencing 
&apos;varname&apos; after it is deallocated / released"/>
    <error id="mismatchSize" severity="error" msg="The allocated size sz is not 
a multiple of the underlying type&apos;s size."/>
    <error id="mismatchAllocDealloc" severity="error" msg="Mismatching 
allocation and deallocation: varname"/>
    <error id="memleakOnRealloc" severity="error" msg="Common realloc mistake: 
&apos;varname&apos; nulled but not freed upon failure"/>
    <error id="nullPointer" severity="error" msg="Null pointer dereference"/>
    <error id="nullPointerDefaultArg" severity="style" msg="Possible null 
pointer dereference if the default parameter value is used: pointer"/>
    <error id="nullPointerRedundantCheck" severity="style" msg="Either the 
condition is redundant or there is possible null pointer dereference: 
pointer."/>
    <error id="zerodiv" severity="error" msg="Division by zero."/>
    <error id="zerodivcond" severity="style" msg="Either the condition is 
redundant or there is division by zero at line 0."/>
    <error id="unusedScopedObject" severity="style" msg="Instance of 
&apos;varname&apos; object is destroyed immediately."/>
    <error id="invalidPointerCast" severity="style" msg="Casting between float* 
and double* which have an incompatible binary data representation."/>
    <error id="shiftNegative" severity="error" msg="Shifting a negative value 
is undefined behaviour"/>
    <error id="wrongPipeParameterSize" severity="error" msg="Buffer 
&apos;varname&apos; must have size of 2 integers if used as parameter of 
pipe()."/>
    <error id="raceAfterInterlockedDecrement" severity="error" msg="Race 
condition: non-interlocked access after InterlockedDecrement(). Use 
InterlockedDecrement() return value instead."/>

    <error id="redundantCopy" severity="style" msg="Buffer &apos;var&apos; is 
being written before its old content has been used."/>
    <error id="redundantAssignment" severity="style" msg="Variable 
&apos;var&apos; is reassigned a value before the old one has been used."/>
    <error id="comparisonFunctionIsAlwaysTrueOrFalse" severity="style" 
msg="Comparison of two identical variables with isless(varName,varName) always 
evaluates to false."/>
    <error id="checkCastIntToCharAndBack" severity="style" msg="Storing 
func_name() return value in char variable and then comparing with EOF."/>
    <error id="cstyleCast" severity="style" msg="C-style pointer casting"/>
    <error id="passedByValue" severity="style" msg="Function parameter 
&apos;parametername&apos; should be passed by reference."/>
    <error id="constStatement" severity="style" msg="Redundant code: Found a 
statement that begins with type constant."/>
    <error id="signedCharArrayIndex" severity="style" msg="Signed 
&apos;char&apos; type used as array index."/>
    <error id="unknownSignCharArrayIndex" severity="style" 
msg="&apos;char&apos; type used as array index."/>
    <error id="charBitOp" severity="style" msg="When using &apos;char&apos; 
variables in bit operations, sign extension can generate unexpected results."/>
    <error id="variableScope" severity="style" msg="The scope of the variable 
&apos;varname&apos; can be reduced."/>
    <error id="redundantAssignInSwitch" severity="style" msg="Variable 
&apos;var&apos; is reassigned a value before the old one has been used. 
&apos;break;&apos; missing?"/>
    <error id="redundantCopyInSwitch" severity="style" msg="Buffer 
&apos;var&apos; is being written before its old content has been used. 
&apos;break;&apos; missing?"/>


    <error id="selfAssignment" severity="style" msg="Redundant assignment of 
&apos;varname&apos; to itself."/>
    <error id="memsetZeroBytes" severity="style" msg="memset() called to fill 0 
bytes."/>
    <error id="memsetFloat" severity="style" msg="The 2nd memset() argument 
&apos;varname&apos; is a float, its representation is implementation defined."/>
    <error id="memsetValueOutOfRange" severity="style" msg="The 2nd memset() 
argument &apos;varname&apos; doesn&apos;t fit into an &apos;unsigned 
char&apos;."/>
    <error id="clarifyCalculation" severity="style" msg="Clarify calculation 
precedence for &apos;+&apos; and &apos;?&apos;."/>
    <error id="clarifyStatement" severity="style" msg="Ineffective statement 
similar to &apos;*A++;&apos;. Did you intend to write &apos;(*A)++;&apos;?"/>

    <error id="duplicateExpression" severity="style" msg="Same expression on 
both sides of &apos;&amp;&amp;&apos;."/>
    <error id="duplicateExpressionTernary" severity="style" msg="Same 
expression in both branches of ternary operator."/>
    <error id="duplicateBreak" severity="style" msg="Consecutive return, break, 
continue, goto or throw statements are unnecessary."/>
    <error id="unreachableCode" severity="style" msg="Statements following 
return, break, continue, goto or throw will never be executed."/>
    <error id="unsignedLessThanZero" severity="style" msg="Checking if unsigned 
variable &apos;varname&apos; is less than zero."/>
    <error id="unsignedPositive" severity="style" msg="Unsigned variable 
&apos;varname&apos; can&apos;t be negative so it is unnecessary to test it."/>
    <error id="pointerLessThanZero" severity="style" msg="A pointer can not be 
negative so it is either pointless or an error to check if it is."/>
    <error id="pointerPositive" severity="style" msg="A pointer can not be 
negative so it is either pointless or an error to check if it is not."/>


    <error id="varFuncNullUB" severity="style" msg="Passing NULL after the last 
typed argument to a variadic function leads to undefined behaviour."/>
    <error id="nanInArithmeticExpression" severity="style" msg="Using NaN/Inf 
in a computation."/>
    <error id="commaSeparatedReturn" severity="style" msg="Comma is used in 
return statement. The comma can easily be misread as a &apos;;&apos;."/>
    <error id="redundantPointerOp" severity="style" msg="Redundant pointer 
operation on &apos;varname&apos; - it&apos;s already a pointer."/>
    <error id="unusedLabelSwitch" severity="style" msg="Label &apos;&apos; is 
not used. Should this be a &apos;case&apos; of the enclosing switch()?"/>
    <error id="unusedLabel" severity="style" msg="Label &apos;&apos; is not 
used."/>
    <error id="unknownEvaluationOrder" severity="error" msg="Expression &apos;x 
= x++;&apos; depends on order of evaluation of side effects"/>
    <error id="invalidIterator1" severity="error" msg="Invalid iterator: 
iterator"/>
    <error id="iterators" severity="error" msg="Same iterator is used with 
different containers &apos;container1&apos; and &apos;container2&apos;."/>
    <error id="mismatchingContainers" severity="error" msg="Iterators of 
different containers are used together."/>
    <error id="eraseDereference" severity="error" msg="Invalid iterator 
&apos;iter&apos; used."/>
    <error id="stlOutOfBounds" severity="error" msg="When i==foo.size(), foo[i] 
is out of bounds."/>
    <error id="invalidIterator2" severity="error" msg="After 
push_back|push_front|insert(), the iterator &apos;iterator&apos; may be 
invalid."/>
    <error id="invalidPointer" severity="error" msg="Invalid pointer 
&apos;pointer&apos; after push_back()."/>
    <error id="stlBoundaries" severity="error" msg="Dangerous comparison using 
operator&lt; on iterator."/>
    <error id="stlIfFind" severity="style" msg="Suspicious condition. The 
result of find() is an iterator, but it is not properly checked."/>
    <error id="stlIfStrFind" severity="style" msg="Inefficient usage of 
string::find() in condition; string::compare() would be faster."/>
    <error id="stlcstr" severity="error" msg="Dangerous usage of c_str(). The 
value returned by c_str() is invalid after this call."/>
    <error id="stlcstrReturn" severity="style" msg="Returning the result of 
c_str() in a function that returns std::string is slow and redundant."/>
    <error id="stlcstrParam" severity="style" msg="Passing the result of 
c_str() to a function that takes std::string as argument no. 0 is slow and 
redundant."/>
    <error id="stlSize" severity="style" msg="Possible inefficient checking for 
&apos;list&apos; emptiness."/>
    <error id="StlMissingComparison" severity="style" msg="Missing bounds check 
for extra iterator increment in loop."/>
    <error id="redundantIfRemove" severity="style" msg="Redundant checking of 
STL container element existence before removing it."/>
    <error id="useAutoPointerCopy" severity="style" msg="Copying 
&apos;auto_ptr&apos; pointer to another does not create two equal objects since 
one has lost its ownership of the pointer."/>
    <error id="useAutoPointerContainer" severity="error" msg="You can randomly 
lose access to pointers if you store &apos;auto_ptr&apos; pointers in an STL 
container."/>
    <error id="useAutoPointerArray" severity="error" msg="Object pointed by an 
&apos;auto_ptr&apos; is destroyed using operator &apos;delete&apos;. You should 
not use &apos;auto_ptr&apos; for pointers obtained with operator 
&apos;new[]&apos;."/>
    <error id="useAutoPointerMalloc" severity="error" msg="Object pointed by an 
&apos;auto_ptr&apos; is destroyed using operator &apos;delete&apos;. You should 
not use &apos;auto_ptr&apos; for pointers obtained with function 
&apos;malloc&apos;."/>
    <error id="uselessCallsCompare" severity="style" msg="It is inefficient to 
call &apos;str.find(str)&apos; as it always returns 0."/>
    <error id="uselessCallsSwap" severity="style" msg="It is inefficient to 
swap a object with itself by calling &apos;str.swap(str)&apos;"/>
    <error id="uselessCallsSubstr" severity="style" msg="Ineffective call of 
function &apos;substr&apos; because it returns a copy of the object. Use 
operator= instead."/>
    <error id="uselessCallsEmpty" severity="style" msg="Ineffective call of 
function &apos;empty()&apos;. Did you intend to call &apos;clear()&apos; 
instead?"/>
    <error id="uselessCallsRemove" severity="style" msg="Return value of 
std::remove() ignored. Elements remain in container."/>
    <error id="derefInvalidIterator" severity="style" msg="Possible dereference 
of an invalid iterator: i"/>

    <error id="sizeofwithsilentarraypointer" severity="style" msg="Using 
&apos;sizeof&apos; on array given as function argument returns size of a 
pointer."/>
    <error id="pointerSize" severity="style" msg="Size of pointer 
&apos;varname&apos; used instead of size of its data."/>
    <error id="sizeofDivisionMemfunc" severity="style" msg="Division by result 
of sizeof(). memset() expects a size in bytes, did you intend to multiply 
instead?"/>
    <error id="sizeofwithnumericparameter" severity="style" msg="Suspicious 
usage of &apos;sizeof&apos; with a numeric constant as parameter."/>
    <error id="sizeofsizeof" severity="style" msg="Calling &apos;sizeof&apos; 
on &apos;sizeof&apos;."/>
    <error id="sizeofCalculation" severity="style" msg="Found calculation 
inside sizeof()."/>


    <error id="sizeofVoid" severity="style" msg="Behaviour of 
&apos;sizeof(void)&apos; is not covered by the ISO C standard."/>
    <error id="sizeofDereferencedVoidPointer" severity="style" 
msg="&apos;*varname&apos; is of type &apos;void&apos;, the behaviour of 
&apos;sizeof(void)&apos; is not covered by the ISO C standard."/>
    <error id="arithOperationsOnVoidPointer" severity="style" 
msg="&apos;varname&apos; is of type &apos;vartype&apos;. When using void 
pointers in calculations, the behaviour is undefined."/>
    <error id="stringLiteralWrite" severity="error" msg="Modifying string 
literal directly or indirectly is undefined behaviour."/>
    <error id="sprintfOverlappingData" severity="error" msg="Undefined 
behavior: Variable &apos;varname&apos; is used as parameter and destination in 
s[n]printf()."/>
    <error id="strPlusChar" severity="error" msg="Unusual pointer arithmetic. A 
value of type &apos;char&apos; is added to a string literal."/>
    <error id="incorrectStringCompare" severity="style" msg="String literal 
&quot;Hello World&quot; doesn&apos;t match length argument for substr()."/>
    <error id="literalWithCharPtrCompare" severity="style" msg="String literal 
compared with variable &apos;foo&apos;. Did you intend to use strcmp() 
instead?"/>
    <error id="charLiteralWithCharPtrCompare" severity="style" msg="Char 
literal compared with pointer &apos;foo&apos;. Did you intend to dereference 
it?"/>
    <error id="incorrectStringBooleanError" severity="style" msg="Conversion of 
string literal &quot;Hello World&quot; to bool always evaluates to true."/>
    <error id="staticStringCompare" severity="style" msg="Unnecessary 
comparison of static strings."/>
    <error id="stringCompare" severity="style" msg="Comparison of identical 
string variables."/>
    <error id="shiftTooManyBits" severity="error" msg="Shifting 32-bit value by 
64 bits is undefined behaviour"/>
    <error id="integerOverflow" severity="error" msg="Signed integer overflow 
for expression &apos;&apos;."/>
    <error id="signConversion" severity="style" msg="Suspicious code: sign 
conversion of var in calculation, even though var can have a negative value"/>
    <error id="truncLongCastAssignment" severity="style" msg="int result is 
assigned to long variable. If the variable is long to avoid loss of 
information, then you have loss of information."/>
    <error id="truncLongCastReturn" severity="style" msg="int result is 
returned as long value. If the return value is long to avoid loss of 
information, then you have loss of information."/>
    <error id="uninitstring" severity="error" msg="Dangerous usage of 
&apos;varname&apos; (strncpy doesn&apos;t always null-terminate it)."/>
    <error id="uninitdata" severity="error" msg="Memory is allocated but not 
initialized: varname"/>
    <error id="uninitvar" severity="error" msg="Uninitialized variable: 
varname"/>
    <error id="uninitStructMember" severity="error" msg="Uninitialized struct 
member: a.b"/>
    <error id="deadpointer" severity="error" msg="Dead pointer usage. Pointer 
&apos;pointer&apos; is dead if it has been assigned &apos;&amp;x&apos; at line 
0."/>
    <error id="unusedFunction" severity="style" msg="The function 
&apos;funcName&apos; is never used."/>
    <error id="unusedVariable" severity="style" msg="Unused variable: varname"/>
    <error id="unusedAllocatedMemory" severity="style" msg="Variable 
&apos;varname&apos; is allocated memory that is never used."/>
    <error id="unreadVariable" severity="style" msg="Variable 
&apos;varname&apos; is assigned a value that is never used."/>
    <error id="unassignedVariable" severity="style" msg="Variable 
&apos;varname&apos; is not assigned a value."/>
    <error id="unusedStructMember" severity="style" msg="struct member 
&apos;structname::variable&apos; is never used."/>
    <error id="postfixOperator" severity="style" msg="Prefer prefix ++/-- 
operators for non-primitive types."/>
    <error id="va_start_wrongParameter" severity="style" msg="&apos;arg1&apos; 
given to va_start() is not last named argument of the function. Did you intend 
to pass &apos;arg2&apos;?"/>
    <error id="va_start_referencePassed" severity="error" msg="Using reference 
&apos;arg1&apos; as parameter for va_start() results in undefined behaviour."/>
    <error id="va_end_missing" severity="error" msg="va_list &apos;vl&apos; was 
opened but not closed by va_end()."/>
    <error id="va_list_usedBeforeStarted" severity="error" msg="va_list 
&apos;vl&apos; used before va_start() was called."/>
    <error id="va_start_subsequentCalls" severity="error" msg="va_start() or 
va_copy() called subsequently on &apos;vl&apos; without va_end() in between."/>
    <error id="missingInclude" severity="style" msg="Include file: &quot;&quot; 
not found."/>
    <error id="missingIncludeSystem" severity="style" msg="Include file: 
&lt;&gt; not found. Please note: Cppcheck does not need standard library 
headers to get proper results."/>
    <error file="" line="1" id="ConfigurationNotChecked" severity="style" 
msg="Skipping configuration &apos;X&apos; since the value of &apos;X&apos; is 
unknown. Use -D if you want to check it. You can use -U to skip it 
explicitly."/>
    <error id="preprocessorErrorDirective" severity="error" msg="#error 
message"/>
</results>



From: Joel Sherrill [mailto:j...@rtems.org]
Sent: quarta-feira, 24 de julho de 2019 12:10
To: Manuel Coutinho
Cc: rtems-de...@rtems.org
Subject: Re: RTEMS Software Coding Standard


On Wed, Jul 24, 2019, 3:59 AM Manuel Coutinho <manuel.couti...@edisoft.pt> 
wrote:
Hello all,

It has been some time since my last email. Hope you are doing well!

Some of you already know that Edisoft together with Embedded Brains (and some 
other institutions) are in a joint project to pre-qualify RTEMS according to 
the ESA (ECSS) standards.

One of the items required is the Software Coding Standard and one of the goals 
of the project is to minimize (hopefully eliminate) any deviation from a 
pre-qualified version of RTEMS and the community RTEMS.

To that end, we ask your ideas of how the RTEMS software coding standard should 
look like. We have looked at your current coding standard 
(https://docs.rtems.org/branches/master/eng/coding.html) and made a preliminary 
analysis to it (see table in attach). For an open-source project, these rules 
are very good. Unfortunately, from a pre-qualification point of view, there are 
not so many rules that are verifiable and even fewer that are automatically 
verifiable by a tool that we can use in the project.

We have some preferences:
 - have only automatically verified tools (to reduce the amount of manual 
verifications to a minimum)
 - use preferentially open-source tools
 - use at most 2 tools
 - the tool(s) should have a "well-defined" rule set and output (e.g. XML, 
YAML, whatever) so that the qualification toolchain (another tool that we are 
developing) can interpret the output and re-format the output to sphinx.

As a side note (please lets not focus on this now), after selecting the rules 
there could be some violations to the rule and still the pre-qualification be 
successful. For that, we just need to justify why the violation occurred (was 
not corrected) and why the code is correct.

We believe a good starting point would be the MISRA rules since they are well 
defined, lots of tools use them, they can eliminate a lot of errors. But we 
welcome any other suggestion.
Please keep in mind that some tools, while they are good to use, don't give a 
well-defined ruleset.

The MISRA C coding guide is not freely available. This is a barrier to open 
discussion about the merit to adopting the rules.

I personally have not seen the entire rule set in a long time since I don't own 
a copy. My recollection is that I am against some of the rules. For example, I 
vaguely recall a rule about 32 character global symbol names and I am strongly 
opposed to that rule. It reflects limits in long unused object formats. And 
that's just one I remember as being odd.

Each rule or handful will have to be proposed for evaluation independent of 
having a copy of MISRA. The way it is checked by a FLOSS tool and its value 
will have to be established.

The use of any rules which are adopted will have to be restricted to certain 
directories. We can't change the style or format of third party code.

It is likely close to time to discuss if we will use an annotation like spdx to 
denote files which have artifacts.


We have looked at cppcheck for some time and only now we found that there is a 
ruleset. You can get it by running "cppcheck --errorlist".

What's the other tool?

After we define this rule set, we suggest that the current standard (in 
https://docs.rtems.org/branches/master/eng/coding.html) be more or less renamed 
to a "Coding guidelines" instead of "Rules" because some of them are not 
verifiable and we believe the community should keep on following them. And 
create a new coding standard with the rules that are selected.

And some of those are verifiable. Let's start with those

Kind regards,
Manuel Coutinho
Technical Manager
Aeronautics & Space Systems manuel.couti...@edisoft.pt
Tel: +351 212 945 906
Fax: +351 212 945 999
Rua Calvet Magalhães, 245
2770-153 Paço de Arcos · Portugal
www.edisoft.pt
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to