我想静态检查对未使用返回值的非void函数的所有调用。
实际上,这就像将__attribute__ ((warn_unused_result))
应用于所有非空函数,但当然对于一个不切实际的大型项目。
是否有可以提供此信息的静态分析工具?
答案 0 :(得分:2)
可以使用clang-query
完成此操作。以下是一个shell脚本,该脚本调用clang-query
来查找返回未使用值的调用:
#!/bin/sh
# cmd.sh: Run clang-query to report unused return values.
# When --dump, print the AST of matching syntax.
if [ "x$1" = "x--dump" ]; then
dump="set output dump"
shift
fi
query='m
callExpr(
isExpansionInMainFile(),
hasParent(anyOf(
compoundStmt(),
ifStmt(hasCondition(expr().bind("cond"))),
whileStmt(hasCondition(expr().bind("cond"))),
doStmt(hasCondition(expr().bind("cond")))
)),
unless(hasType(voidType())),
unless(isTypeDependent()),
unless(cxxOperatorCallExpr()),
unless(callee(namedDecl(anyOf(
hasName("memset"),
hasName("setlength"),
hasName("flags"),
hasName("width"),
hasName("__builtin_memcpy")
)))),
unless(equalsBoundNode("cond")))'
clang-query -c="$dump" -c="$query" "$@"
要在test1.cc
上运行它:
$ ./cmd.sh test1.cc --
查询的基本思想是查找直接父级为复合语句的调用表达式。对此进行了扩展,以处理作为控制流语句的直接父级,请注意不要在调用作为条件表达式出现时报告。
查询处理的其他一些复杂问题:
此选项仅报告翻译单元的主文件,以消除标题中的大量杂音。从消防水带上取下isExpansionInMainFile
过滤器以饮用。
在C ++模板中,我们可能不知道类型是什么,因此禁止报告所有具有依赖类型的调用。
诸如memset
之类的某些函数具有无用或很少有用的返回值。必须将它们过滤掉以查看任何有用的信号。查询中的函数名称列表仅是冰山一角。
C ++重载运算符,包括operator<<
和operator=
,通常返回一个值,但是该值通常被忽略。因此,禁止显示所有重载运算符的报告。
我在我的实用程序库中的某些文件上进行了轻度的测试(使用clang + llvm-8.0.1中的clang-query
),这就是我发现需要过滤掉的某些内容的方式为了这个有用。取决于您的应用程序,可能还有更多需要过滤的内容。
查询语言在https://clang.llvm.org/docs/LibASTMatchersReference.html中进行了描述。有关clang-query
的更多链接和信息,请参见this answer of mine。
答案 1 :(得分:0)
Cppcheck是一个命令行工具,它试图检测C / C ++编译器看不到的错误,它还包括一个基于Web的报告生成器。
答案 2 :(得分:0)
我认为有些软件可以像DevExtreme
这样,social.msdn.microsoft.com
在回答问题how-to-get-a-warning-for-an-unused-return-value?
的过程中,他们提到Visual Studio的Premium和Ultimate版本具有一些工具。 / p>
以及来自http://www.drdobbs.com/cpp/mandatory-error-codes-revisited/191601612
的mandatory-error-codes-revisited