Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions change_notes/2026-08-20-fix-fp-rule-7-0-1-bool-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- `RULE-7-0-1` - `NoConversionFromBool.ql`:
- Fixed false positives where a `bool` value is bound to a reference whose
referenced type is also `bool` (e.g. `bool&`, `const bool&`), including
when this happens via a generic/forwarding-reference parameter (e.g.
`template<class T> void f(T&& t)`, or class template forwarding
constructors such as `std::pair`'s `pair(U1&&, U2&&)`) that happens to be
instantiated with `bool`. Binding a value to a reference of its own type
does not change the type or representation of the value, so this is not
a conversion from `bool` in the sense intended by the rule.
12 changes: 12 additions & 0 deletions cpp/misra/src/rules/RULE-7-0-1/NoConversionFromBool.ql
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ where
conv = e.getConversion() and
conv.getExpr().getType().stripTopLevelSpecifiers() instanceof BoolType and
not conv.getType().stripTopLevelSpecifiers() instanceof BoolType and
// Exclude conversions that only bind a `bool` value to a reference to `bool`
// (e.g. `bool&`, `const bool&`). Binding a value to a reference of its own
// type does not change the type or representation of the value, so this is
// not a "conversion from bool" in the sense intended by the rule. This
// commonly occurs when a `bool` argument is forwarded through a generic
// `bool&`/`const bool&` parameter (e.g. logging helpers, `std::pair`-style
// structured bindings/aggregates).
not conv.getType()
.stripTopLevelSpecifiers()
.(ReferenceType)
.getBaseType()
.stripTopLevelSpecifiers() instanceof BoolType and
// Exclude cases that are explicitly allowed
not (
// Exception: equality operators with both bool operands
Expand Down
35 changes: 35 additions & 0 deletions cpp/misra/test/rules/RULE-7-0-1/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,39 @@ void test_bool_conversion_compliant() {

// Bit-field assignment exception - compliant
bf.bit = b1; // COMPLIANT
}

void f3(bool &b) {}
void f4(const bool &b) {}

template <typename T> void f5(T &&t) {}

template <typename T1, typename T2> struct Pair {
template <typename U1, typename U2> Pair(U1 &&x, U2 &&y) : a(x), b(y) {}
T1 a;
T2 b;
};

void test_bool_reference_conversion_compliant() {
bool b1 = true;

// Binding a bool lvalue to a bool reference parameter - compliant, no
// actual type conversion takes place.
f3(b1); // COMPLIANT

// Binding a bool value to a const bool reference parameter - compliant.
f4(b1); // COMPLIANT
f4(true); // COMPLIANT

// Binding a bool value to a forwarding reference parameter deduced as
// bool - compliant.
f5(b1); // COMPLIANT
f5(true); // COMPLIANT

// Binding a bool value through a generic forwarding-reference constructor,
// where the second template parameter is deduced as bool - compliant. This
// mirrors idiomatic `return {value, overflow_flag};` and structured-binding
// patterns (e.g. std::pair and std::map::insert()'s return value).
Pair<int, bool> p1{1, true}; // COMPLIANT
Pair<int, bool> p2 = {1, b1}; // COMPLIANT
}
Loading