@@ -2079,6 +2079,54 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
2079
2079
}
2080
2080
}
2081
2081
2082
+ /**
2083
+ * Holds if the expression `expr` is one of the `va_list` operands to a `va_*` macro.
2084
+ */
2085
+ private predicate isVAListExpr ( Expr expr ) {
2086
+ exists ( VarArgsExpr parent , Expr originalExpr |
2087
+ (
2088
+ originalExpr = parent .( BuiltInVarArgsStart ) .getVAList ( )
2089
+ or
2090
+ originalExpr = parent .( BuiltInVarArgsEnd ) .getVAList ( )
2091
+ or
2092
+ originalExpr = parent .( BuiltInVarArg ) .getVAList ( )
2093
+ or
2094
+ originalExpr = parent .( BuiltInVarArgCopy ) .getSourceVAList ( )
2095
+ or
2096
+ originalExpr = parent .( BuiltInVarArgCopy ) .getDestinationVAList ( )
2097
+ ) and
2098
+ expr = originalExpr .getFullyConverted ( )
2099
+ )
2100
+ }
2101
+
2102
+ /**
2103
+ * Gets the type of the `va_list` being accessed by `expr`, where `expr` is a `va_list` operand of a
2104
+ * `va_*` macro.
2105
+ *
2106
+ * In the Unix ABI, `va_list` is declared as `typedef struct __va_list_tag va_list[1];`. When used
2107
+ * as the type of a local variable, this gets an implicit array-to-pointer conversion, so that the
2108
+ * actual argument to the `va_*` macro is a prvalue of type `__va_list_tag*`. When used as the type
2109
+ * of a function parameter, the parameter's type decays to `__va_list_tag*`, so that the argument
2110
+ * to the `va_*` macro is still a prvalue of type `__va_list_tag*`, with no implicit conversion
2111
+ * necessary. In either case, we treat `__va_list_tag` as the representative type of the `va_list`.
2112
+ *
2113
+ * In the Windows ABI, `va_list` is declared as a pointer type (usually `char*`). Whether used as
2114
+ * the type of a local variable or of a parameter, this means that the argument to the `va_*` macro
2115
+ * is always an _lvalue_ of type `char*`. We treat `char*` as the representative type of the
2116
+ * `va_list`.
2117
+ */
2118
+ private Type getVAListType ( Expr expr ) {
2119
+ isVAListExpr ( expr ) and
2120
+ if expr .isPRValueCategory ( )
2121
+ then
2122
+ // In the Unix ABI, this will be a prvalue of type `__va_list_tag*`. We want the `__va_list_tag`
2123
+ // type.
2124
+ result = expr .getType ( ) .getUnderlyingType ( ) .( PointerType ) .getBaseType ( )
2125
+ else
2126
+ // In the Windows ABI, this will be an lvalue of some pointer type. We want that pointer type.
2127
+ result = expr .getType ( )
2128
+ }
2129
+
2082
2130
/**
2083
2131
* The IR translation of a `BuiltInVarArgsStart` expression.
2084
2132
*/
@@ -2092,32 +2140,23 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr {
2092
2140
or
2093
2141
tag = VarArgsStartTag ( ) and
2094
2142
opcode instanceof Opcode:: VarArgsStart and
2095
- // Intentionally skip calling `getFullyConverted()`, because we want the type of the
2096
- // `VariableAccess`, even if it has undergone the array-to-pointer conversion that gets applied
2097
- // for the Unix ABI.
2098
- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2143
+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
2099
2144
or
2100
2145
tag = VarArgsVAListStoreTag ( ) and
2101
2146
opcode instanceof Opcode:: Store and
2102
- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2147
+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
2103
2148
}
2104
2149
2105
2150
final override Instruction getFirstInstruction ( ) {
2106
2151
result = getInstruction ( VarArgsStartEllipsisAddressTag ( ) )
2107
2152
}
2108
2153
2109
- final override Instruction getResult ( ) {
2110
- none ( )
2111
- }
2154
+ final override Instruction getResult ( ) { none ( ) }
2112
2155
2113
- final override TranslatedElement getChild ( int id ) {
2114
- id = 0 and result = getVAList ( )
2115
- }
2156
+ final override TranslatedElement getChild ( int id ) { id = 0 and result = getVAList ( ) }
2116
2157
2117
2158
private TranslatedExpr getVAList ( ) {
2118
- // Intentionally skip calling `getFullyConverted()`, because we want the `VariableAccess`, even
2119
- // if it has undergone the array-to-pointer conversion that gets applied for the Unix ABI.
2120
- result = getTranslatedExpr ( expr .getVAList ( ) )
2159
+ result = getTranslatedExpr ( expr .getVAList ( ) .getFullyConverted ( ) )
2121
2160
}
2122
2161
2123
2162
final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -2167,37 +2206,29 @@ class TranslatedVarArg extends TranslatedNonConstantExpr {
2167
2206
final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
2168
2207
tag = VarArgsVAListLoadTag ( ) and
2169
2208
opcode instanceof Opcode:: Load and
2170
- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2209
+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
2171
2210
or
2172
2211
tag = VarArgsArgAddressTag ( ) and
2173
2212
opcode instanceof Opcode:: VarArg and
2174
2213
resultType = getResultType ( )
2175
2214
or
2176
2215
tag = VarArgsMoveNextTag ( ) and
2177
2216
opcode instanceof Opcode:: NextVarArg and
2178
- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2217
+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
2179
2218
or
2180
2219
tag = VarArgsVAListStoreTag ( ) and
2181
2220
opcode instanceof Opcode:: Store and
2182
- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2221
+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
2183
2222
}
2184
2223
2185
- final override Instruction getFirstInstruction ( ) {
2186
- result = getVAList ( ) .getFirstInstruction ( )
2187
- }
2224
+ final override Instruction getFirstInstruction ( ) { result = getVAList ( ) .getFirstInstruction ( ) }
2188
2225
2189
- final override Instruction getResult ( ) {
2190
- result = getInstruction ( VarArgsArgAddressTag ( ) )
2191
- }
2226
+ final override Instruction getResult ( ) { result = getInstruction ( VarArgsArgAddressTag ( ) ) }
2192
2227
2193
- final override TranslatedElement getChild ( int id ) {
2194
- id = 0 and result = getVAList ( )
2195
- }
2228
+ final override TranslatedElement getChild ( int id ) { id = 0 and result = getVAList ( ) }
2196
2229
2197
2230
private TranslatedExpr getVAList ( ) {
2198
- // Intentionally skip calling `getFullyConverted()`, because we want the `VariableAccess`, even
2199
- // if it has undergone the array-to-pointer conversion that gets applied for the Unix ABI.
2200
- result = getTranslatedExpr ( expr .getVAList ( ) )
2231
+ result = getTranslatedExpr ( expr .getVAList ( ) .getFullyConverted ( ) )
2201
2232
}
2202
2233
2203
2234
final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -2262,22 +2293,14 @@ class TranslatedVarArgsEnd extends TranslatedNonConstantExpr {
2262
2293
resultType = getVoidType ( )
2263
2294
}
2264
2295
2265
- final override Instruction getFirstInstruction ( ) {
2266
- result = getVAList ( ) .getFirstInstruction ( )
2267
- }
2296
+ final override Instruction getFirstInstruction ( ) { result = getVAList ( ) .getFirstInstruction ( ) }
2268
2297
2269
- final override Instruction getResult ( ) {
2270
- none ( )
2271
- }
2298
+ final override Instruction getResult ( ) { none ( ) }
2272
2299
2273
- final override TranslatedElement getChild ( int id ) {
2274
- id = 0 and result = getVAList ( )
2275
- }
2300
+ final override TranslatedElement getChild ( int id ) { id = 0 and result = getVAList ( ) }
2276
2301
2277
2302
private TranslatedExpr getVAList ( ) {
2278
- // Intentionally skip calling `getFullyConverted()`, because we want the `VariableAccess`, even
2279
- // if it has undergone the array-to-pointer conversion that gets applied for the Unix ABI.
2280
- result = getTranslatedExpr ( expr .getVAList ( ) )
2303
+ result = getTranslatedExpr ( expr .getVAList ( ) .getFullyConverted ( ) )
2281
2304
}
2282
2305
2283
2306
final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -2307,20 +2330,18 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr {
2307
2330
final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
2308
2331
tag = VarArgsVAListLoadTag ( ) and
2309
2332
opcode instanceof Opcode:: Load and
2310
- resultType = getTypeForPRValue ( expr .getSourceVAList ( ) .getType ( ) )
2333
+ resultType = getTypeForPRValue ( getVAListType ( expr .getSourceVAList ( ) .getFullyConverted ( ) ) )
2311
2334
or
2312
2335
tag = VarArgsVAListStoreTag ( ) and
2313
2336
opcode instanceof Opcode:: Store and
2314
- resultType = getTypeForPRValue ( expr .getDestinationVAList ( ) .getType ( ) )
2337
+ resultType = getTypeForPRValue ( getVAListType ( expr .getDestinationVAList ( ) .getFullyConverted ( ) ) )
2315
2338
}
2316
2339
2317
2340
final override Instruction getFirstInstruction ( ) {
2318
2341
result = getSourceVAList ( ) .getFirstInstruction ( )
2319
2342
}
2320
2343
2321
- final override Instruction getResult ( ) {
2322
- result = getInstruction ( VarArgsVAListStoreTag ( ) )
2323
- }
2344
+ final override Instruction getResult ( ) { result = getInstruction ( VarArgsVAListStoreTag ( ) ) }
2324
2345
2325
2346
final override TranslatedElement getChild ( int id ) {
2326
2347
id = 0 and result = getDestinationVAList ( )
@@ -2329,15 +2350,11 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr {
2329
2350
}
2330
2351
2331
2352
private TranslatedExpr getDestinationVAList ( ) {
2332
- // Intentionally skip calling `getFullyConverted()`, because we want the `VariableAccess`, even
2333
- // if it has undergone the array-to-pointer conversion that gets applied for the Unix ABI.
2334
- result = getTranslatedExpr ( expr .getDestinationVAList ( ) )
2353
+ result = getTranslatedExpr ( expr .getDestinationVAList ( ) .getFullyConverted ( ) )
2335
2354
}
2336
2355
2337
2356
private TranslatedExpr getSourceVAList ( ) {
2338
- // Intentionally skip calling `getFullyConverted()`, because we want the `VariableAccess`, even
2339
- // if it has undergone the array-to-pointer conversion that gets applied for the Unix ABI.
2340
- result = getTranslatedExpr ( expr .getSourceVAList ( ) )
2357
+ result = getTranslatedExpr ( expr .getSourceVAList ( ) .getFullyConverted ( ) )
2341
2358
}
2342
2359
2343
2360
final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
0 commit comments