forked from github/codeql-coding-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOutputParametersUsed.ql
More file actions
82 lines (75 loc) · 2.64 KB
/
OutputParametersUsed.ql
File metadata and controls
82 lines (75 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* @id cpp/autosar/output-parameters-used
* @name A8-4-8: Output parameters shall not be used
* @description Using output parameters can lead to undefined program behaviour, for example when
* they return dangling references.
* @kind problem
* @precision high
* @problem.severity warning
* @tags external/autosar/id/a8-4-8
* correctness
* maintainability
* readability
* external/autosar/strict
* external/autosar/allocated-target/design
* external/autosar/enforcement/automated
* external/autosar/obligation/required
*/
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.FunctionParameter
import codingstandards.cpp.ConstHelpers
import codingstandards.cpp.Operator
/**
* Holds if p is passed as a non-const reference or pointer and is modified.
* This holds for in-out or out-only parameters.
*/
predicate isOutParameter(NonConstPointerorReferenceParameter p) {
any(VariableEffect ve).getTarget() = p
}
/**
* Holds if parameter `p` is a parameter to a user defined assignment operator that
* is defined outside of a class body.
* These require an in-out parameter as the first argument.
*/
predicate isNonMemberUserAssignmentParameter(NonConstPointerorReferenceParameter p) {
p.getFunction() instanceof UserAssignmentOperator and
not p.isMember()
}
/**
* Holds if parameter `p` is a parameter to a stream insertion operator that
* is defined outside of a class body.
* These require an in-out parameter as the first argument.
*
* e.g., `std::ostream& operator<<(std::ostream& os, const T& obj)`
*/
predicate isStreamInsertionStreamParameter(NonConstPointerorReferenceParameter p) {
exists(StreamInsertionOperator op | not op.isMember() | op.getParameter(0) = p)
}
/**
* Holds if parameter `p` is a parameter to a stream insertion operator that
* is defined outside of a class body.
* These require an in-out parameter as the first argument and an out parameter for the second.
*
* e.g., `std::istream& operator>>(std::istream& is, T& obj)`
*/
predicate isStreamExtractionParameter(NonConstPointerorReferenceParameter p) {
exists(StreamExtractionOperator op | not op.isMember() |
op.getParameter(0) = p
or
op.getParameter(1) = p
)
}
predicate isException(NonConstPointerorReferenceParameter p) {
isNonMemberUserAssignmentParameter(p) and p.getIndex() = 0
or
isStreamInsertionStreamParameter(p)
or
isStreamExtractionParameter(p)
}
from NonConstPointerorReferenceParameter p
where
not isExcluded(p, ConstPackage::outputParametersUsedQuery()) and
isOutParameter(p) and
not isException(p)
select p, "Out parameter '" + p.getName() + "' used."