@@ -23,31 +23,60 @@ import codingstandards.cpp.ConstHelpers
2323import codingstandards.cpp.Operator
2424
2525/**
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.
2728 */
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 )
3452}
3553
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
4366 )
4467}
4568
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
4778where
4879 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