13
13
*/
14
14
15
15
import cpp
16
- import semmle.code.cpp.ir.ValueNumbering
16
+ // We don't actually use the global value numbering library in this query, but without it we end up
17
+ // recomputing the IR.
18
+ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
17
19
import semmle.code.cpp.ir.IR
18
20
19
21
predicate instructionHasVariable ( VariableAddressInstruction vai , StackVariable var , Function f ) {
@@ -56,31 +58,31 @@ newtype TGlobalAddress =
56
58
not v .getUnspecifiedType ( ) instanceof PointerToMemberType
57
59
} or
58
60
TLoad ( TGlobalAddress address ) {
59
- address = globalValueNumber ( any ( LoadInstruction load ) .getSourceAddress ( ) )
61
+ address = globalAddress ( any ( LoadInstruction load ) .getSourceAddress ( ) )
60
62
} or
61
63
TConversion ( string kind , TGlobalAddress address , Type fromType , Type toType ) {
62
64
kind = "unchecked" and
63
65
exists ( ConvertInstruction convert |
64
66
uncheckedConversionTypes ( convert , fromType , toType ) and
65
- address = globalValueNumber ( convert .getUnary ( ) )
67
+ address = globalAddress ( convert .getUnary ( ) )
66
68
)
67
69
or
68
70
kind = "checked" and
69
71
exists ( CheckedConvertOrNullInstruction convert |
70
72
checkedConversionTypes ( convert , fromType , toType ) and
71
- address = globalValueNumber ( convert .getUnary ( ) )
73
+ address = globalAddress ( convert .getUnary ( ) )
72
74
)
73
75
or
74
76
kind = "inheritance" and
75
77
exists ( InheritanceConversionInstruction convert |
76
78
inheritanceConversionTypes ( convert , fromType , toType ) and
77
- address = globalValueNumber ( convert .getUnary ( ) )
79
+ address = globalAddress ( convert .getUnary ( ) )
78
80
)
79
81
} or
80
82
TFieldAddress ( TGlobalAddress address , Field f ) {
81
83
exists ( FieldAddressInstruction fai |
82
84
fai .getField ( ) = f and
83
- address = globalValueNumber ( fai .getObjectAddress ( ) )
85
+ address = globalAddress ( fai .getObjectAddress ( ) )
84
86
)
85
87
}
86
88
@@ -105,36 +107,36 @@ predicate inheritanceConversionTypes(
105
107
}
106
108
107
109
/** Gets the HashCons value of an address computed by `instr`, if any. */
108
- TGlobalAddress globalValueNumber ( Instruction instr ) {
110
+ TGlobalAddress globalAddress ( Instruction instr ) {
109
111
result = TGlobalVariable ( instr .( VariableAddressInstruction ) .getASTVariable ( ) )
110
112
or
111
113
not instr instanceof LoadInstruction and
112
- result = globalValueNumber ( instr .( CopyInstruction ) .getSourceValue ( ) )
114
+ result = globalAddress ( instr .( CopyInstruction ) .getSourceValue ( ) )
113
115
or
114
116
exists ( LoadInstruction load | instr = load |
115
- result = TLoad ( globalValueNumber ( load .getSourceAddress ( ) ) )
117
+ result = TLoad ( globalAddress ( load .getSourceAddress ( ) ) )
116
118
)
117
119
or
118
120
exists ( ConvertInstruction convert , Type fromType , Type toType | instr = convert |
119
121
uncheckedConversionTypes ( convert , fromType , toType ) and
120
- result = TConversion ( "unchecked" , globalValueNumber ( convert .getUnary ( ) ) , fromType , toType )
122
+ result = TConversion ( "unchecked" , globalAddress ( convert .getUnary ( ) ) , fromType , toType )
121
123
)
122
124
or
123
125
exists ( CheckedConvertOrNullInstruction convert , Type fromType , Type toType | instr = convert |
124
126
checkedConversionTypes ( convert , fromType , toType ) and
125
- result = TConversion ( "checked" , globalValueNumber ( convert .getUnary ( ) ) , fromType , toType )
127
+ result = TConversion ( "checked" , globalAddress ( convert .getUnary ( ) ) , fromType , toType )
126
128
)
127
129
or
128
130
exists ( InheritanceConversionInstruction convert , Type fromType , Type toType | instr = convert |
129
131
inheritanceConversionTypes ( convert , fromType , toType ) and
130
- result = TConversion ( "inheritance" , globalValueNumber ( convert .getUnary ( ) ) , fromType , toType )
132
+ result = TConversion ( "inheritance" , globalAddress ( convert .getUnary ( ) ) , fromType , toType )
131
133
)
132
134
or
133
135
exists ( FieldAddressInstruction fai | instr = fai |
134
- result = TFieldAddress ( globalValueNumber ( fai .getObjectAddress ( ) ) , fai .getField ( ) )
136
+ result = TFieldAddress ( globalAddress ( fai .getObjectAddress ( ) ) , fai .getField ( ) )
135
137
)
136
138
or
137
- result = globalValueNumber ( instr .( PointerOffsetInstruction ) .getLeft ( ) )
139
+ result = globalAddress ( instr .( PointerOffsetInstruction ) .getLeft ( ) )
138
140
}
139
141
140
142
/** Gets a `StoreInstruction` that may be executed after executing `store`. */
@@ -160,27 +162,27 @@ StoreInstruction getAStoreStrictlyAfter(StoreInstruction store) {
160
162
predicate stackAddressEscapes (
161
163
StoreInstruction store , StackVariable var , TGlobalAddress globalAddress , Function f
162
164
) {
163
- globalAddress = globalValueNumber ( store .getDestinationAddress ( ) ) and
165
+ globalAddress = globalAddress ( store .getDestinationAddress ( ) ) and
164
166
exists ( VariableAddressInstruction vai |
165
167
instructionHasVariable ( pragma [ only_bind_into ] ( vai ) , var , f ) and
166
168
stackPointerFlowsToUse ( store .getSourceValue ( ) , vai )
167
169
) and
168
170
// Ensure there's no subsequent store that overrides the global address.
169
- not globalAddress = globalValueNumber ( getAStoreStrictlyAfter ( store ) .getDestinationAddress ( ) )
171
+ not globalAddress = globalAddress ( getAStoreStrictlyAfter ( store ) .getDestinationAddress ( ) )
170
172
}
171
173
172
174
predicate blockStoresToAddress (
173
175
IRBlock block , int index , StoreInstruction store , TGlobalAddress globalAddress
174
176
) {
175
177
block .getInstruction ( index ) = store and
176
- globalAddress = globalValueNumber ( store .getDestinationAddress ( ) )
178
+ globalAddress = globalAddress ( store .getDestinationAddress ( ) )
177
179
}
178
180
179
181
predicate blockLoadsFromAddress (
180
182
IRBlock block , int index , LoadInstruction load , TGlobalAddress globalAddress
181
183
) {
182
184
block .getInstruction ( index ) = load and
183
- globalAddress = globalValueNumber ( load .getSourceAddress ( ) )
185
+ globalAddress = globalAddress ( load .getSourceAddress ( ) )
184
186
}
185
187
186
188
predicate globalAddressPointsToStack (
215
217
where
216
218
globalAddressPointsToStack ( store , var , call , block , address , isCallBlock , isStoreBlock ) and
217
219
block .getAnInstruction ( ) = load and
218
- globalValueNumber ( load .getSourceAddress ( ) ) = address and
220
+ globalAddress ( load .getSourceAddress ( ) ) = address and
219
221
(
220
222
// We know that we have a sequence:
221
223
// (1) store to `address` -> (2) return from `f` -> (3) load from `address`.
0 commit comments