From 84f007e427f3112442deeb7772f7cdcf2d694ce6 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 09:23:41 +0000 Subject: [PATCH 01/49] Contracts: add metadata. --- .../cpp/exclusions/c/Contracts.qll | 61 +++++++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 + rule_packages/c/Contracts.json | 65 +++++++++++++++++++ rule_packages/cpp/Expressions.json | 1 + 4 files changed, 130 insertions(+) create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/Contracts.qll create mode 100644 rule_packages/c/Contracts.json diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts.qll new file mode 100644 index 0000000000..32a44a4355 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Contracts.qll @@ -0,0 +1,61 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype ContractsQuery = + TDoNotViolateInLineLinkageConstraintsQuery() or + TCheckMathLibraryFunctionParametersQuery() or + TFunctionErrorInformationUntestedQuery() + +predicate isContractsQueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `doNotViolateInLineLinkageConstraints` query + ContractsPackage::doNotViolateInLineLinkageConstraintsQuery() and + queryId = + // `@id` for the `doNotViolateInLineLinkageConstraints` query + "c/cert/do-not-violate-in-line-linkage-constraints" and + ruleId = "MSC40-C" and + category = "rule" + or + query = + // `Query` instance for the `checkMathLibraryFunctionParameters` query + ContractsPackage::checkMathLibraryFunctionParametersQuery() and + queryId = + // `@id` for the `checkMathLibraryFunctionParameters` query + "c/misra/check-math-library-function-parameters" and + ruleId = "DIR-4-11" and + category = "required" + or + query = + // `Query` instance for the `functionErrorInformationUntested` query + ContractsPackage::functionErrorInformationUntestedQuery() and + queryId = + // `@id` for the `functionErrorInformationUntested` query + "c/misra/function-error-information-untested" and + ruleId = "DIR-4-7" and + category = "required" +} + +module ContractsPackage { + Query doNotViolateInLineLinkageConstraintsQuery() { + //autogenerate `Query` type + result = + // `Query` type for `doNotViolateInLineLinkageConstraints` query + TQueryC(TContractsPackageQuery(TDoNotViolateInLineLinkageConstraintsQuery())) + } + + Query checkMathLibraryFunctionParametersQuery() { + //autogenerate `Query` type + result = + // `Query` type for `checkMathLibraryFunctionParameters` query + TQueryC(TContractsPackageQuery(TCheckMathLibraryFunctionParametersQuery())) + } + + Query functionErrorInformationUntestedQuery() { + //autogenerate `Query` type + result = + // `Query` type for `functionErrorInformationUntested` query + TQueryC(TContractsPackageQuery(TFunctionErrorInformationUntestedQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index c2771f4171..6425f27e28 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -9,6 +9,7 @@ import Concurrency2 import Concurrency3 import Concurrency4 import Concurrency5 +import Contracts import Contracts1 import Contracts2 import Contracts3 @@ -80,6 +81,7 @@ newtype TCQuery = TConcurrency3PackageQuery(Concurrency3Query q) or TConcurrency4PackageQuery(Concurrency4Query q) or TConcurrency5PackageQuery(Concurrency5Query q) or + TContractsPackageQuery(ContractsQuery q) or TContracts1PackageQuery(Contracts1Query q) or TContracts2PackageQuery(Contracts2Query q) or TContracts3PackageQuery(Contracts3Query q) or @@ -151,6 +153,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isConcurrency3QueryMetadata(query, queryId, ruleId, category) or isConcurrency4QueryMetadata(query, queryId, ruleId, category) or isConcurrency5QueryMetadata(query, queryId, ruleId, category) or + isContractsQueryMetadata(query, queryId, ruleId, category) or isContracts1QueryMetadata(query, queryId, ruleId, category) or isContracts2QueryMetadata(query, queryId, ruleId, category) or isContracts3QueryMetadata(query, queryId, ruleId, category) or diff --git a/rule_packages/c/Contracts.json b/rule_packages/c/Contracts.json new file mode 100644 index 0000000000..e2239908f0 --- /dev/null +++ b/rule_packages/c/Contracts.json @@ -0,0 +1,65 @@ +{ + "CERT-C": { + "MSC40-C": { + "properties": { + "obligation": "rule" + }, + "queries": [ + { + "description": "Inlined external functions are prohibited by the language standard from defining modifiable static or thread storage objects, or referencing identifiers with internal linkage.", + "kind": "problem", + "name": "Do not violate inline linkage constraints", + "precision": "very-high", + "severity": "error", + "short_name": "DoNotViolateInLineLinkageConstraints", + "tags": [ + "correctness" + ] + } + ], + "title": "Do not violate constraints" + } + }, + "MISRA-C-2012": { + "DIR-4-11": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "Range, domain or pole errors in math functions may return unexpected values, trigger floating-point exceptions or set unexpected error modes.", + "kind": "problem", + "name": "The validity of values passed to `math.h` library functions shall be checked", + "precision": "high", + "severity": "error", + "short_name": "CheckMathLibraryFunctionParameters", + "shared_implementation_short_name": "UncheckedRangeDomainPoleErrors", + "tags": [ + "correctness" + ] + } + ], + "title": "The validity of values passed to library functions shall be checked" + }, + "DIR-4-7": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "A function (whether it is part of the standard library, a third party library or a user defined function) may provide some means of indicating the occurrence of an error. This may be via a global error flag, a parametric error flag, a special return value or some other means. Whenever such a mechanism is provided by a function the calling program shall check for the indication of an error as soon as the function returns.", + "kind": "problem", + "name": "If a function generates error information, then that error information shall be tested", + "precision": "very-high", + "severity": "recommendation", + "short_name": "FunctionErrorInformationUntested", + "shared_implementation_short_name": "FunctionErroneousReturnValueNotTested", + "tags": [ + "maintainability" + ] + } + ], + "title": "If a function returns error information, then that error information shall be tested" + } + } +} \ No newline at end of file diff --git a/rule_packages/cpp/Expressions.json b/rule_packages/cpp/Expressions.json index c0a7b6bb0b..5668c78a0a 100644 --- a/rule_packages/cpp/Expressions.json +++ b/rule_packages/cpp/Expressions.json @@ -86,6 +86,7 @@ "precision": "very-high", "severity": "recommendation", "short_name": "FunctionErroneousReturnValueNotTested", + "shared_implementation_short_name": "FunctionErroneousReturnValueNotTested", "tags": [ "maintainability" ] From 52bdbd7f536c723267489f8822d8c81a99db96e2 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 09:33:15 +0000 Subject: [PATCH 02/49] MSC40-C: Add query for finding inline linkage constraints. Adds a query that finds cases where extern inlined functions reference internal linkage objects, or declare objects which are static or thread local. --- .../DoNotViolateInLineLinkageConstraints.md | 210 ++++++++++++++++++ .../DoNotViolateInLineLinkageConstraints.ql | 59 +++++ ...otViolateInLineLinkageConstraints.expected | 6 + ...DoNotViolateInLineLinkageConstraints.qlref | 1 + c/cert/test/rules/MSC40-C/test.c | 31 +++ 5 files changed, 307 insertions(+) create mode 100644 c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md create mode 100644 c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.ql create mode 100644 c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.expected create mode 100644 c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.qlref create mode 100644 c/cert/test/rules/MSC40-C/test.c diff --git a/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md b/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md new file mode 100644 index 0000000000..26545fb812 --- /dev/null +++ b/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md @@ -0,0 +1,210 @@ +# MSC40-C: Do not violate inline linkage constraints + +This query implements the CERT-C rule MSC40-C: + +> Do not violate constraints + + +## Description + +According to the C Standard, 3.8 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO%2FIEC9899-2011)\], a constraint is a "restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted." Despite the similarity of the terms, a runtime constraint is not a kind of constraint. + +Violating any *shall* statement within a constraint clause in the C Standard requires an [implementation](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) to issue a diagnostic message, the C Standard, 5.1.1.3 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO%2FIEC9899-2011)\] states + +> A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances. + + +The C Standard further explains in a footnote + +> The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program. + + +Any constraint violation is a violation of this rule because it can result in an invalid program. + +## Noncompliant Code Example (Inline, Internal Linkage) + +The C Standard, 6.7.4, paragraph 3 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO%2FIEC9899-2011)\], states + +> An inline definition of a function with external linkage shall not contain a definition of a modifiable object with static or thread storage duration, and shall not contain a reference to an identifier with internal linkage. + + +The motivation behind this constraint lies in the semantics of inline definitions. Paragraph 7 of subclause 6.7.4 reads, in part: + +> An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition. + + +That is, if a function has an external and inline definition, implementations are free to choose which definition to invoke (two distinct invocations of the function may call different definitions, one the external definition, the other the inline definition). Therefore, issues can arise when these definitions reference internally linked objects or mutable objects with static or thread storage duration. + +This noncompliant code example refers to a static variable with file scope and internal linkage from within an external inline function: + +```cpp +static int I = 12; +extern inline void func(int a) { + int b = a * I; + /* ... */ +} + +``` + +## Compliant Solution (Inline, Internal Linkage) + +This compliant solution omits the `static` qualifier; consequently, the variable `I` has external linkage by default: + +```cpp +int I = 12; +extern inline void func(int a) { + int b = a * I; + /* ... */ +} + +``` + +## Noncompliant Code Example (inline, Modifiable Static) + +This noncompliant code example defines a modifiable `static` variable within an `extern inline` function. + +```cpp +extern inline void func(void) { + static int I = 12; + /* Perform calculations which may modify I */ +} + +``` + +## Compliant Solution (Inline, Modifiable Static) + +This compliant solution removes the `static` keyword from the local variable definition. If the modifications to `I` must be retained between invocations of `func()`, it must be declared at file scope so that it will be defined with external linkage. + +```cpp +extern inline void func(void) { + int I = 12; + /* Perform calculations which may modify I */ +} +``` + +## Noncompliant Code Example (Inline, Modifiable static) + +This noncompliant code example includes two translation units: `file1.c` and `file2.c`. The first file, `file1.c`, defines a pseudorandom number generation function: + +```cpp +/* file1.c */ + +/* Externally linked definition of the function get_random() */ +extern unsigned int get_random(void) { + /* Initialize the seeds */ + static unsigned int m_z = 0xdeadbeef; + static unsigned int m_w = 0xbaddecaf; + + /* Compute the next pseudorandom value and update the seeds */ + m_z = 36969 * (m_z & 65535) + (m_z >> 16); + m_w = 18000 * (m_w & 65535) + (m_w >> 16); + return (m_z << 16) + m_w; +} + +``` +The left-shift operation in the last line may wrap, but this is permitted by exception INT30-C-EX3 to rule [INT30-C. Ensure that unsigned integer operations do not wrap](https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap). + +The second file, `file2.c`, defines an `inline` version of this function that references mutable `static` objects—namely, objects that maintain the state of the pseudorandom number generator. Separate invocations of the `get_random()` function can call different definitions, each operating on separate static objects, resulting in a faulty pseudorandom number generator. + +```cpp +/* file2.c */ + +/* Inline definition of get_random function */ +inline unsigned int get_random(void) { + /* + * Initialize the seeds + * Constraint violation: static duration storage referenced + * in non-static inline definition + */ + static unsigned int m_z = 0xdeadbeef; + static unsigned int m_w = 0xbaddecaf; + + /* Compute the next pseudorandom value and update the seeds */ + m_z = 36969 * (m_z & 65535) + (m_z >> 16); + m_w = 18000 * (m_w & 65535) + (m_w >> 16); + return (m_z << 16) + m_w; +} + +int main(void) { + unsigned int rand_no; + for (int ii = 0; ii < 100; ii++) { + /* + * Get a pseudorandom number. Implementation defined whether the + * inline definition in this file or the external definition + * in file2.c is called. + */ + rand_no = get_random(); + /* Use rand_no... */ + } + + /* ... */ + + /* + * Get another pseudorandom number. Behavior is + * implementation defined. + */ + rand_no = get_random(); + /* Use rand_no... */ + return 0; +} + +``` + +## Compliant Solution (Inline, Modifiable static) + +This compliant solution adds the `static` modifier to the `inline` function definition in `file2.c`, giving it internal linkage. All references to `get_random()` in `file.2.c` will now reference the internally linked definition. The first file, which was not changed, is not shown here. + +```cpp +/* file2.c */ + +/* Static inline definition of get_random function */ +static inline unsigned int get_random(void) { + /* + * Initialize the seeds. + * No more constraint violation; the inline function is now + * internally linked. + */ + static unsigned int m_z = 0xdeadbeef; + static unsigned int m_w = 0xbaddecaf; + + /* Compute the next pseudorandom value and update the seeds */ + m_z = 36969 * (m_z & 65535) + (m_z >> 16); + m_w = 18000 * (m_w & 65535) + (m_w >> 16); + return (m_z << 16) + m_w; +} + +int main(void) { + /* Generate pseudorandom numbers using get_random()... */ + return 0; +} + +``` + +## Risk Assessment + +Constraint violations are a broad category of error that can result in unexpected control flow and corrupted data. + +
Rule Severity Likelihood Remediation Cost Priority Level
MSC40-C Low Unlikely Medium P2 L3
+ + +## Automated Detection + +
Tool Version Checker Description
Astrée 23.04 alignas-extended assignment-to-non-modifiable-lvalue cast-pointer-void-arithmetic-implicit element-type-incomplete function-pointer-integer-cast-implicit function-return-type inappropriate-pointer-cast-implicit incompatible-function-pointer-conversion incompatible-object-pointer-conversion initializer-excess invalid-array-size non-constant-static-assert parameter-match-type pointer-integral-cast-implicit pointer-qualifier-cast-const-implicit pointer-qualifier-cast-volatile-implicit redeclaration return-empty return-non-empty static-assert type-compatibility type-compatibility-link type-specifier undeclared-parameter unnamed-parameter Partially checked
Helix QAC 2023.4 C0232, C0233, C0244, C0268, C0321, C0322, C0338, C0422, C0423, C0426, C0427, C0429, C0430, C0431, C0432, C0435, C0436, C0437, C0446, C0447, C0448, C0449, C0451, C0452, C0453, C0454, C0456, C0457, C0458, C0460, C0461, C0462, C0463, C0466, C0467, C0468, C0469, C0476, C0477, C0478, C0481, C0482, C0483, C0484, C0485, C0486, C0487, C0493, C0494, C0495, C0496, C0497, C0513, C0514, C0515, C0536, C0537, C0540, C0541, C0542, C0546, C0547, C0550, C0554, C0555, C0556, C0557, C0558, C0559, C0560, C0561, C0562, C0563, C0564, C0565, C0580, C0588, C0589, C0590, C0591, C0605, C0616, C0619, C0620, C0621, C0622, C0627, C0628, C0629, C0631, C0638, C0640, C0641, C0642, C0643, C0644, C0645, C0646, C0649, C0650, C0651, C0653, C0655, C0656, C0657, C0659, C0664, C0665, C0669, C0671, C0673, C0674, C0675, C0677, C0682, C0683, C0684, C0685, C0690, C0698, C0699, C0708, C0709, C0736, C0737, C0738, C0746, C0747, C0755, C0756, C0757, C0758, C0766, C0767, C0768, C0774, C0775, C0801, C0802, C0803, C0804, C0811, C0821, C0834, C0835, C0844, C0845, C0851, C0852, C0866, C0873, C0877, C0940, C0941, C0943, C0944, C1023, C1024, C1025, C1033, C1047, C1048, C1050, C1061, C1062, C3236, C3237, C3238, C3244 C++4122
Klocwork 2023.4 MISRA.FUNC.STATIC.REDECL
LDRA tool suite 9.7.1 21 S, 145 S, 323 S, 345 S, 387 S, 404 S, 481 S, 580 S, 612 S, 615 S, 646 S
Parasoft C/C++test 2023.1 CERT_C-MSC40-a An inline definition of a function with external linkage shall not contain definitions and uses of static objects
Polyspace Bug Finder CERT C: Rule MSC40-C Checks for inline constraint not respected (rule partially covered)
RuleChecker 23.04 alignas-extended assignment-to-non-modifiable-lvalue cast-pointer-void-arithmetic-implicit element-type-incomplete function-pointer-integer-cast-implicit function-return-type inappropriate-pointer-cast-implicit incompatible-function-pointer-conversion incompatible-object-pointer-conversion initializer-excess invalid-array-size non-constant-static-assert parameter-match-type pointer-integral-cast-implicit pointer-qualifier-cast-const-implicit pointer-qualifier-cast-volatile-implicit redeclaration return-empty return-non-empty static-assert type-compatibility type-compatibility-link type-specifier undeclared-parameter unnamed-parameter Partially checked
+ + +## 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+MSC40-C). + +## Bibliography + +
\[ ISO/IEC 9899:2011 \] 4, "Conformance" 5.1.1.3, "Diagnostics" 6.7.4, "Function Specifiers"
+ + +## Implementation notes + +None + +## References + +* CERT-C: [MSC40-C: Do not violate constraints](https://wiki.sei.cmu.edu/confluence/display/c) diff --git a/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.ql b/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.ql new file mode 100644 index 0000000000..63dec179c6 --- /dev/null +++ b/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.ql @@ -0,0 +1,59 @@ +/** + * @id c/cert/do-not-violate-in-line-linkage-constraints + * @name MSC40-C: Do not violate inline linkage constraints + * @description Inlined external functions are prohibited by the language standard from defining + * modifiable static or thread storage objects, or referencing identifiers with + * internal linkage. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/cert/id/msc40-c + * correctness + * external/cert/obligation/rule + */ + +import cpp +import codingstandards.c.cert +import codingstandards.cpp.Linkage + +/* + * This is C specific, because in C++ all extern function definitions must be identical. + * Only in C is it permitted for an extern function to be defined in multiple translation + * units with different implementations, when using the inline keyword. + */ + +from Element accessOrDecl, Variable v, Function f, string message +where + not isExcluded(f, ContractsPackage::doNotViolateInLineLinkageConstraintsQuery()) and + f.isInline() and + hasExternalLinkage(f) and + // Pre-emptively exclude compiler generated functions + not f.isCompilerGenerated() and + // This rule does not apply to C++, but exclude C++ specific cases anyway + not f instanceof MemberFunction and + not f.isFromUninstantiatedTemplate(_) and + ( + // There exists a modifiable local variable which is static or thread local + exists(LocalVariable lsv, string storageModifier | + lsv.isStatic() and storageModifier = "Static" + or + lsv.isThreadLocal() and storageModifier = "Thread-local" + | + lsv.getFunction() = f and + not lsv.isConst() and + accessOrDecl = lsv and + message = storageModifier + " local variable $@ declared" and + v = lsv + ) + or + // References an identifier with internal linkage + exists(GlobalOrNamespaceVariable gv | + accessOrDecl = v.getAnAccess() and + accessOrDecl.(VariableAccess).getEnclosingFunction() = f and + hasInternalLinkage(v) and + message = "Identifier $@ with internal linkage referenced" and + v = gv + ) + ) +select accessOrDecl, message + " in the extern inlined function $@.", v, v.getName(), f, + f.getQualifiedName() diff --git a/c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.expected b/c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.expected new file mode 100644 index 0000000000..f258d4adef --- /dev/null +++ b/c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.expected @@ -0,0 +1,6 @@ +| test.c:6:14:6:14 | i | Static local variable $@ declared in the extern inlined function $@. | test.c:6:14:6:14 | i | i | test.c:5:20:5:24 | test1 | test1 | +| test.c:7:3:7:4 | g1 | Identifier $@ with internal linkage referenced in the extern inlined function $@. | test.c:1:12:1:13 | g1 | g1 | test.c:5:20:5:24 | test1 | test1 | +| test.c:9:3:9:4 | g3 | Identifier $@ with internal linkage referenced in the extern inlined function $@. | test.c:3:11:3:12 | g3 | g3 | test.c:5:20:5:24 | test1 | test1 | +| test.c:27:14:27:14 | i | Static local variable $@ declared in the extern inlined function $@. | test.c:27:14:27:14 | i | i | test.c:26:13:26:17 | test4 | test4 | +| test.c:28:3:28:4 | g1 | Identifier $@ with internal linkage referenced in the extern inlined function $@. | test.c:1:12:1:13 | g1 | g1 | test.c:26:13:26:17 | test4 | test4 | +| test.c:30:3:30:4 | g3 | Identifier $@ with internal linkage referenced in the extern inlined function $@. | test.c:3:11:3:12 | g3 | g3 | test.c:26:13:26:17 | test4 | test4 | diff --git a/c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.qlref b/c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.qlref new file mode 100644 index 0000000000..f14d4270cc --- /dev/null +++ b/c/cert/test/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.qlref @@ -0,0 +1 @@ +rules/MSC40-C/DoNotViolateInLineLinkageConstraints.ql \ No newline at end of file diff --git a/c/cert/test/rules/MSC40-C/test.c b/c/cert/test/rules/MSC40-C/test.c new file mode 100644 index 0000000000..3ca4afff4a --- /dev/null +++ b/c/cert/test/rules/MSC40-C/test.c @@ -0,0 +1,31 @@ +static int g1 = 0; +extern int g2 = 1; +const int g3 = 1; // defaults to internal linkage + +extern inline void test1() { + static int i = 0; // NON_COMPLIANT + g1++; // NON_COMPLIANT + g2++; // COMPLIANT + g3; // NON_COMPLIANT +} + +extern void test2() { + static int i = 0; // COMPLIANT + g1++; // COMPLIANT + g2++; // COMPLIANT + g3; // COMPLIANT +} + +void test3() { + static int i = 0; // COMPLIANT + g1++; // COMPLIANT + g2++; // COMPLIANT + g3; // COMPLIANT +} + +inline void test4() { + static int i = 0; // NON_COMPLIANT + g1++; // NON_COMPLIANT + g2++; // COMPLIANT + g3; // NON_COMPLIANT +} \ No newline at end of file From dcb32c1a017b50a1602a8d3e2e8afbf35ef0e534 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 09:44:43 +0000 Subject: [PATCH 03/49] DIR-4-11: Add query for checking math.h functions Add query which detects domain and pole errors for math.h functions. --- .../CheckMathLibraryFunctionParameters.ql | 22 +++++++++++++++++++ ...CheckMathLibraryFunctionParameters.testref | 1 + 2 files changed, 23 insertions(+) create mode 100644 c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql create mode 100644 c/misra/test/rules/DIR-4-11/CheckMathLibraryFunctionParameters.testref diff --git a/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql b/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql new file mode 100644 index 0000000000..6810784a0e --- /dev/null +++ b/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql @@ -0,0 +1,22 @@ +/** + * @id c/misra/check-math-library-function-parameters + * @name DIR-4-11: The validity of values passed to `math.h` library functions shall be checked + * @description Range, domain or pole errors in math functions may return unexpected values, trigger + * floating-point exceptions or set unexpected error modes. + * @kind problem + * @precision high + * @problem.severity error + * @tags external/misra/id/dir-4-11 + * correctness + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.uncheckedrangedomainpoleerrors.UncheckedRangeDomainPoleErrors + +class CheckMathLibraryFunctionParametersQuery extends UncheckedRangeDomainPoleErrorsSharedQuery { + CheckMathLibraryFunctionParametersQuery() { + this = ContractsPackage::checkMathLibraryFunctionParametersQuery() + } +} diff --git a/c/misra/test/rules/DIR-4-11/CheckMathLibraryFunctionParameters.testref b/c/misra/test/rules/DIR-4-11/CheckMathLibraryFunctionParameters.testref new file mode 100644 index 0000000000..50cf3fcb51 --- /dev/null +++ b/c/misra/test/rules/DIR-4-11/CheckMathLibraryFunctionParameters.testref @@ -0,0 +1 @@ +c/common/test/rules/uncheckedrangedomainpoleerrors/UncheckedRangeDomainPoleErrors.ql \ No newline at end of file From 377124004116573572197eabd39ceb905e8b5e30 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 09:47:55 +0000 Subject: [PATCH 04/49] DIR-4-7: Create shared query for unchecked return values Create a new shared query from the implementation of M0-3-2, which detects cases where error checking has not occurred after a call to a standard C library function. --- ...tionErroneousReturnValueNotTested.expected | 1 + .../FunctionErroneousReturnValueNotTested.ql | 4 ++ .../test.c | 0 .../FunctionErrorInformationUntested.ql | 26 ++++++++ .../FunctionErrorInformationUntested.testref | 1 + .../FunctionErroneousReturnValueNotTested.ql | 57 +++-------------- ...unctionErroneousReturnValueNotTested.qlref | 1 - .../FunctionErroneousReturnValueNotTested.qll | 62 +++++++++++++++++++ ...tionErroneousReturnValueNotTested.expected | 0 .../FunctionErroneousReturnValueNotTested.ql | 4 ++ .../test.cpp | 17 +++++ 11 files changed, 122 insertions(+), 51 deletions(-) create mode 100644 c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected create mode 100644 c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql rename cpp/autosar/test/rules/M0-3-2/test.cpp => c/common/test/rules/functionerroneousreturnvaluenottested/test.c (100%) create mode 100644 c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql create mode 100644 c/misra/test/rules/DIR-4-7/FunctionErrorInformationUntested.testref delete mode 100644 cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.qlref create mode 100644 cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll rename cpp/{autosar/test/rules/M0-3-2 => common/test/rules/functionerroneousreturnvaluenottested}/FunctionErroneousReturnValueNotTested.expected (100%) create mode 100644 cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql create mode 100644 cpp/common/test/rules/functionerroneousreturnvaluenottested/test.cpp diff --git a/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected b/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected new file mode 100644 index 0000000000..015f52348c --- /dev/null +++ b/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected @@ -0,0 +1 @@ +| test.c:16:3:16:8 | call to remove | Return value is not tested for errors. | diff --git a/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql b/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql new file mode 100644 index 0000000000..12c2196efd --- /dev/null +++ b/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql @@ -0,0 +1,4 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.functionerroneousreturnvaluenottested.FunctionErroneousReturnValueNotTested + +class TestFileQuery extends FunctionErroneousReturnValueNotTestedSharedQuery, TestQuery { } diff --git a/cpp/autosar/test/rules/M0-3-2/test.cpp b/c/common/test/rules/functionerroneousreturnvaluenottested/test.c similarity index 100% rename from cpp/autosar/test/rules/M0-3-2/test.cpp rename to c/common/test/rules/functionerroneousreturnvaluenottested/test.c diff --git a/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql b/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql new file mode 100644 index 0000000000..b827e101e3 --- /dev/null +++ b/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql @@ -0,0 +1,26 @@ +/** + * @id c/misra/function-error-information-untested + * @name DIR-4-7: If a function generates error information, then that error information shall be tested + * @description A function (whether it is part of the standard library, a third party library or a + * user defined function) may provide some means of indicating the occurrence of an + * error. This may be via a global error flag, a parametric error flag, a special + * return value or some other means. Whenever such a mechanism is provided by a + * function the calling program shall check for the indication of an error as soon as + * the function returns. + * @kind problem + * @precision very-high + * @problem.severity recommendation + * @tags external/misra/id/dir-4-7 + * maintainability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.functionerroneousreturnvaluenottested.FunctionErroneousReturnValueNotTested + +class FunctionErrorInformationUntestedQuery extends FunctionErroneousReturnValueNotTestedSharedQuery { + FunctionErrorInformationUntestedQuery() { + this = ContractsPackage::functionErrorInformationUntestedQuery() + } +} diff --git a/c/misra/test/rules/DIR-4-7/FunctionErrorInformationUntested.testref b/c/misra/test/rules/DIR-4-7/FunctionErrorInformationUntested.testref new file mode 100644 index 0000000000..51bd5fbefb --- /dev/null +++ b/c/misra/test/rules/DIR-4-7/FunctionErrorInformationUntested.testref @@ -0,0 +1 @@ +c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql \ No newline at end of file diff --git a/cpp/autosar/src/rules/M0-3-2/FunctionErroneousReturnValueNotTested.ql b/cpp/autosar/src/rules/M0-3-2/FunctionErroneousReturnValueNotTested.ql index aee4e40838..77e6278960 100644 --- a/cpp/autosar/src/rules/M0-3-2/FunctionErroneousReturnValueNotTested.ql +++ b/cpp/autosar/src/rules/M0-3-2/FunctionErroneousReturnValueNotTested.ql @@ -19,54 +19,11 @@ import cpp import codingstandards.cpp.autosar -import codingstandards.cpp.dataflow.DataFlow -import semmle.code.cpp.controlflow.Guards +import codingstandards.cpp.rules.functionerroneousreturnvaluenottested.FunctionErroneousReturnValueNotTested -from FunctionCall fc -where - not isExcluded(fc, ExpressionsPackage::functionErroneousReturnValueNotTestedQuery()) and - fc.getTarget() - .hasGlobalOrStdName([ - // fcntl.h - "open", "openat", "fcntl", "creat", - // locale.h - "setlocale", - // stdlib.h - "system", "getenv", "getenv_s", - // signal.h - "signal", "raise", - // setjmp.h - "setjmp", - // stdio.h - "fopen", "fopen_s", "freopen", "freopen_s", "fclose", "fcloseall", "fflush", "setvbuf", - "fgetc", "getc", "fgets", "fputc", "getchar", "gets", "gets_s", "putchar", "puts", - "ungetc", "scanf", "fscanf", "sscanf", "scanf_s", "fscanf_s", "sscanf_s", "vscanf", - "vfscanf", "vsscanf", "vscanf_s", "vfscanf_s", "vsscanf_s", "printf", "fprintf", - "sprintf", "snprintf", "printf_s", "fprintf_s", "sprintf_s", "snprintf_s", "vprintf", - "vfprintf", "vsprintf", "vsnprintf", "vprintf_s", "vfprintf_s", "vsprintf_s", - "vsnprintf_s", "ftell", "fgetpos", "fseek", "fsetpos", "remove", "rename", "tmpfile", - "tmpfile_s", "tmpnam", "tmpnam_s", - // string.h - "strcpy_s", "strncpy_s", "strcat_s", "strncat_s", "memset_s", "memcpy_s", "memmove_s", - "strerror_s", - // threads.h - "thrd_create", "thrd_sleep", "thrd_detach", "thrd_join", "mtx_init", "mtx_lock", - "mtx_timedlock", "mtx_trylock", "mtx_unlock", "cnd_init", "cnd_signal", "cnd_broadcast", - "cnd_wait", "cnd_timedwait", "tss_create", "tss_get", "tss_set", - // time.h - "time", "clock", "timespec_get", "asctime_s", "ctime_s", "gmtime", "gmtime_s", - "localtime", "localtime_s", - // unistd.h - "write", "read", "close", "unlink", - // wchar.h - "fgetwc", "getwc", "fgetws", "fputwc", "putwc", "fputws", "getwchar", "putwchar", - "ungetwc", "wscanf", "fwscanf", "swscanf", "wscanf_s", "fwscanf_s", "swscanf_s", - "vwscanf", "vfwscanf", "vswscanf", "vwscanf_s", "vfwscanf_s", "vswscanf_s", "wprintf", - "fwprintf", "swprintf", "wprintf_s", "fwprintf_s", "swprintf_s", "snwprintf_s", - "vwprintf", "vfwprintf", "vswprintf", "vwprintf_s", "vfwprintf_s", "vswprintf_s", - "vsnwprintf_s" - ]) and - forall(GuardCondition gc | - not DataFlow::localFlow(DataFlow::exprNode(fc), DataFlow::exprNode(gc.getAChild*())) - ) -select fc, "Return value is not tested for errors." +class FunctionErrorInformationUntestedQuery extends FunctionErroneousReturnValueNotTestedSharedQuery +{ + FunctionErrorInformationUntestedQuery() { + this = ExpressionsPackage::functionErroneousReturnValueNotTestedQuery() + } +} diff --git a/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.qlref b/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.qlref deleted file mode 100644 index 3cfea1dc31..0000000000 --- a/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/M0-3-2/FunctionErroneousReturnValueNotTested.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll b/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll new file mode 100644 index 0000000000..fe4f788847 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll @@ -0,0 +1,62 @@ +/** + * Provides a library which includes a `problems` predicate for reporting unchecked error values. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.dataflow.DataFlow +import semmle.code.cpp.controlflow.Guards +import codingstandards.cpp.Exclusions + +abstract class FunctionErroneousReturnValueNotTestedSharedQuery extends Query { } + +Query getQuery() { result instanceof FunctionErroneousReturnValueNotTestedSharedQuery } + +query predicate problems(FunctionCall fc, string message) { + not isExcluded(fc, getQuery()) and + fc.getTarget() + .hasGlobalOrStdName([ + // fcntl.h + "open", "openat", "fcntl", "creat", + // locale.h + "setlocale", + // stdlib.h + "system", "getenv", "getenv_s", + // signal.h + "signal", "raise", + // setjmp.h + "setjmp", + // stdio.h + "fopen", "fopen_s", "freopen", "freopen_s", "fclose", "fcloseall", "fflush", "setvbuf", + "fgetc", "getc", "fgets", "fputc", "getchar", "gets", "gets_s", "putchar", "puts", + "ungetc", "scanf", "fscanf", "sscanf", "scanf_s", "fscanf_s", "sscanf_s", "vscanf", + "vfscanf", "vsscanf", "vscanf_s", "vfscanf_s", "vsscanf_s", "printf", "fprintf", + "sprintf", "snprintf", "printf_s", "fprintf_s", "sprintf_s", "snprintf_s", "vprintf", + "vfprintf", "vsprintf", "vsnprintf", "vprintf_s", "vfprintf_s", "vsprintf_s", + "vsnprintf_s", "ftell", "fgetpos", "fseek", "fsetpos", "remove", "rename", "tmpfile", + "tmpfile_s", "tmpnam", "tmpnam_s", + // string.h + "strcpy_s", "strncpy_s", "strcat_s", "strncat_s", "memset_s", "memcpy_s", "memmove_s", + "strerror_s", + // threads.h + "thrd_create", "thrd_sleep", "thrd_detach", "thrd_join", "mtx_init", "mtx_lock", + "mtx_timedlock", "mtx_trylock", "mtx_unlock", "cnd_init", "cnd_signal", "cnd_broadcast", + "cnd_wait", "cnd_timedwait", "tss_create", "tss_get", "tss_set", + // time.h + "time", "clock", "timespec_get", "asctime_s", "ctime_s", "gmtime", "gmtime_s", + "localtime", "localtime_s", + // unistd.h + "write", "read", "close", "unlink", + // wchar.h + "fgetwc", "getwc", "fgetws", "fputwc", "putwc", "fputws", "getwchar", "putwchar", + "ungetwc", "wscanf", "fwscanf", "swscanf", "wscanf_s", "fwscanf_s", "swscanf_s", + "vwscanf", "vfwscanf", "vswscanf", "vwscanf_s", "vfwscanf_s", "vswscanf_s", "wprintf", + "fwprintf", "swprintf", "wprintf_s", "fwprintf_s", "swprintf_s", "snwprintf_s", + "vwprintf", "vfwprintf", "vswprintf", "vwprintf_s", "vfwprintf_s", "vswprintf_s", + "vsnwprintf_s" + ]) and + forall(GuardCondition gc | + not DataFlow::localFlow(DataFlow::exprNode(fc), DataFlow::exprNode(gc.getAChild*())) + ) and + message = "Return value is not tested for errors." +} diff --git a/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.expected b/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected similarity index 100% rename from cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.expected rename to cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected diff --git a/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql b/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql new file mode 100644 index 0000000000..12c2196efd --- /dev/null +++ b/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql @@ -0,0 +1,4 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.functionerroneousreturnvaluenottested.FunctionErroneousReturnValueNotTested + +class TestFileQuery extends FunctionErroneousReturnValueNotTestedSharedQuery, TestQuery { } diff --git a/cpp/common/test/rules/functionerroneousreturnvaluenottested/test.cpp b/cpp/common/test/rules/functionerroneousreturnvaluenottested/test.cpp new file mode 100644 index 0000000000..08e2f23dec --- /dev/null +++ b/cpp/common/test/rules/functionerroneousreturnvaluenottested/test.cpp @@ -0,0 +1,17 @@ +#include + +void test_compliant() { + // Return value is passed to an lvalue and then tested. + FILE *fh = fopen("/etc/foo", "r"); + if (!fh) { // COMPLIANT + return; + } + + // Return value is tested immediately as an rvalue. + if (fclose(fh)) // COMPLIANT + return; +} + +void test_noncompliant() { + remove("/bin/bash"); // NON_COMPLIANT +} \ No newline at end of file From 81200896b07034ad5120918e91df6295f2d9feb0 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 09:53:23 +0000 Subject: [PATCH 05/49] FunctionErroneousReturnValueNotTested rewritten for clarity --- .../FunctionErroneousReturnValueNotTested.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll b/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll index fe4f788847..5cd98c05d6 100644 --- a/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll +++ b/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll @@ -55,8 +55,8 @@ query predicate problems(FunctionCall fc, string message) { "vwprintf", "vfwprintf", "vswprintf", "vwprintf_s", "vfwprintf_s", "vswprintf_s", "vsnwprintf_s" ]) and - forall(GuardCondition gc | - not DataFlow::localFlow(DataFlow::exprNode(fc), DataFlow::exprNode(gc.getAChild*())) + not exists(GuardCondition gc | + DataFlow::localFlow(DataFlow::exprNode(fc), DataFlow::exprNode(gc.getAChild*())) ) and message = "Return value is not tested for errors." } From 7e5ef5f8306fee09522415cfda8cf708d8a32ea0 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 09:55:42 +0000 Subject: [PATCH 06/49] Add name of function to message. --- .../FunctionErroneousReturnValueNotTested.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll b/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll index 5cd98c05d6..dd2f7d75e0 100644 --- a/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll +++ b/cpp/common/src/codingstandards/cpp/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.qll @@ -58,5 +58,5 @@ query predicate problems(FunctionCall fc, string message) { not exists(GuardCondition gc | DataFlow::localFlow(DataFlow::exprNode(fc), DataFlow::exprNode(gc.getAChild*())) ) and - message = "Return value is not tested for errors." + message = "Return value from " + fc.getTarget().getName() + " is not tested for errors." } From a19855bd20ace838d2f7748f45de341e5e7b97ef Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 10:02:11 +0000 Subject: [PATCH 07/49] Add implementation scope properties Specify the scope of each of the newly supported rules. --- rule_packages/c/Contracts.json | 15 ++++++++++++--- rule_packages/c/FloatingTypes.json | 5 ++++- rule_packages/cpp/Expressions.json | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/rule_packages/c/Contracts.json b/rule_packages/c/Contracts.json index e2239908f0..735e84d9da 100644 --- a/rule_packages/c/Contracts.json +++ b/rule_packages/c/Contracts.json @@ -14,7 +14,10 @@ "short_name": "DoNotViolateInLineLinkageConstraints", "tags": [ "correctness" - ] + ], + "implementation_scope": { + "description": "This query only considers the constraints related to inline extern functions." + } } ], "title": "Do not violate constraints" @@ -36,7 +39,10 @@ "shared_implementation_short_name": "UncheckedRangeDomainPoleErrors", "tags": [ "correctness" - ] + ], + "implementation_scope": { + "description": "This query identifies possible domain, pole and range errors on a selection of C standard library fuctions from math.h." + } } ], "title": "The validity of values passed to library functions shall be checked" @@ -56,7 +62,10 @@ "shared_implementation_short_name": "FunctionErroneousReturnValueNotTested", "tags": [ "maintainability" - ] + ], + "implementation_scope": { + "description": "This query enforces checking on some C standard library functions that may return error codes." + } } ], "title": "If a function returns error information, then that error information shall be tested" diff --git a/rule_packages/c/FloatingTypes.json b/rule_packages/c/FloatingTypes.json index 1dfd663597..7df2298ad1 100644 --- a/rule_packages/c/FloatingTypes.json +++ b/rule_packages/c/FloatingTypes.json @@ -15,7 +15,10 @@ "shared_implementation_short_name": "UncheckedRangeDomainPoleErrors", "tags": [ "correctness" - ] + ], + "implementation_scope": { + "description": "This query identifies possible domain, pole and range errors on a selection of C standard library fuctions from math.h." + } } ], "title": "Prevent or detect domain and range errors in math functions" diff --git a/rule_packages/cpp/Expressions.json b/rule_packages/cpp/Expressions.json index 5668c78a0a..935c3fa6f1 100644 --- a/rule_packages/cpp/Expressions.json +++ b/rule_packages/cpp/Expressions.json @@ -89,7 +89,10 @@ "shared_implementation_short_name": "FunctionErroneousReturnValueNotTested", "tags": [ "maintainability" - ] + ], + "implementation_scope": { + "description": "The query enforces checking on some C standard library functions that may return error codes." + } } ], "title": "If a function generates error information, then that error information shall be tested." From 9b7102e149ad57a8b45f6b09b5df452d731f1f2c Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 10:03:21 +0000 Subject: [PATCH 08/49] Add change note. --- change_notes/2024-01-30-m0-3-2.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 change_notes/2024-01-30-m0-3-2.md diff --git a/change_notes/2024-01-30-m0-3-2.md b/change_notes/2024-01-30-m0-3-2.md new file mode 100644 index 0000000000..b074f6b2b1 --- /dev/null +++ b/change_notes/2024-01-30-m0-3-2.md @@ -0,0 +1 @@ + * `M0-3-2` - the alert messages now include the name of the called function. \ No newline at end of file From 78d5e793b66136c9ea7eec6c3da011d0af335011 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 11:33:02 +0000 Subject: [PATCH 09/49] Add missing file. --- .../rules/M0-3-2/FunctionErroneousReturnValueNotTested.testref | 1 + 1 file changed, 1 insertion(+) create mode 100644 cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.testref diff --git a/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.testref b/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.testref new file mode 100644 index 0000000000..50847523ce --- /dev/null +++ b/cpp/autosar/test/rules/M0-3-2/FunctionErroneousReturnValueNotTested.testref @@ -0,0 +1 @@ +cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.ql \ No newline at end of file From 9776de1211801f333c827630352daf9bef931455 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 12:58:50 +0000 Subject: [PATCH 10/49] Update expected result files. --- .../FunctionErroneousReturnValueNotTested.expected | 2 +- .../FunctionErroneousReturnValueNotTested.expected | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected b/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected index 015f52348c..dc72201a8a 100644 --- a/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected +++ b/c/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected @@ -1 +1 @@ -| test.c:16:3:16:8 | call to remove | Return value is not tested for errors. | +| test.c:16:3:16:8 | call to remove | Return value from remove is not tested for errors. | diff --git a/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected b/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected index 76cbcebed0..2f681c9210 100644 --- a/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected +++ b/cpp/common/test/rules/functionerroneousreturnvaluenottested/FunctionErroneousReturnValueNotTested.expected @@ -1 +1 @@ -| test.cpp:16:3:16:8 | call to remove | Return value is not tested for errors. | +| test.cpp:16:3:16:8 | call to remove | Return value from remove is not tested for errors. | From af9226208ee43cb49f0940a36972be3061ca7c01 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 13:00:51 +0000 Subject: [PATCH 11/49] Update rules.csv to exclude unimplemented contracts rules. --- rules.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules.csv b/rules.csv index 20af9fbc01..9f4afac4fa 100644 --- a/rules.csv +++ b/rules.csv @@ -614,8 +614,8 @@ c,MISRA-C-2012,DIR-4-9,Yes,Advisory,,,A function should be used in preference to c,MISRA-C-2012,DIR-4-10,Yes,Required,,,Precautions shall be taken in order to prevent the contents of a header file being included more than once,M16-2-3,Preprocessor2,Medium, c,MISRA-C-2012,DIR-4-11,Yes,Required,,,The validity of values passed to library functions shall be checked,,Contracts,Hard, c,MISRA-C-2012,DIR-4-12,Yes,Required,,,Dynamic memory allocation shall not be used,,Banned,Medium, -c,MISRA-C-2012,DIR-4-13,Yes,Advisory,,,Functions which are designed to provide operations on a resource should be called in an appropriate sequence,,Contracts,Hard, -c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts,Hard, +c,MISRA-C-2012,DIR-4-13,No,Advisory,,,Functions which are designed to provide operations on a resource should be called in an appropriate sequence,,,,Rule 22.1, 22.2 and 22.6 cover aspects of this rule. In other cases this is a design issue and needs to be checked manually. +c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts9,Hard,This is supported by CodeQLs default C security queries. c,MISRA-C-2012,RULE-1-1,No,Required,,,"The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits",,,Easy,"This should be checked via the compiler output, rather than CodeQL, which adds unnecessary steps." c,MISRA-C-2012,RULE-1-2,Yes,Advisory,,,Language extensions should not be used,,Language3,Hard, c,MISRA-C-2012,RULE-1-3,Yes,Required,,,There shall be no occurrence of undefined or critical unspecified behaviour,,Language3,Hard, From 3d2cd94fd92681127dbb38fa0833150a2536eb00 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 13:13:14 +0000 Subject: [PATCH 12/49] Update documentation. --- c/cert/src/rules/FLP32-C/UncheckedRangeDomainPoleErrors.md | 2 +- .../src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c/cert/src/rules/FLP32-C/UncheckedRangeDomainPoleErrors.md b/c/cert/src/rules/FLP32-C/UncheckedRangeDomainPoleErrors.md index d6427b9081..ca24a02498 100644 --- a/c/cert/src/rules/FLP32-C/UncheckedRangeDomainPoleErrors.md +++ b/c/cert/src/rules/FLP32-C/UncheckedRangeDomainPoleErrors.md @@ -345,7 +345,7 @@ Independent( INT34-C, FLP32-C, INT33-C) CWE-682 = Union( FLP32-C, list) where li ## Implementation notes -None +This query identifies possible domain, pole and range errors on a selection of C standard library fuctions from math.h. ## References diff --git a/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md b/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md index 26545fb812..f767c91baf 100644 --- a/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md +++ b/c/cert/src/rules/MSC40-C/DoNotViolateInLineLinkageConstraints.md @@ -203,7 +203,7 @@ Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+D ## Implementation notes -None +This query only considers the constraints related to inline extern functions. ## References From bccdb93c2b7b0e2dcbe82feb134c0c0423ae9d81 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 13:13:59 +0000 Subject: [PATCH 13/49] Fix formatting --- c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql b/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql index b827e101e3..63236d422d 100644 --- a/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql +++ b/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql @@ -19,7 +19,8 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.rules.functionerroneousreturnvaluenottested.FunctionErroneousReturnValueNotTested -class FunctionErrorInformationUntestedQuery extends FunctionErroneousReturnValueNotTestedSharedQuery { +class FunctionErrorInformationUntestedQuery extends FunctionErroneousReturnValueNotTestedSharedQuery +{ FunctionErrorInformationUntestedQuery() { this = ContractsPackage::functionErrorInformationUntestedQuery() } From 337604e56719a36e6098e8b8b41114168e3ab39a Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 30 Jan 2024 13:14:37 +0000 Subject: [PATCH 14/49] Fix test formatting --- c/cert/test/rules/MSC40-C/test.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/c/cert/test/rules/MSC40-C/test.c b/c/cert/test/rules/MSC40-C/test.c index 3ca4afff4a..d892935d41 100644 --- a/c/cert/test/rules/MSC40-C/test.c +++ b/c/cert/test/rules/MSC40-C/test.c @@ -4,28 +4,28 @@ const int g3 = 1; // defaults to internal linkage extern inline void test1() { static int i = 0; // NON_COMPLIANT - g1++; // NON_COMPLIANT - g2++; // COMPLIANT - g3; // NON_COMPLIANT + g1++; // NON_COMPLIANT + g2++; // COMPLIANT + g3; // NON_COMPLIANT } extern void test2() { static int i = 0; // COMPLIANT - g1++; // COMPLIANT - g2++; // COMPLIANT - g3; // COMPLIANT + g1++; // COMPLIANT + g2++; // COMPLIANT + g3; // COMPLIANT } void test3() { static int i = 0; // COMPLIANT - g1++; // COMPLIANT - g2++; // COMPLIANT - g3; // COMPLIANT + g1++; // COMPLIANT + g2++; // COMPLIANT + g3; // COMPLIANT } inline void test4() { static int i = 0; // NON_COMPLIANT - g1++; // NON_COMPLIANT - g2++; // COMPLIANT - g3; // NON_COMPLIANT + g1++; // NON_COMPLIANT + g2++; // COMPLIANT + g3; // NON_COMPLIANT } \ No newline at end of file From 9ca0d42a6e32a395dccff48fb1eb16476ccac1ce Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 3 Jun 2024 16:51:30 +0100 Subject: [PATCH 15/49] A3-1-5: Remove invalid interpretation of rule As per: https://forum.misra.org.uk/archive/index.php?thread-1588.html --- ...teFunctionDefinedOutsideClassDefinition.ql | 51 ------------------- ...tionDefinedOutsideClassDefinition.expected | 7 --- ...unctionDefinedOutsideClassDefinition.qlref | 1 - 3 files changed, 59 deletions(-) delete mode 100644 cpp/autosar/src/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.ql delete mode 100644 cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.expected delete mode 100644 cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.qlref diff --git a/cpp/autosar/src/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.ql b/cpp/autosar/src/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.ql deleted file mode 100644 index 920875ca3b..0000000000 --- a/cpp/autosar/src/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.ql +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @id cpp/autosar/trivial-or-template-function-defined-outside-class-definition - * @name A3-1-5: A function shall be defined with a class body if and only if it is intended to be inlined - * @description A function that is either trivial, a template function, or a member of a template - * class may not be defined outside of a class body. - * @kind problem - * @precision very-high - * @problem.severity recommendation - * @tags external/autosar/id/a3-1-5 - * external/autosar/allocated-target/design - * external/autosar/enforcement/partially-automated - * external/autosar/obligation/required - */ - -import cpp -import codingstandards.cpp.autosar -import codingstandards.cpp.Class - -/* - * Find instances of `MemberFunction` where the `MemberFunction` is trivial - * and it is not inlined within the class. - */ - -from MemberFunction mf, string kind -where - not isExcluded(mf, ClassesPackage::trivialOrTemplateFunctionDefinedOutsideClassDefinitionQuery()) and - // The member function `mf` is not defined in the class body. - exists(FunctionDeclarationEntry fde | - fde = mf.getClassBodyDeclarationEntry() and not fde.isDefinition() - ) and - //ignore destructors - not mf instanceof Destructor and - // Report functions that are NOT defined in the class body if they are either trivial or - // either a template member or part of a template class (i.e., they should - // be defined in the class body) - ( - if - mf instanceof TemplateOrTemplateClassMemberFunction and - mf instanceof TrivialMemberFunction - then kind = "template" - else - if mf instanceof TrivialMemberFunction - then kind = "trivial" - else - if mf instanceof TemplateOrTemplateClassMemberFunction - then kind = "template" - else none() - ) -select mf, - "The " + kind + " member function " + mf.getName() + " is not defined in the class body of $@.", - mf.getDeclaringType(), mf.getDeclaringType().getName() diff --git a/cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.expected b/cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.expected deleted file mode 100644 index af8a1d4588..0000000000 --- a/cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.expected +++ /dev/null @@ -1,7 +0,0 @@ -| test.cpp:58:5:58:11 | getB | The trivial member function getB is not defined in the class body of $@. | test.cpp:2:7:2:7 | A | A | -| test.cpp:60:25:60:28 | d | The template member function d is not defined in the class body of $@. | test.cpp:2:7:2:7 | A | A | -| test.cpp:62:5:62:8 | b | The trivial member function b is not defined in the class body of $@. | test.cpp:2:7:2:7 | A | A | -| test.cpp:81:34:81:57 | complexCalculation | The template member function complexCalculation is not defined in the class body of $@. | test.cpp:64:29:64:29 | B | B | -| test.cpp:97:47:97:53 | d | The template member function d is not defined in the class body of $@. | test.cpp:64:29:64:29 | B | B | -| test.cpp:101:27:101:33 | b | The template member function b is not defined in the class body of $@. | test.cpp:64:29:64:29 | B | B | -| test.cpp:106:27:106:36 | getB | The template member function getB is not defined in the class body of $@. | test.cpp:64:29:64:29 | B | B | diff --git a/cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.qlref b/cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.qlref deleted file mode 100644 index c644147bb4..0000000000 --- a/cpp/autosar/test/rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/A3-1-5/TrivialOrTemplateFunctionDefinedOutsideClassDefinition.ql \ No newline at end of file From f1024ae1ca5109f925e9ab7d78e0dd6b8e4c540a Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 3 Jun 2024 17:10:34 +0100 Subject: [PATCH 16/49] A3-1-5: Exclude member functions in template instantiations --- cpp/autosar/test/rules/A3-1-5/test.cpp | 59 +++++++++++++++++--- cpp/common/src/codingstandards/cpp/Class.qll | 5 +- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/cpp/autosar/test/rules/A3-1-5/test.cpp b/cpp/autosar/test/rules/A3-1-5/test.cpp index eb5bc9edb7..62edb8f582 100644 --- a/cpp/autosar/test/rules/A3-1-5/test.cpp +++ b/cpp/autosar/test/rules/A3-1-5/test.cpp @@ -23,7 +23,7 @@ class A { int complexCalculation(); - int gcd(int a, int b) { + int gcd(int a, int b) { // NON_COMPLIANT if (b == 0) return a; int result = gcd(b, (a % b)); @@ -55,11 +55,11 @@ inline int A::complexCalculation() { // COMPLIANT return 1; } -int A::getB() { return 1; } // NON_COMPLIANT +int A::getB() { return 1; } // COMPLIANT -template T A::d(T t) { return t; } // NON_COMPLIANT +template T A::d(T t) { return t; } // COMPLIANT -int A::b() { return 3; } // NON_COMPLIANT +int A::b() { return 3; } // COMPLIANT template class B { public: @@ -76,9 +76,30 @@ template class B { template T d(T t); int complexCalculation(); + + int complexCalculation2() { // COMPLIANT - template + ; + ; + ; + ; + ; + ; + ; + ; + ; + ; + ; + ; + return 1; + } }; -template inline int B::complexCalculation() { // NON_COMPLIANT +void test_B() { + B b; + b.complexCalculation2(); +} + +template inline int B::complexCalculation() { // COMPLIANT ; ; ; @@ -94,16 +115,16 @@ template inline int B::complexCalculation() { // NON_COMPLIANT return 1; } -template template T B::d(T t) { // NON_COMPLIANT +template template T B::d(T t) { // COMPLIANT return t; } -template int B::b() { // NON_COMPLIANT +template int B::b() { // COMPLIANT C c; return 3; } -template int B::getB() { return 3; } // NON_COMPLIANT +template int B::getB() { return 3; } // COMPLIANT template class Foo { public: @@ -121,8 +142,30 @@ class FooBar { public: ~FooBar(); int f1(int a, int b); + + template int complexCalculation() { // COMPLIANT - template + ; + ; + ; + ; + ; + ; + ; + ; + ; + ; + ; + ; + return 1; + } }; +void test_FooBar() { + FooBar foobar; + foobar.complexCalculation(); +} + + FooBar::~FooBar() {} // COMPLIANT want to ignore pImpl uses of destructors int FooBar::f1(int a, int b) { // COMPLIANT not a trivial function diff --git a/cpp/common/src/codingstandards/cpp/Class.qll b/cpp/common/src/codingstandards/cpp/Class.qll index 19bec9fa5f..09d39ce6f8 100644 --- a/cpp/common/src/codingstandards/cpp/Class.qll +++ b/cpp/common/src/codingstandards/cpp/Class.qll @@ -192,7 +192,10 @@ class TrivialMemberFunction extends IntrospectedMemberFunction { * class. */ class TemplateOrTemplateClassMemberFunction extends MemberFunction { - TemplateOrTemplateClassMemberFunction() { isFromUninstantiatedTemplate(_) } + TemplateOrTemplateClassMemberFunction() { + isFromUninstantiatedTemplate(_) or + isFromTemplateInstantiation(_) + } } /** From 87fa7c1c3d9bc079d46d045a182591c2347d7aaa Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 5 Jul 2024 19:49:48 +0200 Subject: [PATCH 17/49] STR34-C: Do not consider integer type aliases in templates --- .../CastCharBeforeConvertingToLargerSizes.ql | 21 +++++---------- ...CharBeforeConvertingToLargerSizes.expected | 21 --------------- ...astCharBeforeConvertingToLargerSizes.qlref | 1 - ...tCharBeforeConvertingToLargerSizes.testref | 1 + ...oreConvertingToLargerSizes_shared.expected | 21 +++++++++++++++ ...ertingToLargerSizes_shared.expected.clang} | 14 +++++----- ...nvertingToLargerSizes_shared.expected.gcc} | 12 ++++----- ...nvertingToLargerSizes_shared.expected.qcc} | 14 +++++----- ...harBeforeConvertingToLargerSizes_shared.ql | 4 +++ .../test.c | 2 ++ ...arBeforeConvertingToLargerSizes_shared.qll | 26 +++++++++++++++++++ ...oreConvertingToLargerSizes_shared.expected | 2 ++ ...harBeforeConvertingToLargerSizes_shared.ql | 4 +++ .../test.cpp | 17 ++++++++++++ rule_packages/c/Strings3.json | 1 + 15 files changed, 105 insertions(+), 56 deletions(-) delete mode 100644 c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected delete mode 100644 c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.qlref create mode 100644 c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref create mode 100644 c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected rename c/{cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.gcc => common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang} (75%) rename c/{cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.clang => common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc} (78%) rename c/{cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc => common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc} (75%) create mode 100644 c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql rename c/{cert/test/rules/STR34-C => common/test/rules/castcharbeforeconvertingtolargersizes_shared}/test.c (95%) create mode 100644 cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll create mode 100644 cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected create mode 100644 cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql create mode 100644 cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.cpp diff --git a/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql b/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql index b0d4088f9f..1f2af0b588 100644 --- a/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql +++ b/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql @@ -14,18 +14,11 @@ import cpp import codingstandards.c.cert -import semmle.code.cpp.commons.CommonType +import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes_shared.CastCharBeforeConvertingToLargerSizes_shared -from Cast c -where - not isExcluded(c, Strings3Package::castCharBeforeConvertingToLargerSizesQuery()) and - // find cases where there is a conversion happening wherein the - // base type is a char - c.getExpr().getType() instanceof CharType and - not c.getExpr().getType() instanceof UnsignedCharType and - // it's a bigger type - c.getType().getSize() > c.getExpr().getType().getSize() and - // and it's some kind of integer type - c.getType() instanceof IntegralType -select c.getExpr(), - "Expression not converted to `unsigned char` before converting to a larger integer type." +class CastCharBeforeConvertingToLargerSizesQuery extends CastCharBeforeConvertingToLargerSizes_sharedSharedQuery +{ + CastCharBeforeConvertingToLargerSizesQuery() { + this = Strings3Package::castCharBeforeConvertingToLargerSizesQuery() + } +} diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected deleted file mode 100644 index 1c6424dc0c..0000000000 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected +++ /dev/null @@ -1,21 +0,0 @@ -| test.c:7:7:7:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:28:11:28:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:29:3:29:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:29:11:29:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:31:11:31:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:32:11:32:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:33:3:33:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:33:11:33:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:34:3:34:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:34:11:34:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:35:3:35:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:35:11:35:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:36:3:36:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:36:11:36:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:37:11:37:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:38:11:38:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:39:3:39:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:39:11:39:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:40:12:40:13 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:42:11:42:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:43:11:43:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.qlref b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.qlref deleted file mode 100644 index 379d3b3f68..0000000000 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql \ No newline at end of file diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref new file mode 100644 index 0000000000..fefb98580c --- /dev/null +++ b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref @@ -0,0 +1 @@ +c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql \ No newline at end of file diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected new file mode 100644 index 0000000000..c318f791e9 --- /dev/null +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected @@ -0,0 +1,21 @@ +| test.c:9:7:9:14 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:30:11:30:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:31:3:31:13 | (unsigned int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:31:11:31:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:33:11:33:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:34:11:34:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:35:3:35:13 | (unsigned int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:35:11:35:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:36:3:36:13 | (unsigned int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:36:11:36:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:37:3:37:13 | (unsigned int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:37:11:37:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:38:3:38:13 | (unsigned int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:38:11:38:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:39:11:39:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:40:11:40:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:41:3:41:13 | (unsigned int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:41:11:41:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:42:12:42:13 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:44:11:44:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:45:11:45:12 | (int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.gcc b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang similarity index 75% rename from c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.gcc rename to c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang index 1cf143a196..0378c8a6b5 100644 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.gcc +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang @@ -1,8 +1,6 @@ -| test.c:7:7:7:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:28:3:28:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:29:3:29:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:9:7:9:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:30:3:30:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:31:3:31:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:32:3:32:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:33:3:33:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:34:3:34:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:35:3:35:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | @@ -10,6 +8,8 @@ | test.c:37:3:37:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:38:3:38:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:39:3:39:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:40:3:40:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:42:11:42:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:43:11:43:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:40:3:40:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:41:3:41:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:42:3:42:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:44:11:44:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:45:11:45:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.clang b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc similarity index 78% rename from c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.clang rename to c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc index 1cf143a196..f729c9e42d 100644 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.clang +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc @@ -1,8 +1,6 @@ -| test.c:7:7:7:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:28:3:28:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:29:3:29:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:9:7:9:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:30:3:30:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:31:3:31:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:32:3:32:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:33:3:33:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:34:3:34:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:35:3:35:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | @@ -10,6 +8,8 @@ | test.c:37:3:37:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:38:3:38:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:39:3:39:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:40:3:40:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:42:11:42:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:40:3:40:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:41:3:41:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:42:3:42:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:43:11:43:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:44:11:44:12 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc similarity index 75% rename from c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc rename to c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc index fec6522014..551423495c 100644 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.expected.qcc +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc @@ -1,8 +1,6 @@ -| test.c:7:7:7:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:28:3:28:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:29:3:29:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:9:7:9:14 | * ... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:30:3:30:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:31:3:31:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:32:3:32:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:33:3:33:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:34:3:34:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:35:3:35:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | @@ -10,6 +8,8 @@ | test.c:37:3:37:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:38:3:38:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | | test.c:39:3:39:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:40:3:40:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:42:3:42:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | -| test.c:43:3:43:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:40:3:40:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:41:3:41:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:42:3:42:14 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:44:3:44:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.c:45:3:45:13 | (...) | Expression not converted to `unsigned char` before converting to a larger integer type. | diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql new file mode 100644 index 0000000000..2aceff89c0 --- /dev/null +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql @@ -0,0 +1,4 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes_shared.CastCharBeforeConvertingToLargerSizes_shared + +class TestFileQuery extends CastCharBeforeConvertingToLargerSizes_sharedSharedQuery, TestQuery { } diff --git a/c/cert/test/rules/STR34-C/test.c b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.c similarity index 95% rename from c/cert/test/rules/STR34-C/test.c rename to c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.c index d4bd825c8e..8865e477fb 100644 --- a/c/cert/test/rules/STR34-C/test.c +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.c @@ -1,3 +1,5 @@ +// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND +// CHANGES SHOULD BE REFLECTED THERE AS WELL. #include #include diff --git a/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll new file mode 100644 index 0000000000..3ef9033910 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll @@ -0,0 +1,26 @@ +/** + * Provides a library which includes a `problems` predicate for reporting.... + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions + +abstract class CastCharBeforeConvertingToLargerSizes_sharedSharedQuery extends Query { } + +Query getQuery() { result instanceof CastCharBeforeConvertingToLargerSizes_sharedSharedQuery } + +query predicate problems(Cast c, string message) { + not isExcluded(c, getQuery()) and + // find cases where there is a conversion happening wherein the + // base type is a char + c.getExpr().getType() instanceof CharType and + not c.getExpr().getType() instanceof UnsignedCharType and + // it's a bigger type + c.getType().getSize() > c.getExpr().getType().getSize() and + // and it's some kind of integer type + c.getType().getUnderlyingType() instanceof IntegralType and + not c.isFromTemplateInstantiation(_) and + message = + "Expression not converted to `unsigned char` before converting to a larger integer type." +} diff --git a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected new file mode 100644 index 0000000000..886d03ddac --- /dev/null +++ b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected @@ -0,0 +1,2 @@ +| test.cpp:11:9:11:9 | (int32_t)... | Expression not converted to `unsigned char` before converting to a larger integer type. | +| test.cpp:12:41:12:41 | (signed int)... | Expression not converted to `unsigned char` before converting to a larger integer type. | diff --git a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql new file mode 100644 index 0000000000..2aceff89c0 --- /dev/null +++ b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql @@ -0,0 +1,4 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes_shared.CastCharBeforeConvertingToLargerSizes_shared + +class TestFileQuery extends CastCharBeforeConvertingToLargerSizes_sharedSharedQuery, TestQuery { } diff --git a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.cpp b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.cpp new file mode 100644 index 0000000000..4e5d90e714 --- /dev/null +++ b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.cpp @@ -0,0 +1,17 @@ +// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND +// CHANGES SHOULD BE REFLECTED THERE AS WELL. +#include + +template S get(T t) { + S s = t; // COMPLIANT + return s; +} + +void test(std::int32_t i32, std::int8_t i8, char c) { + i32 = c; // NON_COMPLIANT + i32 = get(c); // NON_COMPLIANT + i32 = get(c); // COMPLIANT + i32 = i8; // COMPLIANT + i32 = get(i8); // COMPLIANT + i32 = get(i8); // COMPLIANT +} diff --git a/rule_packages/c/Strings3.json b/rule_packages/c/Strings3.json index 9456f4b422..b0131fb55b 100644 --- a/rule_packages/c/Strings3.json +++ b/rule_packages/c/Strings3.json @@ -12,6 +12,7 @@ "precision": "very-high", "severity": "error", "short_name": "CastCharBeforeConvertingToLargerSizes", + "shared_implementation_short_name": "CastCharBeforeConvertingToLargerSizes_shared", "tags": [ "correctness", "security" From dc6bed13a81d6956856ce1c58b9aee12f3d31ab3 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 5 Jul 2024 20:00:09 +0200 Subject: [PATCH 18/49] Add change notes --- change_notes/2024-07-05-fix-fp-576-STR34-C.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 change_notes/2024-07-05-fix-fp-576-STR34-C.md diff --git a/change_notes/2024-07-05-fix-fp-576-STR34-C.md b/change_notes/2024-07-05-fix-fp-576-STR34-C.md new file mode 100644 index 0000000000..340d8f4288 --- /dev/null +++ b/change_notes/2024-07-05-fix-fp-576-STR34-C.md @@ -0,0 +1,2 @@ +- `STR34-C` - `CastCharBeforeConvertingToLargerSizes.ql`: + - Fixes #576. Do not consider integer type aliases in templates. \ No newline at end of file From 80ab9a6954315c6c70b37d257e4b269406b5e01c Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 23 Jul 2024 21:57:11 +0100 Subject: [PATCH 19/49] Add change note --- change_notes/2024-06-03-a3-1-5-trivial-defs.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 change_notes/2024-06-03-a3-1-5-trivial-defs.md diff --git a/change_notes/2024-06-03-a3-1-5-trivial-defs.md b/change_notes/2024-06-03-a3-1-5-trivial-defs.md new file mode 100644 index 0000000000..29a7f48eb5 --- /dev/null +++ b/change_notes/2024-06-03-a3-1-5-trivial-defs.md @@ -0,0 +1,4 @@ + - `A3-1-5` - `TrivialOrTemplateFunctionDefinedOutsideClassDefinition.ql`: + - Query deleted - rule was never intended to cover this case (see https://forum.misra.org.uk/archive/index.php?thread-1588.html). + - `A3-1-5` - `NonTrivialNonTemplateFunctionDefinedInsideClassDefinition.ql`: + - Removed false positives caused by flagging member functions in template instantiations From dfe7dca65eb02779b9004607f9e2832e2eaeec3c Mon Sep 17 00:00:00 2001 From: Luke Cartey <5377966+lcartey@users.noreply.github.com> Date: Tue, 23 Jul 2024 22:02:33 +0100 Subject: [PATCH 20/49] Update cpp/common/src/codingstandards/cpp/Class.qll Co-authored-by: Kristen Newbury --- cpp/common/src/codingstandards/cpp/Class.qll | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/Class.qll b/cpp/common/src/codingstandards/cpp/Class.qll index 09d39ce6f8..73c0930f09 100644 --- a/cpp/common/src/codingstandards/cpp/Class.qll +++ b/cpp/common/src/codingstandards/cpp/Class.qll @@ -193,8 +193,11 @@ class TrivialMemberFunction extends IntrospectedMemberFunction { */ class TemplateOrTemplateClassMemberFunction extends MemberFunction { TemplateOrTemplateClassMemberFunction() { - isFromUninstantiatedTemplate(_) or - isFromTemplateInstantiation(_) +( + isFromUninstantiatedTemplate(_) or + isFromTemplateInstantiation(_) + ) and + not this.isCompilerGenerated() } } From 1de5223159e72821e9d5a8eb4215cf00b372d217 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Wed, 24 Jul 2024 22:26:49 +0100 Subject: [PATCH 21/49] Remove extra line --- cpp/autosar/test/rules/A3-1-5/test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/autosar/test/rules/A3-1-5/test.cpp b/cpp/autosar/test/rules/A3-1-5/test.cpp index 0bff554785..1b2898bf63 100644 --- a/cpp/autosar/test/rules/A3-1-5/test.cpp +++ b/cpp/autosar/test/rules/A3-1-5/test.cpp @@ -172,7 +172,6 @@ void test_FooBar() { foobar.complexCalculation(); } - FooBar::~FooBar() {} // COMPLIANT want to ignore pImpl uses of destructors int FooBar::f1(int a, int b) { // COMPLIANT not a trivial function From 52c7e45ccf8efcb8459cbeb7be779e591e4c3c87 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Wed, 24 Jul 2024 22:30:25 +0100 Subject: [PATCH 22/49] Remove A3-1-5 deleted query --- .../cpp/exclusions/cpp/Classes.qll | 17 ----------------- rule_packages/cpp/Classes.json | 9 --------- 2 files changed, 26 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Classes.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Classes.qll index 92c7a4280e..3daf48c696 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Classes.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Classes.qll @@ -13,7 +13,6 @@ newtype ClassesQuery = TClassDataMembersInitializationConditionQuery() or TRedundantMemberFunctionsShouldBeDefaultedOrLeftUndefinedQuery() or TNonTemplateMemberDefinedInTemplateQuery() or - TTrivialOrTemplateFunctionDefinedOutsideClassDefinitionQuery() or TNonTrivialNonTemplateFunctionDefinedInsideClassDefinitionQuery() or TInParametersForNotCheapToCopyTypesNotPassedByReferenceQuery() or TInParametersForCheapToCopyTypesNotPassedByValueQuery() or @@ -105,15 +104,6 @@ predicate isClassesQueryMetadata(Query query, string queryId, string ruleId, str ruleId = "A14-5-2" and category = "advisory" or - query = - // `Query` instance for the `trivialOrTemplateFunctionDefinedOutsideClassDefinition` query - ClassesPackage::trivialOrTemplateFunctionDefinedOutsideClassDefinitionQuery() and - queryId = - // `@id` for the `trivialOrTemplateFunctionDefinedOutsideClassDefinition` query - "cpp/autosar/trivial-or-template-function-defined-outside-class-definition" and - ruleId = "A3-1-5" and - category = "required" - or query = // `Query` instance for the `nonTrivialNonTemplateFunctionDefinedInsideClassDefinition` query ClassesPackage::nonTrivialNonTemplateFunctionDefinedInsideClassDefinitionQuery() and @@ -251,13 +241,6 @@ module ClassesPackage { TQueryCPP(TClassesPackageQuery(TNonTemplateMemberDefinedInTemplateQuery())) } - Query trivialOrTemplateFunctionDefinedOutsideClassDefinitionQuery() { - //autogenerate `Query` type - result = - // `Query` type for `trivialOrTemplateFunctionDefinedOutsideClassDefinition` query - TQueryCPP(TClassesPackageQuery(TTrivialOrTemplateFunctionDefinedOutsideClassDefinitionQuery())) - } - Query nonTrivialNonTemplateFunctionDefinedInsideClassDefinitionQuery() { //autogenerate `Query` type result = diff --git a/rule_packages/cpp/Classes.json b/rule_packages/cpp/Classes.json index 61eab45081..6dd130a55b 100644 --- a/rule_packages/cpp/Classes.json +++ b/rule_packages/cpp/Classes.json @@ -178,15 +178,6 @@ "obligation": "required" }, "queries": [ - { - "description": "A function that is either trivial, a template function, or a member of a template class may not be defined outside of a class body.", - "kind": "problem", - "name": "A function shall be defined with a class body if and only if it is intended to be inlined", - "precision": "very-high", - "severity": "recommendation", - "short_name": "TrivialOrTemplateFunctionDefinedOutsideClassDefinition", - "tags": [] - }, { "description": "A function that is not either trivial, a template function, or a member of a template class may not be defined within a class body.", "kind": "problem", From 099dbb85308413ee319f42df22c6d3f870dee221 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Wed, 24 Jul 2024 23:28:04 +0100 Subject: [PATCH 23/49] Fix Class.qll formatting. --- cpp/common/src/codingstandards/cpp/Class.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/common/src/codingstandards/cpp/Class.qll b/cpp/common/src/codingstandards/cpp/Class.qll index 3aa7719fb8..6f730736f9 100644 --- a/cpp/common/src/codingstandards/cpp/Class.qll +++ b/cpp/common/src/codingstandards/cpp/Class.qll @@ -192,7 +192,7 @@ class TrivialMemberFunction extends IntrospectedMemberFunction { */ class TemplateOrTemplateClassMemberFunction extends MemberFunction { TemplateOrTemplateClassMemberFunction() { -( + ( isFromUninstantiatedTemplate(_) or isFromTemplateInstantiation(_) ) and From e3a5b8cdd87726a0faa4862e24ee1db9b5257b08 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 25 Jul 2024 20:13:49 +0200 Subject: [PATCH 24/49] renamed the shared query --- .../CastCharBeforeConvertingToLargerSizes.ql | 4 +-- ...tCharBeforeConvertingToLargerSizes.testref | 2 +- ...harBeforeConvertingToLargerSizes.expected} | 0 ...oreConvertingToLargerSizes.expected.clang} | 0 ...eforeConvertingToLargerSizes.expected.gcc} | 0 ...eforeConvertingToLargerSizes.expected.qcc} | 0 .../CastCharBeforeConvertingToLargerSizes.ql} | 4 +-- .../test.c | 0 .../CastCharBeforeConvertingToLargerSizes.qll | 27 +++++++++++++++++++ ...arBeforeConvertingToLargerSizes_shared.qll | 26 ------------------ ...harBeforeConvertingToLargerSizes.expected} | 0 .../CastCharBeforeConvertingToLargerSizes.ql} | 4 +-- .../test.cpp | 0 rule_packages/c/Strings3.json | 2 +- 14 files changed, 35 insertions(+), 34 deletions(-) rename c/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected} (100%) rename c/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.clang} (100%) rename c/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.gcc} (100%) rename c/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.qcc} (100%) rename c/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql} (63%) rename c/common/test/rules/{castcharbeforeconvertingtolargersizes_shared => castcharbeforeconvertingtolargersizes}/test.c (100%) create mode 100644 cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll delete mode 100644 cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll rename cpp/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected} (100%) rename cpp/common/test/rules/{castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql => castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql} (63%) rename cpp/common/test/rules/{castcharbeforeconvertingtolargersizes_shared => castcharbeforeconvertingtolargersizes}/test.cpp (100%) diff --git a/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql b/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql index 1f2af0b588..394df49d99 100644 --- a/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql +++ b/c/cert/src/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.ql @@ -14,9 +14,9 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes_shared.CastCharBeforeConvertingToLargerSizes_shared +import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes.CastCharBeforeConvertingToLargerSizes -class CastCharBeforeConvertingToLargerSizesQuery extends CastCharBeforeConvertingToLargerSizes_sharedSharedQuery +class CastCharBeforeConvertingToLargerSizesQuery extends CastCharBeforeConvertingToLargerSizesSharedQuery { CastCharBeforeConvertingToLargerSizesQuery() { this = Strings3Package::castCharBeforeConvertingToLargerSizesQuery() diff --git a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref index fefb98580c..0e13e05dc3 100644 --- a/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref +++ b/c/cert/test/rules/STR34-C/CastCharBeforeConvertingToLargerSizes.testref @@ -1 +1 @@ -c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql \ No newline at end of file +c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql \ No newline at end of file diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected b/c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected similarity index 100% rename from c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected rename to c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang b/c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.clang similarity index 100% rename from c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.clang rename to c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.clang diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc b/c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.gcc similarity index 100% rename from c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.gcc rename to c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.gcc diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc b/c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.qcc similarity index 100% rename from c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected.qcc rename to c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected.qcc diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql b/c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql similarity index 63% rename from c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql rename to c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql index 2aceff89c0..2a1e49774f 100644 --- a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql +++ b/c/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql @@ -1,4 +1,4 @@ // GENERATED FILE - DO NOT MODIFY -import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes_shared.CastCharBeforeConvertingToLargerSizes_shared +import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes.CastCharBeforeConvertingToLargerSizes -class TestFileQuery extends CastCharBeforeConvertingToLargerSizes_sharedSharedQuery, TestQuery { } +class TestFileQuery extends CastCharBeforeConvertingToLargerSizesSharedQuery, TestQuery { } diff --git a/c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.c b/c/common/test/rules/castcharbeforeconvertingtolargersizes/test.c similarity index 100% rename from c/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.c rename to c/common/test/rules/castcharbeforeconvertingtolargersizes/test.c diff --git a/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll new file mode 100644 index 0000000000..5d396f9a42 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll @@ -0,0 +1,27 @@ +/** + * Provides a library which includes a `problems` predicate for reporting.... + */ + + import cpp + import codingstandards.cpp.Customizations + import codingstandards.cpp.Exclusions + + abstract class CastCharBeforeConvertingToLargerSizesSharedQuery extends Query { } + + Query getQuery() { result instanceof CastCharBeforeConvertingToLargerSizesSharedQuery } + + query predicate problems(Cast c, string message) { + not isExcluded(c, getQuery()) and + // find cases where there is a conversion happening wherein the + // base type is a char + c.getExpr().getType() instanceof CharType and + not c.getExpr().getType() instanceof UnsignedCharType and + // it's a bigger type + c.getType().getSize() > c.getExpr().getType().getSize() and + // and it's some kind of integer type + c.getType().getUnderlyingType() instanceof IntegralType and + not c.isFromTemplateInstantiation(_) and + message = + "Expression not converted to `unsigned char` before converting to a larger integer type." + } + \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll deleted file mode 100644 index 3ef9033910..0000000000 --- a/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.qll +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Provides a library which includes a `problems` predicate for reporting.... - */ - -import cpp -import codingstandards.cpp.Customizations -import codingstandards.cpp.Exclusions - -abstract class CastCharBeforeConvertingToLargerSizes_sharedSharedQuery extends Query { } - -Query getQuery() { result instanceof CastCharBeforeConvertingToLargerSizes_sharedSharedQuery } - -query predicate problems(Cast c, string message) { - not isExcluded(c, getQuery()) and - // find cases where there is a conversion happening wherein the - // base type is a char - c.getExpr().getType() instanceof CharType and - not c.getExpr().getType() instanceof UnsignedCharType and - // it's a bigger type - c.getType().getSize() > c.getExpr().getType().getSize() and - // and it's some kind of integer type - c.getType().getUnderlyingType() instanceof IntegralType and - not c.isFromTemplateInstantiation(_) and - message = - "Expression not converted to `unsigned char` before converting to a larger integer type." -} diff --git a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected similarity index 100% rename from cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.expected rename to cpp/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.expected diff --git a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql similarity index 63% rename from cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql rename to cpp/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql index 2aceff89c0..2a1e49774f 100644 --- a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/CastCharBeforeConvertingToLargerSizes_shared.ql +++ b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.ql @@ -1,4 +1,4 @@ // GENERATED FILE - DO NOT MODIFY -import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes_shared.CastCharBeforeConvertingToLargerSizes_shared +import codingstandards.cpp.rules.castcharbeforeconvertingtolargersizes.CastCharBeforeConvertingToLargerSizes -class TestFileQuery extends CastCharBeforeConvertingToLargerSizes_sharedSharedQuery, TestQuery { } +class TestFileQuery extends CastCharBeforeConvertingToLargerSizesSharedQuery, TestQuery { } diff --git a/cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.cpp b/cpp/common/test/rules/castcharbeforeconvertingtolargersizes/test.cpp similarity index 100% rename from cpp/common/test/rules/castcharbeforeconvertingtolargersizes_shared/test.cpp rename to cpp/common/test/rules/castcharbeforeconvertingtolargersizes/test.cpp diff --git a/rule_packages/c/Strings3.json b/rule_packages/c/Strings3.json index b0131fb55b..1cecf390ec 100644 --- a/rule_packages/c/Strings3.json +++ b/rule_packages/c/Strings3.json @@ -12,7 +12,7 @@ "precision": "very-high", "severity": "error", "short_name": "CastCharBeforeConvertingToLargerSizes", - "shared_implementation_short_name": "CastCharBeforeConvertingToLargerSizes_shared", + "shared_implementation_short_name": "CastCharBeforeConvertingToLargerSizes", "tags": [ "correctness", "security" From 946d5dfcc98f602be23a7cdfc3a0c10dcb258c30 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 25 Jul 2024 20:26:02 +0200 Subject: [PATCH 25/49] Fix formatting --- .../CastCharBeforeConvertingToLargerSizes.qll | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll index 5d396f9a42..66f1006d17 100644 --- a/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll +++ b/cpp/common/src/codingstandards/cpp/rules/castcharbeforeconvertingtolargersizes/CastCharBeforeConvertingToLargerSizes.qll @@ -2,26 +2,25 @@ * Provides a library which includes a `problems` predicate for reporting.... */ - import cpp - import codingstandards.cpp.Customizations - import codingstandards.cpp.Exclusions - - abstract class CastCharBeforeConvertingToLargerSizesSharedQuery extends Query { } - - Query getQuery() { result instanceof CastCharBeforeConvertingToLargerSizesSharedQuery } - - query predicate problems(Cast c, string message) { - not isExcluded(c, getQuery()) and - // find cases where there is a conversion happening wherein the - // base type is a char - c.getExpr().getType() instanceof CharType and - not c.getExpr().getType() instanceof UnsignedCharType and - // it's a bigger type - c.getType().getSize() > c.getExpr().getType().getSize() and - // and it's some kind of integer type - c.getType().getUnderlyingType() instanceof IntegralType and - not c.isFromTemplateInstantiation(_) and - message = - "Expression not converted to `unsigned char` before converting to a larger integer type." - } - \ No newline at end of file +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions + +abstract class CastCharBeforeConvertingToLargerSizesSharedQuery extends Query { } + +Query getQuery() { result instanceof CastCharBeforeConvertingToLargerSizesSharedQuery } + +query predicate problems(Cast c, string message) { + not isExcluded(c, getQuery()) and + // find cases where there is a conversion happening wherein the + // base type is a char + c.getExpr().getType() instanceof CharType and + not c.getExpr().getType() instanceof UnsignedCharType and + // it's a bigger type + c.getType().getSize() > c.getExpr().getType().getSize() and + // and it's some kind of integer type + c.getType().getUnderlyingType() instanceof IntegralType and + not c.isFromTemplateInstantiation(_) and + message = + "Expression not converted to `unsigned char` before converting to a larger integer type." +} From 8f81b4e7dcef93295bb1f486f12cdb4bf2bc9a03 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 27 Oct 2024 14:50:03 +0000 Subject: [PATCH 26/49] EssentialTypes: Correct handling of bitwise binary expressions They shouldn't have the standard type if either both the operands are signed or they are both unsigned. --- .../c/misra/EssentialTypes.qll | 49 +++- c/misra/test/c/misra/EssentialTypes.expected | 275 ++++++++++++++++++ c/misra/test/c/misra/test.c | 80 +++++ 3 files changed, 402 insertions(+), 2 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 4783547ed2..4dbe8dbb34 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -192,8 +192,8 @@ class EssentialEqualityOperationExpr extends EssentialExpr, EqualityOperation { override Type getEssentialType() { result instanceof BoolType } } -class EssentialBinaryBitwiseOperationExpr extends EssentialExpr, BinaryBitwiseOperation { - EssentialBinaryBitwiseOperationExpr() { +class EssentialShiftOperationExpr extends EssentialExpr, BinaryBitwiseOperation { + EssentialShiftOperationExpr() { this instanceof LShiftExpr or this instanceof RShiftExpr } @@ -353,6 +353,51 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera } } +class EssentialBinaryBitwiseExpr extends EssentialExpr, BinaryBitwiseOperation { + EssentialBinaryBitwiseExpr() { + not this instanceof LShiftExpr and + not this instanceof RShiftExpr + } + + override Type getEssentialType() { + exists( + Type leftEssentialType, Type rightEssentialType, + EssentialTypeCategory leftEssentialTypeCategory, + EssentialTypeCategory rightEssentialTypeCategory + | + leftEssentialType = getEssentialType(getLeftOperand()) and + rightEssentialType = getEssentialType(getRightOperand()) and + leftEssentialTypeCategory = getEssentialTypeCategory(leftEssentialType) and + rightEssentialTypeCategory = getEssentialTypeCategory(rightEssentialType) + | + if + leftEssentialTypeCategory = EssentiallySignedType() and + rightEssentialTypeCategory = EssentiallySignedType() + then + if exists(getValue()) + then result = stlr(this) + else ( + if leftEssentialType.getSize() > rightEssentialType.getSize() + then result = leftEssentialType + else result = rightEssentialType + ) + else + if + leftEssentialTypeCategory = EssentiallyUnsignedType() and + rightEssentialTypeCategory = EssentiallyUnsignedType() + then + if exists(getValue()) + then result = utlr(this) + else ( + if leftEssentialType.getSize() > rightEssentialType.getSize() + then result = leftEssentialType + else result = rightEssentialType + ) + else result = this.getStandardType() + ) + } +} + /** * A named Enum type, as per D.5. */ diff --git a/c/misra/test/c/misra/EssentialTypes.expected b/c/misra/test/c/misra/EssentialTypes.expected index c0e010b8e4..19a7090fe9 100644 --- a/c/misra/test/c/misra/EssentialTypes.expected +++ b/c/misra/test/c/misra/EssentialTypes.expected @@ -90,3 +90,278 @@ | test.c:79:3:79:5 | 97 | char | char | essentially Character type | | test.c:80:3:80:6 | 10 | char | char | essentially Character type | | test.c:81:3:81:6 | 0 | char | char | essentially Character type | +| test.c:87:16:87:16 | 0 | signed char | signed char | essentially Signed type | +| test.c:87:16:87:16 | (uint8_t)... | uint8_t | uint8_t | essentially Unsigned type | +| test.c:88:18:88:18 | 0 | signed char | signed char | essentially Signed type | +| test.c:88:18:88:18 | (uint16_t)... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:89:18:89:18 | 0 | signed char | signed char | essentially Signed type | +| test.c:89:18:89:18 | (uint32_t)... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:90:15:90:15 | 0 | signed char | signed char | essentially Signed type | +| test.c:90:15:90:15 | (int8_t)... | int8_t | int8_t | essentially Signed type | +| test.c:91:17:91:17 | 0 | signed char | signed char | essentially Signed type | +| test.c:91:17:91:17 | (int16_t)... | int16_t | int16_t | essentially Signed type | +| test.c:92:16:92:17 | 0 | signed char | signed char | essentially Signed type | +| test.c:94:3:94:4 | (int)... | int | int | essentially Signed type | +| test.c:94:3:94:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:94:3:94:9 | ... & ... | uint8_t | uint8_t | essentially Unsigned type | +| test.c:94:8:94:9 | (int)... | int | int | essentially Signed type | +| test.c:94:8:94:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:95:3:95:5 | (int)... | int | int | essentially Signed type | +| test.c:95:3:95:5 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:95:3:95:10 | ... & ... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:95:9:95:10 | (int)... | int | int | essentially Signed type | +| test.c:95:9:95:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:96:3:96:4 | (int)... | int | int | essentially Signed type | +| test.c:96:3:96:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:96:3:96:10 | ... & ... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:96:8:96:10 | (int)... | int | int | essentially Signed type | +| test.c:96:8:96:10 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:97:3:97:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:97:3:97:10 | ... & ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:97:9:97:10 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:97:9:97:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:98:3:98:4 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:98:3:98:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:98:3:98:10 | ... & ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:98:8:98:10 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:99:3:99:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:99:3:99:11 | ... & ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:99:9:99:11 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:99:9:99:11 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:100:3:100:5 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:100:3:100:5 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:100:3:100:11 | ... & ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:100:9:100:11 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:102:3:102:4 | (int)... | int | int | essentially Signed type | +| test.c:102:3:102:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:102:3:102:9 | ... \| ... | uint8_t | uint8_t | essentially Unsigned type | +| test.c:102:8:102:9 | (int)... | int | int | essentially Signed type | +| test.c:102:8:102:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:103:3:103:5 | (int)... | int | int | essentially Signed type | +| test.c:103:3:103:5 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:103:3:103:10 | ... \| ... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:103:9:103:10 | (int)... | int | int | essentially Signed type | +| test.c:103:9:103:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:104:3:104:4 | (int)... | int | int | essentially Signed type | +| test.c:104:3:104:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:104:3:104:10 | ... \| ... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:104:8:104:10 | (int)... | int | int | essentially Signed type | +| test.c:104:8:104:10 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:105:3:105:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:105:3:105:10 | ... \| ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:105:9:105:10 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:105:9:105:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:106:3:106:4 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:106:3:106:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:106:3:106:10 | ... \| ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:106:8:106:10 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:107:3:107:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:107:3:107:11 | ... \| ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:107:9:107:11 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:107:9:107:11 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:108:3:108:5 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:108:3:108:5 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:108:3:108:11 | ... \| ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:108:9:108:11 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:110:3:110:4 | (int)... | int | int | essentially Signed type | +| test.c:110:3:110:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:110:3:110:9 | ... ^ ... | uint8_t | uint8_t | essentially Unsigned type | +| test.c:110:8:110:9 | (int)... | int | int | essentially Signed type | +| test.c:110:8:110:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:111:3:111:5 | (int)... | int | int | essentially Signed type | +| test.c:111:3:111:5 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:111:3:111:10 | ... ^ ... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:111:9:111:10 | (int)... | int | int | essentially Signed type | +| test.c:111:9:111:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:112:3:112:4 | (int)... | int | int | essentially Signed type | +| test.c:112:3:112:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:112:3:112:10 | ... ^ ... | uint16_t | uint16_t | essentially Unsigned type | +| test.c:112:8:112:10 | (int)... | int | int | essentially Signed type | +| test.c:112:8:112:10 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:113:3:113:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:113:3:113:10 | ... ^ ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:113:9:113:10 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:113:9:113:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:114:3:114:4 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:114:3:114:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:114:3:114:10 | ... ^ ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:114:8:114:10 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:115:3:115:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:115:3:115:11 | ... ^ ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:115:9:115:11 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:115:9:115:11 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:116:3:116:5 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:116:3:116:5 | u16 | uint16_t | uint16_t | essentially Unsigned type | +| test.c:116:3:116:11 | ... ^ ... | uint32_t | uint32_t | essentially Unsigned type | +| test.c:116:9:116:11 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:118:3:118:4 | (int)... | int | int | essentially Signed type | +| test.c:118:3:118:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:118:3:118:9 | ... & ... | int8_t | int8_t | essentially Signed type | +| test.c:118:8:118:9 | (int)... | int | int | essentially Signed type | +| test.c:118:8:118:9 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:119:3:119:5 | (int)... | int | int | essentially Signed type | +| test.c:119:3:119:5 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:119:3:119:10 | ... & ... | int16_t | int16_t | essentially Signed type | +| test.c:119:9:119:10 | (int)... | int | int | essentially Signed type | +| test.c:119:9:119:10 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:120:3:120:4 | (int)... | int | int | essentially Signed type | +| test.c:120:3:120:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:120:3:120:10 | ... & ... | int16_t | int16_t | essentially Signed type | +| test.c:120:8:120:10 | (int)... | int | int | essentially Signed type | +| test.c:120:8:120:10 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:121:3:121:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:121:3:121:10 | ... & ... | int32_t | int32_t | essentially Signed type | +| test.c:121:9:121:10 | (int)... | int | int | essentially Signed type | +| test.c:121:9:121:10 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:122:3:122:4 | (int)... | int | int | essentially Signed type | +| test.c:122:3:122:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:122:3:122:10 | ... & ... | int32_t | int32_t | essentially Signed type | +| test.c:122:8:122:10 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:123:3:123:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:123:3:123:11 | ... & ... | int32_t | int32_t | essentially Signed type | +| test.c:123:9:123:11 | (int)... | int | int | essentially Signed type | +| test.c:123:9:123:11 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:124:3:124:5 | (int)... | int | int | essentially Signed type | +| test.c:124:3:124:5 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:124:3:124:11 | ... & ... | int32_t | int32_t | essentially Signed type | +| test.c:124:9:124:11 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:126:3:126:4 | (int)... | int | int | essentially Signed type | +| test.c:126:3:126:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:126:3:126:9 | ... \| ... | int8_t | int8_t | essentially Signed type | +| test.c:126:8:126:9 | (int)... | int | int | essentially Signed type | +| test.c:126:8:126:9 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:127:3:127:5 | (int)... | int | int | essentially Signed type | +| test.c:127:3:127:5 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:127:3:127:10 | ... \| ... | int16_t | int16_t | essentially Signed type | +| test.c:127:9:127:10 | (int)... | int | int | essentially Signed type | +| test.c:127:9:127:10 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:128:3:128:4 | (int)... | int | int | essentially Signed type | +| test.c:128:3:128:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:128:3:128:10 | ... \| ... | int16_t | int16_t | essentially Signed type | +| test.c:128:8:128:10 | (int)... | int | int | essentially Signed type | +| test.c:128:8:128:10 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:129:3:129:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:129:3:129:10 | ... \| ... | int32_t | int32_t | essentially Signed type | +| test.c:129:9:129:10 | (int)... | int | int | essentially Signed type | +| test.c:129:9:129:10 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:130:3:130:4 | (int)... | int | int | essentially Signed type | +| test.c:130:3:130:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:130:3:130:10 | ... \| ... | int32_t | int32_t | essentially Signed type | +| test.c:130:8:130:10 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:131:3:131:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:131:3:131:11 | ... \| ... | int32_t | int32_t | essentially Signed type | +| test.c:131:9:131:11 | (int)... | int | int | essentially Signed type | +| test.c:131:9:131:11 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:132:3:132:5 | (int)... | int | int | essentially Signed type | +| test.c:132:3:132:5 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:132:3:132:11 | ... \| ... | int32_t | int32_t | essentially Signed type | +| test.c:132:9:132:11 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:134:3:134:4 | (int)... | int | int | essentially Signed type | +| test.c:134:3:134:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:134:3:134:9 | ... ^ ... | int8_t | int8_t | essentially Signed type | +| test.c:134:8:134:9 | (int)... | int | int | essentially Signed type | +| test.c:134:8:134:9 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:135:3:135:5 | (int)... | int | int | essentially Signed type | +| test.c:135:3:135:5 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:135:3:135:10 | ... ^ ... | int16_t | int16_t | essentially Signed type | +| test.c:135:9:135:10 | (int)... | int | int | essentially Signed type | +| test.c:135:9:135:10 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:136:3:136:4 | (int)... | int | int | essentially Signed type | +| test.c:136:3:136:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:136:3:136:10 | ... ^ ... | int16_t | int16_t | essentially Signed type | +| test.c:136:8:136:10 | (int)... | int | int | essentially Signed type | +| test.c:136:8:136:10 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:137:3:137:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:137:3:137:10 | ... ^ ... | int32_t | int32_t | essentially Signed type | +| test.c:137:9:137:10 | (int)... | int | int | essentially Signed type | +| test.c:137:9:137:10 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:138:3:138:4 | (int)... | int | int | essentially Signed type | +| test.c:138:3:138:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:138:3:138:10 | ... ^ ... | int32_t | int32_t | essentially Signed type | +| test.c:138:8:138:10 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:139:3:139:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:139:3:139:11 | ... ^ ... | int32_t | int32_t | essentially Signed type | +| test.c:139:9:139:11 | (int)... | int | int | essentially Signed type | +| test.c:139:9:139:11 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:140:3:140:5 | (int)... | int | int | essentially Signed type | +| test.c:140:3:140:5 | s16 | int16_t | int16_t | essentially Signed type | +| test.c:140:3:140:11 | ... ^ ... | int32_t | int32_t | essentially Signed type | +| test.c:140:9:140:11 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:142:3:142:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:142:3:142:11 | ... & ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:142:9:142:11 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:142:9:142:11 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:143:3:143:5 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:143:3:143:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:143:3:143:11 | ... & ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:143:9:143:11 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:144:3:144:4 | (int)... | int | int | essentially Signed type | +| test.c:144:3:144:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:144:3:144:10 | ... & ... | int | int | essentially Signed type | +| test.c:144:8:144:10 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:145:3:145:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:145:3:145:10 | ... & ... | int | int | essentially Signed type | +| test.c:145:9:145:10 | (int)... | int | int | essentially Signed type | +| test.c:145:9:145:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:146:3:146:4 | (int)... | int | int | essentially Signed type | +| test.c:146:3:146:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:146:3:146:9 | ... & ... | int | int | essentially Signed type | +| test.c:146:8:146:9 | (int)... | int | int | essentially Signed type | +| test.c:146:8:146:9 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:147:3:147:4 | (int)... | int | int | essentially Signed type | +| test.c:147:3:147:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:147:3:147:9 | ... & ... | int | int | essentially Signed type | +| test.c:147:8:147:9 | (int)... | int | int | essentially Signed type | +| test.c:147:8:147:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:149:3:149:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:149:3:149:11 | ... \| ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:149:9:149:11 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:149:9:149:11 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:150:3:150:5 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:150:3:150:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:150:3:150:11 | ... \| ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:150:9:150:11 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:151:3:151:4 | (int)... | int | int | essentially Signed type | +| test.c:151:3:151:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:151:3:151:10 | ... \| ... | int | int | essentially Signed type | +| test.c:151:8:151:10 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:152:3:152:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:152:3:152:10 | ... \| ... | int | int | essentially Signed type | +| test.c:152:9:152:10 | (int)... | int | int | essentially Signed type | +| test.c:152:9:152:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:153:3:153:4 | (int)... | int | int | essentially Signed type | +| test.c:153:3:153:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:153:3:153:9 | ... \| ... | int | int | essentially Signed type | +| test.c:153:8:153:9 | (int)... | int | int | essentially Signed type | +| test.c:153:8:153:9 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:154:3:154:4 | (int)... | int | int | essentially Signed type | +| test.c:154:3:154:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:154:3:154:9 | ... \| ... | int | int | essentially Signed type | +| test.c:154:8:154:9 | (int)... | int | int | essentially Signed type | +| test.c:154:8:154:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:156:3:156:5 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:156:3:156:11 | ... ^ ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:156:9:156:11 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:156:9:156:11 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:157:3:157:5 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:157:3:157:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:157:3:157:11 | ... ^ ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:157:9:157:11 | u32 | uint32_t | uint32_t | essentially Unsigned type | +| test.c:158:3:158:4 | (int)... | int | int | essentially Signed type | +| test.c:158:3:158:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:158:3:158:10 | ... ^ ... | int | int | essentially Signed type | +| test.c:158:8:158:10 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:159:3:159:5 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:159:3:159:10 | ... ^ ... | int | int | essentially Signed type | +| test.c:159:9:159:10 | (int)... | int | int | essentially Signed type | +| test.c:159:9:159:10 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:160:3:160:4 | (int)... | int | int | essentially Signed type | +| test.c:160:3:160:4 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:160:3:160:9 | ... ^ ... | int | int | essentially Signed type | +| test.c:160:8:160:9 | (int)... | int | int | essentially Signed type | +| test.c:160:8:160:9 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:161:3:161:4 | (int)... | int | int | essentially Signed type | +| test.c:161:3:161:4 | s8 | int8_t | int8_t | essentially Signed type | +| test.c:161:3:161:9 | ... ^ ... | int | int | essentially Signed type | +| test.c:161:8:161:9 | (int)... | int | int | essentially Signed type | +| test.c:161:8:161:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | diff --git a/c/misra/test/c/misra/test.c b/c/misra/test/c/misra/test.c index b3fdddd591..dcdfef4eb4 100644 --- a/c/misra/test/c/misra/test.c +++ b/c/misra/test/c/misra/test.c @@ -79,4 +79,84 @@ void testControlChar() { 'a'; // Essentially char '\n'; // Essentially char '\0'; // Essentially char +} + +#include + +void testBitwise() { + uint8_t u8 = 0; + uint16_t u16 = 0; + uint32_t u32 = 0; + int8_t s8 = 0; + int16_t s16 = 0; + int32_t s32 = 0; + + u8 & u8; // Essentially unsigned, char + u16 & u8; // Essentially unsigned, short + u8 & u16; // Essentially unsigned, short + u32 & u8; // Essentially unsigned, int + u8 & u32; // Essentially unsigned, int + u32 & u16; // Essentially unsigned, int + u16 & u32; // Essentially unsigned, int + + u8 | u8; // Essentially unsigned, char + u16 | u8; // Essentially unsigned, short + u8 | u16; // Essentially unsigned, short + u32 | u8; // Essentially unsigned, int + u8 | u32; // Essentially unsigned, int + u32 | u16; // Essentially unsigned, int + u16 | u32; // Essentially unsigned, int + + u8 ^ u8; // Essentially unsigned, char + u16 ^ u8; // Essentially unsigned, short + u8 ^ u16; // Essentially unsigned, short + u32 ^ u8; // Essentially unsigned, int + u8 ^ u32; // Essentially unsigned, int + u32 ^ u16; // Essentially unsigned, int + u16 ^ u32; // Essentially unsigned, int + + s8 & s8; // Essentially signed, char + s16 & s8; // Essentially signed, short + s8 & s16; // Essentially signed, short + s32 & s8; // Essentially signed, int + s8 & s32; // Essentially signed, int + s32 & s16; // Essentially signed, int + s16 & s32; // Essentially signed, int + + s8 | s8; // Essentially signed, char + s16 | s8; // Essentially signed, short + s8 | s16; // Essentially signed, short + s32 | s8; // Essentially signed, int + s8 | s32; // Essentially signed, int + s32 | s16; // Essentially signed, int + s16 | s32; // Essentially signed, int + + s8 ^ s8; // Essentially signed, char + s16 ^ s8; // Essentially signed, short + s8 ^ s16; // Essentially signed, short + s32 ^ s8; // Essentially signed, int + s8 ^ s32; // Essentially signed, int + s32 ^ s16; // Essentially signed, int + s16 ^ s32; // Essentially signed, int + + u32 & s32; // Essentially signed, int + s32 & u32; // Essentially signed, int + u8 & s32; // Essentially signed, int + s32 & u8; // Essentially signed, int + u8 & s8; // Essentially signed, int + s8 & u8; // Essentially signed, int + + u32 | s32; // Essentially signed, int + s32 | u32; // Essentially signed, int + u8 | s32; // Essentially signed, int + s32 | u8; // Essentially signed, int + u8 | s8; // Essentially signed, int + s8 | u8; // Essentially signed, int + + u32 ^ s32; // Essentially signed, int + s32 ^ u32; // Essentially signed, int + u8 ^ s32; // Essentially signed, int + s32 ^ u8; // Essentially signed, int + u8 ^ s8; // Essentially signed, int + s8 ^ u8; // Essentially signed, int } \ No newline at end of file From a5ed461557c57b44df2f6a420e6ecc1bd89cbed2 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 27 Oct 2024 15:28:27 +0000 Subject: [PATCH 27/49] EssentialTypes: Add test cases for shifts --- c/misra/test/c/misra/EssentialTypes.expected | 73 ++++++++++++++++++++ c/misra/test/c/misra/test.c | 38 ++++++++++ 2 files changed, 111 insertions(+) diff --git a/c/misra/test/c/misra/EssentialTypes.expected b/c/misra/test/c/misra/EssentialTypes.expected index 19a7090fe9..95976fe2ab 100644 --- a/c/misra/test/c/misra/EssentialTypes.expected +++ b/c/misra/test/c/misra/EssentialTypes.expected @@ -365,3 +365,76 @@ | test.c:161:3:161:9 | ... ^ ... | int | int | essentially Signed type | | test.c:161:8:161:9 | (int)... | int | int | essentially Signed type | | test.c:161:8:161:9 | u8 | uint8_t | uint8_t | essentially Unsigned type | +| test.c:165:16:165:17 | 1 | signed char | signed char | essentially Signed type | +| test.c:170:3:170:4 | 1 | unsigned char | unsigned char | essentially Unsigned type | +| test.c:170:3:170:9 | ... << ... | unsigned char | unsigned char | essentially Unsigned type | +| test.c:170:9:170:9 | 1 | signed char | signed char | essentially Signed type | +| test.c:171:3:171:6 | 256 | unsigned short | unsigned short | essentially Unsigned type | +| test.c:171:3:171:11 | ... << ... | unsigned short | unsigned short | essentially Unsigned type | +| test.c:171:11:171:11 | 1 | signed char | signed char | essentially Signed type | +| test.c:172:3:172:8 | 65536 | unsigned int | unsigned int | essentially Unsigned type | +| test.c:172:3:172:13 | ... << ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:172:13:172:13 | 1 | signed char | signed char | essentially Signed type | +| test.c:173:3:173:4 | 2 | unsigned char | unsigned char | essentially Unsigned type | +| test.c:173:3:173:9 | ... >> ... | unsigned char | unsigned char | essentially Unsigned type | +| test.c:173:9:173:9 | 1 | signed char | signed char | essentially Signed type | +| test.c:174:3:174:8 | 32768 | unsigned short | unsigned short | essentially Unsigned type | +| test.c:174:3:174:13 | ... >> ... | unsigned short | unsigned short | essentially Unsigned type | +| test.c:174:13:174:13 | 1 | signed char | signed char | essentially Signed type | +| test.c:175:3:175:13 | 2147483648 | unsigned int | unsigned int | essentially Unsigned type | +| test.c:175:3:175:18 | ... >> ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:175:18:175:18 | 1 | signed char | signed char | essentially Signed type | +| test.c:176:3:176:14 | 4294967295 | unsigned long | unsigned long | essentially Unsigned type | +| test.c:176:3:176:19 | ... << ... | unsigned long | unsigned long | essentially Unsigned type | +| test.c:176:3:176:19 | ... << ... | unsigned long | unsigned long long | essentially Unsigned type | +| test.c:176:3:176:19 | ... << ... | unsigned long long | unsigned long | essentially Unsigned type | +| test.c:176:3:176:19 | ... << ... | unsigned long long | unsigned long long | essentially Unsigned type | +| test.c:176:19:176:19 | 1 | signed char | signed char | essentially Signed type | +| test.c:181:3:181:6 | 256 | unsigned short | unsigned short | essentially Unsigned type | +| test.c:181:3:181:11 | ... >> ... | unsigned char | unsigned char | essentially Unsigned type | +| test.c:181:11:181:11 | 1 | signed char | signed char | essentially Signed type | +| test.c:182:3:182:8 | 65536 | unsigned int | unsigned int | essentially Unsigned type | +| test.c:182:3:182:13 | ... >> ... | unsigned short | unsigned short | essentially Unsigned type | +| test.c:182:13:182:13 | 1 | signed char | signed char | essentially Signed type | +| test.c:183:3:183:13 | 4294967296 | unsigned long | unsigned long | essentially Unsigned type | +| test.c:183:3:183:18 | ... >> ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:183:18:183:18 | 1 | signed char | signed char | essentially Signed type | +| test.c:184:3:184:6 | 255 | unsigned char | unsigned char | essentially Unsigned type | +| test.c:184:3:184:11 | ... << ... | unsigned short | unsigned short | essentially Unsigned type | +| test.c:184:11:184:11 | 1 | signed char | signed char | essentially Signed type | +| test.c:185:3:185:8 | 65535 | unsigned short | unsigned short | essentially Unsigned type | +| test.c:185:3:185:13 | ... << ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:185:13:185:13 | 1 | signed char | signed char | essentially Signed type | +| test.c:189:3:189:6 | 255 | unsigned char | unsigned char | essentially Unsigned type | +| test.c:189:3:189:13 | ... >> ... | unsigned char | unsigned char | essentially Unsigned type | +| test.c:189:11:189:13 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:190:3:190:8 | 65535 | unsigned short | unsigned short | essentially Unsigned type | +| test.c:190:3:190:15 | ... >> ... | unsigned short | unsigned short | essentially Unsigned type | +| test.c:190:13:190:15 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:191:3:191:13 | 4294967295 | unsigned int | unsigned int | essentially Unsigned type | +| test.c:191:3:191:20 | ... >> ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:191:18:191:20 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:192:3:192:6 | 255 | unsigned char | unsigned char | essentially Unsigned type | +| test.c:192:3:192:13 | ... << ... | unsigned char | unsigned char | essentially Unsigned type | +| test.c:192:11:192:13 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:193:3:193:8 | 65535 | unsigned short | unsigned short | essentially Unsigned type | +| test.c:193:3:193:15 | ... << ... | unsigned short | unsigned short | essentially Unsigned type | +| test.c:193:13:193:15 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:194:3:194:13 | 4294967295 | unsigned int | unsigned int | essentially Unsigned type | +| test.c:194:3:194:20 | ... << ... | unsigned int | unsigned int | essentially Unsigned type | +| test.c:194:18:194:20 | s32 | int32_t | int32_t | essentially Signed type | +| test.c:197:3:197:5 | 257 | short | short | essentially Signed type | +| test.c:197:3:197:5 | 257 | short | signed short | essentially Signed type | +| test.c:197:3:197:5 | 257 | signed short | short | essentially Signed type | +| test.c:197:3:197:5 | 257 | signed short | signed short | essentially Signed type | +| test.c:197:3:197:10 | ... >> ... | int | int | essentially Signed type | +| test.c:197:10:197:10 | 1 | signed char | signed char | essentially Signed type | +| test.c:198:3:198:7 | 65537 | int | int | essentially Signed type | +| test.c:198:3:198:7 | 65537 | int | signed int | essentially Signed type | +| test.c:198:3:198:7 | 65537 | signed int | int | essentially Signed type | +| test.c:198:3:198:7 | 65537 | signed int | signed int | essentially Signed type | +| test.c:198:3:198:12 | ... >> ... | int | int | essentially Signed type | +| test.c:198:12:198:12 | 1 | signed char | signed char | essentially Signed type | +| test.c:199:3:199:12 | 4294967297 | long | long | essentially Signed type | +| test.c:199:3:199:17 | ... >> ... | long | long | essentially Signed type | +| test.c:199:17:199:17 | 1 | signed char | signed char | essentially Signed type | diff --git a/c/misra/test/c/misra/test.c b/c/misra/test/c/misra/test.c index dcdfef4eb4..e271a67e30 100644 --- a/c/misra/test/c/misra/test.c +++ b/c/misra/test/c/misra/test.c @@ -159,4 +159,42 @@ void testBitwise() { s32 ^ u8; // Essentially signed, int u8 ^ s8; // Essentially signed, int s8 ^ u8; // Essentially signed, int +} + +void testShifts() { + int32_t s32 = 1; + + // Left hand is unsigned and both are constants, so UTLR + // In these cases the UTLR is the same as the essential type of + // the left operand + 1U << 1; // Essentially unsigned char + 256U << 1; // Essentially unsigned short + 65536U << 1; // Essentially unsigned int + 2U >> 1; // Essentially unsigned char + 32768U >> 1; // Essentially unsigned short - 2^15 >> 1 = 2^14 + 2147483648U >> 1; // Essentially unsigned int - 2^31 >> 1 = 2^30 + 4294967295LU << 1; // Essentially unsigned long + + // Left hand is unsigned and both are constants, so UTLR + // In these cases the UTLR is not the same as the essential type of + // the left operand + 256U >> 1; // Essentially unsigned char + 65536U >> 1; // Essentially unsigned short + 4294967296U >> 1; // Essentially unsigned int + 255U << 1; // Essentially unsigned short + 65535U << 1; // Essentially unsigned int + + // Left hand is unsigned, but left isn't a constant, so essential type of left + // operand + 255U >> s32; // Essentially unsigned char + 65535U >> s32; // Essentially unsigned short + 4294967295U >> s32; // Essentially unsigned int + 255U << s32; // Essentially unsigned char + 65535U << s32; // Essentially unsigned short + 4294967295U << s32; // Essentially unsigned int + + // Left hand operand signed int, so result is standard type + 257 >> 1; // Essentially signed int + 65537 >> 1; // Essentially signed int + 4294967297 >> 1; // Essentially signed long } \ No newline at end of file From aba9528b7341251ee35555a32be7e04f5cfa226d Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 27 Oct 2024 15:41:21 +0000 Subject: [PATCH 28/49] RULE-10-3: Expand test cases for binary bitwise operators --- ...gnmentOfIncompatibleEssentialType.expected | 6 +++++ c/misra/test/rules/RULE-10-3/test.c | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/c/misra/test/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.expected b/c/misra/test/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.expected index 3867abd0ca..b64f970bfe 100644 --- a/c/misra/test/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.expected +++ b/c/misra/test/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.expected @@ -131,3 +131,9 @@ | test.c:356:10:356:11 | e1 | Assignment of essentially Enum Type value to an object of essentially Floating type. | | test.c:357:10:357:10 | s | Assignment of essentially Signed type value to an object of essentially Floating type. | | test.c:358:10:358:10 | u | Assignment of essentially Unsigned type value to an object of essentially Floating type. | +| test.c:369:12:369:20 | ... & ... | Assignment of essentially Unsigned type value to an object of essentially Signed type. | +| test.c:370:12:370:20 | ... \| ... | Assignment of essentially Unsigned type value to an object of essentially Signed type. | +| test.c:371:12:371:20 | ... ^ ... | Assignment of essentially Unsigned type value to an object of essentially Signed type. | +| test.c:376:20:376:27 | ... & ... | Assignment of value of essentially Signed type of size 2 bytes to an object narrower essential type of size 1 bytes. | +| test.c:381:23:381:30 | ... & ... | Assignment of value of essentially Unsigned type of size 2 bytes to an object narrower essential type of size 1 bytes. | +| test.c:384:22:384:29 | ... & ... | Assignment of essentially Signed type value to an object of essentially Unsigned type. | diff --git a/c/misra/test/rules/RULE-10-3/test.c b/c/misra/test/rules/RULE-10-3/test.c index 30ab2985ae..f4ad487ae1 100644 --- a/c/misra/test/rules/RULE-10-3/test.c +++ b/c/misra/test/rules/RULE-10-3/test.c @@ -357,4 +357,29 @@ void testStructAssignment() { s1.f = s; // NON_COMPLIANT s1.f = u; // NON_COMPLIANT s1.f = f; // COMPLIANT +} + +void testBinaryBitwise() { + signed int s32 = 100; // COMPLIANT - wider + signed short s16 = 0; // COMPLIANT - wider + signed char s8 = 0; // COMPLIANT - wider + unsigned int u32 = 100; // COMPLIANT - by exception 1 + unsigned char u8 = 0; // COMPLIANT - by exception 1 + unsigned short u16 = 0; // COMPLIANT - by exception 1 + int x1 = s32 & u32; // NON_COMPLIANT - integer promotion to u32 + int x2 = s32 | u32; // NON_COMPLIANT - integer promotion to u32 + int x3 = s32 ^ u32; // NON_COMPLIANT - integer promotion to u32 + int x4 = s16 & s32; // COMPLIANT + int x5 = s16 & u16; // COMPLIANT + int x6 = s16 & s8; // COMPLIANT + signed short x7 = s16 & s8; // COMPLIANT + signed char x8 = s16 & s8; // NON_COMPLIANT + signed char x9 = s8 & s8; // COMPLIANT + signed short x10 = s8 & s8; // COMPLIANT + unsigned int x11 = u16 & u8; // COMPLIANT + unsigned short x12 = u16 & u8; // COMPLIANT + unsigned char x13 = u16 & u8; // NON_COMPLIANT + unsigned char x14 = u8 & u8; // COMPLIANT + unsigned short x15 = u8 & u8; // COMPLIANT + unsigned int x16 = s16 & s8; // NON_COMPLIANT } \ No newline at end of file From 5b753e0cbde1f57b22909fc05922e2c61ab032df Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 28 Oct 2024 08:47:04 -0700 Subject: [PATCH 29/49] Add change note --- change_notes/2024-10-28-essential-types-bitwise.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 change_notes/2024-10-28-essential-types-bitwise.md diff --git a/change_notes/2024-10-28-essential-types-bitwise.md b/change_notes/2024-10-28-essential-types-bitwise.md new file mode 100644 index 0000000000..a382290351 --- /dev/null +++ b/change_notes/2024-10-28-essential-types-bitwise.md @@ -0,0 +1,2 @@ + - `RULE-10-1`, `RULE-10-3`, `RULE-10-4`, `RULE-10-5`, `RULE-10-6`, `RULE-10-7`, `RULE-10-8`, `RULE-12-2` - `OperandsOfAnInappropriateEssentialType.ql`, `AssignmentOfIncompatibleEssentialType.ql`, `OperandsWithMismatchedEssentialTypeCategory.ql`, `InappropriateEssentialTypeCast.ql`, `AssignmentToWiderEssentialType,ql`, `ImplicitConversionOfCompositeExpression.ql`, `InappropriateCastOfCompositeExpression.ql`: + - False positives and false negatives removed due to fixing incorrect essential type of the binary bitwise operations `^`, `|` and `&`. Previously the standard type was used, instead of applying the essential type rules which dictate that if both arguments have the same signedness, the essential type will have the same signedness and a rank equal to the larger of the two operands. \ No newline at end of file From 3342bb525e410e4c8d2b4232e73a5c3f06b00659 Mon Sep 17 00:00:00 2001 From: "rakesh.pothengil" Date: Tue, 17 Dec 2024 16:07:55 +0900 Subject: [PATCH 30/49] Fixes #824 --- change_notes/2024-12-17-fix-fp-824-a15-4-4 | 2 ++ cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 change_notes/2024-12-17-fix-fp-824-a15-4-4 diff --git a/change_notes/2024-12-17-fix-fp-824-a15-4-4 b/change_notes/2024-12-17-fix-fp-824-a15-4-4 new file mode 100644 index 0000000000..0908c14ffa --- /dev/null +++ b/change_notes/2024-12-17-fix-fp-824-a15-4-4 @@ -0,0 +1,2 @@ + - `A15-4-4` - `MissingNoExcept.ql`: + - Reduce false positives by not reporting on functions that have a noexcept specification with a complex expression. diff --git a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql index 7701a8a1ea..2721b42af3 100644 --- a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql +++ b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql @@ -28,6 +28,9 @@ where not isNoExceptTrue(f) and // Not explicitly marked noexcept(false) not isNoExceptExplicitlyFalse(f) and + // Not having a noexcept specification that + // could not be computed as true or false above. + not exists(f.getADeclarationEntry().getNoExceptExpr()) and // Not compiler generated not f.isCompilerGenerated() and // The function is defined in this database From 23ddafa76ec60d06ef5f339062647f41cfb436ef Mon Sep 17 00:00:00 2001 From: "rakesh.pothengil" Date: Wed, 18 Dec 2024 11:13:46 +0900 Subject: [PATCH 31/49] Fix #540 --- change_notes/2024-12-18-fix-fp-540-a3-9-1.md | 2 ++ .../rules/A3-9-1/VariableWidthIntegerTypesUsed.ql | 4 ++++ cpp/autosar/test/rules/A3-9-1/test.cpp | 13 ++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 change_notes/2024-12-18-fix-fp-540-a3-9-1.md diff --git a/change_notes/2024-12-18-fix-fp-540-a3-9-1.md b/change_notes/2024-12-18-fix-fp-540-a3-9-1.md new file mode 100644 index 0000000000..fbd09ca840 --- /dev/null +++ b/change_notes/2024-12-18-fix-fp-540-a3-9-1.md @@ -0,0 +1,2 @@ + - `A3-9-1` - `VariableWidthIntegerTypesUsed.ql`: + - Reduce false positives by not considering variables from template instantiations. diff --git a/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql b/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql index 84a38b0f6a..fa19ad998f 100644 --- a/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql +++ b/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql @@ -32,6 +32,10 @@ where typeStrippedOfSpecifiers instanceof SignedCharType ) and not v instanceof ExcludedVariable and + // Dont consider template instantiations because instantiations with + // Fixed Width Types are recorded after stripping their typedef'd type, + // thereby, causing false positives (#540). + not v.isFromTemplateInstantiation(_) and //post-increment/post-decrement operators are required by the standard to have a dummy int parameter not v.(Parameter).getFunction() instanceof PostIncrementOperator and not v.(Parameter).getFunction() instanceof PostDecrementOperator diff --git a/cpp/autosar/test/rules/A3-9-1/test.cpp b/cpp/autosar/test/rules/A3-9-1/test.cpp index 882738eea1..7ffb87ca39 100644 --- a/cpp/autosar/test/rules/A3-9-1/test.cpp +++ b/cpp/autosar/test/rules/A3-9-1/test.cpp @@ -75,4 +75,15 @@ void test_variable_width_type_qualified_variables() { struct test_fix_fp_614 { test_fix_fp_614 operator++(int); // COMPLIANT test_fix_fp_614 operator--(int); // COMPLIANT -}; \ No newline at end of file +}; + +// COMPLIANT - instantiated with Fixed Width Types. +template constexpr void test_fix_fp_540(MyType value) { + value++; +} + +int call_test_fix_fp_540() { + test_fix_fp_540(19); + test_fix_fp_540(20); + return 0; +} From f5394d0b1ef8bad2b32ef07298eebb7803a902b6 Mon Sep 17 00:00:00 2001 From: "rakesh.pothengil" Date: Thu, 19 Dec 2024 11:17:11 +0900 Subject: [PATCH 32/49] Check called functions with noexcept(unknown) --- change_notes/2024-12-17-fix-fp-824-a15-4-4 | 2 +- .../src/rules/A15-4-4/MissingNoExcept.ql | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/change_notes/2024-12-17-fix-fp-824-a15-4-4 b/change_notes/2024-12-17-fix-fp-824-a15-4-4 index 0908c14ffa..89ccf49815 100644 --- a/change_notes/2024-12-17-fix-fp-824-a15-4-4 +++ b/change_notes/2024-12-17-fix-fp-824-a15-4-4 @@ -1,2 +1,2 @@ - `A15-4-4` - `MissingNoExcept.ql`: - - Reduce false positives by not reporting on functions that have a noexcept specification with a complex expression. + - Reduce false positives by not reporting on functions that have a noexcept specification with a complex expression or call other such functions. diff --git a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql index 2721b42af3..33369e00a4 100644 --- a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql +++ b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql @@ -19,6 +19,36 @@ import codingstandards.cpp.autosar import codingstandards.cpp.exceptions.ExceptionSpecifications import codingstandards.cpp.exceptions.ExceptionFlow +// These functions have a noexcept specification that could not be resolved +// to noexcept(true). So either, they are noexcept(false) functions which +// means, they can throw an exception OR they have an expression which +// could not be resolved to "true" or "false". Even in this case, lets +// be more conservative and assume they may thrown an exception. +class FunctionWithUnknownNoExcept extends Function { + FunctionWithUnknownNoExcept() { + // Exists a noexcept specification but not noexcept(true) + exists(this.getADeclarationEntry().getNoExceptExpr()) and + not isNoExceptTrue(this) + } +} + +// This predicate checks if a function can call to other functions +// that may have a noexcept specification which cannot be resolved to +// noexcept(true). +predicate mayCallThrowingFunctions(Function f) { + // Exists a call in this function + exists(Call fc | + fc.getEnclosingFunction() = f and + ( + // Either this call is to a function with an unknown noexcept OR + fc.getTarget() instanceof FunctionWithUnknownNoExcept + or + // That function can further have calls to unknown noexcept functions. + mayCallThrowingFunctions(fc.getTarget()) + ) + ) +} + from Function f where not isExcluded(f, Exceptions1Package::missingNoExceptQuery()) and @@ -31,6 +61,9 @@ where // Not having a noexcept specification that // could not be computed as true or false above. not exists(f.getADeclarationEntry().getNoExceptExpr()) and + // Not calling function(s) which have a noexcept specification that + // could not be computed as true. + not mayCallThrowingFunctions(f) and // Not compiler generated not f.isCompilerGenerated() and // The function is defined in this database From 81ff0c08005b59e4b2bcd87c97b30da738e4e435 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Fri, 27 Dec 2024 23:38:55 +0000 Subject: [PATCH 33/49] Skip external help integration from forks PRs from forks do not have access to the help repo. --- .github/workflows/code-scanning-pack-gen.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/code-scanning-pack-gen.yml b/.github/workflows/code-scanning-pack-gen.yml index 1b620260c3..51ffb1edb7 100644 --- a/.github/workflows/code-scanning-pack-gen.yml +++ b/.github/workflows/code-scanning-pack-gen.yml @@ -80,6 +80,8 @@ jobs: - name: Checkout external help files id: checkout-external-help-files + # Forks do not have access to an appropriate token for the help files + if: !github.event.pull_request.head.repo.fork uses: actions/checkout@v4 with: ssh-key: ${{ secrets.CODEQL_CODING_STANDARDS_HELP_KEY }} @@ -88,7 +90,7 @@ jobs: path: external-help-files - name: Include external help files - if: steps.checkout-external-help-files.outcome == 'success' + if: !github.event.pull_request.head.repo.fork && steps.checkout-external-help-files.outcome == 'success' run: | pushd external-help-files find . -name '*.md' -exec rsync -av --relative {} "$GITHUB_WORKSPACE" \; From 6b8ba85dea62ff4ebac192b15db278e51cb431c0 Mon Sep 17 00:00:00 2001 From: Luke Cartey <5377966+lcartey@users.noreply.github.com> Date: Sun, 5 Jan 2025 23:05:14 +0000 Subject: [PATCH 34/49] Update rules.csv Use Contracts8 as next entry --- rules.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules.csv b/rules.csv index 8391149b9f..a7f6c1f0db 100644 --- a/rules.csv +++ b/rules.csv @@ -615,7 +615,7 @@ c,MISRA-C-2012,DIR-4-10,Yes,Required,,,Precautions shall be taken in order to pr c,MISRA-C-2012,DIR-4-11,Yes,Required,,,The validity of values passed to library functions shall be checked,,Contracts,Hard, c,MISRA-C-2012,DIR-4-12,Yes,Required,,,Dynamic memory allocation shall not be used,,Banned,Medium, c,MISRA-C-2012,DIR-4-13,No,Advisory,,,Functions which are designed to provide operations on a resource should be called in an appropriate sequence,,,,"Rule 22.1, 22.2 and 22.6 cover aspects of this rule. In other cases this is a design issue and needs to be checked manually." -c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts9,Hard,This is supported by CodeQLs default C security queries. +c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts8,Hard,This is supported by CodeQLs default C security queries. c,MISRA-C-2012,RULE-1-1,No,Required,,,"The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits",,,Easy,"This should be checked via the compiler output, rather than CodeQL, which adds unnecessary steps." c,MISRA-C-2012,RULE-1-2,Yes,Advisory,,,Language extensions should not be used,,Language3,Hard, c,MISRA-C-2012,RULE-1-3,Yes,Required,,,There shall be no occurrence of undefined or critical unspecified behaviour,,Language3,Hard, From 6f595af4c404c3d77e6eea7f7f0568ecb4d5c189 Mon Sep 17 00:00:00 2001 From: Luke Cartey <5377966+lcartey@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:21:17 +0000 Subject: [PATCH 35/49] Exclude Dependabot PRs from help checkout Dependabot does not have access to the external help repo. --- .github/workflows/code-scanning-pack-gen.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-scanning-pack-gen.yml b/.github/workflows/code-scanning-pack-gen.yml index 51ffb1edb7..b67db3d413 100644 --- a/.github/workflows/code-scanning-pack-gen.yml +++ b/.github/workflows/code-scanning-pack-gen.yml @@ -81,7 +81,7 @@ jobs: - name: Checkout external help files id: checkout-external-help-files # Forks do not have access to an appropriate token for the help files - if: !github.event.pull_request.head.repo.fork + if: !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' uses: actions/checkout@v4 with: ssh-key: ${{ secrets.CODEQL_CODING_STANDARDS_HELP_KEY }} @@ -90,7 +90,7 @@ jobs: path: external-help-files - name: Include external help files - if: !github.event.pull_request.head.repo.fork && steps.checkout-external-help-files.outcome == 'success' + if: !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]'&& steps.checkout-external-help-files.outcome == 'success' run: | pushd external-help-files find . -name '*.md' -exec rsync -av --relative {} "$GITHUB_WORKSPACE" \; From b817d0cde9701c3d2b1e343a9eb37ab224f6aff7 Mon Sep 17 00:00:00 2001 From: Luke Cartey <5377966+lcartey@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:17:03 +0000 Subject: [PATCH 36/49] Improve comment Explain why we exclude dependabot PRs. --- .github/workflows/code-scanning-pack-gen.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-scanning-pack-gen.yml b/.github/workflows/code-scanning-pack-gen.yml index b67db3d413..85a157d8b6 100644 --- a/.github/workflows/code-scanning-pack-gen.yml +++ b/.github/workflows/code-scanning-pack-gen.yml @@ -80,7 +80,7 @@ jobs: - name: Checkout external help files id: checkout-external-help-files - # Forks do not have access to an appropriate token for the help files + # PRs from forks and dependabot do not have access to an appropriate token for cloning the help files repos if: !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' uses: actions/checkout@v4 with: From b952fc8595c121804533c184eeeed739d138c09e Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 6 Jan 2025 23:27:04 +0000 Subject: [PATCH 37/49] Use expression syntax --- .github/workflows/code-scanning-pack-gen.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-scanning-pack-gen.yml b/.github/workflows/code-scanning-pack-gen.yml index 85a157d8b6..678b3be403 100644 --- a/.github/workflows/code-scanning-pack-gen.yml +++ b/.github/workflows/code-scanning-pack-gen.yml @@ -81,7 +81,7 @@ jobs: - name: Checkout external help files id: checkout-external-help-files # PRs from forks and dependabot do not have access to an appropriate token for cloning the help files repos - if: !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} uses: actions/checkout@v4 with: ssh-key: ${{ secrets.CODEQL_CODING_STANDARDS_HELP_KEY }} @@ -90,7 +90,7 @@ jobs: path: external-help-files - name: Include external help files - if: !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]'&& steps.checkout-external-help-files.outcome == 'success' + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]'&& steps.checkout-external-help-files.outcome == 'success' }} run: | pushd external-help-files find . -name '*.md' -exec rsync -av --relative {} "$GITHUB_WORKSPACE" \; From 99a310642c211ff13204cbbe624ea999b6d545a0 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 22:08:19 +0000 Subject: [PATCH 38/49] Contracts: Add MISRA C 2012 tags --- rule_packages/c/Contracts.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rule_packages/c/Contracts.json b/rule_packages/c/Contracts.json index 735e84d9da..40bf3d8b0b 100644 --- a/rule_packages/c/Contracts.json +++ b/rule_packages/c/Contracts.json @@ -38,7 +38,8 @@ "short_name": "CheckMathLibraryFunctionParameters", "shared_implementation_short_name": "UncheckedRangeDomainPoleErrors", "tags": [ - "correctness" + "correctness", + "external/misra/c/2012/third-edition-first-revision" ], "implementation_scope": { "description": "This query identifies possible domain, pole and range errors on a selection of C standard library fuctions from math.h." @@ -61,7 +62,8 @@ "short_name": "FunctionErrorInformationUntested", "shared_implementation_short_name": "FunctionErroneousReturnValueNotTested", "tags": [ - "maintainability" + "maintainability", + "external/misra/c/2012/third-edition-first-revision" ], "implementation_scope": { "description": "This query enforces checking on some C standard library functions that may return error codes." From 82440695528fce9e12846cb92298572cd7aa1fdd Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 22:15:43 +0000 Subject: [PATCH 39/49] Regenerate package files --- c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql | 1 + c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql | 1 + 2 files changed, 2 insertions(+) diff --git a/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql b/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql index 6810784a0e..4011b210f8 100644 --- a/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql +++ b/c/misra/src/rules/DIR-4-11/CheckMathLibraryFunctionParameters.ql @@ -8,6 +8,7 @@ * @problem.severity error * @tags external/misra/id/dir-4-11 * correctness + * external/misra/c/2012/third-edition-first-revision * external/misra/obligation/required */ diff --git a/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql b/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql index 63236d422d..0c0a3d7b1a 100644 --- a/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql +++ b/c/misra/src/rules/DIR-4-7/FunctionErrorInformationUntested.ql @@ -12,6 +12,7 @@ * @problem.severity recommendation * @tags external/misra/id/dir-4-7 * maintainability + * external/misra/c/2012/third-edition-first-revision * external/misra/obligation/required */ From 37ac088223e3cab5e000fb36103d4fa70056e84a Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 23:03:53 +0000 Subject: [PATCH 40/49] EssentialType: Merge binary operation implementations EssentialBinaryArithmeticOperation and EssentialBinaryBitwiseOperation only differ in their handling of + and - operations, so combine the two implementations to reduce duplication. In addition, change the characteristic predicate to an allow list. This ensures we only capture the intended binary operations, and exclude any others. --- .../c/misra/EssentialTypes.qll | 71 ++++++------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 4dbe8dbb34..57250d42c5 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -286,11 +286,26 @@ class EssentialConditionalExpr extends EssentialExpr, ConditionalExpr { } } -class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOperation { - EssentialBinaryArithmeticExpr() { - // GNU C extension has min/max which we can ignore - not this instanceof MinExpr and - not this instanceof MaxExpr +/** + * A binary operation subject to usual conversions, with essential type behaviour as specified by D.7.9. + */ +class EssentialBinaryOperationSubjectToUsualConversions extends EssentialExpr, BinaryOperation { + EssentialBinaryOperationSubjectToUsualConversions() { + this instanceof MulExpr + or + this instanceof DivExpr + or + this instanceof RemExpr + or + this instanceof AddExpr + or + this instanceof SubExpr + or + this instanceof BitwiseAndExpr + or + this instanceof BitwiseOrExpr + or + this instanceof BitwiseXorExpr } override Type getEssentialType() { @@ -353,51 +368,7 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera } } -class EssentialBinaryBitwiseExpr extends EssentialExpr, BinaryBitwiseOperation { - EssentialBinaryBitwiseExpr() { - not this instanceof LShiftExpr and - not this instanceof RShiftExpr - } - - override Type getEssentialType() { - exists( - Type leftEssentialType, Type rightEssentialType, - EssentialTypeCategory leftEssentialTypeCategory, - EssentialTypeCategory rightEssentialTypeCategory - | - leftEssentialType = getEssentialType(getLeftOperand()) and - rightEssentialType = getEssentialType(getRightOperand()) and - leftEssentialTypeCategory = getEssentialTypeCategory(leftEssentialType) and - rightEssentialTypeCategory = getEssentialTypeCategory(rightEssentialType) - | - if - leftEssentialTypeCategory = EssentiallySignedType() and - rightEssentialTypeCategory = EssentiallySignedType() - then - if exists(getValue()) - then result = stlr(this) - else ( - if leftEssentialType.getSize() > rightEssentialType.getSize() - then result = leftEssentialType - else result = rightEssentialType - ) - else - if - leftEssentialTypeCategory = EssentiallyUnsignedType() and - rightEssentialTypeCategory = EssentiallyUnsignedType() - then - if exists(getValue()) - then result = utlr(this) - else ( - if leftEssentialType.getSize() > rightEssentialType.getSize() - then result = leftEssentialType - else result = rightEssentialType - ) - else result = this.getStandardType() - ) - } -} - +// } /** * A named Enum type, as per D.5. */ From 9dc3f1894b3b853c7c8459cc25715698d06eaff2 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 23:19:27 +0000 Subject: [PATCH 41/49] EssentialType: extract Add/Sub expressions Extract out add/sub expressions special behaviour to improve clarity. This commit also simplifies the add case by avoiding referring to left/right explicitly. --- .../c/misra/EssentialTypes.qll | 66 ++++++++++++------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 57250d42c5..2852f5d842 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -342,28 +342,50 @@ class EssentialBinaryOperationSubjectToUsualConversions extends EssentialExpr, B then result = leftEssentialType else result = rightEssentialType ) - else - if - this instanceof AddExpr and - ( - leftEssentialTypeCategory = EssentiallyCharacterType() - or - rightEssentialTypeCategory = EssentiallyCharacterType() - ) and - ( - leftEssentialTypeCategory = - [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] - or - rightEssentialTypeCategory = - [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] - ) - or - this instanceof SubExpr and - leftEssentialTypeCategory = EssentiallyCharacterType() and - rightEssentialTypeCategory = - [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] - then result instanceof PlainCharType - else result = this.getStandardType() + else result = this.getStandardType() + ) + } +} + +/** + * An add expression, with essential type behaviour as specified by D.7.9. + */ +class EssentialAddExpr extends EssentialBinaryOperationSubjectToUsualConversions, AddExpr { + override Type getEssentialType() { + exists( + EssentialTypeCategory operandTypeCategory, EssentialTypeCategory otherOperandTypeCategory + | + operandTypeCategory = getEssentialTypeCategory(getEssentialType(getAnOperand())) and + otherOperandTypeCategory = getEssentialTypeCategory(getEssentialType(getAnOperand())) + | + if + operandTypeCategory = EssentiallyCharacterType() and + otherOperandTypeCategory = + [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] + then result instanceof PlainCharType + else result = super.getEssentialType() + ) + } +} + +/** + * A sub expression, with essential type behaviour as specified by D.7.9. + */ +class EssentialSubExpr extends EssentialBinaryOperationSubjectToUsualConversions, SubExpr { + override Type getEssentialType() { + exists( + EssentialTypeCategory leftEssentialTypeCategory, + EssentialTypeCategory rightEssentialTypeCategory + | + leftEssentialTypeCategory = getEssentialTypeCategory(getEssentialType(getLeftOperand())) and + rightEssentialTypeCategory = getEssentialTypeCategory(getEssentialType(getRightOperand())) + | + if + leftEssentialTypeCategory = EssentiallyCharacterType() and + rightEssentialTypeCategory = + [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] + then result instanceof PlainCharType + else result = super.getEssentialType() ) } } From 29420e93e0f286a6cafe06a6ef44989c2e517676 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 23:33:13 +0000 Subject: [PATCH 42/49] EssentialType: Combine binary cases Reduce repitition through combining cases. --- .../c/misra/EssentialTypes.qll | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 2852f5d842..633660b952 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -320,29 +320,21 @@ class EssentialBinaryOperationSubjectToUsualConversions extends EssentialExpr, B rightEssentialTypeCategory = getEssentialTypeCategory(rightEssentialType) | if - leftEssentialTypeCategory = EssentiallySignedType() and - rightEssentialTypeCategory = EssentiallySignedType() + leftEssentialTypeCategory = rightEssentialTypeCategory and + leftEssentialTypeCategory = + [EssentiallyUnsignedType(), EssentiallySignedType().(TEssentialTypeCategory)] then if exists(getValue()) - then result = stlr(this) - else ( + then ( + leftEssentialTypeCategory = EssentiallySignedType() and result = stlr(this) + or + leftEssentialTypeCategory = EssentiallyUnsignedType() and result = utlr(this) + ) else ( if leftEssentialType.getSize() > rightEssentialType.getSize() then result = leftEssentialType else result = rightEssentialType ) - else - if - leftEssentialTypeCategory = EssentiallyUnsignedType() and - rightEssentialTypeCategory = EssentiallyUnsignedType() - then - if exists(getValue()) - then result = utlr(this) - else ( - if leftEssentialType.getSize() > rightEssentialType.getSize() - then result = leftEssentialType - else result = rightEssentialType - ) - else result = this.getStandardType() + else result = this.getStandardType() ) } } From 62da9c88ba9c6a5acb88f79a94405947f3505a4c Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 23:45:14 +0000 Subject: [PATCH 43/49] EssentialType: Simplify (Signed or Unsigned) --- .../c/misra/EssentialTypes.qll | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 633660b952..555d3d2b2d 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -31,17 +31,19 @@ class EssentialTypeCategory extends TEssentialTypeCategory { } } +class EssentiallySignedOrUnsignedType extends EssentialTypeCategory { + EssentiallySignedOrUnsignedType() { + this = EssentiallySignedType() or this = EssentiallyUnsignedType() + } +} + /** * An expression in the program that evaluates to a compile time constant signed or unsigned integer. */ private class ConstantIntegerExpr extends Expr { pragma[noinline] ConstantIntegerExpr() { - getEssentialTypeCategory(this.getType()) = - [ - EssentiallyUnsignedType().(EssentialTypeCategory), - EssentiallySignedType().(EssentialTypeCategory) - ] and + getEssentialTypeCategory(this.getType()) instanceof EssentiallySignedOrUnsignedType and exists(this.getValue().toFloat()) and not this instanceof Conversion } @@ -235,9 +237,7 @@ class EssentialUnaryPlusExpr extends EssentialExpr, UnaryPlusExpr { operandEssentialType = getEssentialType(getOperand()) and operandEssentialTypeCategory = getEssentialTypeCategory(operandEssentialType) | - if - operandEssentialTypeCategory = - [EssentiallyUnsignedType().(TEssentialTypeCategory), EssentiallySignedType()] + if operandEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType then result = operandEssentialType else result = getStandardType() ) @@ -321,8 +321,7 @@ class EssentialBinaryOperationSubjectToUsualConversions extends EssentialExpr, B | if leftEssentialTypeCategory = rightEssentialTypeCategory and - leftEssentialTypeCategory = - [EssentiallyUnsignedType(), EssentiallySignedType().(TEssentialTypeCategory)] + leftEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType then if exists(getValue()) then ( @@ -352,8 +351,7 @@ class EssentialAddExpr extends EssentialBinaryOperationSubjectToUsualConversions | if operandTypeCategory = EssentiallyCharacterType() and - otherOperandTypeCategory = - [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] + otherOperandTypeCategory instanceof EssentiallySignedOrUnsignedType then result instanceof PlainCharType else result = super.getEssentialType() ) @@ -374,8 +372,7 @@ class EssentialSubExpr extends EssentialBinaryOperationSubjectToUsualConversions | if leftEssentialTypeCategory = EssentiallyCharacterType() and - rightEssentialTypeCategory = - [EssentiallySignedType(), EssentiallyUnsignedType().(TEssentialTypeCategory)] + rightEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType then result instanceof PlainCharType else result = super.getEssentialType() ) From cd8ea6767da83d0783502e826a4c7be6b86bdb05 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 23:48:01 +0000 Subject: [PATCH 44/49] EssentialType: Reduce duplication in conditional calc Avoid repeating code for both the signed and unsigned cases. --- .../src/codingstandards/c/misra/EssentialTypes.qll | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 555d3d2b2d..97a9604f58 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -267,21 +267,13 @@ class EssentialConditionalExpr extends EssentialExpr, ConditionalExpr { then result = thenEssentialType else if - getEssentialTypeCategory(thenEssentialType) = EssentiallySignedType() and - getEssentialTypeCategory(elseEssentialType) = EssentiallySignedType() + getEssentialTypeCategory(thenEssentialType) = getEssentialTypeCategory(elseEssentialType) and + getEssentialTypeCategory(thenEssentialType) instanceof EssentiallySignedOrUnsignedType then if thenEssentialType.getSize() > elseEssentialType.getSize() then result = thenEssentialType else result = elseEssentialType - else - if - getEssentialTypeCategory(thenEssentialType) = EssentiallyUnsignedType() and - getEssentialTypeCategory(elseEssentialType) = EssentiallyUnsignedType() - then - if thenEssentialType.getSize() > elseEssentialType.getSize() - then result = thenEssentialType - else result = elseEssentialType - else result = this.getStandardType() + else result = this.getStandardType() ) } } From 7a465dd340948eb3a6a5a0e6f5b14c068bc601a7 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Sun, 12 Jan 2025 23:52:35 +0000 Subject: [PATCH 45/49] EssentialType: Add maxRank predicate --- .../c/misra/EssentialTypes.qll | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 97a9604f58..0a4e64e98d 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -257,6 +257,13 @@ class EssentialUnaryMinusExpr extends EssentialExpr, UnaryMinusExpr { } } +bindingset[essentialTypeA, essentialTypeB] +private Type maxRankType(Type essentialTypeA, Type essentialTypeB) { + if essentialTypeA.getSize() > essentialTypeB.getSize() + then result = essentialTypeA + else result = essentialTypeB +} + class EssentialConditionalExpr extends EssentialExpr, ConditionalExpr { override Type getEssentialType() { exists(Type thenEssentialType, Type elseEssentialType | @@ -269,10 +276,7 @@ class EssentialConditionalExpr extends EssentialExpr, ConditionalExpr { if getEssentialTypeCategory(thenEssentialType) = getEssentialTypeCategory(elseEssentialType) and getEssentialTypeCategory(thenEssentialType) instanceof EssentiallySignedOrUnsignedType - then - if thenEssentialType.getSize() > elseEssentialType.getSize() - then result = thenEssentialType - else result = elseEssentialType + then result = maxRankType(thenEssentialType, elseEssentialType) else result = this.getStandardType() ) } @@ -316,15 +320,11 @@ class EssentialBinaryOperationSubjectToUsualConversions extends EssentialExpr, B leftEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType then if exists(getValue()) - then ( + then leftEssentialTypeCategory = EssentiallySignedType() and result = stlr(this) or leftEssentialTypeCategory = EssentiallyUnsignedType() and result = utlr(this) - ) else ( - if leftEssentialType.getSize() > rightEssentialType.getSize() - then result = leftEssentialType - else result = rightEssentialType - ) + else result = maxRankType(leftEssentialType, rightEssentialType) else result = this.getStandardType() ) } From 3fd82fd7bf2cb2a61f2c1c476d53806f2e932834 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 13 Jan 2025 00:06:10 +0000 Subject: [PATCH 46/49] EssentialType: Fix test comments --- c/misra/test/c/misra/test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/misra/test/c/misra/test.c b/c/misra/test/c/misra/test.c index e271a67e30..7bcb5d7bad 100644 --- a/c/misra/test/c/misra/test.c +++ b/c/misra/test/c/misra/test.c @@ -139,8 +139,8 @@ void testBitwise() { s32 ^ s16; // Essentially signed, int s16 ^ s32; // Essentially signed, int - u32 & s32; // Essentially signed, int - s32 & u32; // Essentially signed, int + u32 & s32; // Essentially unsigned, int + s32 & u32; // Essentially unsigned, int u8 & s32; // Essentially signed, int s32 & u8; // Essentially signed, int u8 & s8; // Essentially signed, int From 8a070839bb679f5eb7ed57638cfb3ed4ab662485 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 13 Jan 2025 00:11:41 +0000 Subject: [PATCH 47/49] Avoid formatting colisions --- c/misra/test/c/misra/test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/c/misra/test/c/misra/test.c b/c/misra/test/c/misra/test.c index 7bcb5d7bad..36a3eb0b10 100644 --- a/c/misra/test/c/misra/test.c +++ b/c/misra/test/c/misra/test.c @@ -82,8 +82,8 @@ void testControlChar() { } #include - -void testBitwise() { +// clang-format off +void testBitwise() { // Clang format disabled to avoid confusion with variable declarations uint8_t u8 = 0; uint16_t u16 = 0; uint32_t u32 = 0; @@ -160,7 +160,7 @@ void testBitwise() { u8 ^ s8; // Essentially signed, int s8 ^ u8; // Essentially signed, int } - +// clang-format on void testShifts() { int32_t s32 = 1; From 2c2c3fbac9f7efeca6199d9ee626ccc67092e863 Mon Sep 17 00:00:00 2001 From: knewbury01 Date: Tue, 14 Jan 2025 14:59:01 +0000 Subject: [PATCH 48/49] Bump version to 2.41.0-dev --- c/cert/src/qlpack.yml | 2 +- c/cert/test/qlpack.yml | 2 +- c/common/src/qlpack.yml | 2 +- c/common/test/qlpack.yml | 2 +- c/misra/src/qlpack.yml | 2 +- c/misra/test/qlpack.yml | 2 +- cpp/autosar/src/qlpack.yml | 2 +- cpp/autosar/test/qlpack.yml | 2 +- cpp/cert/src/qlpack.yml | 2 +- cpp/cert/test/qlpack.yml | 2 +- cpp/common/src/qlpack.yml | 2 +- cpp/common/test/qlpack.yml | 2 +- cpp/misra/src/qlpack.yml | 2 +- cpp/misra/test/qlpack.yml | 2 +- cpp/report/src/qlpack.yml | 2 +- docs/user_manual.md | 12 ++++++------ 16 files changed, 21 insertions(+), 21 deletions(-) diff --git a/c/cert/src/qlpack.yml b/c/cert/src/qlpack.yml index 2778e44435..4945abe49c 100644 --- a/c/cert/src/qlpack.yml +++ b/c/cert/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cert-c-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev description: CERT C 2016 suites: codeql-suites license: MIT diff --git a/c/cert/test/qlpack.yml b/c/cert/test/qlpack.yml index 461ebe9677..af5e71d2a1 100644 --- a/c/cert/test/qlpack.yml +++ b/c/cert/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cert-c-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/c/common/src/qlpack.yml b/c/common/src/qlpack.yml index f39f3cb1c4..9545a88178 100644 --- a/c/common/src/qlpack.yml +++ b/c/common/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/common-c-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev license: MIT dependencies: codeql/common-cpp-coding-standards: '*' diff --git a/c/common/test/qlpack.yml b/c/common/test/qlpack.yml index d417a17df2..febda7a63b 100644 --- a/c/common/test/qlpack.yml +++ b/c/common/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/common-c-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/c/misra/src/qlpack.yml b/c/misra/src/qlpack.yml index 9aceed1a49..758c059c01 100644 --- a/c/misra/src/qlpack.yml +++ b/c/misra/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/misra-c-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev description: MISRA C 2012 suites: codeql-suites license: MIT diff --git a/c/misra/test/qlpack.yml b/c/misra/test/qlpack.yml index d53bc95f28..d367e8d06d 100644 --- a/c/misra/test/qlpack.yml +++ b/c/misra/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/misra-c-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/cpp/autosar/src/qlpack.yml b/cpp/autosar/src/qlpack.yml index f44ad54c74..565cfc12db 100644 --- a/cpp/autosar/src/qlpack.yml +++ b/cpp/autosar/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/autosar-cpp-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev description: AUTOSAR C++14 Guidelines R22-11, R21-11, R20-11, R19-11 and R19-03 suites: codeql-suites license: MIT diff --git a/cpp/autosar/test/qlpack.yml b/cpp/autosar/test/qlpack.yml index 178d8cc314..66755fe907 100644 --- a/cpp/autosar/test/qlpack.yml +++ b/cpp/autosar/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/autosar-cpp-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/cpp/cert/src/qlpack.yml b/cpp/cert/src/qlpack.yml index 735dd9f5b4..cc981411c2 100644 --- a/cpp/cert/src/qlpack.yml +++ b/cpp/cert/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cert-cpp-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev description: CERT C++ 2016 suites: codeql-suites license: MIT diff --git a/cpp/cert/test/qlpack.yml b/cpp/cert/test/qlpack.yml index 3a6d02e7d4..af6e4f8659 100644 --- a/cpp/cert/test/qlpack.yml +++ b/cpp/cert/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cert-cpp-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/cpp/common/src/qlpack.yml b/cpp/common/src/qlpack.yml index 1ae6dfd997..4d0aeb01f1 100644 --- a/cpp/common/src/qlpack.yml +++ b/cpp/common/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/common-cpp-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev license: MIT dependencies: codeql/cpp-all: 1.4.2 diff --git a/cpp/common/test/qlpack.yml b/cpp/common/test/qlpack.yml index 90236b203e..a6d2ae30eb 100644 --- a/cpp/common/test/qlpack.yml +++ b/cpp/common/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/common-cpp-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/cpp/misra/src/qlpack.yml b/cpp/misra/src/qlpack.yml index 96fc96ce24..a6ac09f1b1 100644 --- a/cpp/misra/src/qlpack.yml +++ b/cpp/misra/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/misra-cpp-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev description: MISRA C++ 2023 default-suite: codeql-suites/misra-cpp-default.qls license: MIT diff --git a/cpp/misra/test/qlpack.yml b/cpp/misra/test/qlpack.yml index 207facda4e..0265144f4f 100644 --- a/cpp/misra/test/qlpack.yml +++ b/cpp/misra/test/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/misra-cpp-coding-standards-tests -version: 2.40.0-dev +version: 2.41.0-dev extractor: cpp license: MIT dependencies: diff --git a/cpp/report/src/qlpack.yml b/cpp/report/src/qlpack.yml index e569153ae8..d1c854206c 100644 --- a/cpp/report/src/qlpack.yml +++ b/cpp/report/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/report-cpp-coding-standards -version: 2.40.0-dev +version: 2.41.0-dev license: MIT dependencies: codeql/cpp-all: 1.4.2 diff --git a/docs/user_manual.md b/docs/user_manual.md index 952a9a3c99..d076759571 100644 --- a/docs/user_manual.md +++ b/docs/user_manual.md @@ -33,14 +33,14 @@ ## Release information -This user manual documents release `2.40.0-dev` of the coding standards located at [https://github.com/github/codeql-coding-standards](https://github.com/github/codeql-coding-standards). +This user manual documents release `2.41.0-dev` of the coding standards located at [https://github.com/github/codeql-coding-standards](https://github.com/github/codeql-coding-standards). The release page documents the release notes and contains the following artifacts part of the release: - `coding-standards-codeql-packs-2.37.0-dev.zip`: CodeQL packs that can be used with GitHub Code Scanning or the CodeQL CLI as documented in the section _Operating manual_. -- `code-scanning-cpp-query-pack-2.40.0-dev.zip`: Legacy packaging for the queries and scripts to be used with GitHub Code Scanning or the CodeQL CLI as documented in the section _Operating manual_. -- `supported_rules_list_2.40.0-dev.csv`: A Comma Separated File (CSV) containing the supported rules per standard and the queries that implement the rule. -- `supported_rules_list_2.40.0-dev.md`: A Markdown formatted file with a table containing the supported rules per standard and the queries that implement the rule. -- `user_manual_2.40.0-dev.md`: This user manual. +- `code-scanning-cpp-query-pack-2.41.0-dev.zip`: Legacy packaging for the queries and scripts to be used with GitHub Code Scanning or the CodeQL CLI as documented in the section _Operating manual_. +- `supported_rules_list_2.41.0-dev.csv`: A Comma Separated File (CSV) containing the supported rules per standard and the queries that implement the rule. +- `supported_rules_list_2.41.0-dev.md`: A Markdown formatted file with a table containing the supported rules per standard and the queries that implement the rule. +- `user_manual_2.41.0-dev.md`: This user manual. - `Source Code (zip)`: A zip archive containing the contents of https://github.com/github/codeql-coding-standards - `Source Code (tar.gz)`: A GZip compressed tar archive containing the contents of https://github.com/github/codeql-coding-standards - `checksums.txt`: A text file containing sha256 checksums for the aforementioned artifacts. @@ -573,7 +573,7 @@ This section describes known failure modes for "CodeQL Coding Standards" and des | | Out of space | Less output. Some files may be only be partially analyzed, or not analyzed at all. | Error reported on the command line. | Increase space. If it remains an issue report space consumption issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). | | | False positives | More output. Results are reported which are not violations of the guidelines. | All reported results must be reviewed. | Report false positive issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). | | | False negatives | Less output. Violations of the guidelines are not reported. | Other validation and verification processes during software development should be used to complement the analysis performed by CodeQL Coding Standards. | Report false negative issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). | -| | Modifying coding standard suite | More or less output. If queries are added to the query set more result can be reported. If queries are removed less results might be reported. | All queries supported by the CodeQL Coding Standards are listed in the release artifacts `supported_rules_list_2.40.0-dev.csv` where VERSION is replaced with the used release. The rules in the resulting Sarif file must be cross-referenced with the expected rules in this list to determine the validity of the used CodeQL suite. | Ensure that the CodeQL Coding Standards are not modified in ways that are not documented as supported modifications. | +| | Modifying coding standard suite | More or less output. If queries are added to the query set more result can be reported. If queries are removed less results might be reported. | All queries supported by the CodeQL Coding Standards are listed in the release artifacts `supported_rules_list_2.41.0-dev.csv` where VERSION is replaced with the used release. The rules in the resulting Sarif file must be cross-referenced with the expected rules in this list to determine the validity of the used CodeQL suite. | Ensure that the CodeQL Coding Standards are not modified in ways that are not documented as supported modifications. | | | Incorrect deviation record specification | More output. Results are reported for guidelines for which a deviation is assigned. | Analysis integrity report lists all deviations and incorrectly specified deviation records with a reason. Ensure that all deviation records are correctly specified. | Ensure that the deviation record is specified according to the specification in the user manual. | | | Incorrect deviation permit specification | More output. Results are reported for guidelines for which a deviation is assigned. | Analysis integrity report lists all deviations and incorrectly specified deviation permits with a reason. Ensure that all deviation permits are correctly specified. | Ensure that the deviation record is specified according to the specification in the user manual. | | | Unapproved use of a deviation record | Less output. Results for guideline violations are not reported. | Validate that the deviation record use is approved by verifying the approved-by attribute of the deviation record specification. | Ensure that each raised deviation record is approved by an independent approver through an auditable process. | From eae738532551f269a1c5cf07f6748c6ed708d6ee Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Thu, 16 Jan 2025 23:02:20 +0000 Subject: [PATCH 49/49] Remove stray comment --- c/misra/src/codingstandards/c/misra/EssentialTypes.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll index 0a4e64e98d..50b588d422 100644 --- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll +++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll @@ -371,7 +371,6 @@ class EssentialSubExpr extends EssentialBinaryOperationSubjectToUsualConversions } } -// } /** * A named Enum type, as per D.5. */