Reputation: 1141
I would like to statically inspect all calls to non-void functions where the return value is not used.
In effect this would be like applying __attribute__ ((warn_unused_result))
to all non-void functions, but of course for a large project that is not practical to do.
Is there any static analysis tool that can provide this information?
Upvotes: 12
Views: 1335
Reputation: 12749
This can be done using clang-query
. Here is a shell script that invokes clang-query
to find calls that return a value that is not used:
#!/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" "$@"
To run this on, say, test1.cc
:
$ ./cmd.sh test1.cc --
The basic idea of the query is to look for call expressions whose immediate parent is a compound statement. That is expanded to handle an immediate parent that is a control flow statement, being careful not to report when the call appears as the conditional expression.
Some other complications the query deals with:
This only reports in the main file of a translation unit in order to eliminate the voluminous noise from headers. Remove the isExpansionInMainFile
filter to drink from the fire hose.
In C++ templates, we might not know what the type is, so suppress reporting all calls with dependent types.
Some functions like memset
have useless or only rarely useful return values. They have to be filtered out to see any useful signal. The list of function names in the query is just the tip of that iceberg.
C++ overloaded operators, including operator<<
and operator=
, usually return a value, but that value is most often ignored. So suppress reports for all overloaded operators.
I've tested this lightly (with clang-query
from clang+llvm-8.0.1) on some files in a utility library of mine, which is how I found some of the things that need to be filtered out for this to be useful. There are probably many more things that need filtering, depending on your application.
The query language is described at https://clang.llvm.org/docs/LibASTMatchersReference.html . See this answer of mine for some more links and information about clang-query
.
Upvotes: 3
Reputation: 3993
I think there are software can do this like DevExtreme
and in social.msdn.microsoft.com
in the answer for this question how-to-get-a-warning-for-an-unused-return-value?
they mention that Premium and Ultimate versions of visual studio has some tools.
and this mandatory-error-codes-revisited
from: http://www.drdobbs.com/cpp/mandatory-error-codes-revisited/191601612
Upvotes: 0
Reputation: 447
Cppcheck is a command-line tool that tries to detect bugs that your C/C++ compiler doesn't see, it also includes a web based report generator.
Upvotes: 1