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

时间:2011-04-26 20:34:34

标签: c++ exception static-analysis control-flow parasoft

我们使用Parasoft C++test来静态分析我们的代码。它在使用以下代码时遇到问题:

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

    *x;
}

它在*x;行警告:

  

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

不知何故,结论是控制流可以传递到catch(...)块,删除x,越过throw;,然后转到*x;。我尝试了throw std::exception("");和其他几个人并得到了同样的东西。 Parasoft当然知道异常并将它们合并到其控制流中,因为还有许多其他测试涉及异常检查。它只是在这种情况下混淆了,还是实际上有一些方法来执行这个程序同时命中delete x;*x;

3 个答案:

答案 0 :(得分:2)

所以这个工具是错的(我之前已经说过,我知道),我认为你不想接受这个警告。

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

然后,您可以开始使用无警告构建,而无需使用工具来重写现有的有效代码。

对于新代码,您必须采用该工具理解的一些样式。这不是一个问题,因为这将是您目前正在处理的代码,因此如果您需要稍微重写以消除警告,那么问题就不那么重要了。

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

我建议在auto_ptr中存储像x这样的指针。如果auto_ptr超出范围,它将自动删除auto_ptr的内容 - 除非你明确地将其从auto_ptr中取出。这在眼睛上更容易,并且很好地证明了这个函数获得了指针的所有权。

void foo(auto_ptr<int> x)
{
    bar();
    *x;
}

我希望ParaSoft对此代码没有任何问题。

答案 1 :(得分:0)

也许这是一个愚蠢的建议,但如果你最后离开捕获物,Parasoft会怎么说?即。

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

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

答案 2 :(得分:0)

快速更新:

1)上述规则根本不是流量分析规则。话虽如此,规则(ID MRM-31)在C ++测试9.2.0及更高版本中得到了改进。在C ++测试中也有相应的流分析规则(ID:BD-RES-FREE),它应该做你想要的。