1
1
/**
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
+ */
16
16
17
17
import cpp
18
18
import codingstandards.cpp.autosar
19
19
import semmle.code.cpp.dataflow.DataFlow
20
20
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
+ }
26
42
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
+ }
30
46
31
47
/*
32
48
* 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()
36
52
* access of `ret_val`. However, such a case _would_ be flagged by A0-1-1 - Useless assignment.
37
53
*/
38
54
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