|
| 1 | +/** |
| 2 | + * Provides a configurable module UnusedReturnValue with a `problems` predicate |
| 3 | + * for the following issue: |
| 4 | + * The value returned by a function having a non-void return type that is not an |
| 5 | + * overloaded operator shall be used. |
| 6 | + */ |
| 7 | + |
| 8 | +import cpp |
| 9 | +import codingstandards.cpp.Customizations |
| 10 | +import codingstandards.cpp.Exclusions |
| 11 | + |
| 12 | +signature module UnusedReturnValueSharedConfigSig { |
| 13 | + Query getQuery(); |
| 14 | +} |
| 15 | + |
| 16 | +module UnusedReturnValueShared<UnusedReturnValueSharedConfigSig Config> { |
| 17 | + /* |
| 18 | + * This query performs a simple syntactic check to ensure that the return value of the function is |
| 19 | + * not completely ignored. This matches the examples given in the rule, although the text itself is |
| 20 | + * not entirely clear. This means it will not find cases where something is done with the return |
| 21 | + * value, but it is not meaningfully read. For example: `int ret_val = f();`, with no subsequent |
| 22 | + * access of `ret_val`. However, such a case _would_ be flagged by A0-1-1 - Useless assignment. |
| 23 | + */ |
| 24 | + |
| 25 | + query predicate problems(FunctionCall fc, string message, Function f, string funcName) { |
| 26 | + not isExcluded(fc, Config::getQuery()) and |
| 27 | + message = "Return value from call to $@ is unused." and |
| 28 | + funcName = f.getName() and |
| 29 | + // Find function calls in `ExprStmt`s, which indicate the return value is ignored |
| 30 | + fc.getParent() instanceof ExprStmt and |
| 31 | + // Ignore calls to void functions, which don't return values |
| 32 | + not fc.getUnderlyingType() instanceof VoidType and |
| 33 | + // Get the function target |
| 34 | + f = fc.getTarget() and |
| 35 | + // Overloaded (i.e. user defined) operators should behave in the same way as built-in operators, |
| 36 | + // so the rule does not require the use of the return value |
| 37 | + not f instanceof Operator and |
| 38 | + // Exclude cases where the function call is generated within a macro, as the user of the macro is |
| 39 | + // not necessarily able to address those results |
| 40 | + not fc.isAffectedByMacro() and |
| 41 | + // Rule allows disabling this rule where a static_cast<void> or a C-style cast to void is applied |
| 42 | + not exists(Cast cast | cast instanceof StaticCast or cast instanceof CStyleCast | |
| 43 | + fc.getExplicitlyConverted() = cast and |
| 44 | + cast.getActualType() instanceof VoidType |
| 45 | + ) |
| 46 | + } |
| 47 | +} |
0 commit comments