Skip to content

Fix Rule 14.3 detection for bounded expressions - #8819

Open
jfdeverge wants to merge 1 commit into
cppcheck-opensource:mainfrom
jfdeverge:dev/fix_misra_14_3
Open

Fix Rule 14.3 detection for bounded expressions#8819
jfdeverge wants to merge 1 commit into
cppcheck-opensource:mainfrom
jfdeverge:dev/fix_misra_14_3

Conversation

@jfdeverge

Copy link
Copy Markdown
Contributor

There was missing detection of 'MISRA C:2012 Rule 14.3" on some specific code structure generated by Matlab Simulink coder.
We identified these issues by comparing its results with reports previously generated by our company’s internal tool on the same software.

The bug report would have looked like below.

Problem

Cppcheck did not report a MISRA C:2012 Rule 14.3 violation when a comparison
used an integer expression whose range was provably bounded by casts and
constant arithmetic. The existing check handled a variable compared with a
value outside the variable's declared type range, but did not evaluate this
equivalent expression form.

Minimal Reproducer

typedef unsigned int uint32;
typedef unsigned long long uint64;
typedef long long sint64;

void f(uint32 x)
{
    uint64 tmp = ((uint64)x) + 1ULL;
    if (tmp > 4294967295ULL)
        tmp = 4294967295ULL;

    if ((((sint64)((uint32)tmp)) - 1LL) > 4294967295LL) {
    }
}

After the clamp and casts, the left-hand expression cannot exceed
UINT32_MAX - 1. Therefore the final condition is always false and should
produce the compareValueOutOfTypeRangeError diagnostic, which the MISRA
postprocessor maps to Rule 14.3.

Observed Behavior

Before the fix, the final comparison produced no diagnostic. This allowed the
generated-code pattern to pass through the cppcheck-based MISRA pipeline
without the expected Rule 14.3 finding.

Fix

The condition checker now:

  • calculates ranges for supported scalar integer types;
  • recursively evaluates integer casts, transparent parentheses, and addition
    or subtraction by constant expressions;
  • evaluates comparisons against the resulting interval when the result is
    provably always true or always false; and
  • retains the existing compareValueOutOfTypeRangeError diagnostic path.

Uncertain or unsupported ranges remain unreported to avoid speculative
findings. Interval arithmetic includes overflow guards.

Regression Coverage

The exact typedef-based reproducer is covered by
TestCondition::compareOutOfTypeRange in test/testcondition.cpp. The focused
test, the complete TestCondition suite, and the registered CTest target pass
with the fix.

Comment thread lib/checkcondition.cpp Fixed
Comment thread test/testcondition.cpp
" if ((((sint64)((uint32)tmp)) - 1LL) < 0LL) {}\n"
" if ((((sint64)((uint32)tmp)) - 1LL) > 4294967295LL) {}\n"
"}\n", settingsUnix64);
ASSERT_EQUALS("[test.cpp:9:43]: (style) Comparing expression of type 'signed long long' against value 4294967295. Condition is always false. [compareValueOutOfTypeRangeError]\n",

@chrchr-github chrchr-github Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text/ID of the warning seems incorrect. 4294967295 is within range for signed long long.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello! The condition is essentially (sint64), the diagnostic log is correct. But the check is only possible because there is a (uint32) inside.

@chrchr-github

Copy link
Copy Markdown
Collaborator

I have created this ticket: https://trac.cppcheck.net/ticket/15000

@jfdeverge

Copy link
Copy Markdown
Contributor Author

I will update the commit message with Fix #15000 ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants