-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathLogicalOperation.qll
More file actions
131 lines (107 loc) · 3.73 KB
/
LogicalOperation.qll
File metadata and controls
131 lines (107 loc) · 3.73 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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Provides classes for modeling logical operations such as `!`, `&&`, `||`, and
* the ternary `? :` expression.
*/
import semmle.code.cpp.exprs.Expr
/**
* A C/C++ unary logical operation.
*/
class UnaryLogicalOperation extends UnaryOperation, @un_log_op_expr { }
/**
* A C/C++ logical not expression.
* ```
* c = !a;
* ```
*/
class NotExpr extends UnaryLogicalOperation, @notexpr {
override string getOperator() { result = "!" }
override string getAPrimaryQlClass() { result = "NotExpr" }
override int getPrecedence() { result = 16 }
}
/**
* A C/C++ binary logical operation.
*/
class BinaryLogicalOperation extends BinaryOperation, @bin_log_op_expr {
/**
* Holds if the truth of this binary logical expression having value `wholeIsTrue`
* implies that the truth of the child expression `part` has truth value `partIsTrue`.
*
* For example if the binary operation:
* ```
* x && y
* ```
* is true, `x` and `y` must also be true, so `impliesValue(x, true, true)` and
* `impliesValue(y, true, true)` hold.
*/
predicate impliesValue(Expr part, boolean partIsTrue, boolean wholeIsTrue) { none() } // overridden in subclasses
}
/**
* A C/C++ logical AND expression.
* ```
* if (a && b) { }
* ```
*/
class LogicalAndExpr extends BinaryLogicalOperation, @andlogicalexpr {
override string getOperator() { result = "&&" }
override string getAPrimaryQlClass() { result = "LogicalAndExpr" }
override int getPrecedence() { result = 5 }
override predicate impliesValue(Expr part, boolean partIsTrue, boolean wholeIsTrue) {
wholeIsTrue = true and partIsTrue = true and part = this.getAnOperand()
or
wholeIsTrue = true and
this.getAnOperand().(BinaryLogicalOperation).impliesValue(part, partIsTrue, true)
}
}
/**
* A C/C++ logical OR expression.
* ```
* if (a || b) { }
* ```
*/
class LogicalOrExpr extends BinaryLogicalOperation, @orlogicalexpr {
override string getOperator() { result = "||" }
override string getAPrimaryQlClass() { result = "LogicalOrExpr" }
override int getPrecedence() { result = 4 }
override predicate impliesValue(Expr part, boolean partIsTrue, boolean wholeIsTrue) {
wholeIsTrue = false and partIsTrue = false and part = this.getAnOperand()
or
wholeIsTrue = false and
this.getAnOperand().(BinaryLogicalOperation).impliesValue(part, partIsTrue, false)
}
}
/**
* A C/C++ conditional ternary expression.
* ```
* a = (b > c ? d : e);
* ```
*/
class ConditionalExpr extends Operation, @conditionalexpr {
/** Gets the condition of this conditional expression. */
Expr getCondition() { expr_cond_guard(underlyingElement(this), unresolveElement(result)) }
override string getAPrimaryQlClass() { result = "ConditionalExpr" }
/** Gets the 'then' expression of this conditional expression. */
Expr getThen() {
if this.isTwoOperand()
then result = this.getCondition()
else expr_cond_true(underlyingElement(this), unresolveElement(result))
}
/** Gets the 'else' expression of this conditional expression. */
Expr getElse() { expr_cond_false(underlyingElement(this), unresolveElement(result)) }
/**
* Holds if this expression used the two operand form `guard ? : false`.
*/
predicate isTwoOperand() { expr_cond_two_operand(underlyingElement(this)) }
override string getOperator() { result = "?" }
override string toString() { result = "... ? ... : ..." }
override int getPrecedence() { result = 3 }
override predicate mayBeImpure() {
this.getCondition().mayBeImpure() or
this.getThen().mayBeImpure() or
this.getElse().mayBeImpure()
}
override predicate mayBeGloballyImpure() {
this.getCondition().mayBeGloballyImpure() or
this.getThen().mayBeGloballyImpure() or
this.getElse().mayBeGloballyImpure()
}
}