-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathBlock.qll
More file actions
128 lines (115 loc) · 3.03 KB
/
Block.qll
File metadata and controls
128 lines (115 loc) · 3.03 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
/**
* Provides a class to model C/C++ block statements, enclosed by `{` and `}`.
*/
import semmle.code.cpp.Element
import semmle.code.cpp.stmts.Stmt
/**
* A C/C++ block statement.
*
* For example, the block from `{` to `}` in the following code:
* ```
* {
* int a;
* int b = 1;
* a = b;
* }
* ```
*/
class BlockStmt extends Stmt, @stmt_block {
override string getAPrimaryQlClass() { result = "BlockStmt" }
/**
* Gets a child declaration of this block.
*
* For example, for the block
* ```
* { int a; int b = 1; a = b; }
* ```
* it would have 2 results, for the declarations of `a` and `b`.
*/
Declaration getADeclaration() { result = this.getAStmt().(DeclStmt).getADeclaration() }
/**
* Gets a body statement of this block.
*
* For example, for the block
* ```
* { int a; int b = 1; a = b; }
* ```
* it would have 3 results, for the declarations of `a` and `b` and
* for the expression statement `a = b`.
*/
Stmt getAStmt() { result = this.getAChild() }
/**
* Gets the `n`th body statement of this block, indexed from 0.
*
* For example, for the block
* ```
* { int a; int b = 1; a = b; }
* ```
* `getStmt(2)`'s result is the expression statement `a = b`.
*/
Stmt getStmt(int n) { result = this.getChild(n) }
/**
* Gets the last body statement of this block.
*
* For example, for the block
* ```
* { int a; int b = 1; a = b; }
* ```
* the result is the expression statement `a = b`.
*/
Stmt getLastStmt() { result = this.getStmt(this.getNumStmt() - 1) }
/**
* Gets the last body statement of this block. If this last statement
* is itself a block, returns the last statement of that block, and so on.
*
* For example, for the block
* ```
* { int a; int b = 1; { a = b; } }
* ```
* the result is the expression statement `a = b`.
*/
Stmt getLastStmtIn() {
if this.getLastStmt() instanceof BlockStmt
then result = this.getLastStmt().(BlockStmt).getLastStmtIn()
else result = this.getLastStmt()
}
/**
* Gets the number of body statements in this block.
*
* For example, for the block
* ```
* { int a; int b = 1; a = b; }
* ```
* the result is 3.
*/
int getNumStmt() { result = count(this.getAStmt()) }
/**
* Holds if the block has no statements.
*
* For example, the block
* ```
* { }
* ```
* is empty, as is the block
* ```
* {
* // a comment
* }
* ```
*/
predicate isEmpty() { this.getNumStmt() = 0 }
/**
* Gets the index of the given statement within this block, indexed from 0.
*
* For example, for the block
* ```
* { int a; int b = 1; a = b; }
* ```
* if `s` is the expression statement `a = b` then `getIndexOfStmt(s)`
* has result 2.
*/
int getIndexOfStmt(Stmt s) { this.getStmt(result) = s }
override string toString() { result = "{ ... }" }
override predicate mayBeImpure() { this.getAStmt().mayBeImpure() }
override predicate mayBeGloballyImpure() { this.getAStmt().mayBeGloballyImpure() }
}