diff --git a/cpp/autosar/src/rules/M3-1-2/FunctionsDeclaredAtBlockScope.ql b/cpp/autosar/src/rules/M3-1-2/FunctionsDeclaredAtBlockScope.ql index 87d9af147b..c0b2c322a8 100644 --- a/cpp/autosar/src/rules/M3-1-2/FunctionsDeclaredAtBlockScope.ql +++ b/cpp/autosar/src/rules/M3-1-2/FunctionsDeclaredAtBlockScope.ql @@ -17,10 +17,10 @@ import cpp import codingstandards.cpp.autosar +import codingstandards.cpp.rules.functiondeclaredatblockscope.FunctionDeclaredAtBlockScope -from DeclStmt decl, Function f -where - not isExcluded(decl, DeclarationsPackage::functionsDeclaredAtBlockScopeQuery()) and - not isExcluded(f, DeclarationsPackage::functionsDeclaredAtBlockScopeQuery()) and - decl.getADeclaration() = f -select f, "Function " + f.getName() + " is declared at block scope." +module FunctionDeclaredAtBlockScopeConfig implements FunctionDeclaredAtBlockScopeConfigSig { + Query getQuery() { result = DeclarationsPackage::functionsDeclaredAtBlockScopeQuery() } +} + +import FunctionDeclaredAtBlockScope diff --git a/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.qlref b/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.qlref deleted file mode 100644 index c2a7a10925..0000000000 --- a/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/M3-1-2/FunctionsDeclaredAtBlockScope.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.testref b/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.testref new file mode 100644 index 0000000000..0c0e3c1016 --- /dev/null +++ b/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.testref @@ -0,0 +1 @@ +cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.ql \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll new file mode 100644 index 0000000000..0f2c682a77 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Declarations3.qll @@ -0,0 +1,44 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Declarations3Query = + TVariableDeclaredArrayTypeQuery() or + TBlockScopeFunctionAmbiguousQuery() + +predicate isDeclarations3QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `variableDeclaredArrayType` query + Declarations3Package::variableDeclaredArrayTypeQuery() and + queryId = + // `@id` for the `variableDeclaredArrayType` query + "cpp/misra/variable-declared-array-type" and + ruleId = "RULE-11-3-1" and + category = "advisory" + or + query = + // `Query` instance for the `blockScopeFunctionAmbiguous` query + Declarations3Package::blockScopeFunctionAmbiguousQuery() and + queryId = + // `@id` for the `blockScopeFunctionAmbiguous` query + "cpp/misra/block-scope-function-ambiguous" and + ruleId = "RULE-6-0-1" and + category = "required" +} + +module Declarations3Package { + Query variableDeclaredArrayTypeQuery() { + //autogenerate `Query` type + result = + // `Query` type for `variableDeclaredArrayType` query + TQueryCPP(TDeclarations3PackageQuery(TVariableDeclaredArrayTypeQuery())) + } + + Query blockScopeFunctionAmbiguousQuery() { + //autogenerate `Query` type + result = + // `Query` type for `blockScopeFunctionAmbiguous` query + TQueryCPP(TDeclarations3PackageQuery(TBlockScopeFunctionAmbiguousQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll index 652d12307c..b3552ab911 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll @@ -33,6 +33,7 @@ import DeadCode8 import DeadCode9 import Declarations import Declarations1 +import Declarations3 import ExceptionSafety import Exceptions1 import Exceptions2 @@ -129,6 +130,7 @@ newtype TCPPQuery = TDeadCode9PackageQuery(DeadCode9Query q) or TDeclarationsPackageQuery(DeclarationsQuery q) or TDeclarations1PackageQuery(Declarations1Query q) or + TDeclarations3PackageQuery(Declarations3Query q) or TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or TExceptions1PackageQuery(Exceptions1Query q) or TExceptions2PackageQuery(Exceptions2Query q) or @@ -225,6 +227,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isDeadCode9QueryMetadata(query, queryId, ruleId, category) or isDeclarationsQueryMetadata(query, queryId, ruleId, category) or isDeclarations1QueryMetadata(query, queryId, ruleId, category) or + isDeclarations3QueryMetadata(query, queryId, ruleId, category) or isExceptionSafetyQueryMetadata(query, queryId, ruleId, category) or isExceptions1QueryMetadata(query, queryId, ruleId, category) or isExceptions2QueryMetadata(query, queryId, ruleId, category) or diff --git a/cpp/common/src/codingstandards/cpp/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.qll b/cpp/common/src/codingstandards/cpp/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.qll new file mode 100644 index 0000000000..9343f37342 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.qll @@ -0,0 +1,25 @@ +/** + * Provides a configurable module FunctionDeclaredAtBlockScope with a `problems` predicate + * for the following issue: + * A function declared at block scope can make code harder to read and may lead to + * developer confusion. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions + +signature module FunctionDeclaredAtBlockScopeConfigSig { + Query getQuery(); +} + +module FunctionDeclaredAtBlockScope { + query predicate problems(Function f, string message) { + exists(DeclStmt decl | + not isExcluded(decl, Config::getQuery()) and + not isExcluded(f, Config::getQuery()) and + decl.getADeclaration() = f and + message = "Function " + f.getName() + " is declared at block scope." + ) + } +} diff --git a/cpp/common/test/includes/standard-library/string_view b/cpp/common/test/includes/standard-library/string_view index d46bc57b44..ac531a10ef 100644 --- a/cpp/common/test/includes/standard-library/string_view +++ b/cpp/common/test/includes/standard-library/string_view @@ -75,6 +75,13 @@ typedef basic_string_view wstring_view; typedef basic_string_view u16string_view; typedef basic_string_view u32string_view; +inline namespace literals { +inline namespace string_view_literals { +// suffix for basic_string_view literals +constexpr string_view operator""sv(const char *str, size_t len) noexcept; +} // namespace string_view_literals +} // namespace literals + } // namespace std #endif // _GHLIBCPP_STRING_VIEW diff --git a/cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.expected b/cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.expected similarity index 100% rename from cpp/autosar/test/rules/M3-1-2/FunctionsDeclaredAtBlockScope.expected rename to cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.expected diff --git a/cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.ql b/cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.ql new file mode 100644 index 0000000000..f91abb4c7d --- /dev/null +++ b/cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.ql @@ -0,0 +1,8 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.functiondeclaredatblockscope.FunctionDeclaredAtBlockScope + +module TestFileConfig implements FunctionDeclaredAtBlockScopeConfigSig { + Query getQuery() { result instanceof TestQuery } +} + +import FunctionDeclaredAtBlockScope diff --git a/cpp/autosar/test/rules/M3-1-2/test.cpp b/cpp/common/test/rules/functiondeclaredatblockscope/test.cpp similarity index 100% rename from cpp/autosar/test/rules/M3-1-2/test.cpp rename to cpp/common/test/rules/functiondeclaredatblockscope/test.cpp diff --git a/cpp/misra/src/rules/RULE-11-3-1/VariableDeclaredArrayType.ql b/cpp/misra/src/rules/RULE-11-3-1/VariableDeclaredArrayType.ql new file mode 100644 index 0000000000..24b08fae09 --- /dev/null +++ b/cpp/misra/src/rules/RULE-11-3-1/VariableDeclaredArrayType.ql @@ -0,0 +1,35 @@ +/** + * @id cpp/misra/variable-declared-array-type + * @name RULE-11-3-1: Variables of array type should not be declared + * @description Using array type instead of container types can lead to difficulty manually managing + * size and accesses. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-11-3-1 + * correctness + * maintainability + * readability + * scope/single-translation-unit + * external/misra/enforcement/decidable + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.cpp.misra + +class FixedSizeCharArray extends Variable { + FixedSizeCharArray() { + this.isStatic() and + this.getUnspecifiedType().stripType() instanceof CharType and + this.getInitializer().getExpr() instanceof StringLiteral + } +} + +from Variable v +where + not isExcluded(v, Declarations3Package::variableDeclaredArrayTypeQuery()) and + exists(ArrayType a | v.getType() = a | not v instanceof FixedSizeCharArray) and + // Exclude the compiler generated __func__ as it is the only way to access the function name information + not v.getName() = "__func__" +select v, "Variable " + v.getName() + " has an array type." diff --git a/cpp/misra/src/rules/RULE-6-0-1/BlockScopeFunctionAmbiguous.ql b/cpp/misra/src/rules/RULE-6-0-1/BlockScopeFunctionAmbiguous.ql new file mode 100644 index 0000000000..504cbfc63e --- /dev/null +++ b/cpp/misra/src/rules/RULE-6-0-1/BlockScopeFunctionAmbiguous.ql @@ -0,0 +1,25 @@ +/** + * @id cpp/misra/block-scope-function-ambiguous + * @name RULE-6-0-1: Block scope declarations shall not be visually ambiguous + * @description A function declared at block scope can make code harder to read and may lead to + * developer confusion. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-6-0-1 + * maintainability + * readability + * scope/single-translation-unit + * external/misra/enforcement/decidable + * external/misra/obligation/required + */ + +import cpp +import codingstandards.cpp.misra +import codingstandards.cpp.rules.functiondeclaredatblockscope.FunctionDeclaredAtBlockScope + +module BlockScopeFunctionAmbiguousConfig implements FunctionDeclaredAtBlockScopeConfigSig { + Query getQuery() { result = Declarations3Package::blockScopeFunctionAmbiguousQuery() } +} + +import FunctionDeclaredAtBlockScope diff --git a/cpp/misra/test/rules/RULE-11-3-1/VariableDeclaredArrayType.expected b/cpp/misra/test/rules/RULE-11-3-1/VariableDeclaredArrayType.expected new file mode 100644 index 0000000000..efe6eefa3c --- /dev/null +++ b/cpp/misra/test/rules/RULE-11-3-1/VariableDeclaredArrayType.expected @@ -0,0 +1,9 @@ +| test.cpp:5:5:5:5 | g | Variable g has an array type. | +| test.cpp:9:24:9:24 | a | Variable a has an array type. | +| test.cpp:10:7:10:8 | a1 | Variable a1 has an array type. | +| test.cpp:14:7:14:8 | a1 | Variable a1 has an array type. | +| test.cpp:19:7:19:7 | x | Variable x has an array type. | +| test.cpp:20:17:20:17 | a | Variable a has an array type. | +| test.cpp:22:8:22:9 | x1 | Variable x1 has an array type. | +| test.cpp:28:6:28:7 | g1 | Variable g1 has an array type. | +| test.cpp:34:21:34:21 | p | Variable p has an array type. | diff --git a/cpp/misra/test/rules/RULE-11-3-1/VariableDeclaredArrayType.qlref b/cpp/misra/test/rules/RULE-11-3-1/VariableDeclaredArrayType.qlref new file mode 100644 index 0000000000..7756cec49e --- /dev/null +++ b/cpp/misra/test/rules/RULE-11-3-1/VariableDeclaredArrayType.qlref @@ -0,0 +1 @@ +rules/RULE-11-3-1/VariableDeclaredArrayType.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-11-3-1/test.cpp b/cpp/misra/test/rules/RULE-11-3-1/test.cpp new file mode 100644 index 0000000000..ee54c28ab5 --- /dev/null +++ b/cpp/misra/test/rules/RULE-11-3-1/test.cpp @@ -0,0 +1,36 @@ + +#include +#include + +int g[100]; // NON_COMPLIANT + +class C { +public: + static constexpr int a[1]{0}; // NON_COMPLIANT + int a1[1]; // NON_COMPLIANT +}; + +struct S { + int a1[1]; // NON_COMPLIANT +}; + +void test_c_arrays() { + + int x[100]; // NON_COMPLIANT + constexpr int a[]{0, 1, 2}; // NON_COMPLIANT + const size_t s{1}; + char x1[s]; // NON_COMPLIANT + std::array x2; // COMPLIANT + + __func__; // COMPLIANT +} + +char g1[] = "abc"; // NON_COMPLIANT +const char g2[] = "abc"; // COMPLIANT + +using namespace std::literals; +const auto g3 = "abc"sv; // COMPLIANT + +void param_test(int p[1], int (&p1)[1], int (*p2)[1], + int *p3) { // NON_COMPLIANT -- p, rest are compliant +} \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-6-0-1/BlockScopeFunctionAmbiguous.testref b/cpp/misra/test/rules/RULE-6-0-1/BlockScopeFunctionAmbiguous.testref new file mode 100644 index 0000000000..0c0e3c1016 --- /dev/null +++ b/cpp/misra/test/rules/RULE-6-0-1/BlockScopeFunctionAmbiguous.testref @@ -0,0 +1 @@ +cpp/common/test/rules/functiondeclaredatblockscope/FunctionDeclaredAtBlockScope.ql \ No newline at end of file diff --git a/rule_packages/cpp/Declarations.json b/rule_packages/cpp/Declarations.json index 61d286026a..e4daae17fb 100644 --- a/rule_packages/cpp/Declarations.json +++ b/rule_packages/cpp/Declarations.json @@ -291,6 +291,7 @@ "precision": "very-high", "severity": "warning", "short_name": "FunctionsDeclaredAtBlockScope", + "shared_implementation_short_name": "FunctionDeclaredAtBlockScope", "tags": [ "correctness", "maintainability" diff --git a/rule_packages/cpp/Declarations3.json b/rule_packages/cpp/Declarations3.json new file mode 100644 index 0000000000..f1c0718e9d --- /dev/null +++ b/rule_packages/cpp/Declarations3.json @@ -0,0 +1,53 @@ +{ + "MISRA-C++-2023": { + "RULE-11-3-1": { + "properties": { + "enforcement": "decidable", + "obligation": "advisory" + }, + "queries": [ + { + "description": "Using array type instead of container types can lead to difficulty manually managing size and accesses.", + "kind": "problem", + "name": "Variables of array type should not be declared", + "precision": "very-high", + "severity": "error", + "short_name": "VariableDeclaredArrayType", + "tags": [ + "correctness", + "maintainability", + "readability", + "scope/single-translation-unit" + ] + } + ], + "title": "Variables of array type should not be declared" + }, + "RULE-6-0-1": { + "properties": { + "enforcement": "decidable", + "obligation": "required" + }, + "queries": [ + { + "description": "A function declared at block scope can make code harder to read and may lead to developer confusion.", + "kind": "problem", + "name": "Block scope declarations shall not be visually ambiguous", + "precision": "very-high", + "severity": "warning", + "short_name": "BlockScopeFunctionAmbiguous", + "shared_implementation_short_name": "FunctionDeclaredAtBlockScope", + "tags": [ + "maintainability", + "readability", + "scope/single-translation-unit" + ], + "implementation_scope": { + "description": "The rule checks for functions in block scope only. The information CodeQL has access to in the database is not enough to cover the object with redundant parentheses case." + } + } + ], + "title": "Block scope declarations shall not be visually ambiguous" + } + } +} \ No newline at end of file diff --git a/rules.csv b/rules.csv index 008020f371..3f81aac7f3 100644 --- a/rules.csv +++ b/rules.csv @@ -849,7 +849,7 @@ cpp,MISRA-C++-2023,RULE-5-13-4,Yes,Required,Decidable,Single Translation Unit,Un cpp,MISRA-C++-2023,RULE-5-13-5,Yes,Required,Decidable,Single Translation Unit,The lowercase form of L shall not be used as the first character in a literal suffix,RULE-7-3,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-5-13-6,Yes,Required,Decidable,Single Translation Unit,An integer-literal of type long long shall not use a single L or l in any suffix,,Expressions2,Easy, cpp,MISRA-C++-2023,RULE-5-13-7,No,Required,Decidable,Single Translation Unit,String literals with different encoding prefixes shall not be concatenated,A2-13-2,,, -cpp,MISRA-C++-2023,RULE-6-0-1,Yes,Required,Decidable,Single Translation Unit,Block scope declarations shall not be visually ambiguous,"M3-1-2,DCL53-CPP",Declarations2,Easy, +cpp,MISRA-C++-2023,RULE-6-0-1,Yes,Required,Decidable,Single Translation Unit,Block scope declarations shall not be visually ambiguous,"M3-1-2,DCL53-CPP",Declarations3,Easy, cpp,MISRA-C++-2023,RULE-6-0-2,Yes,Advisory,Decidable,Single Translation Unit,"When an array with external linkage is declared, its size should be explicitly specified",RULE-18-8,Linkage1,Import, cpp,MISRA-C++-2023,RULE-6-0-3,Yes,Advisory,Decidable,Single Translation Unit,"The only declarations in the global namespace should be main, namespace declarations and extern ""C"" declarations",M7-3-1,ImportMisra23,Import, cpp,MISRA-C++-2023,RULE-6-0-4,Yes,Required,Decidable,Single Translation Unit,The identifier main shall not be used for a function other than the global function main,M7-3-2,ImportMisra23,Import, @@ -922,7 +922,7 @@ cpp,MISRA-C++-2023,RULE-10-2-2,Yes,Advisory,Decidable,Single Translation Unit,Un cpp,MISRA-C++-2023,RULE-10-2-3,Yes,Required,Decidable,Single Translation Unit,The numeric value of an unscoped enumeration with no fixed underlying type shall not be used,A4-5-1,Banned3,Easy, cpp,MISRA-C++-2023,RULE-10-3-1,Yes,Advisory,Decidable,Single Translation Unit,There should be no unnamed namespaces in header files,"DCL59-CPP, M7-3-3",Banned4,Easy, cpp,MISRA-C++-2023,RULE-10-4-1,Yes,Required,Decidable,Single Translation Unit,The asm declaration shall not be used,A7-4-1,ImportMisra23,Import, -cpp,MISRA-C++-2023,RULE-11-3-1,Yes,Advisory,Decidable,Single Translation Unit,Variables of array type should not be declared,,Declarations2,Easy, +cpp,MISRA-C++-2023,RULE-11-3-1,Yes,Advisory,Decidable,Single Translation Unit,Variables of array type should not be declared,A18-1-1,Declarations3,Easy, cpp,MISRA-C++-2023,RULE-11-3-2,Yes,Advisory,Decidable,Single Translation Unit,The declaration of an object should contain no more than two levels of pointer indirection,A5-0-3,ImportMisra23,Import, 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