From dacccc6f5c3bf0a4b060639bff74408d858c54a8 Mon Sep 17 00:00:00 2001 From: Jan Schlosser Date: Tue, 27 Oct 2026 09:59:35 +0100 Subject: [PATCH] Fix false positives in RULE-8-2-6 for implicit conversions Implicit conversions, such as the implicit this in unevaluated operands, are not casts and were reported as integral to pointer casts. --- .../2026-10-27-fix-fp-rule-8-2-6-implicit-casts.md | 2 ++ .../rules/RULE-8-2-6/IntToPointerCastProhibited.ql | 3 +++ .../RULE-8-2-6/IntToPointerCastProhibited.expected | 1 + cpp/misra/test/rules/RULE-8-2-6/test.cpp | 14 +++++++++++++- 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 change_notes/2026-10-27-fix-fp-rule-8-2-6-implicit-casts.md diff --git a/change_notes/2026-10-27-fix-fp-rule-8-2-6-implicit-casts.md b/change_notes/2026-10-27-fix-fp-rule-8-2-6-implicit-casts.md new file mode 100644 index 0000000000..5e424ebfcc --- /dev/null +++ b/change_notes/2026-10-27-fix-fp-rule-8-2-6-implicit-casts.md @@ -0,0 +1,2 @@ +- `RULE-8-2-6` - `IntToPointerCastProhibited.ql`: + - Remove false positives for implicit conversions, such as the implicit `this` in unevaluated operands (e.g. `sizeof(member)`). diff --git a/cpp/misra/src/rules/RULE-8-2-6/IntToPointerCastProhibited.ql b/cpp/misra/src/rules/RULE-8-2-6/IntToPointerCastProhibited.ql index 0a97dc5359..7dfb8c04bc 100644 --- a/cpp/misra/src/rules/RULE-8-2-6/IntToPointerCastProhibited.ql +++ b/cpp/misra/src/rules/RULE-8-2-6/IntToPointerCastProhibited.ql @@ -20,6 +20,9 @@ import codingstandards.cpp.misra from Cast cast, Type sourceType, PointerType targetType, string typeKind where not isExcluded(cast, Conversions2Package::intToPointerCastProhibitedQuery()) and + // Implicit conversions are not casts, e.g. null pointer constants or the implicit `this` in an + // unevaluated operand. + not cast.isImplicit() and sourceType = cast.getExpr().getType().getUnspecifiedType() and targetType = cast.getType().getUnspecifiedType() and ( diff --git a/cpp/misra/test/rules/RULE-8-2-6/IntToPointerCastProhibited.expected b/cpp/misra/test/rules/RULE-8-2-6/IntToPointerCastProhibited.expected index 18accdc95e..93efa8b935 100644 --- a/cpp/misra/test/rules/RULE-8-2-6/IntToPointerCastProhibited.expected +++ b/cpp/misra/test/rules/RULE-8-2-6/IntToPointerCastProhibited.expected @@ -9,3 +9,4 @@ | test.cpp:35:22:35:57 | reinterpret_cast... | Cast from pointer to void type 'void *' to pointer type 'int32_t *'. | | test.cpp:43:14:43:41 | reinterpret_cast... | Cast from integral type 'int32_t' to pointer type 'void *'. | | test.cpp:44:14:44:41 | reinterpret_cast... | Cast from integral type 'int64_t' to pointer type 'void *'. | +| test.cpp:100:12:100:58 | reinterpret_cast... | Cast from integral type 'unsigned long' to pointer type 'TestStruct *'. | diff --git a/cpp/misra/test/rules/RULE-8-2-6/test.cpp b/cpp/misra/test/rules/RULE-8-2-6/test.cpp index 5abd52242e..f14853be3f 100644 --- a/cpp/misra/test/rules/RULE-8-2-6/test.cpp +++ b/cpp/misra/test/rules/RULE-8-2-6/test.cpp @@ -87,4 +87,16 @@ void test_compliant_regular_pointer_operations() { // Regular pointer operations that don't involve forbidden casts TestStruct *l4 = l2; // COMPLIANT std::int32_t *l5 = l3; // COMPLIANT -} \ No newline at end of file +} +// The implicit `this` of a member access in an unevaluated operand is +// extracted as a conversion of 0 to a pointer. It is not a cast. +struct ImplicitThis { + std::int32_t m1; + static constexpr unsigned long size() noexcept { + return sizeof(m1); // COMPLIANT + } + TestStruct *nonCompliant(std::int64_t l1) { + // The implicit `this` of m1 is compliant, the explicit cast is not + return reinterpret_cast(l1 + sizeof(m1)); // NON_COMPLIANT + } +};