11/**
2- * @id cpp/autosar/unused-return-value
3- * @name A0-1-2: Unused return value
4- * @description The value returned by a function having a non-void return type that is not an
5- * overloaded operator shall be used.
6- * @kind problem
7- * @precision very-high
8- * @problem.severity warning
9- * @tags external/autosar/id/a0-1-2
10- * readability
11- * maintainability
12- * external/autosar/allocated-target/implementation
13- * external/autosar/enforcement/automated
14- * external/autosar/obligation/required
15- */
2+ * @id cpp/autosar/unused-return-value
3+ * @name A0-1-2: Unused return value
4+ * @description The value returned by a function having a non-void return type that is not an
5+ * overloaded operator shall be used.
6+ * @kind problem
7+ * @precision very-high
8+ * @problem.severity warning
9+ * @tags external/autosar/id/a0-1-2
10+ * readability
11+ * maintainability
12+ * external/autosar/allocated-target/implementation
13+ * external/autosar/enforcement/automated
14+ * external/autosar/obligation/required
15+ */
1616
1717import cpp
1818import codingstandards.cpp.autosar
1919import semmle.code.cpp.dataflow.DataFlow
2020
21- // Type isEdgeCase(Expr expr) {
22- // // 1. c-style casts to void.
23- // expr.(CStyleCast).getUnderlyingType()
24- // // 2. Assignment to std::ignore
25- // }
21+ predicate isStdIgnore ( Element element ) {
22+ exists ( NameQualifier nq |
23+ nq .getQualifiedElement ( ) .toString ( ) = "ignore" and
24+ nq .toString ( ) = "std::" and
25+ element .toString ( ) = "ignore"
26+ )
27+ }
28+
29+ /* The statement std::ignore = f() is not recognized an assignment; therefore, we do some painful acrobatics. */
30+ predicate isAssignment ( FunctionCall assignment ) {
31+ exists ( Operator operator |
32+ assignment .getTarget ( ) = operator and
33+ operator .getName ( ) = "operator=" and
34+ // check if this is indeed an operator for assignment by checking if there are no overloads
35+ not exists ( operator .getAnOverload ( ) )
36+ )
37+ }
38+
39+ predicate isAssignmentOperand ( Expr operand ) {
40+ exists ( FunctionCall assignment | isAssignment ( assignment ) and operand = assignment .getAChild ( ) )
41+ }
2642
27- from CStyleCast expr
28- where any ( )
29- select expr , expr . getType ( )
43+ predicate returnValueIsAssignedToStdIgnore ( FunctionCall fc ) {
44+ isAssignmentOperand ( fc ) and exists ( Element stdIgnore | isStdIgnore ( stdIgnore ) )
45+ }
3046
3147/*
3248 * This query performs a simple syntactic check to ensure that the return value of the function is
@@ -36,21 +52,29 @@ select expr, expr.getType()
3652 * access of `ret_val`. However, such a case _would_ be flagged by A0-1-1 - Useless assignment.
3753 */
3854
39- // from FunctionCall fc, Function f
40- // where
41- // not isExcluded(fc, DeadCodePackage::unusedReturnValueQuery()) and
42- // // Find function calls in `ExprStmt`s, which indicate the return value is ignored
43- // fc.getParent() instanceof ExprStmt and
44- // // Ignore calls to void functions, which don't return values
45- // not fc.getUnderlyingType() instanceof VoidType and
46- // // Get the function target
47- // f = fc.getTarget() and
48- // // Overloaded (i.e. user defined) operators should behave in the same way as built-in operators,
49- // // so the rule does not require the use of the return value
50- // not f instanceof Operator and
51- // // Exclude cases where the function call is generated within a macro, as the user of the macro is
52- // // not necessarily able to address thoes results
53- // not fc.isAffectedByMacro() and
54- // // Rule allows disabling this rule where a static_cast<void> is applied
55- // not fc.getExplicitlyConverted().(StaticCast).getActualType() instanceof VoidType
56- // select fc, "Return value from call to $@ is unused.", f, f.getName()
55+ from FunctionCall fc , Function f
56+ where
57+ not isExcluded ( fc , DeadCodePackage:: unusedReturnValueQuery ( ) ) and
58+ // Find function calls in `ExprStmt`s, which indicate the return value is ignored
59+ fc .getParent ( ) instanceof ExprStmt and
60+ // Ignore calls to void functions, which don't return values
61+ not fc .getUnderlyingType ( ) instanceof VoidType and
62+ // Get the function target
63+ f = fc .getTarget ( ) and
64+ // Overloaded (i.e. user defined) operators should behave in the same way as built-in operators,
65+ // so the rule does not require the use of the return value
66+ not f instanceof Operator and
67+ // Exclude cases where the function call is generated within a macro, as the user of the macro is
68+ // not necessarily able to address those results
69+ not fc .isAffectedByMacro ( ) and
70+ // Rule allows disabling this rule where a static_cast<void> or a C-style cast to void is applied
71+ not (
72+ fc .getExplicitlyConverted ( ) .( StaticCast ) .getActualType ( ) instanceof VoidType
73+ or
74+ exists ( CStyleCast cast |
75+ not cast .isCompilerGenerated ( ) and
76+ cast .getExpr ( ) = fc
77+ )
78+ ) and
79+ not returnValueIsAssignedToStdIgnore ( fc )
80+ select fc , "Return value from call to $@ is unused." , f , f .getName ( )
0 commit comments