From cffca13504822be81dcf86e597d2d1cec16dd930 Mon Sep 17 00:00:00 2001 From: Jan Schlosser Date: Thu, 8 Oct 2026 14:54:36 +0200 Subject: [PATCH] Fix RULE-15-1-3 false positives for lambda conversion operators The closure type of a captureless lambda has a compiler-generated conversion operator to a function pointer. It is implicit by definition and cannot be declared explicit, so reporting it is a false positive. Exclude conversion operators declared by a Closure and add regression tests for captureless, generic and capturing lambdas. --- ...6-10-08-fix-fp-rule-15-1-3-lambda-conversion.md | 4 ++++ .../RULE-15-1-3/NonExplicitConversionMember.ql | 3 +++ cpp/misra/test/rules/RULE-15-1-3/test.cpp | 14 +++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 change_notes/2026-10-08-fix-fp-rule-15-1-3-lambda-conversion.md diff --git a/change_notes/2026-10-08-fix-fp-rule-15-1-3-lambda-conversion.md b/change_notes/2026-10-08-fix-fp-rule-15-1-3-lambda-conversion.md new file mode 100644 index 0000000000..122b028451 --- /dev/null +++ b/change_notes/2026-10-08-fix-fp-rule-15-1-3-lambda-conversion.md @@ -0,0 +1,4 @@ +- `RULE-15-1-3` - `NonExplicitConversionMember.ql`: + - Fixed false positives on the compiler-generated conversion operator of a + captureless lambda's closure type (conversion to a function pointer). This + operator is implicit by definition and cannot be declared `explicit`. diff --git a/cpp/misra/src/rules/RULE-15-1-3/NonExplicitConversionMember.ql b/cpp/misra/src/rules/RULE-15-1-3/NonExplicitConversionMember.ql index c85e0d259c..7d6594c4c2 100644 --- a/cpp/misra/src/rules/RULE-15-1-3/NonExplicitConversionMember.ql +++ b/cpp/misra/src/rules/RULE-15-1-3/NonExplicitConversionMember.ql @@ -42,6 +42,9 @@ where exists(ConversionOperator co | x = co and not co.isExplicit() and + // The conversion to a function pointer of a captureless lambda is + // compiler-generated and cannot be declared explicit. + not co.getDeclaringType() instanceof Closure and message = "Conversion operator shall be explicit." ) ) diff --git a/cpp/misra/test/rules/RULE-15-1-3/test.cpp b/cpp/misra/test/rules/RULE-15-1-3/test.cpp index c1470de113..41145356f5 100644 --- a/cpp/misra/test/rules/RULE-15-1-3/test.cpp +++ b/cpp/misra/test/rules/RULE-15-1-3/test.cpp @@ -44,4 +44,16 @@ class TestClass7 { operator double() const; // NON_COMPLIANT operator const char *() const; // NON_COMPLIANT explicit operator void *() const; // COMPLIANT -}; \ No newline at end of file +}; + +void test_lambdas() { + // The conversion to a function pointer of a captureless lambda's closure + // type is compiler-generated and cannot be declared explicit. + auto l1 = [](std::int32_t a) { return a; }; // COMPLIANT + auto l2 = [](auto a) { return a; }; // COMPLIANT + l2(1); + std::int32_t captured = 0; + auto l3 = [captured](std::int32_t a) { return a + captured; }; // COMPLIANT + (void)l1; + (void)l3; +}