From cced8d4b7c9f68939f6cf25c9a2c928d6a918fde Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Tue, 1 Nov 2022 18:49:44 -0400 Subject: [PATCH 1/8] Tests for Contracts6 * tests for contracts6 --- .vscode/tasks.json | 5 +++ c/cert/test/rules/EXP40-C/test.c | 52 +++++++++++++++++++++++ c/misra/test/rules/RULE-12-2/test.c | 65 +++++++++++++++++++++++++++++ c/misra/test/rules/RULE-17-5/test.c | 49 ++++++++++++++++++++++ c/misra/test/rules/RULE-17-7/test.c | 18 ++++++++ rules.csv | 8 ++-- 6 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 c/cert/test/rules/EXP40-C/test.c create mode 100644 c/misra/test/rules/RULE-12-2/test.c create mode 100644 c/misra/test/rules/RULE-17-5/test.c create mode 100644 c/misra/test/rules/RULE-17-7/test.c diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d1f141cced..3b5c694798 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -192,6 +192,11 @@ "Classes", "Comments", "Contracts1", + "Contracts2", + "Contracts3", + "Contracts4", + "Contracts5", + "Contracts6", "Concurrency", "Concurrency", "Concurrency1", diff --git a/c/cert/test/rules/EXP40-C/test.c b/c/cert/test/rules/EXP40-C/test.c new file mode 100644 index 0000000000..5723f72c30 --- /dev/null +++ b/c/cert/test/rules/EXP40-C/test.c @@ -0,0 +1,52 @@ +void f1() { + const int a = 3; + int *aa; + + aa = &a; // NON_COMPLIANT + *aa = 100; +} + +void f1a() { + const int a = 3; + int *aa; + + aa = &a; // COMPLIANT +} + +void f2() { + int a = 3; + int *aa; + a = 3; + + aa = &a; + *aa = a; + *aa = &a; +} + +void f4a(int *a) { + *a = 100; // NON_COMPLAINT +} + +void f4b(int *a) {} + +void f4() { + const int a = 100; + int *p1 = &a; // NON_COMPLIANT + const int **p2; + + *p2 = &a; // NON_COMPLIANT + + f4a(p1); // NON_COMPLIANT + f4a(*p2); // NON_COMPLIANT +} + +void f5() { + const int a = 100; + int *p1 = &a; // COMPLIANT + const int **p2; + + *p2 = &a; // COMPLIANT + + f4b(p1); + f4b(*p2); +} \ No newline at end of file diff --git a/c/misra/test/rules/RULE-12-2/test.c b/c/misra/test/rules/RULE-12-2/test.c new file mode 100644 index 0000000000..b2b88ebda0 --- /dev/null +++ b/c/misra/test/rules/RULE-12-2/test.c @@ -0,0 +1,65 @@ + + +const short int s1 = 15; +const short int s2 = -1; +const short int s3 = 16; +const int s4 = -1; +const int s5 = 32; +const int s6 = 21; + +const long int s7 = 64; +const long int s8 = 63; + +void f1() { + int a; + short b; + long c; + char d; + + a = a << s1; // COMPLIANT + a = a << s2; // NON_COMPLIANT + a = a << s3; // COMPLIANT + a = a << s4; // NON_COMPLIANT + a = a << s5; // NON_COMPLIANT + a = a << s6; // COMPLIANT + a = a << s7; // NON_COMPLIANT + a = a << s8; // NON_COMPLIANT + + b = b << s1; // COMPLIANT + b = b << s2; // NON_COMPLIANT + b = b << s3; // NON_COMPLIANT + b = b << s4; // NON_COMPLIANT + b = b << s5; // NON_COMPLIANT + b = b << s6; // NON_COMPLIANT + b = b << s7; // NON_COMPLIANT + b = b << s8; // NON_COMPLIANT + + c = c << s1; // COMPLIANT + c = c << s2; // NON_COMPLIANT + c = c << s3; // COMPLIANT + c = c << s4; // NON_COMPLIANT + c = c << s5; // COMPLIANT + c = c << s6; // COMPLIANT + c = c << s7; // NON_COMPLIANT + c = c << s8; // COMPLIANT + + d = d << -1; // NON_COMPLIANT + d = d << 8; // NON_COMPLIANT + d = d << 7; // COMPLIANT + d = d << 0; // COMPLIANT +} + +void f2() { + int a; + short b; + char c; + long long d; + + int aa = 10; + aa++; + + a = a << aa; + b = b << aa; + c = c << aa; + d = d << aa; +} \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-5/test.c b/c/misra/test/rules/RULE-17-5/test.c new file mode 100644 index 0000000000..2488d2d632 --- /dev/null +++ b/c/misra/test/rules/RULE-17-5/test.c @@ -0,0 +1,49 @@ +void f1(int ar[3]); +void f2(int a, int ar[3]); +void f3(int *ar); +void f4(int a, int *ar); + +void t1() { + int *ar; + + int ar2[3] = {1, 2}; + int *ar2p = ar2; + + int ar3[3] = {1, 2, 3}; + int *ar3p = ar3; + + int ar4[4] = {1, 2, 3}; + int *ar4p = ar4; + + f1(0); // NON_COMPLAINT + f1(ar); // NON_COMPLAINT + f1(ar2); // NON_COMPLIANT + f1(ar2p); // NON_COMPLIANT + f1(ar3); // COMPLIANT + f1(ar3p); // COMPLIANT + f1(ar4); // COMPLIANT + + f2(0, 0); // NON_COMPLAINT + f2(0, ar); // NON_COMPLAINT + f2(0, ar2); // NON_COMPLIANT + f2(0, ar2p); // NON_COMPLIANT + f2(0, ar3); // COMPLIANT + f2(0, ar3p); // COMPLIANT + f2(0, ar4); // COMPLIANT + + f3(0); // COMPLAINT + f3(ar); // COMPLAINT + f3(ar2); // COMPLIANT + f3(ar2p); // COMPLIANT + f3(ar3); // COMPLIANT + f3(ar3p); // COMPLIANT + f3(ar4); // COMPLIANT + + f4(0, 0); // COMPLAINT + f4(0, ar); // COMPLAINT + f4(0, ar2); // COMPLIANT + f4(0, ar2p); // COMPLIANT + f4(0, ar3); // COMPLIANT + f4(0, ar3p); // COMPLIANT + f4(0, ar4); // COMPLIANT +} \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-7/test.c b/c/misra/test/rules/RULE-17-7/test.c new file mode 100644 index 0000000000..bd58fc774e --- /dev/null +++ b/c/misra/test/rules/RULE-17-7/test.c @@ -0,0 +1,18 @@ +void f1() {} +int f2() { return 0; } + +int t1() { + f1(); + f2(); // NON_COMPLAINT + (void)f2(); // COMPLIANT + int a = f2(); // COMPLIANT + a = f2(); // COMPLIANT + + void (*fp1)(void) = &f1; + int (*fp2)(void) = &f2; + + (*f1)(); // COMPLIANT + (*f2)(); // NON_COMPLIANT + (void)(*f2)(); // COMPLIANT + a = (*f2)(); // COMPLIANT +} \ No newline at end of file diff --git a/rules.csv b/rules.csv index ec8b29eaf9..be49c00433 100644 --- a/rules.csv +++ b/rules.csv @@ -523,7 +523,7 @@ c,CERT-C,EXP35-C,Yes,Rule,,,Do not modify objects with temporary lifetime,,Inval c,CERT-C,EXP36-C,Yes,Rule,,,Do not cast pointers into more strictly aligned pointer types,,Pointers3,Medium, c,CERT-C,EXP37-C,Yes,Rule,,,Call functions with the correct number and type of arguments,,Expressions,Easy, c,CERT-C,EXP39-C,Yes,Rule,,,Do not access a variable through a pointer of an incompatible type,,Pointers3,Medium, -c,CERT-C,EXP40-C,Yes,Rule,,,Do not modify constant objects,,Contracts,Medium, +c,CERT-C,EXP40-C,Yes,Rule,,,Do not modify constant objects,,Contracts6,Medium, c,CERT-C,EXP42-C,Yes,Rule,,,Do not compare padding data,,Memory,Medium, c,CERT-C,EXP43-C,Yes,Rule,,,Avoid undefined behavior when using restrict-qualified pointers,,Pointers3,Medium, c,CERT-C,EXP44-C,Yes,Rule,,,"Do not rely on side effects in operands to sizeof, _Alignof, or _Generic",M5-3-4,SideEffects1,Medium, @@ -683,7 +683,7 @@ c,MISRA-C-2012,RULE-11-7,Yes,Required,,,A cast shall not be performed between po c,MISRA-C-2012,RULE-11-8,Yes,Required,,,A cast shall not remove any const or volatile qualification from the type pointed to by a pointer,,Pointers1,Easy, c,MISRA-C-2012,RULE-11-9,Yes,Required,,,The macro NULL shall be the only permitted form of integer null pointer constant,,Pointers1,Easy, c,MISRA-C-2012,RULE-12-1,Yes,Advisory,,,The precedence of operators within expressions should be made explicit,,SideEffects1,Medium, -c,MISRA-C-2012,RULE-12-2,Yes,Required,,,The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand,,Contracts,Hard, +c,MISRA-C-2012,RULE-12-2,Yes,Required,,,The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand,,Contracts6,Hard, c,MISRA-C-2012,RULE-12-3,Yes,Advisory,,,The comma operator should not be used,M5-18-1,Banned,Import, c,MISRA-C-2012,RULE-12-4,Yes,Advisory,,,Evaluation of constant expressions should not lead to unsigned integer wrap-around,INT30-C,Types,Easy, c,MISRA-C-2012,RULE-12-5,Yes,Mandatory,,,The sizeof operator shall not have an operand which is a function parameter declared as �array of type�,,Types,Medium, @@ -715,9 +715,9 @@ c,MISRA-C-2012,RULE-17-1,Yes,Required,,,The features of shall not be c,MISRA-C-2012,RULE-17-2,Yes,Required,,,"Functions shall not call themselves, either directly or indirectly",A7-5-2,Statements,Import, c,MISRA-C-2012,RULE-17-3,Yes,Mandatory,,,A function shall not be declared implicitly,,Declarations,Medium, c,MISRA-C-2012,RULE-17-4,Yes,Mandatory,,,All exit paths from a function with non-void return type shall have an explicit return statement with an expression,MSC52-CPP,Statements,Medium, -c,MISRA-C-2012,RULE-17-5,Yes,Advisory,,,The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements,,Contracts,Hard, +c,MISRA-C-2012,RULE-17-5,Yes,Advisory,,,The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements,,Contracts6,Hard, c,MISRA-C-2012,RULE-17-6,No,Mandatory,,,The declaration of an array parameter shall not contain the static keyword between the [ ],,,, -c,MISRA-C-2012,RULE-17-7,Yes,Required,,,The value returned by a function having non-void return type shall be used,A0-1-2,Contracts,Import, +c,MISRA-C-2012,RULE-17-7,Yes,Required,,,The value returned by a function having non-void return type shall be used,A0-1-2,Contracts6,Import, c,MISRA-C-2012,RULE-17-8,Yes,Advisory,,,A function parameter should not be modified,,SideEffects2,Medium, c,MISRA-C-2012,RULE-18-1,Yes,Required,,,A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand,M5-0-16,Pointers1,Import, c,MISRA-C-2012,RULE-18-2,Yes,Required,,,Subtraction between pointers shall only be applied to pointers that address elements of the same array,M5-0-17,Pointers1,Import, From 861347b876b1b55531bc9737a56ec790242d4c7c Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Tue, 8 Nov 2022 17:27:39 +0100 Subject: [PATCH 2/8] Init project Contracts6 --- .../EXP40-C/DoNotModifyConstantObjects.md | 96 +++++++++++++++++++ .../EXP40-C/DoNotModifyConstantObjects.ql | 18 ++++ .../DoNotModifyConstantObjects.expected | 1 + .../EXP40-C/DoNotModifyConstantObjects.qlref | 1 + .../RightHandOperandOfAShiftOperatorRange.ql | 19 ++++ .../ArrayFunctionArgumentNumberOfElements.ql | 19 ++++ .../ValueReturnedByAFunctionNotUsed.ql | 18 ++++ ...tHandOperandOfAShiftOperatorRange.expected | 1 + ...ightHandOperandOfAShiftOperatorRange.qlref | 1 + ...yFunctionArgumentNumberOfElements.expected | 1 + ...rrayFunctionArgumentNumberOfElements.qlref | 1 + .../ValueReturnedByAFunctionNotUsed.expected | 1 + .../ValueReturnedByAFunctionNotUsed.qlref | 1 + .../cpp/exclusions/c/Contracts6.qll | 74 ++++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 + rule_packages/c/Contracts6.json | 74 ++++++++++++++ 16 files changed, 329 insertions(+) create mode 100644 c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md create mode 100644 c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql create mode 100644 c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected create mode 100644 c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.qlref create mode 100644 c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql create mode 100644 c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql create mode 100644 c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql create mode 100644 c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected create mode 100644 c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref create mode 100644 c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected create mode 100644 c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.qlref create mode 100644 c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected create mode 100644 c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.qlref create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll create mode 100644 rule_packages/c/Contracts6.json diff --git a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md new file mode 100644 index 0000000000..3ddecd6abf --- /dev/null +++ b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md @@ -0,0 +1,96 @@ +# EXP40-C: Do not modify constant objects + +This query implements the CERT-C rule EXP40-C: + +> Do not modify constant objects + + + +## Description + +The C Standard, 6.7.3, paragraph 6 \[[IS](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)[O/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], states + +> If an attempt is made to modify an object defined with a `const`-qualified type through use of an [lvalue](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-lvalue) with non-`const`-qualified type, the behavior is undefined. + + +See also [undefined behavior 64](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_64). + +There are existing compiler [implementations](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) that allow `const`-qualified objects to be modified without generating a warning message. + +Avoid casting away `const` qualification because doing so makes it possible to modify `const`-qualified objects without issuing diagnostics. (See [EXP05-C. Do not cast away a const qualification](https://wiki.sei.cmu.edu/confluence/display/c/EXP05-C.+Do+not+cast+away+a+const+qualification) and [STR30-C. Do not attempt to modify string literals](https://wiki.sei.cmu.edu/confluence/display/c/STR30-C.+Do+not+attempt+to+modify+string+literals) for more details.) + +## Noncompliant Code Example + +This noncompliant code example allows a constant object to be modified: + +```cpp +const int **ipp; +int *ip; +const int i = 42; + +void func(void) { + ipp = &ip; /* Constraint violation */ + *ipp = &i; /* Valid */ + *ip = 0; /* Modifies constant i (was 42) */ +} +``` +The first assignment is unsafe because it allows the code that follows it to attempt to change the value of the `const` object `i`. + +**Implementation Details** + +If `ipp`, `ip`, and `i` are declared as automatic variables, this example compiles without warning with Microsoft Visual Studio 2013 when compiled in C mode (`/TC`) and the resulting program changes the value of `i`. GCC 4.8.1 generates a warning but compiles, and the resulting program changes the value of `i`. + +If `ipp`, `ip`, and `i` are declared with static storage duration, this program compiles without warning and terminates abnormally with Microsoft Visual Studio 2013, and compiles with warning and terminates abnormally with GCC 4.8.1. + +## Compliant Solution + +The compliant solution depends on the intent of the programmer. If the intent is that the value of `i` is modifiable, then it should not be declared as a constant, as in this compliant solution: + +```cpp +int **ipp; +int *ip; +int i = 42; + +void func(void) { + ipp = &ip; /* Valid */ + *ipp = &i; /* Valid */ + *ip = 0; /* Valid */ +} +``` +If the intent is that the value of i is not meant to change, then do not write noncompliant code that attempts to modify it. + +## Risk Assessment + +Modifying constant objects through nonconstant references is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior). + +
Rule Severity Likelihood Remediation Cost Priority Level
EXP40-C Low Unlikely Medium P2 L3
+ + +## Automated Detection + +
Tool Version Checker Description
Astrée 22.04 assignment-to-non-modifiable-lvalue pointer-qualifier-cast-const pointer-qualifier-cast-const-implicit write-to-constant-memory Fully checked
Axivion Bauhaus Suite 7.2.0 CertC-EXP40
Coverity 2017.07 PW MISRA C 2004 Rule 11.5 Implemented
Helix QAC 2022.3 C0563
LDRA tool suite 9.7.1 582 S Fully implemented
Parasoft C/C++test 2022.1 CERT_C-EXP40-a A cast shall not remove any 'const' or 'volatile' qualification from the type of a pointer or reference
Polyspace Bug Finder R2022b CERT C: Rule EXP40-C Checks for write operations on const qualified objects (rule fully covered)
PRQA QA-C 9.7 0563 Partially implemented
RuleChecker 22.04 assignment-to-non-modifiable-lvalue pointer-qualifier-cast-const pointer-qualifier-cast-const-implicit Partially checked
TrustInSoft Analyzer 1.38 mem_access Exhaustively verified (see the compliant and the non-compliant example ).
+ + +## Related Vulnerabilities + +Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+EXP40-C). + +## Related Guidelines + +[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions) + +
Taxonomy Taxonomy item Relationship
CERT C Secure Coding Standard EXP05-C. Do not cast away a const qualification Prior to 2018-01-12: CERT: Unspecified Relationship
CERT C Secure Coding Standard STR30-C. Do not attempt to modify string literals Prior to 2018-01-12: CERT: Unspecified Relationship
+ + +## Bibliography + +
\[ ISO/IEC 9899:2011 \] Subclause 6.7.3, "Type Qualifiers"
+ + +## Implementation notes + +None + +## References + +* CERT-C: [EXP40-C: Do not modify constant objects](https://wiki.sei.cmu.edu/confluence/display/c) diff --git a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql new file mode 100644 index 0000000000..51fcdb422a --- /dev/null +++ b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql @@ -0,0 +1,18 @@ +/** + * @id c/cert/do-not-modify-constant-objects + * @name EXP40-C: Do not modify constant objects + * @description + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/cert/id/exp40-c + * external/cert/obligation/rule + */ + +import cpp +import codingstandards.c.cert + +from +where + not isExcluded(x, Contracts6Package::doNotModifyConstantObjectsQuery()) and +select diff --git a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected new file mode 100644 index 0000000000..2ec1a0ac6c --- /dev/null +++ b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected @@ -0,0 +1 @@ +No expected results have yet been specified \ No newline at end of file diff --git a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.qlref b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.qlref new file mode 100644 index 0000000000..c07ac22f37 --- /dev/null +++ b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.qlref @@ -0,0 +1 @@ +rules/EXP40-C/DoNotModifyConstantObjects.ql \ No newline at end of file diff --git a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql new file mode 100644 index 0000000000..dc3d7b99f9 --- /dev/null +++ b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql @@ -0,0 +1,19 @@ +/** + * @id c/misra/right-hand-operand-of-a-shift-operator-range + * @name RULE-12-2: The right hand operand of a shift operator shall lie in the range zero to one less than the width in + * @description The right hand operand of a shift operator shall lie in the range zero to one less + * than the width in bits of the essential type of the left hand operand + * @kind problem + * @precision high + * @problem.severity error + * @tags external/misra/id/rule-12-2 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from +where + not isExcluded(x, Contracts6Package::rightHandOperandOfAShiftOperatorRangeQuery()) and +select diff --git a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql new file mode 100644 index 0000000000..651027af50 --- /dev/null +++ b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql @@ -0,0 +1,19 @@ +/** + * @id c/misra/array-function-argument-number-of-elements + * @name RULE-17-5: The function argument corresponding to a parameter declared to have an array type shall have an + * @description The function argument corresponding to a parameter declared to have an array type + * shall have an appropriate number of elements + * @kind problem + * @precision high + * @problem.severity error + * @tags external/misra/id/rule-17-5 + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.c.misra + +from +where + not isExcluded(x, Contracts6Package::arrayFunctionArgumentNumberOfElementsQuery()) and +select diff --git a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql new file mode 100644 index 0000000000..face46fcf5 --- /dev/null +++ b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql @@ -0,0 +1,18 @@ +/** + * @id c/misra/value-returned-by-a-function-not-used + * @name RULE-17-7: The value returned by a function having non-void return type shall be used + * @description + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-17-7 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from +where + not isExcluded(x, Contracts6Package::valueReturnedByAFunctionNotUsedQuery()) and +select diff --git a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected new file mode 100644 index 0000000000..2ec1a0ac6c --- /dev/null +++ b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected @@ -0,0 +1 @@ +No expected results have yet been specified \ No newline at end of file diff --git a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref new file mode 100644 index 0000000000..d32cc27dcd --- /dev/null +++ b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref @@ -0,0 +1 @@ +rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected new file mode 100644 index 0000000000..2ec1a0ac6c --- /dev/null +++ b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected @@ -0,0 +1 @@ +No expected results have yet been specified \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.qlref b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.qlref new file mode 100644 index 0000000000..41a893a32c --- /dev/null +++ b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.qlref @@ -0,0 +1 @@ +rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected b/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected new file mode 100644 index 0000000000..2ec1a0ac6c --- /dev/null +++ b/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected @@ -0,0 +1 @@ +No expected results have yet been specified \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.qlref b/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.qlref new file mode 100644 index 0000000000..a365eed3d8 --- /dev/null +++ b/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.qlref @@ -0,0 +1 @@ +rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll new file mode 100644 index 0000000000..246a7af26b --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll @@ -0,0 +1,74 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Contracts6Query = + TDoNotModifyConstantObjectsQuery() or + TRightHandOperandOfAShiftOperatorRangeQuery() or + TArrayFunctionArgumentNumberOfElementsQuery() or + TValueReturnedByAFunctionNotUsedQuery() + +predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId) { + query = + // `Query` instance for the `doNotModifyConstantObjects` query + Contracts6Package::doNotModifyConstantObjectsQuery() and + queryId = + // `@id` for the `doNotModifyConstantObjects` query + "c/cert/do-not-modify-constant-objects" and + ruleId = "EXP40-C" + or + query = + // `Query` instance for the `rightHandOperandOfAShiftOperatorRange` query + Contracts6Package::rightHandOperandOfAShiftOperatorRangeQuery() and + queryId = + // `@id` for the `rightHandOperandOfAShiftOperatorRange` query + "c/misra/right-hand-operand-of-a-shift-operator-range" and + ruleId = "RULE-12-2" + or + query = + // `Query` instance for the `arrayFunctionArgumentNumberOfElements` query + Contracts6Package::arrayFunctionArgumentNumberOfElementsQuery() and + queryId = + // `@id` for the `arrayFunctionArgumentNumberOfElements` query + "c/misra/array-function-argument-number-of-elements" and + ruleId = "RULE-17-5" + or + query = + // `Query` instance for the `valueReturnedByAFunctionNotUsed` query + Contracts6Package::valueReturnedByAFunctionNotUsedQuery() and + queryId = + // `@id` for the `valueReturnedByAFunctionNotUsed` query + "c/misra/value-returned-by-a-function-not-used" and + ruleId = "RULE-17-7" +} + +module Contracts6Package { + Query doNotModifyConstantObjectsQuery() { + //autogenerate `Query` type + result = + // `Query` type for `doNotModifyConstantObjects` query + TQueryC(TContracts6PackageQuery(TDoNotModifyConstantObjectsQuery())) + } + + Query rightHandOperandOfAShiftOperatorRangeQuery() { + //autogenerate `Query` type + result = + // `Query` type for `rightHandOperandOfAShiftOperatorRange` query + TQueryC(TContracts6PackageQuery(TRightHandOperandOfAShiftOperatorRangeQuery())) + } + + Query arrayFunctionArgumentNumberOfElementsQuery() { + //autogenerate `Query` type + result = + // `Query` type for `arrayFunctionArgumentNumberOfElements` query + TQueryC(TContracts6PackageQuery(TArrayFunctionArgumentNumberOfElementsQuery())) + } + + Query valueReturnedByAFunctionNotUsedQuery() { + //autogenerate `Query` type + result = + // `Query` type for `valueReturnedByAFunctionNotUsed` query + TQueryC(TContracts6PackageQuery(TValueReturnedByAFunctionNotUsedQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index ad05d9b737..33802d7235 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -12,6 +12,7 @@ import Contracts1 import Contracts2 import Contracts3 import Contracts4 +import Contracts6 import Declarations1 import Declarations2 import Declarations3 @@ -48,6 +49,7 @@ newtype TCQuery = TContracts2PackageQuery(Contracts2Query q) or TContracts3PackageQuery(Contracts3Query q) or TContracts4PackageQuery(Contracts4Query q) or + TContracts6PackageQuery(Contracts6Query q) or TDeclarations1PackageQuery(Declarations1Query q) or TDeclarations2PackageQuery(Declarations2Query q) or TDeclarations3PackageQuery(Declarations3Query q) or @@ -84,6 +86,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId) { isContracts2QueryMetadata(query, queryId, ruleId) or isContracts3QueryMetadata(query, queryId, ruleId) or isContracts4QueryMetadata(query, queryId, ruleId) or + isContracts6QueryMetadata(query, queryId, ruleId) or isDeclarations1QueryMetadata(query, queryId, ruleId) or isDeclarations2QueryMetadata(query, queryId, ruleId) or isDeclarations3QueryMetadata(query, queryId, ruleId) or diff --git a/rule_packages/c/Contracts6.json b/rule_packages/c/Contracts6.json new file mode 100644 index 0000000000..0113b16542 --- /dev/null +++ b/rule_packages/c/Contracts6.json @@ -0,0 +1,74 @@ +{ + "CERT-C": { + "EXP40-C": { + "properties": { + "obligation": "rule" + }, + "queries": [ + { + "description": "", + "kind": "problem", + "name": "Do not modify constant objects", + "precision": "very-high", + "severity": "error", + "short_name": "DoNotModifyConstantObjects", + "tags": [] + } + ], + "title": "Do not modify constant objects" + } + }, + "MISRA-C-2012": { + "RULE-12-2": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand", + "kind": "problem", + "name": "The right hand operand of a shift operator shall lie in the range zero to one less than the width in", + "precision": "high", + "severity": "error", + "short_name": "RightHandOperandOfAShiftOperatorRange", + "tags": [] + } + ], + "title": "The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand" + }, + "RULE-17-5": { + "properties": { + "obligation": "advisory" + }, + "queries": [ + { + "description": "The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements", + "kind": "problem", + "name": "The function argument corresponding to a parameter declared to have an array type shall have an", + "precision": "high", + "severity": "error", + "short_name": "ArrayFunctionArgumentNumberOfElements", + "tags": [] + } + ], + "title": "The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements" + }, + "RULE-17-7": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "", + "kind": "problem", + "name": "The value returned by a function having non-void return type shall be used", + "precision": "very-high", + "severity": "error", + "short_name": "ValueReturnedByAFunctionNotUsed", + "tags": [] + } + ], + "title": "The value returned by a function having non-void return type shall be used" + } + } +} \ No newline at end of file From 266c3e58ea697e593d0f4a2abe54a31d2372ebd7 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 2 Feb 2023 14:30:43 +0100 Subject: [PATCH 3/8] Misra rules 12-2 17-5 17-7 --- .../RightHandOperandOfAShiftOperatorRange.ql | 11 +++- .../ArrayFunctionArgumentNumberOfElements.ql | 62 ++++++++++++++++++- .../ValueReturnedByAFunctionNotUsed.ql | 16 +++-- ...tHandOperandOfAShiftOperatorRange.expected | 22 ++++++- c/misra/test/rules/RULE-12-2/test.c | 23 +++++-- ...yFunctionArgumentNumberOfElements.expected | 10 ++- c/misra/test/rules/RULE-17-5/test.c | 21 ++++++- .../ValueReturnedByAFunctionNotUsed.expected | 3 +- .../cpp/exclusions/c/Contracts6.qll | 14 +++-- 9 files changed, 158 insertions(+), 24 deletions(-) diff --git a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql index dc3d7b99f9..d69d276745 100644 --- a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql +++ b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql @@ -12,8 +12,15 @@ import cpp import codingstandards.c.misra +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis -from +from BinaryOperation x, int max_size where not isExcluded(x, Contracts6Package::rightHandOperandOfAShiftOperatorRangeQuery()) and -select + (x instanceof LShiftExpr or x instanceof RShiftExpr) and + max_size = (8 * x.getLeftOperand().getExplicitlyConverted().getUnderlyingType().getSize()) - 1 and + exists(Expr rhs | rhs = x.getRightOperand().getFullyConverted() | + lowerBound(rhs) < 0 or + upperBound(rhs) > max_size + ) +select x, "The right hand operand of the shift operator is not in the range 0 to " + max_size + "." diff --git a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql index 651027af50..2081f7b702 100644 --- a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql +++ b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql @@ -12,8 +12,64 @@ import cpp import codingstandards.c.misra +import semmle.code.cpp.dataflow.DataFlow -from +/** + * Models a function parameter of type array with specified size + * ``` + * void f1(int ar[3]); + * ``` + */ +class ArrayParameter extends Parameter { + ArrayParameter() { this.getType().(ArrayType).hasArraySize() } + + Expr getAMatchingArgument() { + exists(FunctionCall fc | + this.getFunction() = fc.getTarget() and + result = fc.getArgument(this.getIndex()) + ) + } + + int getArraySize() { result = this.getType().(ArrayType).getArraySize() } +} + +/** + * The number of initialized elements in an ArrayAggregateLiteral. + * In the following examples the result=2 + * ``` + * int arr3[3] = {1, 2}; + * int arr2[2] = {1, 2, 3}; + * ``` + */ +int countElements(ArrayAggregateLiteral l) { result = count(l.getElementExpr(_)) } + +class SmallArrayConfig extends DataFlow::Configuration { + SmallArrayConfig() { this = "SmallArrayConfig" } + + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ArrayAggregateLiteral } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(ArrayParameter p).getAMatchingArgument() + } +} + +from Expr arg, ArrayParameter p where - not isExcluded(x, Contracts6Package::arrayFunctionArgumentNumberOfElementsQuery()) and -select + not isExcluded(arg, Contracts6Package::arrayFunctionArgumentNumberOfElementsQuery()) and + exists(SmallArrayConfig config | arg = p.getAMatchingArgument() | + // the argument is a value and not an arrey + not arg.getType() instanceof DerivedType + or + // the argument is an array too small + arg.getType().(ArrayType).getArraySize() < p.getArraySize() + or + // the argument is a pointer and its value does not come from a literal of the correct + arg.getType() instanceof PointerType and + not exists(ArrayAggregateLiteral l | + config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(arg)) and + countElements(l) >= p.getArraySize() + ) + ) +select arg, + "The function argument does not have a sufficient number or elements declared in the $@.", p, + "parameter" diff --git a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql index face46fcf5..4fa1705a23 100644 --- a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql +++ b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql @@ -1,7 +1,7 @@ /** * @id c/misra/value-returned-by-a-function-not-used * @name RULE-17-7: The value returned by a function having non-void return type shall be used - * @description + * @description * @kind problem * @precision very-high * @problem.severity error @@ -11,8 +11,16 @@ import cpp import codingstandards.c.misra +import semmle.code.cpp.dataflow.DataFlow -from +from Call c where - not isExcluded(x, Contracts6Package::valueReturnedByAFunctionNotUsedQuery()) and -select + not isExcluded(c, Contracts6Package::valueReturnedByAFunctionNotUsedQuery()) and + // Calls in `ExprStmt`s indicate that the return value is ignored + c.getParent() instanceof ExprStmt and + // Ignore calls to void functions or where the return value is cast to `void` + not c.getActualType() instanceof VoidType and + // Exclude cases where the function call is generated within a macro, as the user of the macro is + // not necessarily able to address thoes results + not c.isAffectedByMacro() +select c, "The value returned by this call shall be used or cast to `void`." diff --git a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected index 2ec1a0ac6c..9f1dea64f3 100644 --- a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected +++ b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected @@ -1 +1,21 @@ -No expected results have yet been specified \ No newline at end of file +| test.c:20:7:20:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | +| test.c:22:7:22:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | +| test.c:23:7:23:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | +| test.c:25:7:25:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | +| test.c:26:7:26:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | +| test.c:29:7:29:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:30:7:30:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:31:7:31:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:32:7:32:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:33:7:33:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:34:7:34:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:35:7:35:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:38:7:38:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 63. | +| test.c:40:7:40:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 63. | +| test.c:43:7:43:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 63. | +| test.c:46:7:46:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | +| test.c:47:7:47:12 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | +| test.c:63:7:63:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | +| test.c:71:8:71:14 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | +| test.c:75:3:75:19 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | +| test.c:77:3:77:12 | ... >> ... | The right hand operand of the shift operator is not in the range 0 to 63. | diff --git a/c/misra/test/rules/RULE-12-2/test.c b/c/misra/test/rules/RULE-12-2/test.c index b2b88ebda0..563a903503 100644 --- a/c/misra/test/rules/RULE-12-2/test.c +++ b/c/misra/test/rules/RULE-12-2/test.c @@ -1,4 +1,4 @@ - +#include const short int s1 = 15; const short int s2 = -1; @@ -58,8 +58,21 @@ void f2() { int aa = 10; aa++; - a = a << aa; - b = b << aa; - c = c << aa; - d = d << aa; + a = a << aa; // COMPLIANT + b = b << aa; // COMPLIANT + c = c << aa; // NON_COMPLIANT + d = d << aa; // COMPLIANT +} + +void f3() { + uint8_t u8; + uint16_t u16; + u8 = u8 << 7; // COMPLIANT + u8 = u8 << 8; // NON_COMPLIANT + u16 = (uint16_t)u8 << 9; // COMPLIANT +// 0u is essentially unsigned char + 0u << 10; // NON_COMPLIANT[FALSE_NEGATIVE] + (uint16_t)0 << 20; // NON_COMPLIANT + 0UL << 10; // COMPLIANT + 0UL >> 100; // NON_COMPLIANT } \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected index 2ec1a0ac6c..913f6f1c34 100644 --- a/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected +++ b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected @@ -1 +1,9 @@ -No expected results have yet been specified \ No newline at end of file +| test.c:18:6:18:6 | 0 | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter | +| test.c:19:6:19:7 | ar | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter | +| test.c:21:6:21:9 | ar2p | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter | +| test.c:26:9:26:9 | 0 | The function argument does not have a sufficient number or elements declared in the $@. | test.c:2:20:2:21 | ar | parameter | +| test.c:27:9:27:10 | ar | The function argument does not have a sufficient number or elements declared in the $@. | test.c:2:20:2:21 | ar | parameter | +| test.c:29:9:29:12 | ar2p | The function argument does not have a sufficient number or elements declared in the $@. | test.c:2:20:2:21 | ar | parameter | +| test.c:61:6:61:8 | ar2 | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter | +| test.c:62:6:62:9 | ar2b | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter | +| test.c:63:6:63:9 | ar2p | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter | diff --git a/c/misra/test/rules/RULE-17-5/test.c b/c/misra/test/rules/RULE-17-5/test.c index 2488d2d632..bbac126630 100644 --- a/c/misra/test/rules/RULE-17-5/test.c +++ b/c/misra/test/rules/RULE-17-5/test.c @@ -17,7 +17,7 @@ void t1() { f1(0); // NON_COMPLAINT f1(ar); // NON_COMPLAINT - f1(ar2); // NON_COMPLIANT + f1(ar2); // COMPLIANT f1(ar2p); // NON_COMPLIANT f1(ar3); // COMPLIANT f1(ar3p); // COMPLIANT @@ -25,7 +25,7 @@ void t1() { f2(0, 0); // NON_COMPLAINT f2(0, ar); // NON_COMPLAINT - f2(0, ar2); // NON_COMPLIANT + f2(0, ar2); // COMPLIANT f2(0, ar2p); // NON_COMPLIANT f2(0, ar3); // COMPLIANT f2(0, ar3p); // COMPLIANT @@ -46,4 +46,21 @@ void t1() { f4(0, ar3); // COMPLIANT f4(0, ar3p); // COMPLIANT f4(0, ar4); // COMPLIANT +} + +void t2() { + int ar2[2] = {1, 2}; + int ar2b[2] = {1, 2, 3}; + int *ar2p = ar2; + int ar3[3]; + ar3[0] = 1; + ar3[1] = 2; + ar3[2] = 3; + int ar4[4] = {1, 2, 3, 4}; + + f1(ar2); // NON_COMPLIANT + f1(ar2b); // NON_COMPLIANT + f1(ar2p); // NON_COMPLIANT + f1(ar3); // COMPLIANT + f1(ar4); // COMPLIANT } \ No newline at end of file diff --git a/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected b/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected index 2ec1a0ac6c..95b54ed874 100644 --- a/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected +++ b/c/misra/test/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.expected @@ -1 +1,2 @@ -No expected results have yet been specified \ No newline at end of file +| test.c:6:3:6:4 | call to f2 | The value returned by this call shall be used or cast to `void`. | +| test.c:15:3:15:9 | call to expression | The value returned by this call shall be used or cast to `void`. | diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll index 246a7af26b..6aeacb6e7d 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll @@ -9,14 +9,15 @@ newtype Contracts6Query = TArrayFunctionArgumentNumberOfElementsQuery() or TValueReturnedByAFunctionNotUsedQuery() -predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId) { +predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId, string category) { query = // `Query` instance for the `doNotModifyConstantObjects` query Contracts6Package::doNotModifyConstantObjectsQuery() and queryId = // `@id` for the `doNotModifyConstantObjects` query "c/cert/do-not-modify-constant-objects" and - ruleId = "EXP40-C" + ruleId = "EXP40-C" and + category = "rule" or query = // `Query` instance for the `rightHandOperandOfAShiftOperatorRange` query @@ -24,7 +25,8 @@ predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId) queryId = // `@id` for the `rightHandOperandOfAShiftOperatorRange` query "c/misra/right-hand-operand-of-a-shift-operator-range" and - ruleId = "RULE-12-2" + ruleId = "RULE-12-2" and + category = "required" or query = // `Query` instance for the `arrayFunctionArgumentNumberOfElements` query @@ -32,7 +34,8 @@ predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId) queryId = // `@id` for the `arrayFunctionArgumentNumberOfElements` query "c/misra/array-function-argument-number-of-elements" and - ruleId = "RULE-17-5" + ruleId = "RULE-17-5" and + category = "advisory" or query = // `Query` instance for the `valueReturnedByAFunctionNotUsed` query @@ -40,7 +43,8 @@ predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId) queryId = // `@id` for the `valueReturnedByAFunctionNotUsed` query "c/misra/value-returned-by-a-function-not-used" and - ruleId = "RULE-17-7" + ruleId = "RULE-17-7" and + category = "required" } module Contracts6Package { From 8240376bba0c3e5e0f2793e4bd1a606b36381a53 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 2 Feb 2023 17:44:45 +0100 Subject: [PATCH 4/8] IMplement EXP40-C --- .../EXP40-C/DoNotModifyConstantObjects.md | 3 +- .../EXP40-C/DoNotModifyConstantObjects.ql | 55 +++++++++++++++++-- .../DoNotModifyConstantObjects.expected | 30 +++++++++- c/cert/test/rules/EXP40-C/test.c | 45 +++++++++++++-- .../ArrayFunctionArgumentNumberOfElements.ql | 7 ++- .../ValueReturnedByAFunctionNotUsed.ql | 6 +- .../cpp/exclusions/c/Contracts6.qll | 9 --- rule_packages/c/Contracts6.json | 38 +++++-------- rules.csv | 6 +- 9 files changed, 144 insertions(+), 55 deletions(-) diff --git a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md index 3ddecd6abf..6effa8e7c4 100644 --- a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md +++ b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.md @@ -5,7 +5,6 @@ This query implements the CERT-C rule EXP40-C: > Do not modify constant objects - ## Description The C Standard, 6.7.3, paragraph 6 \[[IS](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)[O/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\], states @@ -89,7 +88,7 @@ Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+D ## Implementation notes -None +The implementation does not consider pointer aliasing via multiple indirection. ## References diff --git a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql index 51fcdb422a..08901f2016 100644 --- a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql +++ b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql @@ -1,18 +1,61 @@ /** * @id c/cert/do-not-modify-constant-objects * @name EXP40-C: Do not modify constant objects - * @description - * @kind problem - * @precision very-high + * @description Do not modify constant objects. This may result in undefined behavior. + * @kind path-problem + * @precision high * @problem.severity error * @tags external/cert/id/exp40-c + * correctness * external/cert/obligation/rule */ import cpp import codingstandards.c.cert +import semmle.code.cpp.dataflow.DataFlow +import DataFlow::PathGraph +import codingstandards.cpp.SideEffect -from +class ConstRemovingCast extends Cast { + ConstRemovingCast() { + this.getExpr().getType().(DerivedType).getBaseType*().isConst() and + not this.getType().(DerivedType).getBaseType*().isConst() + } +} + +class MaybeReturnsStringLiteralFunctionCall extends FunctionCall { + MaybeReturnsStringLiteralFunctionCall() { + getTarget().getName() in [ + "strpbrk", "strchr", "strrchr", "strstr", "wcspbrk", "wcschr", "wcsrchr", "wcsstr", + "memchr", "wmemchr" + ] + } +} + +class MyDataFlowConfCast extends DataFlow::Configuration { + MyDataFlowConfCast() { this = "MyDataFlowConfCast" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().getFullyConverted() instanceof ConstRemovingCast + or + source.asExpr().getFullyConverted() = any(MaybeReturnsStringLiteralFunctionCall c) + } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(Assignment a).getLValue().(PointerDereferenceExpr).getOperand() + } +} + +from MyDataFlowConfCast conf, DataFlow::PathNode src, DataFlow::PathNode sink where - not isExcluded(x, Contracts6Package::doNotModifyConstantObjectsQuery()) and -select + conf.hasFlowPath(src, sink) + or + sink.getNode() + .asExpr() + .(VariableEffect) + .getTarget() + .getType() + .(DerivedType) + .getBaseType*() + .isConst() +select sink, src, sink, "Const variable assigned with non const-value." diff --git a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected index 2ec1a0ac6c..3211c4fab1 100644 --- a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected +++ b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected @@ -1 +1,29 @@ -No expected results have yet been specified \ No newline at end of file +edges +| test.c:5:8:5:9 | & ... | test.c:6:4:6:5 | aa | +| test.c:26:15:26:15 | a | test.c:27:4:27:4 | a | +| test.c:34:13:34:14 | & ... | test.c:39:7:39:8 | p1 | +| test.c:39:7:39:8 | p1 | test.c:26:15:26:15 | a | +| test.c:40:7:40:9 | * ... | test.c:26:15:26:15 | a | +| test.c:59:7:59:8 | & ... | test.c:60:4:60:4 | p | +| test.c:79:11:79:16 | call to strchr | test.c:81:6:81:12 | ... ++ | +nodes +| test.c:5:8:5:9 | & ... | semmle.label | & ... | +| test.c:6:4:6:5 | aa | semmle.label | aa | +| test.c:26:15:26:15 | a | semmle.label | a | +| test.c:27:4:27:4 | a | semmle.label | a | +| test.c:34:13:34:14 | & ... | semmle.label | & ... | +| test.c:39:7:39:8 | p1 | semmle.label | p1 | +| test.c:40:7:40:9 | * ... | semmle.label | * ... | +| test.c:59:7:59:8 | & ... | semmle.label | & ... | +| test.c:60:4:60:4 | p | semmle.label | p | +| test.c:74:12:74:12 | s | semmle.label | s | +| test.c:79:11:79:16 | call to strchr | semmle.label | call to strchr | +| test.c:81:6:81:12 | ... ++ | semmle.label | ... ++ | +subpaths +#select +| test.c:6:4:6:5 | aa | test.c:5:8:5:9 | & ... | test.c:6:4:6:5 | aa | Const variable assigned with non const-value. | +| test.c:27:4:27:4 | a | test.c:34:13:34:14 | & ... | test.c:27:4:27:4 | a | Const variable assigned with non const-value. | +| test.c:27:4:27:4 | a | test.c:40:7:40:9 | * ... | test.c:27:4:27:4 | a | Const variable assigned with non const-value. | +| test.c:60:4:60:4 | p | test.c:59:7:59:8 | & ... | test.c:60:4:60:4 | p | Const variable assigned with non const-value. | +| test.c:74:12:74:12 | s | test.c:74:12:74:12 | s | test.c:74:12:74:12 | s | Const variable assigned with non const-value. | +| test.c:81:6:81:12 | ... ++ | test.c:79:11:79:16 | call to strchr | test.c:81:6:81:12 | ... ++ | Const variable assigned with non const-value. | diff --git a/c/cert/test/rules/EXP40-C/test.c b/c/cert/test/rules/EXP40-C/test.c index 5723f72c30..f8c9b6d545 100644 --- a/c/cert/test/rules/EXP40-C/test.c +++ b/c/cert/test/rules/EXP40-C/test.c @@ -2,8 +2,8 @@ void f1() { const int a = 3; int *aa; - aa = &a; // NON_COMPLIANT - *aa = 100; + aa = &a; + *aa = 100; // NON_COMPLIANT } void f1a() { @@ -31,13 +31,13 @@ void f4b(int *a) {} void f4() { const int a = 100; - int *p1 = &a; // NON_COMPLIANT + int *p1 = &a; // COMPLIANT const int **p2; - *p2 = &a; // NON_COMPLIANT + *p2 = &a; // COMPLIANT - f4a(p1); // NON_COMPLIANT - f4a(*p2); // NON_COMPLIANT + f4a(p1); // COMPLIANT + f4a(*p2); // COMPLIANT } void f5() { @@ -49,4 +49,37 @@ void f5() { f4b(p1); f4b(*p2); +} + +#include + +void f6a() { + char *p; + const char c = 'A'; + p = &c; + *p = 0; // NON_COMPLIANT +} + +void f6b() { + const char **cpp; + char *p; + const char c = 'A'; + cpp = &p; + *cpp = &c; + *p = 0; // NON_COMPLIANT[FALSE_NEGATIVE] +} + +const char s[] = "foo"; // source +void f7() { + *(char *)s = '\0'; // NON_COMPLIANT +} + +const char *f8(const char *pathname) { + char *slash; + slash = strchr(pathname, '/'); + if (slash) { + *slash++ = '\0'; // NON_COMPLIANT + return slash; + } + return pathname; } \ No newline at end of file diff --git a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql index 2081f7b702..55dd237e89 100644 --- a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql +++ b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql @@ -1,12 +1,13 @@ /** * @id c/misra/array-function-argument-number-of-elements - * @name RULE-17-5: The function argument corresponding to a parameter declared to have an array type shall have an - * @description The function argument corresponding to a parameter declared to have an array type - * shall have an appropriate number of elements + * @name RULE-17-5: An array founction argument shall have an appropriate number of elements + * @description The function argument corresponding to an array parameter shall have an appropriate + * number of elements * @kind problem * @precision high * @problem.severity error * @tags external/misra/id/rule-17-5 + * correctness * external/misra/obligation/advisory */ diff --git a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql index 4fa1705a23..906c11add0 100644 --- a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql +++ b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql @@ -1,11 +1,13 @@ /** * @id c/misra/value-returned-by-a-function-not-used - * @name RULE-17-7: The value returned by a function having non-void return type shall be used - * @description + * @name RULE-17-7: Return values should be used or cast to void + * @description The value returned by a function having non-void return type shall be used or cast + * to void * @kind problem * @precision very-high * @problem.severity error * @tags external/misra/id/rule-17-7 + * correctness * external/misra/obligation/required */ diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll index 6aeacb6e7d..5f55b28b2e 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll @@ -19,15 +19,6 @@ predicate isContracts6QueryMetadata(Query query, string queryId, string ruleId, ruleId = "EXP40-C" and category = "rule" or - query = - // `Query` instance for the `rightHandOperandOfAShiftOperatorRange` query - Contracts6Package::rightHandOperandOfAShiftOperatorRangeQuery() and - queryId = - // `@id` for the `rightHandOperandOfAShiftOperatorRange` query - "c/misra/right-hand-operand-of-a-shift-operator-range" and - ruleId = "RULE-12-2" and - category = "required" - or query = // `Query` instance for the `arrayFunctionArgumentNumberOfElements` query Contracts6Package::arrayFunctionArgumentNumberOfElementsQuery() and diff --git a/rule_packages/c/Contracts6.json b/rule_packages/c/Contracts6.json index 0113b16542..8708f9e3af 100644 --- a/rule_packages/c/Contracts6.json +++ b/rule_packages/c/Contracts6.json @@ -6,36 +6,22 @@ }, "queries": [ { - "description": "", - "kind": "problem", + "description": "Do not modify constant objects. This may result in undefined behavior.", + "kind": "path-problem", "name": "Do not modify constant objects", - "precision": "very-high", + "precision": "high", "severity": "error", "short_name": "DoNotModifyConstantObjects", - "tags": [] + "tags": ["correctness"], + "implementation_scope": { + "description": "The implementation does not consider pointer aliasing via multiple indirection." + } } ], "title": "Do not modify constant objects" } }, "MISRA-C-2012": { - "RULE-12-2": { - "properties": { - "obligation": "required" - }, - "queries": [ - { - "description": "The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand", - "kind": "problem", - "name": "The right hand operand of a shift operator shall lie in the range zero to one less than the width in", - "precision": "high", - "severity": "error", - "short_name": "RightHandOperandOfAShiftOperatorRange", - "tags": [] - } - ], - "title": "The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand" - }, "RULE-17-5": { "properties": { "obligation": "advisory" @@ -48,7 +34,10 @@ "precision": "high", "severity": "error", "short_name": "ArrayFunctionArgumentNumberOfElements", - "tags": [] + "tags": ["correctness"], + "implementation_scope": { + "description": "The rule is enforced in the context of a single function." + } } ], "title": "The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements" @@ -65,7 +54,10 @@ "precision": "very-high", "severity": "error", "short_name": "ValueReturnedByAFunctionNotUsed", - "tags": [] + "tags": ["correctness"], + "implementation_scope": { + "description": "The rule is enforced in the context of a single function." + } } ], "title": "The value returned by a function having non-void return type shall be used" diff --git a/rules.csv b/rules.csv index 0e010aab04..d5dc6ca5b1 100644 --- a/rules.csv +++ b/rules.csv @@ -523,7 +523,7 @@ c,CERT-C,EXP35-C,Yes,Rule,,,Do not modify objects with temporary lifetime,,Inval c,CERT-C,EXP36-C,Yes,Rule,,,Do not cast pointers into more strictly aligned pointer types,,Pointers3,Medium, c,CERT-C,EXP37-C,Yes,Rule,,,Call functions with the correct number and type of arguments,,Expressions,Easy, c,CERT-C,EXP39-C,Yes,Rule,,,Do not access a variable through a pointer of an incompatible type,,Pointers3,Medium, -c,CERT-C,EXP40-C,Yes,Rule,,,Do not modify constant objects,,Contracts6,Medium, +c,CERT-C,EXP40-C,Yes,Rule,,,Do not modify constant objects,,Contracts6,Hard, c,CERT-C,EXP42-C,Yes,Rule,,,Do not compare padding data,,Memory,Medium, c,CERT-C,EXP43-C,Yes,Rule,,,Avoid undefined behavior when using restrict-qualified pointers,,Pointers3,Medium, c,CERT-C,EXP44-C,Yes,Rule,,,"Do not rely on side effects in operands to sizeof, _Alignof, or _Generic",M5-3-4,SideEffects1,Medium, @@ -683,7 +683,7 @@ c,MISRA-C-2012,RULE-11-7,Yes,Required,,,A cast shall not be performed between po c,MISRA-C-2012,RULE-11-8,Yes,Required,,,A cast shall not remove any const or volatile qualification from the type pointed to by a pointer,,Pointers1,Easy, c,MISRA-C-2012,RULE-11-9,Yes,Required,,,The macro NULL shall be the only permitted form of integer null pointer constant,,Pointers1,Easy, c,MISRA-C-2012,RULE-12-1,Yes,Advisory,,,The precedence of operators within expressions should be made explicit,,SideEffects1,Medium, -c,MISRA-C-2012,RULE-12-2,Yes,Required,,,The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand,,Contracts6,Hard, +c,MISRA-C-2012,RULE-12-2,Yes,Required,,,The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand,,Contracts,Medium, c,MISRA-C-2012,RULE-12-3,Yes,Advisory,,,The comma operator should not be used,M5-18-1,Banned,Import, c,MISRA-C-2012,RULE-12-4,Yes,Advisory,,,Evaluation of constant expressions should not lead to unsigned integer wrap-around,INT30-C,Types,Easy, c,MISRA-C-2012,RULE-12-5,Yes,Mandatory,,,The sizeof operator shall not have an operand which is a function parameter declared as �array of type�,,Types,Medium, @@ -717,7 +717,7 @@ c,MISRA-C-2012,RULE-17-3,Yes,Mandatory,,,A function shall not be declared implic c,MISRA-C-2012,RULE-17-4,Yes,Mandatory,,,All exit paths from a function with non-void return type shall have an explicit return statement with an expression,MSC52-CPP,Statements,Medium, c,MISRA-C-2012,RULE-17-5,Yes,Advisory,,,The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements,,Contracts6,Hard, c,MISRA-C-2012,RULE-17-6,No,Mandatory,,,The declaration of an array parameter shall not contain the static keyword between the [ ],,,, -c,MISRA-C-2012,RULE-17-7,Yes,Required,,,The value returned by a function having non-void return type shall be used,A0-1-2,Contracts6,Import, +c,MISRA-C-2012,RULE-17-7,Yes,Required,,,The value returned by a function having non-void return type shall be used,A0-1-2,Contracts6,Easy, c,MISRA-C-2012,RULE-17-8,Yes,Advisory,,,A function parameter should not be modified,,SideEffects2,Medium, c,MISRA-C-2012,RULE-18-1,Yes,Required,,,A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand,M5-0-16,Pointers1,Import, c,MISRA-C-2012,RULE-18-2,Yes,Required,,,Subtraction between pointers shall only be applied to pointers that address elements of the same array,M5-0-17,Pointers1,Import, From 9242d22eb9865b71ce7d21e9e69b4eb663c7bfa9 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 2 Feb 2023 17:50:15 +0100 Subject: [PATCH 5/8] Fix for CI/CD --- .../RightHandOperandOfAShiftOperatorRange.ql | 26 ------- ...tHandOperandOfAShiftOperatorRange.expected | 21 ----- ...ightHandOperandOfAShiftOperatorRange.qlref | 1 - c/misra/test/rules/RULE-12-2/test.c | 78 ------------------- rule_packages/c/Contracts6.json | 22 ++---- 5 files changed, 8 insertions(+), 140 deletions(-) delete mode 100644 c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql delete mode 100644 c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected delete mode 100644 c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref delete mode 100644 c/misra/test/rules/RULE-12-2/test.c diff --git a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql deleted file mode 100644 index d69d276745..0000000000 --- a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @id c/misra/right-hand-operand-of-a-shift-operator-range - * @name RULE-12-2: The right hand operand of a shift operator shall lie in the range zero to one less than the width in - * @description The right hand operand of a shift operator shall lie in the range zero to one less - * than the width in bits of the essential type of the left hand operand - * @kind problem - * @precision high - * @problem.severity error - * @tags external/misra/id/rule-12-2 - * external/misra/obligation/required - */ - -import cpp -import codingstandards.c.misra -import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis - -from BinaryOperation x, int max_size -where - not isExcluded(x, Contracts6Package::rightHandOperandOfAShiftOperatorRangeQuery()) and - (x instanceof LShiftExpr or x instanceof RShiftExpr) and - max_size = (8 * x.getLeftOperand().getExplicitlyConverted().getUnderlyingType().getSize()) - 1 and - exists(Expr rhs | rhs = x.getRightOperand().getFullyConverted() | - lowerBound(rhs) < 0 or - upperBound(rhs) > max_size - ) -select x, "The right hand operand of the shift operator is not in the range 0 to " + max_size + "." diff --git a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected deleted file mode 100644 index 9f1dea64f3..0000000000 --- a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.expected +++ /dev/null @@ -1,21 +0,0 @@ -| test.c:20:7:20:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | -| test.c:22:7:22:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | -| test.c:23:7:23:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | -| test.c:25:7:25:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | -| test.c:26:7:26:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 31. | -| test.c:29:7:29:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:30:7:30:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:31:7:31:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:32:7:32:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:33:7:33:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:34:7:34:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:35:7:35:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:38:7:38:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 63. | -| test.c:40:7:40:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 63. | -| test.c:43:7:43:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 63. | -| test.c:46:7:46:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | -| test.c:47:7:47:12 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | -| test.c:63:7:63:13 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | -| test.c:71:8:71:14 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 7. | -| test.c:75:3:75:19 | ... << ... | The right hand operand of the shift operator is not in the range 0 to 15. | -| test.c:77:3:77:12 | ... >> ... | The right hand operand of the shift operator is not in the range 0 to 63. | diff --git a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref deleted file mode 100644 index d32cc27dcd..0000000000 --- a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-12-2/RightHandOperandOfAShiftOperatorRange.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-12-2/test.c b/c/misra/test/rules/RULE-12-2/test.c deleted file mode 100644 index 563a903503..0000000000 --- a/c/misra/test/rules/RULE-12-2/test.c +++ /dev/null @@ -1,78 +0,0 @@ -#include - -const short int s1 = 15; -const short int s2 = -1; -const short int s3 = 16; -const int s4 = -1; -const int s5 = 32; -const int s6 = 21; - -const long int s7 = 64; -const long int s8 = 63; - -void f1() { - int a; - short b; - long c; - char d; - - a = a << s1; // COMPLIANT - a = a << s2; // NON_COMPLIANT - a = a << s3; // COMPLIANT - a = a << s4; // NON_COMPLIANT - a = a << s5; // NON_COMPLIANT - a = a << s6; // COMPLIANT - a = a << s7; // NON_COMPLIANT - a = a << s8; // NON_COMPLIANT - - b = b << s1; // COMPLIANT - b = b << s2; // NON_COMPLIANT - b = b << s3; // NON_COMPLIANT - b = b << s4; // NON_COMPLIANT - b = b << s5; // NON_COMPLIANT - b = b << s6; // NON_COMPLIANT - b = b << s7; // NON_COMPLIANT - b = b << s8; // NON_COMPLIANT - - c = c << s1; // COMPLIANT - c = c << s2; // NON_COMPLIANT - c = c << s3; // COMPLIANT - c = c << s4; // NON_COMPLIANT - c = c << s5; // COMPLIANT - c = c << s6; // COMPLIANT - c = c << s7; // NON_COMPLIANT - c = c << s8; // COMPLIANT - - d = d << -1; // NON_COMPLIANT - d = d << 8; // NON_COMPLIANT - d = d << 7; // COMPLIANT - d = d << 0; // COMPLIANT -} - -void f2() { - int a; - short b; - char c; - long long d; - - int aa = 10; - aa++; - - a = a << aa; // COMPLIANT - b = b << aa; // COMPLIANT - c = c << aa; // NON_COMPLIANT - d = d << aa; // COMPLIANT -} - -void f3() { - uint8_t u8; - uint16_t u16; - u8 = u8 << 7; // COMPLIANT - u8 = u8 << 8; // NON_COMPLIANT - u16 = (uint16_t)u8 << 9; // COMPLIANT -// 0u is essentially unsigned char - 0u << 10; // NON_COMPLIANT[FALSE_NEGATIVE] - (uint16_t)0 << 20; // NON_COMPLIANT - 0UL << 10; // COMPLIANT - 0UL >> 100; // NON_COMPLIANT -} \ No newline at end of file diff --git a/rule_packages/c/Contracts6.json b/rule_packages/c/Contracts6.json index 8708f9e3af..bc707f19f4 100644 --- a/rule_packages/c/Contracts6.json +++ b/rule_packages/c/Contracts6.json @@ -28,19 +28,16 @@ }, "queries": [ { - "description": "The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements", + "description": "The function argument corresponding to an array parameter shall have an appropriate number of elements.", "kind": "problem", - "name": "The function argument corresponding to a parameter declared to have an array type shall have an", + "name": "An array founction argument shall have an appropriate number of elements", "precision": "high", "severity": "error", "short_name": "ArrayFunctionArgumentNumberOfElements", - "tags": ["correctness"], - "implementation_scope": { - "description": "The rule is enforced in the context of a single function." - } + "tags": ["correctness"] } ], - "title": "The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements" + "title": "The function argument corresponding to an array parameter shall have an appropriate number of elements" }, "RULE-17-7": { "properties": { @@ -48,19 +45,16 @@ }, "queries": [ { - "description": "", + "description": "The value returned by a function having non-void return type shall be used or cast to void.", "kind": "problem", - "name": "The value returned by a function having non-void return type shall be used", + "name": "Return values should be used or cast to void", "precision": "very-high", "severity": "error", "short_name": "ValueReturnedByAFunctionNotUsed", - "tags": ["correctness"], - "implementation_scope": { - "description": "The rule is enforced in the context of a single function." - } + "tags": ["correctness"] } ], - "title": "The value returned by a function having non-void return type shall be used" + "title": "The value returned by a function having non-void return type shall be used or cast to void" } } } \ No newline at end of file From 5b619c54a15da850072e4ac634c0a85755f8b81c Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 2 Feb 2023 18:00:13 +0100 Subject: [PATCH 6/8] Regenerate Contracts6.qll --- .../src/codingstandards/cpp/exclusions/c/Contracts6.qll | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll index 5f55b28b2e..bd897bd79f 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts6.qll @@ -5,7 +5,6 @@ import codingstandards.cpp.exclusions.RuleMetadata newtype Contracts6Query = TDoNotModifyConstantObjectsQuery() or - TRightHandOperandOfAShiftOperatorRangeQuery() or TArrayFunctionArgumentNumberOfElementsQuery() or TValueReturnedByAFunctionNotUsedQuery() @@ -46,13 +45,6 @@ module Contracts6Package { TQueryC(TContracts6PackageQuery(TDoNotModifyConstantObjectsQuery())) } - Query rightHandOperandOfAShiftOperatorRangeQuery() { - //autogenerate `Query` type - result = - // `Query` type for `rightHandOperandOfAShiftOperatorRange` query - TQueryC(TContracts6PackageQuery(TRightHandOperandOfAShiftOperatorRangeQuery())) - } - Query arrayFunctionArgumentNumberOfElementsQuery() { //autogenerate `Query` type result = From 3a71ed25186852061b1a685f8ca490cae9ef5b8e Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 2 Feb 2023 18:01:35 +0100 Subject: [PATCH 7/8] Fixing rules description --- .../rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql | 2 +- c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql index 55dd237e89..0b5b95016c 100644 --- a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql +++ b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql @@ -2,7 +2,7 @@ * @id c/misra/array-function-argument-number-of-elements * @name RULE-17-5: An array founction argument shall have an appropriate number of elements * @description The function argument corresponding to an array parameter shall have an appropriate - * number of elements + * number of elements. * @kind problem * @precision high * @problem.severity error diff --git a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql index 906c11add0..3b224544f2 100644 --- a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql +++ b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql @@ -2,7 +2,7 @@ * @id c/misra/value-returned-by-a-function-not-used * @name RULE-17-7: Return values should be used or cast to void * @description The value returned by a function having non-void return type shall be used or cast - * to void + * to void. * @kind problem * @precision very-high * @problem.severity error From 27ca680f23c5995c947b20a450ba08959af6a529 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Wed, 8 Feb 2023 17:58:07 +0100 Subject: [PATCH 8/8] Typo fix COMPLAINT->COMPLIANT --- c/cert/test/rules/EXP40-C/test.c | 2 +- c/misra/test/rules/RULE-17-5/test.c | 16 ++++++++-------- c/misra/test/rules/RULE-17-7/test.c | 2 +- .../CStandardLibraryHeadersAreDeprecated.cpp | 2 +- .../deleteofpointertoincompleteclass/test.cpp | 4 ++-- .../rules/validcontainerelementaccess/test.cpp | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/c/cert/test/rules/EXP40-C/test.c b/c/cert/test/rules/EXP40-C/test.c index f8c9b6d545..dca79d3d36 100644 --- a/c/cert/test/rules/EXP40-C/test.c +++ b/c/cert/test/rules/EXP40-C/test.c @@ -24,7 +24,7 @@ void f2() { } void f4a(int *a) { - *a = 100; // NON_COMPLAINT + *a = 100; // NON_COMPLIANT } void f4b(int *a) {} diff --git a/c/misra/test/rules/RULE-17-5/test.c b/c/misra/test/rules/RULE-17-5/test.c index bbac126630..8e76a55642 100644 --- a/c/misra/test/rules/RULE-17-5/test.c +++ b/c/misra/test/rules/RULE-17-5/test.c @@ -15,32 +15,32 @@ void t1() { int ar4[4] = {1, 2, 3}; int *ar4p = ar4; - f1(0); // NON_COMPLAINT - f1(ar); // NON_COMPLAINT + f1(0); // NON_COMPLIANT + f1(ar); // NON_COMPLIANT f1(ar2); // COMPLIANT f1(ar2p); // NON_COMPLIANT f1(ar3); // COMPLIANT f1(ar3p); // COMPLIANT f1(ar4); // COMPLIANT - f2(0, 0); // NON_COMPLAINT - f2(0, ar); // NON_COMPLAINT + f2(0, 0); // NON_COMPLIANT + f2(0, ar); // NON_COMPLIANT f2(0, ar2); // COMPLIANT f2(0, ar2p); // NON_COMPLIANT f2(0, ar3); // COMPLIANT f2(0, ar3p); // COMPLIANT f2(0, ar4); // COMPLIANT - f3(0); // COMPLAINT - f3(ar); // COMPLAINT + f3(0); // COMPLIANT + f3(ar); // COMPLIANT f3(ar2); // COMPLIANT f3(ar2p); // COMPLIANT f3(ar3); // COMPLIANT f3(ar3p); // COMPLIANT f3(ar4); // COMPLIANT - f4(0, 0); // COMPLAINT - f4(0, ar); // COMPLAINT + f4(0, 0); // COMPLIANT + f4(0, ar); // COMPLIANT f4(0, ar2); // COMPLIANT f4(0, ar2p); // COMPLIANT f4(0, ar3); // COMPLIANT diff --git a/c/misra/test/rules/RULE-17-7/test.c b/c/misra/test/rules/RULE-17-7/test.c index bd58fc774e..1d31639275 100644 --- a/c/misra/test/rules/RULE-17-7/test.c +++ b/c/misra/test/rules/RULE-17-7/test.c @@ -3,7 +3,7 @@ int f2() { return 0; } int t1() { f1(); - f2(); // NON_COMPLAINT + f2(); // NON_COMPLIANT (void)f2(); // COMPLIANT int a = f2(); // COMPLIANT a = f2(); // COMPLIANT diff --git a/cpp/autosar/test/rules/A1-1-1/CStandardLibraryHeadersAreDeprecated.cpp b/cpp/autosar/test/rules/A1-1-1/CStandardLibraryHeadersAreDeprecated.cpp index b984336e54..a5149ac02a 100644 --- a/cpp/autosar/test/rules/A1-1-1/CStandardLibraryHeadersAreDeprecated.cpp +++ b/cpp/autosar/test/rules/A1-1-1/CStandardLibraryHeadersAreDeprecated.cpp @@ -1,5 +1,5 @@ #include // NON_COMPLIANT -#include // NON_COMPLAINT +#include // NON_COMPLIANT #include // NON_COMPLIANT #include // NON_COMPLIANT #include // NON_COMPLIANT diff --git a/cpp/common/test/rules/deleteofpointertoincompleteclass/test.cpp b/cpp/common/test/rules/deleteofpointertoincompleteclass/test.cpp index 2a5f002c67..c659a87740 100644 --- a/cpp/common/test/rules/deleteofpointertoincompleteclass/test.cpp +++ b/cpp/common/test/rules/deleteofpointertoincompleteclass/test.cpp @@ -1,7 +1,7 @@ class A { class B *impl; - void test() { delete impl; } // NON_COMPLAINT + void test() { delete impl; } // NON_COMPLIANT }; class D {}; @@ -9,5 +9,5 @@ class D {}; class C { class D *impl1; - void test() { delete impl1; } // COMPLAINT + void test() { delete impl1; } // COMPLIANT }; \ No newline at end of file diff --git a/cpp/common/test/rules/validcontainerelementaccess/test.cpp b/cpp/common/test/rules/validcontainerelementaccess/test.cpp index 45957ec141..55c94cf8f1 100644 --- a/cpp/common/test/rules/validcontainerelementaccess/test.cpp +++ b/cpp/common/test/rules/validcontainerelementaccess/test.cpp @@ -111,7 +111,7 @@ void f11(std::string cs) { const char *cp = cs.c_str(); const char *cpe = cp + 2; - while (cp < cpe) { // COMPLAINT + while (cp < cpe) { // COMPLIANT std::string arg(cp); // COMPLIANT cp += arg.size() + 1; }