@@ -23,31 +23,60 @@ import codingstandards.cpp.ConstHelpers
23
23
import codingstandards.cpp.Operator
24
24
25
25
/**
26
- * Non-const T& and T* `Parameter`s to `Function`s
26
+ * Holds if p is passed as a non-const reference or pointer and is modified.
27
+ * This holds for in-out or out-only parameters.
27
28
*/
28
- class NonConstReferenceOrPointerParameterCandidate extends FunctionParameter {
29
- NonConstReferenceOrPointerParameterCandidate ( ) {
30
- this instanceof NonConstReferenceParameter
31
- or
32
- this instanceof NonConstPointerParameter
33
- }
29
+ predicate isOutParameter ( NonConstPointerorReferenceParameter p ) {
30
+ any ( VariableEffect ve ) .getTarget ( ) = p
31
+ }
32
+
33
+ /**
34
+ * Holds if parameter `p` is a parameter to a user defined assignment operator that
35
+ * is defined outside of a class body.
36
+ * These require an in-out parameter as the first argument.
37
+ */
38
+ predicate isNonMemberUserAssignmentParameter ( NonConstPointerorReferenceParameter p ) {
39
+ p .getFunction ( ) instanceof UserAssignmentOperator and
40
+ not p .isMember ( )
41
+ }
42
+
43
+ /**
44
+ * Holds if parameter `p` is a parameter to a stream insertion operator that
45
+ * is defined outside of a class body.
46
+ * These require an in-out parameter as the first argument.
47
+ *
48
+ * e.g., `std::ostream& operator<<(std::ostream& os, const T& obj)`
49
+ */
50
+ predicate isStreamInsertionStreamParameter ( NonConstPointerorReferenceParameter p ) {
51
+ exists ( StreamInsertionOperator op | not op .isMember ( ) | op .getParameter ( 0 ) = p )
34
52
}
35
53
36
- pragma [ inline]
37
- predicate isFirstAccess ( VariableAccess va ) {
38
- not exists ( VariableAccess otherVa |
39
- otherVa .getTarget ( ) = va .getTarget ( ) or
40
- otherVa .getQualifier ( ) .( VariableAccess ) .getTarget ( ) = va .getTarget ( )
41
- |
42
- otherVa .getASuccessor ( ) = va
54
+ /**
55
+ * Holds if parameter `p` is a parameter to a stream insertion operator that
56
+ * is defined outside of a class body.
57
+ * These require an in-out parameter as the first argument and an out parameter for the second.
58
+ *
59
+ * e.g., `std::istream& operator>>(std::istream& is, T& obj)`
60
+ */
61
+ predicate isStreamExtractionParameter ( NonConstPointerorReferenceParameter p ) {
62
+ exists ( StreamExtractionOperator op | not op .isMember ( ) |
63
+ op .getParameter ( 0 ) = p
64
+ or
65
+ op .getParameter ( 1 ) = p
43
66
)
44
67
}
45
68
46
- from NonConstReferenceOrPointerParameterCandidate p , VariableEffect ve
69
+ predicate isException ( NonConstPointerorReferenceParameter p ) {
70
+ isNonMemberUserAssignmentParameter ( p ) and p .getIndex ( ) = 0
71
+ or
72
+ isStreamInsertionStreamParameter ( p )
73
+ or
74
+ isStreamExtractionParameter ( p )
75
+ }
76
+
77
+ from NonConstPointerorReferenceParameter p
47
78
where
48
79
not isExcluded ( p , ConstPackage:: outputParametersUsedQuery ( ) ) and
49
- ve .getTarget ( ) = p and
50
- isFirstAccess ( ve .getAnAccess ( ) ) and
51
- not ve instanceof AnyAssignOperation and
52
- not ve instanceof CrementOperation
53
- select p , "Out parameter " + p .getName ( ) + " that is modified before being read."
80
+ isOutParameter ( p ) and
81
+ not isException ( p )
82
+ select p , "Out parameter '" + p .getName ( ) + "' used."
0 commit comments