diff --git a/cpp/autosar/src/rules/A9-5-1/UnionKeywordUsedAutosarCpp.ql b/cpp/autosar/src/rules/A9-5-1/UnionKeywordUsedAutosarCpp.ql new file mode 100644 index 0000000000..c530c988d1 --- /dev/null +++ b/cpp/autosar/src/rules/A9-5-1/UnionKeywordUsedAutosarCpp.ql @@ -0,0 +1,25 @@ +/** + * @id cpp/autosar/union-keyword-used-autosar-cpp + * @name A9-5-1: Unions shall not be used + * @description Unions shall not be used. Tagged unions can be used if 'std::variant' is not + * available. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/autosar/id/a9-5-1 + * correctness + * scope/single-translation-unit + * external/autosar/allocated-target/implementation + * external/autosar/enforcement/automated + * external/autosar/obligation/required + */ + +import cpp +import codingstandards.cpp.autosar +import codingstandards.cpp.rules.unionkeywordused.UnionKeywordUsed + +module UnionKeywordUsedAutosarCppConfig implements UnionKeywordUsedConfigSig { + Query getQuery() { result = BannedSyntaxPackage::unionKeywordUsedAutosarCppQuery() } +} + +import UnionKeywordUsed diff --git a/cpp/autosar/src/rules/A9-5-1/UnionsUsed.ql b/cpp/autosar/src/rules/A9-5-1/UnionsUsed.ql deleted file mode 100644 index d44e44dedf..0000000000 --- a/cpp/autosar/src/rules/A9-5-1/UnionsUsed.ql +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @id cpp/autosar/unions-used - * @name A9-5-1: Unions shall not be used - * @description Unions shall not be used. Tagged untions can be used if std::variant is not - * available. - * @kind problem - * @precision very-high - * @problem.severity error - * @tags external/autosar/id/a9-5-1 - * correctness - * scope/single-translation-unit - * external/autosar/allocated-target/implementation - * external/autosar/enforcement/automated - * external/autosar/obligation/required - */ - -import cpp -import codingstandards.cpp.autosar - -// A tagged union is a class or a struct -// that has exactly one union and exactly one enum with -// corresponding member variable that represents -// the data type in the union -class TaggedUnion extends UserType { - TaggedUnion() { - (this instanceof Class or this instanceof Struct) and - count(Enum e | e.getParentScope() = this) = 1 and - count(Union u | u.getParentScope() = this) = 1 and - count(MemberVariable m, Enum e | - m.getDeclaringType() = this and - e.getDeclaringType() = this and - m.getType().getName() = e.getName() - ) = 1 - } -} - -from Union u -where - not isExcluded(u, BannedSyntaxPackage::unionsUsedQuery()) and - not u.getParentScope() instanceof TaggedUnion -select u, u.getName() + " is not a tagged union." diff --git a/cpp/autosar/src/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql b/cpp/autosar/src/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql deleted file mode 100644 index fceba2030b..0000000000 --- a/cpp/autosar/src/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @id cpp/autosar/bit-fields-shall-be-used-only-when-interfacing-to-hardware-or-conforming-to-communication-protocols - * @name A9-6-2: Bit-fields shall be used only when interfacing to hardware or conforming to communication protocols - * @description The usage of bit-fields increases code complexity and certain aspects of bit-field - * manipulation can be error prone and implementation defined. Hence a bit-field usage - * is reserved only when interfacing to hardware or conformance to communication - * protocols. - * @kind problem - * @precision very-high - * @problem.severity recommendation - * @tags external/autosar/id/a9-6-2 - * maintainability - * external/autosar/allocated-target/design - * external/autosar/enforcement/partially-automated - * external/autosar/obligation/required - */ - -import cpp -import codingstandards.cpp.autosar -import codingstandards.cpp.HardwareOrProtocolInterface - -/* - * The condition that is allowed that is IF this is a bit-field, then it should be part of a class - * that is flagged as a hardware or protocol class. To detect this we look for violations of that form. - */ - -from BitField bf, Class c -where - not isExcluded(bf, - RepresentationPackage::bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery()) and - not isExcluded(c, - RepresentationPackage::bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery()) and - bf = c.getAField() and - not c instanceof HardwareOrProtocolInterfaceClass -select bf, "Bit-field used within a class that is not a hardware or protocol class." diff --git a/cpp/autosar/src/rules/A9-6-2/BitFieldsShouldNotBeDeclaredAutosarCpp.ql b/cpp/autosar/src/rules/A9-6-2/BitFieldsShouldNotBeDeclaredAutosarCpp.ql new file mode 100644 index 0000000000..c11e4b0224 --- /dev/null +++ b/cpp/autosar/src/rules/A9-6-2/BitFieldsShouldNotBeDeclaredAutosarCpp.ql @@ -0,0 +1,28 @@ +/** + * @id cpp/autosar/bit-fields-should-not-be-declared-autosar-cpp + * @name A9-6-2: Bit-fields shall be used only when interfacing to hardware or conforming to communication protocols + * @description The usage of bit-fields increases code complexity and certain aspects of bit-field + * manipulation can be error prone and implementation defined. Hence a bit-field usage + * is reserved only when interfacing to hardware or conformance to communication + * protocols. + * @kind problem + * @precision very-high + * @problem.severity recommendation + * @tags external/autosar/id/a9-6-2 + * maintainability + * external/autosar/allocated-target/design + * external/autosar/enforcement/partially-automated + * external/autosar/obligation/required + */ + +import cpp +import codingstandards.cpp.autosar +import codingstandards.cpp.rules.bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols.BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols + +module BitFieldsShouldNotBeDeclaredAutosarCppConfig implements + BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsConfigSig +{ + Query getQuery() { result = RepresentationPackage::bitFieldsShouldNotBeDeclaredAutosarCppQuery() } +} + +import BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols diff --git a/cpp/autosar/test/rules/A9-5-1/UnionKeywordUsedAutosarCpp.testref b/cpp/autosar/test/rules/A9-5-1/UnionKeywordUsedAutosarCpp.testref new file mode 100644 index 0000000000..4a4d9956dd --- /dev/null +++ b/cpp/autosar/test/rules/A9-5-1/UnionKeywordUsedAutosarCpp.testref @@ -0,0 +1 @@ +cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/A9-5-1/UnionsUsed.testref b/cpp/autosar/test/rules/A9-5-1/UnionsUsed.testref new file mode 100644 index 0000000000..4a4d9956dd --- /dev/null +++ b/cpp/autosar/test/rules/A9-5-1/UnionsUsed.testref @@ -0,0 +1 @@ +cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.expected b/cpp/autosar/test/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.expected deleted file mode 100644 index bd8406858a..0000000000 --- a/cpp/autosar/test/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.expected +++ /dev/null @@ -1 +0,0 @@ -| test.cpp:57:8:57:8 | c | Bit-field used within a class that is not a hardware or protocol class. | diff --git a/cpp/autosar/test/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.qlref b/cpp/autosar/test/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.qlref deleted file mode 100644 index 940b76de4e..0000000000 --- a/cpp/autosar/test/rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/A9-6-2/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/A9-6-2/BitFieldsShouldNotBeDeclaredAutosarCpp.testref b/cpp/autosar/test/rules/A9-6-2/BitFieldsShouldNotBeDeclaredAutosarCpp.testref new file mode 100644 index 0000000000..7c79532ac7 --- /dev/null +++ b/cpp/autosar/test/rules/A9-6-2/BitFieldsShouldNotBeDeclaredAutosarCpp.testref @@ -0,0 +1 @@ +cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/CommonTypes.qll b/cpp/common/src/codingstandards/cpp/CommonTypes.qll new file mode 100644 index 0000000000..3c8ea46b08 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/CommonTypes.qll @@ -0,0 +1,287 @@ +import cpp as default + +/* + * Implementations of the C/C++ Fixed Width Types from cstdint. + * + * TODO: Deprecate once this is available in the CodeQL standard library. + */ + +/** + * A parent class representing C/C++ a typedef'd `UserType` such as `int8_t`. + */ +abstract private class IntegralUnderlyingUserType extends default::UserType { + IntegralUnderlyingUserType() { this.getUnderlyingType() instanceof default::IntegralType } +} + +abstract private class TFixedWidthIntegralType extends IntegralUnderlyingUserType { } + +/** + * A C/C++ fixed-width numeric type, such as `int8_t`. + */ +class FixedWidthIntegralType extends TFixedWidthIntegralType { + FixedWidthIntegralType() { this instanceof TFixedWidthIntegralType } +} + +abstract private class TMinimumWidthIntegralType extends IntegralUnderlyingUserType { } + +/** + * A C/C++ minimum-width numeric type, such as `int_least8_t`. + */ +class MinimumWidthIntegralType extends TMinimumWidthIntegralType { + MinimumWidthIntegralType() { this instanceof TMinimumWidthIntegralType } +} + +abstract private class TFastestMinimumWidthIntegralType extends IntegralUnderlyingUserType { } + +/** + * A C/C++ minimum-width numeric type, representing the fastest integer type with a + * width of at least `N` such as `int_fast8_t`. + */ +class FastestMinimumWidthIntegralType extends TFastestMinimumWidthIntegralType { + FastestMinimumWidthIntegralType() { this instanceof TFastestMinimumWidthIntegralType } +} + +/** + * An enum type based on a fixed-width integer type. For instance, `enum e: uint8_t = { a, b };` + */ +class FixedWidthEnumType extends default::UserType { + FixedWidthEnumType() { + this.(default::Enum).getExplicitUnderlyingType() instanceof FixedWidthIntegralType + } +} + +/** + * The C/C++ `int8_t` type. + */ +class Int8_t extends TFixedWidthIntegralType { + Int8_t() { this.hasGlobalOrStdName("int8_t") } + + override string getAPrimaryQlClass() { result = "Int8_t" } +} + +/** + * The C/C++ `int16_t` type. + */ +class Int16_t extends TFixedWidthIntegralType { + Int16_t() { this.hasGlobalOrStdName("int16_t") } + + override string getAPrimaryQlClass() { result = "Int16_t" } +} + +/** + * The C/C++ `int32_t` type. + */ +class Int32_t extends TFixedWidthIntegralType { + Int32_t() { this.hasGlobalOrStdName("int32_t") } + + override string getAPrimaryQlClass() { result = "Int32_t" } +} + +/** + * The C/C++ `int64_t` type. + */ +class Int64_t extends TFixedWidthIntegralType { + Int64_t() { this.hasGlobalOrStdName("int64_t") } + + override string getAPrimaryQlClass() { result = "Int64_t" } +} + +/** + * The C/C++ `uint8_t` type. + */ +class UInt8_t extends TFixedWidthIntegralType { + UInt8_t() { this.hasGlobalOrStdName("uint8_t") } + + override string getAPrimaryQlClass() { result = "UInt8_t" } +} + +/** + * The C/C++ `uint16_t` type. + */ +class UInt16_t extends TFixedWidthIntegralType { + UInt16_t() { this.hasGlobalOrStdName("uint16_t") } + + override string getAPrimaryQlClass() { result = "UInt16_t" } +} + +/** + * The C/C++ `uint32_t` type. + */ +class UInt32_t extends TFixedWidthIntegralType { + UInt32_t() { this.hasGlobalOrStdName("uint32_t") } + + override string getAPrimaryQlClass() { result = "UInt32_t" } +} + +/** + * The C/C++ `uint64_t` type. + */ +class UInt64_t extends TFixedWidthIntegralType { + UInt64_t() { this.hasGlobalOrStdName("uint64_t") } + + override string getAPrimaryQlClass() { result = "UInt64_t" } +} + +/** + * The C/C++ `int_least8_t` type. + */ +class Int_least8_t extends TMinimumWidthIntegralType { + Int_least8_t() { this.hasGlobalOrStdName("int_least8_t") } + + override string getAPrimaryQlClass() { result = "Int_least8_t" } +} + +/** + * The C/C++ `int_least16_t` type. + */ +class Int_least16_t extends TMinimumWidthIntegralType { + Int_least16_t() { this.hasGlobalOrStdName("int_least16_t") } + + override string getAPrimaryQlClass() { result = "Int_least16_t" } +} + +/** + * The C/C++ `int_least32_t` type. + */ +class Int_least32_t extends TMinimumWidthIntegralType { + Int_least32_t() { this.hasGlobalOrStdName("int_least32_t") } + + override string getAPrimaryQlClass() { result = "Int_least32_t" } +} + +/** + * The C/C++ `int_least64_t` type. + */ +class Int_least64_t extends TMinimumWidthIntegralType { + Int_least64_t() { this.hasGlobalOrStdName("int_least64_t") } + + override string getAPrimaryQlClass() { result = "Int_least64_t" } +} + +/** + * The C/C++ `uint_least8_t` type. + */ +class UInt_least8_t extends TMinimumWidthIntegralType { + UInt_least8_t() { this.hasGlobalOrStdName("uint_least8_t") } + + override string getAPrimaryQlClass() { result = "UInt_least8_t" } +} + +/** + * The C/C++ `uint_least16_t` type. + */ +class UInt_least16_t extends TMinimumWidthIntegralType { + UInt_least16_t() { this.hasGlobalOrStdName("uint_least16_t") } + + override string getAPrimaryQlClass() { result = "UInt_least16_t" } +} + +/** + * The C/C++ `uint_least32_t` type. + */ +class UInt_least32_t extends TMinimumWidthIntegralType { + UInt_least32_t() { this.hasGlobalOrStdName("uint_least32_t") } + + override string getAPrimaryQlClass() { result = "UInt_least32_t" } +} + +/** + * The C/C++ `uint_least64_t` type. + */ +class UInt_least64_t extends TMinimumWidthIntegralType { + UInt_least64_t() { this.hasGlobalOrStdName("uint_least64_t") } + + override string getAPrimaryQlClass() { result = "UInt_least64_t" } +} + +/** + * The C/C++ `int_fast8_t` type. + */ +class Int_fast8_t extends TFastestMinimumWidthIntegralType { + Int_fast8_t() { this.hasGlobalOrStdName("int_fast8_t") } + + override string getAPrimaryQlClass() { result = "Int_fast8_t" } +} + +/** + * The C/C++ `int_fast16_t` type. + */ +class Int_fast16_t extends TFastestMinimumWidthIntegralType { + Int_fast16_t() { this.hasGlobalOrStdName("int_fast16_t") } + + override string getAPrimaryQlClass() { result = "Int_fast16_t" } +} + +/** + * The C/C++ `int_fast32_t` type. + */ +class Int_fast32_t extends TFastestMinimumWidthIntegralType { + Int_fast32_t() { this.hasGlobalOrStdName("int_fast32_t") } + + override string getAPrimaryQlClass() { result = "Int_fast32_t" } +} + +/** + * The C/C++ `int_fast64_t` type. + */ +class Int_fast64_t extends TFastestMinimumWidthIntegralType { + Int_fast64_t() { this.hasGlobalOrStdName("int_fast64_t") } + + override string getAPrimaryQlClass() { result = "Int_fast64_t" } +} + +/** + * The C/C++ `uint_fast8_t` type. + */ +class UInt_fast8_t extends TFastestMinimumWidthIntegralType { + UInt_fast8_t() { this.hasGlobalOrStdName("uint_fast8_t") } + + override string getAPrimaryQlClass() { result = "UInt_fast8_t" } +} + +/** + * The C/C++ `uint_fast16_t` type. + */ +class UInt_fast16_t extends TFastestMinimumWidthIntegralType { + UInt_fast16_t() { this.hasGlobalOrStdName("uint_fast16_t") } + + override string getAPrimaryQlClass() { result = "UInt_fast16_t" } +} + +/** + * The C/C++ `uint_fast32_t` type. + */ +class UInt_fast32_t extends TFastestMinimumWidthIntegralType { + UInt_fast32_t() { this.hasGlobalOrStdName("uint_fast32_t") } + + override string getAPrimaryQlClass() { result = "UInt_fast32_t" } +} + +/** + * The C/C++ `uint_fast64_t` type. + */ +class UInt_fast64_t extends TFastestMinimumWidthIntegralType { + UInt_fast64_t() { this.hasGlobalOrStdName("uint_fast64_t") } + + override string getAPrimaryQlClass() { result = "UInt_fast64_t" } +} + +/** + * Type that models a type that is either a pointer or a reference type. + */ +class PointerOrReferenceType extends default::DerivedType { + PointerOrReferenceType() { + this instanceof default::PointerType or + this instanceof default::ReferenceType + } +} + +/** + * Type that models a char type that is explicitly signed or unsigned. + */ +class ExplictlySignedOrUnsignedCharType extends default::CharType { + ExplictlySignedOrUnsignedCharType() { + isExplicitlySigned() or + isExplicitlyUnsigned() + } +} diff --git a/cpp/autosar/src/codingstandards/cpp/HardwareOrProtocolInterface.qll b/cpp/common/src/codingstandards/cpp/HardwareOrProtocolInterface.qll similarity index 97% rename from cpp/autosar/src/codingstandards/cpp/HardwareOrProtocolInterface.qll rename to cpp/common/src/codingstandards/cpp/HardwareOrProtocolInterface.qll index b0b20b82d9..b14e52872f 100644 --- a/cpp/autosar/src/codingstandards/cpp/HardwareOrProtocolInterface.qll +++ b/cpp/common/src/codingstandards/cpp/HardwareOrProtocolInterface.qll @@ -1,4 +1,4 @@ -import codingstandards.cpp.autosar +import cpp import codingstandards.cpp.CommonTypes as CommonTypes abstract class HardwareOrProtocolInterfaceClass extends Class { } diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned5.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned5.qll new file mode 100644 index 0000000000..849bc908e0 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned5.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Banned5Query = TBitFieldsShouldNotBeDeclaredMisraCppQuery() + +predicate isBanned5QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `bitFieldsShouldNotBeDeclaredMisraCpp` query + Banned5Package::bitFieldsShouldNotBeDeclaredMisraCppQuery() and + queryId = + // `@id` for the `bitFieldsShouldNotBeDeclaredMisraCpp` query + "cpp/misra/bit-fields-should-not-be-declared-misra-cpp" and + ruleId = "RULE-12-2-1" and + category = "advisory" +} + +module Banned5Package { + Query bitFieldsShouldNotBeDeclaredMisraCppQuery() { + //autogenerate `Query` type + result = + // `Query` type for `bitFieldsShouldNotBeDeclaredMisraCpp` query + TQueryCPP(TBanned5PackageQuery(TBitFieldsShouldNotBeDeclaredMisraCppQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned6.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned6.qll new file mode 100644 index 0000000000..651136f099 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned6.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Banned6Query = TUnionKeywordUsedMisraCppQuery() + +predicate isBanned6QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `unionKeywordUsedMisraCpp` query + Banned6Package::unionKeywordUsedMisraCppQuery() and + queryId = + // `@id` for the `unionKeywordUsedMisraCpp` query + "cpp/misra/union-keyword-used-misra-cpp" and + ruleId = "RULE-12-3-1" and + category = "required" +} + +module Banned6Package { + Query unionKeywordUsedMisraCppQuery() { + //autogenerate `Query` type + result = + // `Query` type for `unionKeywordUsedMisraCpp` query + TQueryCPP(TBanned6PackageQuery(TUnionKeywordUsedMisraCppQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned8.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned8.qll new file mode 100644 index 0000000000..b167d61b10 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned8.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Banned8Query = TBuiltInUnaryPlusOperatorShouldNotBeUsedQuery() + +predicate isBanned8QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `builtInUnaryPlusOperatorShouldNotBeUsed` query + Banned8Package::builtInUnaryPlusOperatorShouldNotBeUsedQuery() and + queryId = + // `@id` for the `builtInUnaryPlusOperatorShouldNotBeUsed` query + "cpp/misra/built-in-unary-plus-operator-should-not-be-used" and + ruleId = "RULE-8-3-2" and + category = "advisory" +} + +module Banned8Package { + Query builtInUnaryPlusOperatorShouldNotBeUsedQuery() { + //autogenerate `Query` type + result = + // `Query` type for `builtInUnaryPlusOperatorShouldNotBeUsed` query + TQueryCPP(TBanned8PackageQuery(TBuiltInUnaryPlusOperatorShouldNotBeUsedQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/BannedSyntax.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/BannedSyntax.qll index c473616374..2ab3d63acd 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/BannedSyntax.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/BannedSyntax.qll @@ -16,7 +16,7 @@ newtype BannedSyntaxQuery = TTypedefSpecifierUsedQuery() or TAsmDeclarationUsedQuery() or TFunctionsDefinedUsingTheEllipsisNotationQuery() or - TUnionsUsedQuery() or + TUnionKeywordUsedAutosarCppQuery() or TCommaOperatorUsedQuery() or TUsingDirectivesUsedQuery() or TUsingDeclarationsUsedInHeaderFilesQuery() or @@ -132,11 +132,11 @@ predicate isBannedSyntaxQueryMetadata(Query query, string queryId, string ruleId category = "required" or query = - // `Query` instance for the `unionsUsed` query - BannedSyntaxPackage::unionsUsedQuery() and + // `Query` instance for the `unionKeywordUsedAutosarCpp` query + BannedSyntaxPackage::unionKeywordUsedAutosarCppQuery() and queryId = - // `@id` for the `unionsUsed` query - "cpp/autosar/unions-used" and + // `@id` for the `unionKeywordUsedAutosarCpp` query + "cpp/autosar/union-keyword-used-autosar-cpp" and ruleId = "A9-5-1" and category = "required" or @@ -262,11 +262,11 @@ module BannedSyntaxPackage { TQueryCPP(TBannedSyntaxPackageQuery(TFunctionsDefinedUsingTheEllipsisNotationQuery())) } - Query unionsUsedQuery() { + Query unionKeywordUsedAutosarCppQuery() { //autogenerate `Query` type result = - // `Query` type for `unionsUsed` query - TQueryCPP(TBannedSyntaxPackageQuery(TUnionsUsedQuery())) + // `Query` type for `unionKeywordUsedAutosarCpp` query + TQueryCPP(TBannedSyntaxPackageQuery(TUnionKeywordUsedAutosarCppQuery())) } Query commaOperatorUsedQuery() { diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll index fd07ef14e0..f6243f714d 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll @@ -4,7 +4,7 @@ import RuleMetadata import codingstandards.cpp.exclusions.RuleMetadata newtype RepresentationQuery = - TBitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery() or + TBitFieldsShouldNotBeDeclaredAutosarCppQuery() or TAuditPossibleHardwareInterfaceDueToBitFieldUsageInDataTypeDefinitionQuery() or TObjectAssignedToAnOverlappingObjectAutosarCppQuery() or TDoNotPassAliasedPointerToParamQuery() or @@ -16,11 +16,11 @@ newtype RepresentationQuery = predicate isRepresentationQueryMetadata(Query query, string queryId, string ruleId, string category) { query = - // `Query` instance for the `bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols` query - RepresentationPackage::bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery() and + // `Query` instance for the `bitFieldsShouldNotBeDeclaredAutosarCpp` query + RepresentationPackage::bitFieldsShouldNotBeDeclaredAutosarCppQuery() and queryId = - // `@id` for the `bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols` query - "cpp/autosar/bit-fields-shall-be-used-only-when-interfacing-to-hardware-or-conforming-to-communication-protocols" and + // `@id` for the `bitFieldsShouldNotBeDeclaredAutosarCpp` query + "cpp/autosar/bit-fields-should-not-be-declared-autosar-cpp" and ruleId = "A9-6-2" and category = "required" or @@ -98,11 +98,11 @@ predicate isRepresentationQueryMetadata(Query query, string queryId, string rule } module RepresentationPackage { - Query bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery() { + Query bitFieldsShouldNotBeDeclaredAutosarCppQuery() { //autogenerate `Query` type result = - // `Query` type for `bitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols` query - TQueryCPP(TRepresentationPackageQuery(TBitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery())) + // `Query` type for `bitFieldsShouldNotBeDeclaredAutosarCpp` query + TQueryCPP(TRepresentationPackageQuery(TBitFieldsShouldNotBeDeclaredAutosarCppQuery())) } Query auditPossibleHardwareInterfaceDueToBitFieldUsageInDataTypeDefinitionQuery() { diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll index 1ef6ce7758..afe1fffbf6 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll @@ -4,6 +4,9 @@ import codingstandards.cpp.exclusions.RuleMetadata //** Import packages for this language **/ import Allocations import Banned1 +import Banned5 +import Banned6 +import Banned8 import BannedAPIs import BannedFunctions import BannedLibraries @@ -95,6 +98,9 @@ import VirtualFunctions newtype TCPPQuery = TAllocationsPackageQuery(AllocationsQuery q) or TBanned1PackageQuery(Banned1Query q) or + TBanned5PackageQuery(Banned5Query q) or + TBanned6PackageQuery(Banned6Query q) or + TBanned8PackageQuery(Banned8Query q) or TBannedAPIsPackageQuery(BannedAPIsQuery q) or TBannedFunctionsPackageQuery(BannedFunctionsQuery q) or TBannedLibrariesPackageQuery(BannedLibrariesQuery q) or @@ -186,6 +192,9 @@ newtype TCPPQuery = predicate isQueryMetadata(Query query, string queryId, string ruleId, string category) { isAllocationsQueryMetadata(query, queryId, ruleId, category) or isBanned1QueryMetadata(query, queryId, ruleId, category) or + isBanned5QueryMetadata(query, queryId, ruleId, category) or + isBanned6QueryMetadata(query, queryId, ruleId, category) or + isBanned8QueryMetadata(query, queryId, ruleId, category) or isBannedAPIsQueryMetadata(query, queryId, ruleId, category) or isBannedFunctionsQueryMetadata(query, queryId, ruleId, category) or isBannedLibrariesQueryMetadata(query, queryId, ruleId, category) or diff --git a/cpp/common/src/codingstandards/cpp/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.qll b/cpp/common/src/codingstandards/cpp/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.qll new file mode 100644 index 0000000000..54b5393318 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.qll @@ -0,0 +1,33 @@ +/** + * Provides a configurable module BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols with a `problems` predicate + * for the following issue: + * The exact layout and the order of bits resulting from bit-fields in a struct is + * implementation-defined and therefore not portable. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions +import codingstandards.cpp.HardwareOrProtocolInterface + +signature module BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsConfigSig +{ + Query getQuery(); +} + +module BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols< + BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsConfigSig Config> +{ + query predicate problems(BitField bf, Class c, string message) { + /* + * The condition that is allowed that is IF this is a bit-field, then it should be part of a class + * that is flagged as a hardware or protocol class. To detect this we look for violations of that form. + */ + + not isExcluded(bf, Config::getQuery()) and + not isExcluded(c, Config::getQuery()) and + bf = c.getAField() and + not c instanceof HardwareOrProtocolInterfaceClass and + message = "Bit-field used within a class that is not a hardware or protocol class." + } +} diff --git a/cpp/common/src/codingstandards/cpp/rules/unionkeywordused/UnionKeywordUsed.qll b/cpp/common/src/codingstandards/cpp/rules/unionkeywordused/UnionKeywordUsed.qll new file mode 100644 index 0000000000..e57b44ca54 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/unionkeywordused/UnionKeywordUsed.qll @@ -0,0 +1,39 @@ +/** + * Provides a configurable module UnionKeywordUsed with a `problems` predicate + * for the following issue: + * Unions shall not be used. Tagged unions can be used if 'std::variant' is not + * available. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions + +signature module UnionKeywordUsedConfigSig { + Query getQuery(); +} + +// A tagged union is a class or a struct +// that has exactly one union and exactly one enum with +// corresponding member variable that represents +// the data type in the union +class TaggedUnion extends UserType { + TaggedUnion() { + (this instanceof Class or this instanceof Struct) and + count(Enum e | e.getParentScope() = this) = 1 and + count(Union u | u.getParentScope() = this) = 1 and + count(MemberVariable m, Enum e | + m.getDeclaringType() = this and + e.getDeclaringType() = this and + m.getType().getName() = e.getName() + ) = 1 + } +} + +module UnionKeywordUsed { + query predicate problems(Union u, string message) { + not isExcluded(u, Config::getQuery()) and + not u.getParentScope() instanceof TaggedUnion and + message = u.getName() + " is not a tagged union." + } +} diff --git a/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.expected b/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.expected new file mode 100644 index 0000000000..0daa7ed79c --- /dev/null +++ b/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.expected @@ -0,0 +1 @@ +| test.cpp:57:8:57:8 | c | test.cpp:53:7:53:8 | B2 | Bit-field used within a class that is not a hardware or protocol class. | diff --git a/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql b/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql new file mode 100644 index 0000000000..e017aaf26d --- /dev/null +++ b/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql @@ -0,0 +1,10 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols.BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols + +module TestFileConfig implements + BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsConfigSig +{ + Query getQuery() { result instanceof TestQuery } +} + +import BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols diff --git a/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/test.cpp b/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/test.cpp new file mode 100644 index 0000000000..62bc5b5a3b --- /dev/null +++ b/cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/test.cpp @@ -0,0 +1,58 @@ +typedef int MYINT; + +/** + * @HardwareOrProtocolInterface + */ +class HW_A {}; + +/** + * @HardwareOrProtocolInterface + */ +class HW_A1 : HW_A { +public: + int a1; + int a2; +}; + +/** + * @HardwareOrProtocolInterface + */ +class HW_A2 : HW_A { +public: + int a1 : 2; // NON_COMPLIANT + int a2; +}; + +/** + * @HardwareOrProtocolInterface + */ +class HW_B {}; + +class B {}; + +/** + * @HardwareOrProtocolInterface + */ +class HW_B1 : HW_B { +public: + int a; +}; + +/** + * @HardwareOrProtocolInterface + */ +class HW_B2 : HW_B { +public: + int a1; + MYINT a2 : 2; // NON_COMPLIANT + + char b1; + char c1 : 2; // NON_COMPLIANT +}; + +class B2 : B { +public: + int a; + char b; + char c : 2; // NON_COMPLIANT +}; diff --git a/cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.expected b/cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.expected new file mode 100644 index 0000000000..d9a71c2a3e --- /dev/null +++ b/cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.expected @@ -0,0 +1,2 @@ +| test.cpp:14:9:14:9 | u | u is not a tagged union. | +| test.cpp:21:7:21:7 | u | u is not a tagged union. | diff --git a/cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql b/cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql new file mode 100644 index 0000000000..e8c12bb84c --- /dev/null +++ b/cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql @@ -0,0 +1,8 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.unionkeywordused.UnionKeywordUsed + +module TestFileConfig implements UnionKeywordUsedConfigSig { + Query getQuery() { result instanceof TestQuery } +} + +import UnionKeywordUsed diff --git a/cpp/common/test/rules/unionkeywordused/test.cpp b/cpp/common/test/rules/unionkeywordused/test.cpp new file mode 100644 index 0000000000..37cea01a70 --- /dev/null +++ b/cpp/common/test/rules/unionkeywordused/test.cpp @@ -0,0 +1,30 @@ + +struct union_with_tag { + enum class TYPE { integer, floating }; + + union u { // COMPLIANT - union with tag + int i; + float f; + }; + + TYPE tag; +}; + +struct union_sans_tag { + union u { // NON_COMPLIANT + int i; + float f; + }; + int x; +}; + +union u { // NON_COMPLIANT + int i; + float f; +}; + +void test_unions() { + union_with_tag u1; + union_sans_tag u2; + u u3; +} diff --git a/cpp/misra/src/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclared.ql b/cpp/misra/src/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclared.ql new file mode 100644 index 0000000000..d1479f8800 --- /dev/null +++ b/cpp/misra/src/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclared.ql @@ -0,0 +1,26 @@ +/** + * @id cpp/misra/bit-fields-should-not-be-declared + * @name RULE-12-2-1: Bit-fields should not be declared + * @description The exact layout and the order of bits resulting from bit-fields in a struct is + * implementation-defined and therefore not portable. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-12-2-1 + * scope/single-translation-unit + * correctness + * external/misra/enforcement/decidable + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols.BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols + +module BitFieldsShouldNotBeDeclaredConfig implements + BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsConfigSig +{ + Query getQuery() { result = Banned5Package::bitFieldsShouldNotBeDeclaredQuery() } +} + +import BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols diff --git a/cpp/misra/src/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclaredMisraCpp.ql b/cpp/misra/src/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclaredMisraCpp.ql new file mode 100644 index 0000000000..67c0e6386d --- /dev/null +++ b/cpp/misra/src/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclaredMisraCpp.ql @@ -0,0 +1,26 @@ +/** + * @id cpp/misra/bit-fields-should-not-be-declared-misra-cpp + * @name RULE-12-2-1: Bit-fields should not be declared + * @description The exact layout and the order of bits resulting from bit-fields in a struct is + * implementation-defined and therefore not portable. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-12-2-1 + * scope/single-translation-unit + * correctness + * external/misra/enforcement/decidable + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols.BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols + +module BitFieldsShouldNotBeDeclaredMisraCppConfig implements + BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsConfigSig +{ + Query getQuery() { result = Banned5Package::bitFieldsShouldNotBeDeclaredMisraCppQuery() } +} + +import BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols diff --git a/cpp/misra/src/rules/RULE-12-3-1/UnionKeywordUsed.ql b/cpp/misra/src/rules/RULE-12-3-1/UnionKeywordUsed.ql new file mode 100644 index 0000000000..0153cea1fc --- /dev/null +++ b/cpp/misra/src/rules/RULE-12-3-1/UnionKeywordUsed.ql @@ -0,0 +1,24 @@ +/** + * @id cpp/misra/union-keyword-used + * @name RULE-12-3-1: The union keyword shall not be used + * @description Using unions should be avoided and 'std::variant' should be used as a type-safe + * alternative. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-12-3-1 + * scope/single-translation-unit + * correctness + * external/misra/enforcement/decidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.unionkeywordused.UnionKeywordUsed + +module UnionKeywordUsedConfig implements UnionKeywordUsedConfigSig { + Query getQuery() { result = Banned6Package::unionKeywordUsedQuery() } +} + +import UnionKeywordUsed diff --git a/cpp/misra/src/rules/RULE-12-3-1/UnionKeywordUsedMisraCpp.ql b/cpp/misra/src/rules/RULE-12-3-1/UnionKeywordUsedMisraCpp.ql new file mode 100644 index 0000000000..a086d0dacd --- /dev/null +++ b/cpp/misra/src/rules/RULE-12-3-1/UnionKeywordUsedMisraCpp.ql @@ -0,0 +1,24 @@ +/** + * @id cpp/misra/union-keyword-used-misra-cpp + * @name RULE-12-3-1: The union keyword shall not be used + * @description Using unions should be avoided and 'std::variant' should be used as a type-safe + * alternative. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-12-3-1 + * scope/single-translation-unit + * correctness + * external/misra/enforcement/decidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.unionkeywordused.UnionKeywordUsed + +module UnionKeywordUsedMisraCppConfig implements UnionKeywordUsedConfigSig { + Query getQuery() { result = Banned6Package::unionKeywordUsedMisraCppQuery() } +} + +import UnionKeywordUsed diff --git a/cpp/misra/src/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.ql b/cpp/misra/src/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.ql new file mode 100644 index 0000000000..cf3e56e395 --- /dev/null +++ b/cpp/misra/src/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.ql @@ -0,0 +1,21 @@ +/** + * @id cpp/misra/built-in-unary-plus-operator-should-not-be-used + * @name RULE-8-3-2: The built-in unary + operator should not be used + * @description Using the built-in unary '+' operator may trigger unexpected implicit type + * conversions. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-8-3-2 + * scope/single-translation-unit + * correctness + * external/misra/enforcement/decidable + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.cpp.misra + +from UnaryPlusExpr e +where not e.isFromUninstantiatedTemplate(_) +select e, "Use of built-in unary + operator." diff --git a/cpp/misra/test/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclaredMisraCpp.testref b/cpp/misra/test/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclaredMisraCpp.testref new file mode 100644 index 0000000000..7c79532ac7 --- /dev/null +++ b/cpp/misra/test/rules/RULE-12-2-1/BitFieldsShouldNotBeDeclaredMisraCpp.testref @@ -0,0 +1 @@ +cpp/common/test/rules/bitfieldsshallbeusedonlywheninterfacingtohardwareorconformingtocommunicationprotocols/BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-12-3-1/UnionKeywordUsed.testref b/cpp/misra/test/rules/RULE-12-3-1/UnionKeywordUsed.testref new file mode 100644 index 0000000000..4a4d9956dd --- /dev/null +++ b/cpp/misra/test/rules/RULE-12-3-1/UnionKeywordUsed.testref @@ -0,0 +1 @@ +cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-12-3-1/UnionKeywordUsedMisraCpp.testref b/cpp/misra/test/rules/RULE-12-3-1/UnionKeywordUsedMisraCpp.testref new file mode 100644 index 0000000000..4a4d9956dd --- /dev/null +++ b/cpp/misra/test/rules/RULE-12-3-1/UnionKeywordUsedMisraCpp.testref @@ -0,0 +1 @@ +cpp/common/test/rules/unionkeywordused/UnionKeywordUsed.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.expected b/cpp/misra/test/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.expected new file mode 100644 index 0000000000..14e6ea6a41 --- /dev/null +++ b/cpp/misra/test/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.expected @@ -0,0 +1,18 @@ +| test.cpp:12:12:12:14 | + ... | Use of built-in unary + operator. | +| test.cpp:15:12:15:14 | + ... | Use of built-in unary + operator. | +| test.cpp:18:12:18:15 | + ... | Use of built-in unary + operator. | +| test.cpp:21:12:21:14 | + ... | Use of built-in unary + operator. | +| test.cpp:24:12:24:14 | + ... | Use of built-in unary + operator. | +| test.cpp:26:12:26:27 | + ... | Use of built-in unary + operator. | +| test.cpp:29:18:29:25 | + ... | Use of built-in unary + operator. | +| test.cpp:30:12:30:27 | + ... | Use of built-in unary + operator. | +| test.cpp:33:12:33:13 | + ... | Use of built-in unary + operator. | +| test.cpp:34:12:34:15 | + ... | Use of built-in unary + operator. | +| test.cpp:35:12:35:16 | + ... | Use of built-in unary + operator. | +| test.cpp:38:7:38:8 | + ... | Use of built-in unary + operator. | +| test.cpp:42:12:42:15 | + ... | Use of built-in unary + operator. | +| test.cpp:45:12:45:13 | + ... | Use of built-in unary + operator. | +| test.cpp:48:12:48:15 | + ... | Use of built-in unary + operator. | +| test.cpp:64:10:64:13 | + ... | Use of built-in unary + operator. | +| test.cpp:64:10:64:13 | + ... | Use of built-in unary + operator. | +| test.cpp:75:14:75:17 | + ... | Use of built-in unary + operator. | diff --git a/cpp/misra/test/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.qlref b/cpp/misra/test/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.qlref new file mode 100644 index 0000000000..44ec8857e8 --- /dev/null +++ b/cpp/misra/test/rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.qlref @@ -0,0 +1 @@ +rules/RULE-8-3-2/BuiltInUnaryPlusOperatorShouldNotBeUsed.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-8-3-2/test.cpp b/cpp/misra/test/rules/RULE-8-3-2/test.cpp new file mode 100644 index 0000000000..33ebf29cfa --- /dev/null +++ b/cpp/misra/test/rules/RULE-8-3-2/test.cpp @@ -0,0 +1,76 @@ +#include + +// Helper types +enum UnscopedEnum { A, B, C }; +enum SmallEnum : uint8_t { S1, S2 }; + +uint8_t operator+(SmallEnum e) { return static_cast(e); } + +void test_unary_plus() { + // === NON-COMPLIANT: integral promotion === + uint8_t u8 = 1; + auto a = +u8; // NON_COMPLIANT: promotes to int + + int8_t i8 = 1; + auto b = +i8; // NON_COMPLIANT: promotes to int + + uint16_t u16 = 1; + auto c = +u16; // NON_COMPLIANT: promotes to int + + char ch = 'x'; + auto d = +ch; // NON_COMPLIANT: promotes to int + + bool bl = true; + auto e = +bl; // NON_COMPLIANT: promotes to int + + auto f = +UnscopedEnum::A; // NON_COMPLIANT: promotes to int + + // === NON_COMPLIANT: function/lambda decay === + void (*fp)() = +[]() {}; // NON_COMPLIANT: lambda decays to pointer + auto g = +test_unary_plus; // NON_COMPLIANT: function decays to pointer + + // === NON_COMPLIANT: literals and expressions === + auto h = +1; // NON_COMPLIANT: unary + on literal + auto i = +'a'; // NON_COMPLIANT: promotes char to int + auto j = +true; // NON_COMPLIANT: promotes bool to int + + int x; + x = +1; // NON_COMPLIANT: unary +, not += + + // === NON_COMPLIANT: larger types (still built-in +) === + int i32 = 1; + auto k = +i32; // NON_COMPLIANT: built-in unary + + + long l = 1; + auto m = +l; // NON_COMPLIANT: built-in unary + + + double dbl = 1.0; + auto n = +dbl; // NON_COMPLIANT: built-in unary + + + // === COMPLIANT: user-defined operator+ === + auto o = +SmallEnum::S1; // COMPLIANT: calls user-defined operator+ + auto p = operator+(SmallEnum::S2); // COMPLIANT: explicit call + + // === COMPLIANT: not unary + === + auto q = 1 + 2; // COMPLIANT: binary + + auto r = u8 + u8; // COMPLIANT: binary + + + int y = 0; + y += 1; // COMPLIANT: compound assignment +} + +// === NON_COMPLIANT: in other contexts === +template T promote(T val) { + return +val; // NON_COMPLIANT (when T is built-in type) +} + +void test_template() { + promote(uint8_t{1}); // Instantiates NON_COMPLIANT case + promote(1); // Instantiates NON_COMPLIANT case +} + +// === NON_COMPLIANT: array decay === +void test_array() { + int arr[5]; + auto ptr = +arr; // NON_COMPLIANT: array decays to pointer +} diff --git a/rule_packages/cpp/Banned5.json b/rule_packages/cpp/Banned5.json new file mode 100644 index 0000000000..662768673b --- /dev/null +++ b/rule_packages/cpp/Banned5.json @@ -0,0 +1,26 @@ +{ + "MISRA-C++-2023": { + "RULE-12-2-1": { + "properties": { + "enforcement": "decidable", + "obligation": "advisory" + }, + "queries": [ + { + "description": "The exact layout and the order of bits resulting from bit-fields in a struct is implementation-defined and therefore not portable.", + "kind": "problem", + "name": "Bit-fields should not be declared", + "precision": "very-high", + "severity": "error", + "short_name": "BitFieldsShouldNotBeDeclaredMisraCpp", + "shared_implementation_short_name": "BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols", + "tags": [ + "scope/single-translation-unit", + "correctness" + ] + } + ], + "title": "Bit-fields should not be declared" + } + } +} \ No newline at end of file diff --git a/rule_packages/cpp/Banned6.json b/rule_packages/cpp/Banned6.json new file mode 100644 index 0000000000..8adf3d6b7a --- /dev/null +++ b/rule_packages/cpp/Banned6.json @@ -0,0 +1,26 @@ +{ + "MISRA-C++-2023": { + "RULE-12-3-1": { + "properties": { + "enforcement": "decidable", + "obligation": "required" + }, + "queries": [ + { + "description": "Using unions should be avoided and 'std::variant' should be used as a type-safe alternative.", + "kind": "problem", + "name": "The union keyword shall not be used", + "precision": "very-high", + "severity": "error", + "short_name": "UnionKeywordUsedMisraCpp", + "shared_implementation_short_name": "UnionKeywordUsed", + "tags": [ + "scope/single-translation-unit", + "correctness" + ] + } + ], + "title": "The union keyword shall not be used" + } + } +} \ No newline at end of file diff --git a/rule_packages/cpp/Banned8.json b/rule_packages/cpp/Banned8.json new file mode 100644 index 0000000000..9febf4cfd3 --- /dev/null +++ b/rule_packages/cpp/Banned8.json @@ -0,0 +1,25 @@ +{ + "MISRA-C++-2023": { + "RULE-8-3-2": { + "properties": { + "enforcement": "decidable", + "obligation": "advisory" + }, + "queries": [ + { + "description": "Using the built-in unary '+' operator may trigger unexpected implicit type conversions.", + "kind": "problem", + "name": "The built-in unary + operator should not be used", + "precision": "very-high", + "severity": "error", + "short_name": "BuiltInUnaryPlusOperatorShouldNotBeUsed", + "tags": [ + "scope/single-translation-unit", + "correctness" + ] + } + ], + "title": "The built-in unary + operator should not be used" + } + } +} \ No newline at end of file diff --git a/rule_packages/cpp/BannedSyntax.json b/rule_packages/cpp/BannedSyntax.json index 8f739145f7..55ae8a62c7 100644 --- a/rule_packages/cpp/BannedSyntax.json +++ b/rule_packages/cpp/BannedSyntax.json @@ -313,12 +313,13 @@ }, "queries": [ { - "description": "Unions shall not be used. Tagged untions can be used if std::variant is not available.", + "description": "Unions shall not be used. Tagged unions can be used if 'std::variant' is not available.", "kind": "problem", "name": "Unions shall not be used", "precision": "very-high", "severity": "error", - "short_name": "UnionsUsed", + "short_name": "UnionKeywordUsedAutosarCpp", + "shared_implementation_short_name": "UnionKeywordUsed", "tags": [ "correctness", "scope/single-translation-unit" diff --git a/rule_packages/cpp/Representation.json b/rule_packages/cpp/Representation.json index 08056422cc..709bf930e7 100644 --- a/rule_packages/cpp/Representation.json +++ b/rule_packages/cpp/Representation.json @@ -15,7 +15,8 @@ "name": "Bit-fields shall be used only when interfacing to hardware or conforming to communication protocols", "precision": "very-high", "severity": "recommendation", - "short_name": "BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols", + "short_name": "BitFieldsShouldNotBeDeclaredAutosarCpp", + "shared_implementation_short_name": "BitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocols", "tags": [ "maintainability" ] diff --git a/rules.csv b/rules.csv index 172087714d..cf512b3378 100644 --- a/rules.csv +++ b/rules.csv @@ -894,7 +894,7 @@ cpp,MISRA-C++-2023,RULE-8-2-9,Yes,Required,Decidable,Single Translation Unit,The cpp,MISRA-C++-2023,RULE-8-2-10,Yes,Required,Undecidable,System,"Functions shall not call themselves, either directly or indirectly",A7-5-2,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-8-2-11,Yes,Required,Decidable,Single Translation Unit,An argument passed via ellipsis shall have an appropriate type,,Preconditions,Easy, cpp,MISRA-C++-2023,RULE-8-3-1,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary - operator should not be applied to an expression of unsigned type,M5-3-2,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-8-3-2,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary + operator should not be used,,Banned,Easy, +cpp,MISRA-C++-2023,RULE-8-3-2,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary + operator should not be used,,Banned8,Easy, cpp,MISRA-C++-2023,RULE-8-7-1,Yes,Required,Undecidable,System,Pointer arithmetic shall not form an invalid pointer,ARR30-C,Memory1,Easy, cpp,MISRA-C++-2023,RULE-8-7-2,Yes,Required,Undecidable,System,Subtraction between pointers shall only be applied to pointers that address elements of the same array,ARR36-C,Memory2,Easy, cpp,MISRA-C++-2023,RULE-8-9-1,Yes,Required,Undecidable,System,"The built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same array",ARR36-C,Memory3,Easy, @@ -927,10 +927,10 @@ cpp,MISRA-C++-2023,RULE-11-3-2,Yes,Advisory,Decidable,Single Translation Unit,Th cpp,MISRA-C++-2023,RULE-11-6-1,Yes,Advisory,Decidable,Single Translation Unit,All variables should be initialized,,Declarations2,Easy, cpp,MISRA-C++-2023,RULE-11-6-2,Yes,Mandatory,Undecidable,System,The value of an object must not be read before it has been set,A8-5-0,Lifetime,Import cpp,MISRA-C++-2023,RULE-11-6-3,Yes,Required,Decidable,Single Translation Unit,"Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique",RULE-8-12,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-12-2-1,Yes,Advisory,Decidable,Single Translation Unit,Bit-fields should not be declared,A9-6-2,Banned,Easy, +cpp,MISRA-C++-2023,RULE-12-2-1,Yes,Advisory,Decidable,Single Translation Unit,Bit-fields should not be declared,A9-6-2,Banned5,Easy, cpp,MISRA-C++-2023,RULE-12-2-2,Yes,Required,Decidable,Single Translation Unit,A bit-field shall have an appropriate type,RULE-6-1,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-12-2-3,Yes,Required,Decidable,Single Translation Unit,A named bit-field with signed integer type shall not have a length of one bit,M9-6-4,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-12-3-1,Yes,Required,Decidable,Single Translation Unit,The union keyword shall not be used,RULE-19-2,Banned,Easy, +cpp,MISRA-C++-2023,RULE-12-3-1,Yes,Required,Decidable,Single Translation Unit,The union keyword shall not be used,RULE-19-2,Banned6,Easy, cpp,MISRA-C++-2023,RULE-13-1-1,Yes,Advisory,Decidable,Single Translation Unit,Classes should not be inherited virtually,,Classes2,Easy, cpp,MISRA-C++-2023,RULE-13-1-2,Yes,Required,Decidable,Single Translation Unit,An accessible base class shall not be both virtual and non-virtual in the same hierarchy,M10-1-3,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-13-3-1,Yes,Required,Decidable,Single Translation Unit,"User-declared member functions shall use the virtual, override and final specifiers appropriately",,Classes2,Easy,