From 9ca0d42a6e32a395dccff48fb1eb16476ccac1ce Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Mon, 3 Jun 2024 16:51:30 +0100 Subject: [PATCH 1/7] 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 920875ca3..000000000 --- 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 af8a1d458..000000000 --- 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 c644147bb..000000000 --- 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 2/7] 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 eb5bc9edb..62edb8f58 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 19bec9fa5..09d39ce6f 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 80ab9a6954315c6c70b37d257e4b269406b5e01c Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Tue, 23 Jul 2024 21:57:11 +0100 Subject: [PATCH 3/7] 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 000000000..29a7f48eb --- /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 4/7] 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 09d39ce6f..73c0930f0 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 5/7] 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 0bff55478..1b2898bf6 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 6/7] 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 92c7a4280..3daf48c69 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 61eab4508..6dd130a55 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 7/7] 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 3aa7719fb..6f730736f 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