Skip to content

Commit 1346592

Browse files
authored
Merge pull request github#3092 from dbartol/dbartol/VarArgIR2_ElectricBoogaloo
C++: Better IR for varargs
2 parents 6c2842b + fb71f78 commit 1346592

File tree

10 files changed

+4117
-3605
lines changed

10 files changed

+4117
-3605
lines changed

cpp/ql/src/semmle/code/cpp/exprs/BuiltInOperations.qll

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ abstract class BuiltInOperation extends Expr {
88
override string getCanonicalQLClass() { result = "BuiltInOperation" }
99
}
1010

11+
/**
12+
* A C/C++ built-in operation that is used to support functions with variable numbers of arguments.
13+
* This includes `va_start`, `va_end`, `va_copy`, and `va_arg`.
14+
*/
15+
class VarArgsExpr extends BuiltInOperation {
16+
VarArgsExpr() {
17+
this instanceof BuiltInVarArgsStart
18+
or
19+
this instanceof BuiltInVarArgsEnd
20+
or
21+
this instanceof BuiltInVarArg
22+
or
23+
this instanceof BuiltInVarArgCopy
24+
}
25+
}
26+
1127
/**
1228
* A C/C++ `__builtin_va_start` built-in operation (used by some
1329
* implementations of `va_start`).
@@ -20,6 +36,16 @@ class BuiltInVarArgsStart extends BuiltInOperation, @vastartexpr {
2036
override string toString() { result = "__builtin_va_start" }
2137

2238
override string getCanonicalQLClass() { result = "BuiltInVarArgsStart" }
39+
40+
/**
41+
* Gets the `va_list` argument.
42+
*/
43+
final Expr getVAList() { result = getChild(0) }
44+
45+
/**
46+
* Gets the argument that specifies the last named parameter before the ellipsis.
47+
*/
48+
final VariableAccess getLastNamedParameter() { result = getChild(1) }
2349
}
2450

2551
/**
@@ -35,6 +61,11 @@ class BuiltInVarArgsEnd extends BuiltInOperation, @vaendexpr {
3561
override string toString() { result = "__builtin_va_end" }
3662

3763
override string getCanonicalQLClass() { result = "BuiltInVarArgsEnd" }
64+
65+
/**
66+
* Gets the `va_list` argument.
67+
*/
68+
final Expr getVAList() { result = getChild(0) }
3869
}
3970

4071
/**
@@ -48,6 +79,11 @@ class BuiltInVarArg extends BuiltInOperation, @vaargexpr {
4879
override string toString() { result = "__builtin_va_arg" }
4980

5081
override string getCanonicalQLClass() { result = "BuiltInVarArg" }
82+
83+
/**
84+
* Gets the `va_list` argument.
85+
*/
86+
final Expr getVAList() { result = getChild(0) }
5187
}
5288

5389
/**
@@ -63,6 +99,16 @@ class BuiltInVarArgCopy extends BuiltInOperation, @vacopyexpr {
6399
override string toString() { result = "__builtin_va_copy" }
64100

65101
override string getCanonicalQLClass() { result = "BuiltInVarArgCopy" }
102+
103+
/**
104+
* Gets the destination `va_list` argument.
105+
*/
106+
final Expr getDestinationVAList() { result = getChild(0) }
107+
108+
/**
109+
* Gets the the source `va_list` argument.
110+
*/
111+
final Expr getSourceVAList() { result = getChild(1) }
66112
}
67113

68114
/**

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private newtype TOpcode =
7070
TVarArgsStart() or
7171
TVarArgsEnd() or
7272
TVarArg() or
73-
TVarArgCopy() or
73+
TNextVarArg() or
7474
TCallSideEffect() or
7575
TCallReadSideEffect() or
7676
TIndirectReadSideEffect() or
@@ -629,20 +629,20 @@ module Opcode {
629629
final override string toString() { result = "BuiltIn" }
630630
}
631631

632-
class VarArgsStart extends BuiltInOperationOpcode, TVarArgsStart {
632+
class VarArgsStart extends UnaryOpcode, TVarArgsStart {
633633
final override string toString() { result = "VarArgsStart" }
634634
}
635635

636-
class VarArgsEnd extends BuiltInOperationOpcode, TVarArgsEnd {
636+
class VarArgsEnd extends UnaryOpcode, TVarArgsEnd {
637637
final override string toString() { result = "VarArgsEnd" }
638638
}
639639

640-
class VarArg extends BuiltInOperationOpcode, TVarArg {
640+
class VarArg extends UnaryOpcode, TVarArg {
641641
final override string toString() { result = "VarArg" }
642642
}
643643

644-
class VarArgCopy extends BuiltInOperationOpcode, TVarArgCopy {
645-
final override string toString() { result = "VarArgCopy" }
644+
class NextVarArg extends UnaryOpcode, TNextVarArg {
645+
final override string toString() { result = "NextVarArg" }
646646
}
647647

648648
class CallSideEffect extends WriteSideEffectOpcode, EscapedWriteOpcode, MayWriteOpcode,

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ newtype TInstructionTag =
6464
InitializerElementAddressTag() or
6565
InitializerElementDefaultValueTag() or
6666
InitializerElementDefaultValueStoreTag() or
67+
VarArgsStartEllipsisAddressTag() or
68+
VarArgsStartTag() or
69+
VarArgsVAListLoadTag() or
70+
VarArgsArgAddressTag() or
71+
VarArgsArgLoadTag() or
72+
VarArgsMoveNextTag() or
73+
VarArgsVAListStoreTag() or
6774
AsmTag() or
6875
AsmInputTag(int elementIndex) { exists(AsmStmt asm | exists(asm.getChild(elementIndex))) }
6976

@@ -188,6 +195,20 @@ string getInstructionTagId(TInstructionTag tag) {
188195
or
189196
tag = InitializerElementDefaultValueStoreTag() and result = "InitElemDefValStore"
190197
or
198+
tag = VarArgsStartEllipsisAddressTag() and result = "VarArgsStartEllipsisAddr"
199+
or
200+
tag = VarArgsStartTag() and result = "VarArgsStart"
201+
or
202+
tag = VarArgsVAListLoadTag() and result = "VarArgsVAListLoad"
203+
or
204+
tag = VarArgsArgAddressTag() and result = "VarArgsArgAddr"
205+
or
206+
tag = VarArgsArgLoadTag() and result = "VaArgsArgLoad"
207+
or
208+
tag = VarArgsMoveNextTag() and result = "VarArgsMoveNext"
209+
or
210+
tag = VarArgsVAListStoreTag() and result = "VarArgsVAListStore"
211+
or
191212
tag = AsmTag() and result = "Asm"
192213
or
193214
exists(int index | tag = AsmInputTag(index) and result = "AsmInputTag(" + index + ")")

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ private predicate ignoreExprAndDescendants(Expr expr) {
8383
exists(DeleteExpr deleteExpr | deleteExpr.getAllocatorCall() = expr)
8484
or
8585
exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getAllocatorCall() = expr)
86+
or
87+
exists(BuiltInVarArgsStart vaStartExpr |
88+
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
89+
)
8690
}
8791

8892
/**

0 commit comments

Comments
 (0)