0

我目前正在尝试使用 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 的静态分析。规则说

移位运算符的右手操作数应位于比左手操作数的基础类型的位宽度小 0 到 1 之间

规则文档指出,此特定规则报告违规,如果

  • 右侧操作数是具有负值或值超过左侧操作数长度(以位为单位)的常数
  • 右手操作数不是常数,并且不被特定模式检查

由于我没有对右手操作数使用常量,因此 MISRA-C 规则规定我在此语句周围加上限制检查。MISRA-C 还指出

使用无符号整数类型将确保操作数为非负数,因此只需要检查上限(在运行时动态或通过查看)。否则,将需要检查这两个限制。”

由于我使用的是无符号类型,uint32_t因此我只需要检查右手操作数的上限。但是,对于val << (32u - n),我不能具有nas的值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(32u - n)尽管进行了极限检查,为什么 parasoft 软件仍然报告右手操作数的错误?

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

4

1 回答 1

0

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

尽管进行了极限检查,为什么 parasoft 软件仍然报告右手操作数为 (32u - n) 的错误?

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

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

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

您的原始代码很好,除了32->之外32u,它还符合 MISRA。不要仅仅为了使可能损坏的工具保持沉默而将其与防御性编程混为一谈。仅当您有理由相信它n实际上为零或大于 32 时才添加此类检查。

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

(为了挑剔,MISRA-C:2004 不允许inline,因为它不允许 C99,因此您需要 MISRA-C:2012。)

于 2020-09-17T08:25:23.273 回答