diff --git a/change_notes/2023-03-15-fix-reported-fp-for-A15-4-4.md b/change_notes/2023-03-15-fix-reported-fp-for-A15-4-4.md new file mode 100644 index 0000000000..c7cb61d2c9 --- /dev/null +++ b/change_notes/2023-03-15-fix-reported-fp-for-A15-4-4.md @@ -0,0 +1,2 @@ +- `A15-4-4` - `MissingNoExcept.ql` + - Exclude call operators embedded in a lambda expression from functions to be declared `noexcept` or `noexcept(false)`. diff --git a/change_notes/2023-03-15-fix-reported-fp-for-A2-7-3.md b/change_notes/2023-03-15-fix-reported-fp-for-A2-7-3.md new file mode 100644 index 0000000000..ce98bab27a --- /dev/null +++ b/change_notes/2023-03-15-fix-reported-fp-for-A2-7-3.md @@ -0,0 +1,2 @@ +- `A2-7-3` - `UndocumentedUserDefinedType.ql`: + - Exclude lambda functions from program elements to be documented. diff --git a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql index 1857003826..0226c20d30 100644 --- a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql +++ b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql @@ -31,5 +31,7 @@ where // Not compiler generated not f.isCompilerGenerated() and // The function is defined in this database - f.hasDefinition() + f.hasDefinition() and + // This function is not an overriden call operator of a lambda expression + not exists(LambdaExpression lambda | lambda.getLambdaFunction() = f) select f, "Function " + f.getName() + " could be declared noexcept(true)." diff --git a/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql b/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql index 54925718f2..247f3ef2a1 100644 --- a/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql +++ b/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql @@ -36,9 +36,7 @@ class DocumentableDeclaration extends Declaration { // Exclude instantiated template functions, which cannot reasonably be documented. not this.(Function).isFromTemplateInstantiation(_) and // Exclude anonymous lambda functions. - not exists(LambdaExpression lc | - lc.getLambdaFunction() = this and not lc.getEnclosingElement() instanceof Initializer - ) + not exists(LambdaExpression lc | lc.getLambdaFunction() = this) or this instanceof MemberVariable and declarationType = "member variable" and diff --git a/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected b/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected index b91ac0e0ce..bdd73be2eb 100644 --- a/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected +++ b/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected @@ -1,14 +1,14 @@ -| test.cpp:22:10:22:11 | 0 | Definition of $@ is unused. | test.cpp:22:7:22:7 | y | y | -| test.cpp:25:3:25:5 | ... ++ | Definition of $@ is unused. | test.cpp:24:7:24:7 | z | z | -| test.cpp:42:3:42:7 | ... = ... | Definition of $@ is unused. | test.cpp:20:41:20:41 | p | p | -| test.cpp:44:10:44:11 | 0 | Definition of $@ is unused. | test.cpp:44:7:44:8 | l3 | l3 | -| test.cpp:45:13:45:22 | new | Definition of $@ is unused. | test.cpp:45:8:45:9 | l4 | l4 | -| test.cpp:48:8:48:8 | {...} | Definition of $@ is unused. | test.cpp:48:5:48:6 | a2 | a2 | -| test.cpp:49:11:49:15 | new | Definition of $@ is unused. | test.cpp:49:6:49:7 | a3 | a3 | -| test.cpp:50:11:50:17 | new | Definition of $@ is unused. | test.cpp:50:6:50:7 | a4 | a4 | -| test.cpp:51:11:51:17 | 0 | Definition of $@ is unused. | test.cpp:51:6:51:7 | a5 | a5 | -| test.cpp:55:3:55:10 | ... = ... | Definition of $@ is unused. | test.cpp:52:5:52:6 | a6 | a6 | -| test.cpp:60:11:60:15 | new | Definition of $@ is unused. | test.cpp:60:6:60:7 | b3 | b3 | -| test.cpp:61:11:61:17 | new | Definition of $@ is unused. | test.cpp:61:6:61:7 | b4 | b4 | -| test.cpp:62:11:62:17 | 0 | Definition of $@ is unused. | test.cpp:62:6:62:7 | b5 | b5 | -| test.cpp:70:11:70:17 | 0 | Definition of $@ is unused. | test.cpp:70:6:70:7 | c5 | c5 | +| test.cpp:55:10:55:11 | 0 | Definition of $@ is unused. | test.cpp:55:7:55:7 | y | y | +| test.cpp:58:3:58:5 | ... ++ | Definition of $@ is unused. | test.cpp:57:7:57:7 | z | z | +| test.cpp:75:3:75:7 | ... = ... | Definition of $@ is unused. | test.cpp:53:41:53:41 | p | p | +| test.cpp:77:10:77:11 | 0 | Definition of $@ is unused. | test.cpp:77:7:77:8 | l3 | l3 | +| test.cpp:78:13:78:22 | new | Definition of $@ is unused. | test.cpp:78:8:78:9 | l4 | l4 | +| test.cpp:81:8:81:8 | {...} | Definition of $@ is unused. | test.cpp:81:5:81:6 | a2 | a2 | +| test.cpp:82:11:82:15 | new | Definition of $@ is unused. | test.cpp:82:6:82:7 | a3 | a3 | +| test.cpp:83:11:83:17 | new | Definition of $@ is unused. | test.cpp:83:6:83:7 | a4 | a4 | +| test.cpp:84:11:84:17 | 0 | Definition of $@ is unused. | test.cpp:84:6:84:7 | a5 | a5 | +| test.cpp:88:3:88:10 | ... = ... | Definition of $@ is unused. | test.cpp:85:5:85:6 | a6 | a6 | +| test.cpp:93:11:93:15 | new | Definition of $@ is unused. | test.cpp:93:6:93:7 | b3 | b3 | +| test.cpp:94:11:94:17 | new | Definition of $@ is unused. | test.cpp:94:6:94:7 | b4 | b4 | +| test.cpp:95:11:95:17 | 0 | Definition of $@ is unused. | test.cpp:95:6:95:7 | b5 | b5 | +| test.cpp:103:11:103:17 | 0 | Definition of $@ is unused. | test.cpp:103:6:103:7 | c5 | c5 | diff --git a/cpp/autosar/test/rules/A0-1-1/options.clang b/cpp/autosar/test/rules/A0-1-1/options.clang deleted file mode 100644 index 751f1364f6..0000000000 --- a/cpp/autosar/test/rules/A0-1-1/options.clang +++ /dev/null @@ -1 +0,0 @@ --Wall \ No newline at end of file diff --git a/cpp/autosar/test/rules/A0-1-1/test.cpp b/cpp/autosar/test/rules/A0-1-1/test.cpp index 98c8058219..824d649c6a 100644 --- a/cpp/autosar/test/rules/A0-1-1/test.cpp +++ b/cpp/autosar/test/rules/A0-1-1/test.cpp @@ -17,6 +17,39 @@ struct C { int m; }; +void sample1(int x){}; +void sample2(int y){}; + +static void foo(B &b) noexcept { + b.g(); + B bar{}; + bar.g(); + B b2 = B(); + auto b3 = &b2; + b3->g(); + B &b4 = b; + b4.g(); + auto &b5 = *new B(); + b5.g(); + /* Below causes a compile error (non-const reference when initialized should + * hold an lvalue) + */ + // auto &b6 = new B(); + // b6.g(); +} + +template void test() { + T t; + t.g(); +} + +template void call_test() { + // call it with type parameter B to trigger indexing + test(); +} + +void call_call_test() { call_test(); } + int test_useless_assignment(int &x, int p) { x = 0; // COMPLIANT - x is a reference parameter, so is visible by the caller int y = 0; // NON_COMPLIANT - never used @@ -49,7 +82,7 @@ int test_useless_assignment(int &x, int p) { A *a3 = new A; // NON_COMPLIANT - POD class, no constructor/destructor A *a4 = new A(); // NON_COMPLIANT - POD class, no constructor/destructor A *a5 = nullptr; // NON_COMPLIANT - null never read - A a6{}; // COMPLIANT - `m` assigned below + A a6{}; // COMPLIANT - `f` assigned below a6.f = 2; // COMPLIANT - we don't track the fields here, but we do track `a6`, // so we'd consider this used by the assignment below a6.f = 1; // NON_COMPLIANT - assignment into `f`, but `a6` is not used @@ -69,5 +102,14 @@ int test_useless_assignment(int &x, int p) { C *c4 = new C(); // COMPLIANT - this will call a constructor?? C *c5 = nullptr; // NON_COMPLIANT - null never read + A a7{1, 2}; // COMPLIANT - used in the `sample1` call below + sample1(a7.f + a7.f2); // COMPLIANT - object access is a valid use + + // A *a8; // COMPLIANT - value not given at declaration + // a8 = &a7; + // sample2(a8->f); // COMPLIANT - object access is a valid use + return y; } + +int main() { return 0; } \ No newline at end of file diff --git a/cpp/autosar/test/rules/A15-4-4/test.cpp b/cpp/autosar/test/rules/A15-4-4/test.cpp index 6834c7a8ce..f0b676373e 100644 --- a/cpp/autosar/test/rules/A15-4-4/test.cpp +++ b/cpp/autosar/test/rules/A15-4-4/test.cpp @@ -24,4 +24,10 @@ void test_indirect_throw() { // COMPLIANT - throws an exception indirectly class A { public: A() = delete; // COMPLIANT - deleted functions imply `noexcept(true)`. -}; \ No newline at end of file +}; + +/* Added for testing FP of embedded operator inside lambdas being reported */ +void lambda_example() noexcept { + auto with_capture = [=]() {}; + auto empty_capture = []() {}; +} \ No newline at end of file diff --git a/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected b/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected index 77ede66305..0ae42152f7 100644 --- a/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected +++ b/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected @@ -6,5 +6,4 @@ | test.cpp:78:6:78:6 | declaration of d | Declaration entry for function d is missing documentation. | | test.cpp:81:6:81:6 | definition of e | Declaration entry for function e is missing documentation. | | test.cpp:88:1:88:30 | definition of message_to_string_undocumented | Declaration entry for function message_to_string_undocumented is missing documentation. | -| test.cpp:113:14:113:14 | definition of operator() | Declaration entry for function operator() is missing documentation. | | test.cpp:160:21:160:24 | definition of kBar | Declaration entry for member variable kBar is missing documentation. | diff --git a/cpp/autosar/test/rules/A2-7-3/test.cpp b/cpp/autosar/test/rules/A2-7-3/test.cpp index b467e05c80..bc174d918d 100644 --- a/cpp/autosar/test/rules/A2-7-3/test.cpp +++ b/cpp/autosar/test/rules/A2-7-3/test.cpp @@ -110,7 +110,7 @@ std::string template_function_test() { // COMPLIANT /// @brief function assigned_lambda_test. int assigned_lambda_test() { - auto l = [](int x, int y) { return x + y; }; // NON_COMPLIANT + auto l = [](int x, int y) { return x + y; }; // COMPLIANT: We exclude lambdas. return l(2, 3); } @@ -160,4 +160,4 @@ template class A2_7_3 final { const std::string kBar{"bar"}; // NON_COMPLIANT }; /// @brief This is the instantiateA2_7_3 documentation -void instantiateA2_7_3() { A2_7_3 instance; } +void instantiateA2_7_3() { A2_7_3 instance; } \ No newline at end of file diff --git a/cpp/autosar/test/rules/A5-2-6/test.cpp b/cpp/autosar/test/rules/A5-2-6/test.cpp index 9b7976ed23..0649f7dbc9 100644 --- a/cpp/autosar/test/rules/A5-2-6/test.cpp +++ b/cpp/autosar/test/rules/A5-2-6/test.cpp @@ -15,4 +15,20 @@ void f2(int p1, int p2) { if ((p1 > 0) || (p2 > 0)) { // COMPLIANT f1(); } + + struct Sample { + int x; + } sample; + + if ((p1 > 0) || + sample.x) { // COMPLIANT: struct member accessors (.) are excluded + f1(); + } + + Sample *sample_ptr = &sample; + + if ((p1 > 0) || sample_ptr->x) { // COMPLIANT: struct member accessors with + // dereference (->) are excluded + f1(); + } } \ No newline at end of file