-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathSharedPtrPassedToFunctionWithImproperSemantics.ql
More file actions
82 lines (78 loc) · 3.62 KB
/
SharedPtrPassedToFunctionWithImproperSemantics.ql
File metadata and controls
82 lines (78 loc) · 3.62 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/shared-ptr-passed-to-function-with-improper-semantics
* @name A8-4-13: A std::shared_ptr shall be passed to a function as a copy if the function shares ownership, as an lvalue reference if the function replaces the managed object, or as a const lvalue reference if the function retains a reference count
* @description A std::shared_ptr shall be passed to a function as: (1) a copy to express the
* function shares ownership (2) an lvalue reference to express that the function
* replaces the managed object (3) a const lvalue reference to express that the
* function retains a reference count.
* @kind problem
* @precision high
* @problem.severity warning
* @tags external/autosar/id/a8-4-13
* maintainability
* external/autosar/allocated-target/design
* external/autosar/enforcement/automated
* external/autosar/obligation/required
*/
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.SmartPointers
VariableAccess underlyingObjectAffectingSharedPointerExpr(Function f) {
exists(FunctionCall fc |
// Find a call in the function
fc.getEnclosingFunction() = f and
// include only calls to methods which modify the underlying object
fc = any(AutosarSharedPointer s).getAModifyingCall() and
// Report the qualifier
fc.getQualifier() = result
)
}
predicate flowsToUnderlyingObjectAffectingExpr(Parameter p) {
// check if a parameter flows locally to an expression which affects smart pointer lifetime
p.getType().stripType() instanceof AutosarSharedPointer and
localExprFlow(p.getAnAccess(), underlyingObjectAffectingSharedPointerExpr(p.getFunction()))
or
// else handle nested cases, such as passing smart pointers as reference arguments
exists(FunctionCall fc, VariableAccess va, int index |
// calls to functions that are not methods of AutosarSmartPointer and which do not
// result in a constructor call are excluded from 'flowsToLifetimeAffectingExpr'.
// therefore, recurse through function calls where the parameter 'p' flows to an argument
fc.getEnclosingFunction() = p.getFunction() and
fc.getArgument(index) = va and
localExprFlow(p.getAnAccess(), va) and
flowsToUnderlyingObjectAffectingExpr(fc.getTarget().getParameter(index))
)
}
from DefinedSmartPointerParameter p, string problem
where
not isExcluded(p, SmartPointers1Package::smartPointerAsParameterWithoutLifetimeSemanticsQuery()) and
p.getType().stripType() instanceof AutosarSharedPointer and
(
// handle the parameter depending on its derived type
p.getType() instanceof RValueReferenceType and
problem = "Parameter of type std::shared_ptr passed as rvalue reference."
or
p.getType() instanceof LValueReferenceType and
(
p.getType().(LValueReferenceType).getBaseType().isConst() and
not localExprFlow(p.getAnAccess(),
any(Variable var, ConstructorCall cc |
var.getType() instanceof AutosarSharedPointer and
var.getAnAssignedValue() = cc and
cc.getTarget() instanceof CopyConstructor
|
cc.getArgument(0)
)) and
problem =
"Parameter of type 'const std::shared_ptr' passed as lvalue reference with no copy made."
or
not p.getType().(LValueReferenceType).getBaseType().isConst() and
not flowsToUnderlyingObjectAffectingExpr(p) and
problem =
"Parameter of type std::shared_ptr passed as lvalue reference but not used to modify underlying object."
)
or
p.getType() instanceof PointerType and
problem = "Parameter of type std::shared_ptr passed as raw pointer."
)
select p, problem