混淆控制流分析从Parasoft c++测试

Confusing control flow analysis from Parasoft C++test

本文关键字:c++ 测试 Parasoft 控制流分析      更新时间:2023-10-16

我们使用Parasoft c++测试来静态分析我们的代码。它遇到如下代码的问题:

void foo(int* x) {
    try {
        bar();
    } catch(...) {
        delete x;
        throw;
    }
    *x;
}

*x;行警告:

释放的内存在任何情况下都不应该被访问

从某种程度上说,控制流可以通过catch(...)块,删除x,通过throw;,到达*x;。我尝试了throw std::exception("");和其他几个,得到了同样的东西。Parasoft当然知道异常,并将它们合并到控制流中,因为有许多其他测试涉及异常检查。在这种情况下,它只是混淆了,还是实际上有一些方法可以让这个程序的执行同时击中delete x;*x; ?

所以这个工具是错误的(我知道以前有人说过),我假设您不想切换警告。

我同意@Pascal的评论,重写代码只是为了绕过某些工具的限制是有些危险的。您可以做的是仅对当前存在此问题的文件禁用此警告。

然后,你有一个警告免费的构建开始,没有一个工具告诉重写现有的有效代码。

对于新代码,您必须采用工具能够理解的样式。这不是一个问题,因为这将是你目前正在处理的代码,所以如果你需要稍微重写它以摆脱警告,这将不是一个问题。

虽然正确,但现有的风格远非理想。

我建议将像x这样的指针存储在auto_ptr中。这将在auto_ptr的内容超出作用域时自动删除它——除非您显式地将其从auto_ptr中删除。这样看起来容易多了,也很好地说明了这个函数获得了指针的所有权。
void foo(auto_ptr<int> x)
{
    bar();
    *x;
}

我希望ParaSoft对这段代码没有问题。

也许这是一个愚蠢的建议,但是如果你把catch留到最后,Parasoft会说什么呢?例如

void foo(int* x) 
  {
  try 
    {
    bar();
    *x;
    } 
  catch(...) 
    {
    delete x;
    throw;
    }      
  }

我意识到这可能不适用于语句和异常的所有组合,例如,如果您在foo的不同阶段使用不同的处理来捕获多个异常类型,但如果您真的想要摆脱警告,它至少可以为您提供一个解决方案。

快速更新:

1)上述规则根本不是流分析规则。也就是说,该规则(ID MRM-31)在c++测试9.2.0和更高版本中得到了改进。在c++测试(ID: BD-RES-FREE)中也有一个相应的流分析规则,它应该做你想做的事情。