-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathAtomicVariableTwiceInExpression.ql
More file actions
53 lines (51 loc) · 1.87 KB
/
AtomicVariableTwiceInExpression.ql
File metadata and controls
53 lines (51 loc) · 1.87 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
/**
* @id c/cert/atomic-variable-twice-in-expression
* @name CON40-C: Do not refer to an atomic variable twice in an expression
* @description Atomic variables that are referred to twice in the same expression can produce
* unpredictable program behavior.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/cert/id/con40-c
* correctness
* concurrency
* external/cert/severity/medium
* external/cert/likelihood/probable
* external/cert/remediation-cost/medium
* external/cert/priority/p8
* external/cert/level/l2
* external/cert/obligation/rule
*/
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Concurrency
from MacroInvocation mi, Variable v, Locatable whereFound
where
not isExcluded(whereFound, Concurrency5Package::atomicVariableTwiceInExpressionQuery()) and
(
// There isn't a way to safely use this construct in a way that is also
// possible the reliably detect so advise against using it.
(
mi instanceof AtomicStore
or
// This construct is generally safe, but must be used in a loop. To lower
// the false positive rate we don't look at the conditions of the loop and
// instead assume if it is found in a looping construct that it is likely
// related to the safety property.
mi instanceof AtomicCompareExchange and
not exists(Loop l | mi.getAGeneratedElement().(Expr).getParent*() = l)
) and
whereFound = mi
)
or
mi.getMacroName() = "ATOMIC_VAR_INIT" and
exists(Expr av |
av = mi.getAGeneratedElement() and
av = v.getAnAssignedValue() and
exists(Assignment m |
not m instanceof AssignXorExpr and
m.getLValue().(VariableAccess).getTarget() = v and
whereFound = m
)
)
select mi, "Atomic variable possibly referred to twice in an $@.", whereFound, "expression"