@@ -2079,6 +2079,54 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
20792079 }
20802080}
20812081
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+
20822130/**
20832131 * The IR translation of a `BuiltInVarArgsStart` expression.
20842132 */
@@ -2092,32 +2140,23 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr {
20922140 or
20932141 tag = VarArgsStartTag ( ) and
20942142 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 ( ) ) )
20992144 or
21002145 tag = VarArgsVAListStoreTag ( ) and
21012146 opcode instanceof Opcode:: Store and
2102- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2147+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
21032148 }
21042149
21052150 final override Instruction getFirstInstruction ( ) {
21062151 result = getInstruction ( VarArgsStartEllipsisAddressTag ( ) )
21072152 }
21082153
2109- final override Instruction getResult ( ) {
2110- none ( )
2111- }
2154+ final override Instruction getResult ( ) { none ( ) }
21122155
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 ( ) }
21162157
21172158 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 ( ) )
21212160 }
21222161
21232162 final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -2167,37 +2206,29 @@ class TranslatedVarArg extends TranslatedNonConstantExpr {
21672206 final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
21682207 tag = VarArgsVAListLoadTag ( ) and
21692208 opcode instanceof Opcode:: Load and
2170- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2209+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
21712210 or
21722211 tag = VarArgsArgAddressTag ( ) and
21732212 opcode instanceof Opcode:: VarArg and
21742213 resultType = getResultType ( )
21752214 or
21762215 tag = VarArgsMoveNextTag ( ) and
21772216 opcode instanceof Opcode:: NextVarArg and
2178- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2217+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
21792218 or
21802219 tag = VarArgsVAListStoreTag ( ) and
21812220 opcode instanceof Opcode:: Store and
2182- resultType = getTypeForPRValue ( expr .getVAList ( ) .getType ( ) )
2221+ resultType = getTypeForPRValue ( getVAListType ( expr .getVAList ( ) .getFullyConverted ( ) ) )
21832222 }
21842223
2185- final override Instruction getFirstInstruction ( ) {
2186- result = getVAList ( ) .getFirstInstruction ( )
2187- }
2224+ final override Instruction getFirstInstruction ( ) { result = getVAList ( ) .getFirstInstruction ( ) }
21882225
2189- final override Instruction getResult ( ) {
2190- result = getInstruction ( VarArgsArgAddressTag ( ) )
2191- }
2226+ final override Instruction getResult ( ) { result = getInstruction ( VarArgsArgAddressTag ( ) ) }
21922227
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 ( ) }
21962229
21972230 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 ( ) )
22012232 }
22022233
22032234 final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -2262,22 +2293,14 @@ class TranslatedVarArgsEnd extends TranslatedNonConstantExpr {
22622293 resultType = getVoidType ( )
22632294 }
22642295
2265- final override Instruction getFirstInstruction ( ) {
2266- result = getVAList ( ) .getFirstInstruction ( )
2267- }
2296+ final override Instruction getFirstInstruction ( ) { result = getVAList ( ) .getFirstInstruction ( ) }
22682297
2269- final override Instruction getResult ( ) {
2270- none ( )
2271- }
2298+ final override Instruction getResult ( ) { none ( ) }
22722299
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 ( ) }
22762301
22772302 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 ( ) )
22812304 }
22822305
22832306 final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -2307,20 +2330,18 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr {
23072330 final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
23082331 tag = VarArgsVAListLoadTag ( ) and
23092332 opcode instanceof Opcode:: Load and
2310- resultType = getTypeForPRValue ( expr .getSourceVAList ( ) .getType ( ) )
2333+ resultType = getTypeForPRValue ( getVAListType ( expr .getSourceVAList ( ) .getFullyConverted ( ) ) )
23112334 or
23122335 tag = VarArgsVAListStoreTag ( ) and
23132336 opcode instanceof Opcode:: Store and
2314- resultType = getTypeForPRValue ( expr .getDestinationVAList ( ) .getType ( ) )
2337+ resultType = getTypeForPRValue ( getVAListType ( expr .getDestinationVAList ( ) .getFullyConverted ( ) ) )
23152338 }
23162339
23172340 final override Instruction getFirstInstruction ( ) {
23182341 result = getSourceVAList ( ) .getFirstInstruction ( )
23192342 }
23202343
2321- final override Instruction getResult ( ) {
2322- result = getInstruction ( VarArgsVAListStoreTag ( ) )
2323- }
2344+ final override Instruction getResult ( ) { result = getInstruction ( VarArgsVAListStoreTag ( ) ) }
23242345
23252346 final override TranslatedElement getChild ( int id ) {
23262347 id = 0 and result = getDestinationVAList ( )
@@ -2329,15 +2350,11 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr {
23292350 }
23302351
23312352 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 ( ) )
23352354 }
23362355
23372356 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 ( ) )
23412358 }
23422359
23432360 final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
0 commit comments