clang静态分析仪跳过一些检查

Hem*_*ant 6 c++ frontend clang-static-analyzer llvm-clang

我正在使用clang静态分析仪4.0.0.对于以下示例

int fun(){

    int aa = 1,bb = 0;
    int cc = aa/bb; // 1) devide by zero. // Reported by clang

    int *pt = nullptr;
    int a = *pt;    // 2) null pointer dereference. // NOT Reported by clang

    int b;
    int c = a + b;  // 3) Unused initialization. // Reported by clang

    return cc;
}
Run Code Online (Sandbox Code Playgroud)

Clang静态分析仪仅报告两个问题1和3,并跳过问题2.

如果我改变了这样的问题顺序

int fun(){

    int *pt = nullptr;
    int a = *pt;    // 1) null pointer dereference. // Reported by clang

    int aa = 1,bb = 0;
    int cc = aa/bb; // 2) devide by zero. // NOT Reported by clang

    int b;
    int c = a + b;  // 3) Unused initialization. // Reported by clang

    return cc;
}
Run Code Online (Sandbox Code Playgroud)

然后clang静态分析器报告1和3并跳过2.

我用这个命令运行clang静态分析器

clang-check.exe -analyze D:\ testsrc\anothercpp.cpp

这是非常不一致的行为.无论问题的顺序如何,其中一个问题都会被忽略.另外,我用clang 5.0.1检查了这个场景,只是为了得到相同的结果.

有没有人知道为什么静态分析仪会发生这种情况?

提前致谢.

-Hemant

Pau*_*ulR 4

快速浏览一下代码,您观察到的行为似乎是设计使然。

DereferenceChecker可能发现空指针取消引用的程序报告错误时,它会创建一个“错误节点”,停止对路径敏感分析的进一步探索。

void DereferenceChecker::reportBug(ProgramStateRef State, const Stmt *S,
                                   CheckerContext &C) const {
  // Generate an error node.
ExplodedNode *N = C.generateErrorNode(State);
Run Code Online (Sandbox Code Playgroud)

CheckerContext::generateErrorNode 被记录为停止探索程序中的给定路径。

  /// \brief Generate a transition to a node that will be used to report
  /// an error. This node will be a sink. That is, it will stop exploration of
  /// the given path.
  ///
  /// @param State The state of the generated node.
  /// @param Tag The tag to uniquely identify the creation site. If null,
  ///        the default tag for the checker will be used.
  ExplodedNode *generateErrorNode(ProgramStateRef State = nullptr,
                                  const ProgramPointTag *Tag = nullptr) {
    return generateSink(State, Pred,
                       (Tag ? Tag : Location.getTag()));
}
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为在发生像空指针取消引用这样严重的错误之后,无法对程序做出很多有意义的预测。由于空指针取消引用是C++ 中未定义的行为,因此该标准允许任何情况发生。只有查看程序的详细信息及其运行环境,才能做出更多预测。这些预测可能超出了静态分析器的范围。

实际上,您一次只能修复一个错误,并且可能会继续修复错误,直到静态分析器停止发出有效的投诉。

检测未使用的变量不需要路径敏感分析。因此这种类型的检查器仍然可以工作。