12

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?

Nicholas Bishop
  • 1,141
  • 9
  • 21
  • 1
    compile with `gcc -Wall` , you are gonna get warnings for all those occurances – RoiHatam May 05 '17 at 18:52
  • 2
    @Roi No, you won't get any warnings about that. –  May 05 '17 at 18:55
  • @NeilButterworth What is this then `warning: control reaches end of non-void function [-Wreturn-type]` – RoiHatam May 05 '17 at 18:58
  • 2
    That's not an unused return value, it's no value being returned. The two things are completely different. –  May 05 '17 at 18:59
  • 2
    @RoiHatam That's something different. That when the function itself forget to return a value. What we have here is when the caller of the function doesn't use its returned value. – Galik May 05 '17 at 19:00
  • @NeilButterworth Thank you – RoiHatam May 05 '17 at 19:01
  • @Galik Thank you I misread. – RoiHatam May 05 '17 at 19:01
  • If you need this ability for only 1 language, what would it be: C or C++? I suspect posting for only 1 language would have prevented a DV. – chux - Reinstate Monica May 05 '17 at 19:10
  • 1
    I'd rather not speculate about why someone downvoted :) I am specifically interested in both C and C++ for this question. – Nicholas Bishop May 05 '17 at 19:32
  • It's easy enough to set up an example program to test on -- even one that is written in the common subset of C and C++. Having done so, I can tell you that no combination of warning options causes either `gcc` or `g++` to warn about unused function results for functions without the `warn_unused_result` attribute. (As judged by enabling *all* warnings.) – John Bollinger May 05 '17 at 19:35
  • 1
    That's quite useless. For `printf` for example one typically does not test the result and there are a lot of other functions one does not use the result, although they return one. "but of course for a large project that is not practical to do." - That's a wrong presumption. It is of course the best and correct way to do so! Why do you assume it is not possible? For a single function one knows best if the result is more "informative" or always has to be checked. – too honest for this site May 05 '17 at 21:22
  • I'm aware that one typically doesn't check the return value of `printf`, but that doesn't mean it's a useless thing to check: "Upon successful return, these functions return the number of characters printed (excluding the null byte used to end output to strings). [...] If an output error is encountered, a negative value is returned." (from the man page) – Nicholas Bishop May 05 '17 at 21:29
  • 1
    voted to reopen, this question is the opposite of "too broad" – M.M May 06 '17 at 00:24
  • Why not try to use static analizer such as cppcheck or pvs-studio? – Denis Sablukov Oct 29 '18 at 09:09

3 Answers3

3

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.

Scott McPeak
  • 8,803
  • 2
  • 40
  • 79
1

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.

sbh
  • 407
  • 4
  • 13
0

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.

Read this:https://social.msdn.microsoft.com/Forums/vstudio/en-US/4355715a-5af7-4a2b-8aa0-bc2112eaa911/how-to-get-a-warning-for-an-unused-return-value?forum=vclanguage

and this mandatory-error-codes-revisited from: http://www.drdobbs.com/cpp/mandatory-error-codes-revisited/191601612

I_Al-thamary
  • 3,385
  • 2
  • 24
  • 37