MISRA2004-12_8-3 规则对 RHS 操作数 (32u - n) 有静态分析违规,即使有限制检查

MISRA2004-12_8-3 rule has static analysis violation for RHS operand (32u - n) even with limits check

我目前正在尝试使用 Parasoft 软件修复我使用 MISRA C 编码标准的代码的静态分析违规。我的代码最初有这个功能:

static inline uint32_t rotate_right(uint32_t val, uint32_t n)
{
    return (val >> n) | (val << (32 - n));
}

这会导致静态分析违反规则 MISRA2004-12_8-3。规则说

The right-hand operand of a shift operator shall lie between zero and one less than the width in bits of the underlying type of the left-hand operand

规则文档指出,如果

,此特定规则会报告违规
  • the right-hand operand is a constant with negative value or with value that exceeds the length (in bits) of the left-hand operand
  • the right-hand operand is not a constant and is not checked by specific pattern

由于我没有为右侧操作数使用常量,MISRA-C 规则规定我用限制检查包围此语句。 MISRA-C 还指出

Use of an unsigned integer type will ensure that the operand is non-negative, so then only the upper limit needs to be checked (dynamically at run-time or by review). Otherwise both limits will need to be checked."

由于我使用的是无符号类型,uint32_t,我只需要检查右手操作数的上限。但是,对于 val << (32u - n),我不能将 n 的值设为 0u。因此,我尝试通过添加以下检查来解决此违规问题:

static inline uint32_t rotate_right(uint32_t val, uint32_t n)
{
    if (n == 0u)
    {
        return val;
    }
    else if ((n > 0u) && (n <= 31u))
    {
        return (val >> n) | (val << (32u - n)); 
    }
    else
    {
        return 0u;
    }
}

这样做可以解决 (val >> n) 的静态分析违规问题,但仍会报告 (val << (32u - n)) 的静态分析违规问题。

因此,我的问题是:

  1. if语句明确限制了n的值小于32u。因此,(32u - n) 的值也将小于或等于 32u。尽管进行了限制检查,为什么 parasoft 软件仍然报告右侧操作数为 (32u - n) 的错误?

  2. 解决此违规行为的正确方法是什么?

正如 MISRA-C 文档所说,只有在 run-time 或代码审查期间动态检查它才是明智的。这当然不会阻止功能失调的静态分析器在静态分析期间尝试这样做......

Why is parasoft software still reporting an error for the right-hand operand being (32u - n) despite the limit check?

可能是因为它被窃听并报告误报。

当然,除非它发现某些 caller-side 代码提供的 n 大于 32。一些静态分析器在检查整个项目而不是单个翻译单元时能够给出更智能的警告。

What is the correct way to resolve this violation?

您的原始代码很好,除了 32 -> 32u,它符合 MISRA 标准。不要只是为了让可能损坏的工具安静下来而将其与防御性编程混为一谈。仅当您有理由相信 n 实际上为零或大于 32 时才添加此类检查。

对于 MISRA-C 合规性,声明代码审查将涵盖变量 n 的情况就足够了。

(挑剔一点,MISRA-C:2004 不允许 inline 因为它不允许 C99,所以你需要 MISRA-C:2012。)