Skip to content

Commit 09d7ed0

Browse files
authored
Merge pull request github#3612 from dbartol/github/codeql-c-analysis-team/69_union
C++: Share `TInstruction` across IR stages
2 parents 8107fba + 687d6d2 commit 09d7ed0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1246
-1107
lines changed

config/identical-files.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,18 @@
9696
"cpp/ql/src/semmle/code/cpp/ir/implementation/UseSoundEscapeAnalysis.qll",
9797
"csharp/ql/src/experimental/ir/implementation/UseSoundEscapeAnalysis.qll"
9898
],
99+
"IR IRFunctionBase": [
100+
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll",
101+
"csharp/ql/src/experimental/ir/implementation/internal/IRFunctionBase.qll"
102+
],
99103
"IR Operand Tag": [
100104
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll",
101105
"csharp/ql/src/experimental/ir/implementation/internal/OperandTag.qll"
102106
],
107+
"IR TInstruction":[
108+
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TInstruction.qll",
109+
"csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll"
110+
],
103111
"IR TIRVariable":[
104112
"cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll",
105113
"csharp/ql/src/experimental/ir/implementation/internal/TIRVariable.qll"
@@ -177,6 +185,11 @@
177185
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll",
178186
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRBlockImports.qll"
179187
],
188+
"C++ IR IRFunctionImports": [
189+
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRFunctionImports.qll",
190+
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll",
191+
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/IRFunctionImports.qll"
192+
],
180193
"C++ IR IRVariableImports": [
181194
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRVariableImports.qll",
182195
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll",
@@ -287,6 +300,10 @@
287300
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRBlockImports.qll",
288301
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRBlockImports.qll"
289302
],
303+
"C# IR IRFunctionImports": [
304+
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRFunctionImports.qll",
305+
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRFunctionImports.qll"
306+
],
290307
"C# IR IRVariableImports": [
291308
"csharp/ql/src/experimental/ir/implementation/raw/internal/IRVariableImports.qll",
292309
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/IRVariableImports.qll"

cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import semmle.code.cpp.ir.ValueNumbering
2323
class NullInstruction extends ConstantValueInstruction {
2424
NullInstruction() {
2525
this.getValue() = "0" and
26-
this.getResultType().getUnspecifiedType() instanceof PointerType
26+
this.getResultIRType() instanceof IRAddressType
2727
}
2828
}
2929

@@ -44,8 +44,8 @@ predicate explicitNullTestOfInstruction(Instruction checked, Instruction bool) {
4444
bool =
4545
any(ConvertInstruction convert |
4646
checked = convert.getUnary() and
47-
convert.getResultType() instanceof BoolType and
48-
checked.getResultType() instanceof PointerType
47+
convert.getResultIRType() instanceof IRBooleanType and
48+
checked.getResultIRType() instanceof IRAddressType
4949
)
5050
}
5151

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,13 @@ private class SideEffectOutNode extends OutNode {
128128
* `kind`.
129129
*/
130130
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
131-
result.getCall() = call and
132-
result.getReturnKind() = kind
131+
// There should be only one `OutNode` for a given `(call, kind)` pair. Showing the optimizer that
132+
// this is true helps it make better decisions downstream, especially in virtual dispatch.
133+
result =
134+
unique(OutNode outNode |
135+
outNode.getCall() = call and
136+
outNode.getReturnKind() = kind
137+
)
133138
}
134139

135140
/**

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ private class IRSizedType extends IRType {
111111
this = TIRFunctionAddressType(byteSize) or
112112
this = TIROpaqueType(_, byteSize)
113113
}
114+
// Don't override `getByteSize()` here. The optimizer seems to generate better code when this is
115+
// overridden only in the leaf classes.
114116
}
115117

116118
/**
@@ -128,7 +130,7 @@ class IRBooleanType extends IRSizedType, TIRBooleanType {
128130
}
129131

130132
/**
131-
* A numberic type. This includes `IRSignedIntegerType`, `IRUnsignedIntegerType`, and
133+
* A numeric type. This includes `IRSignedIntegerType`, `IRUnsignedIntegerType`, and
132134
* `IRFloatingPointType`.
133135
*/
134136
class IRNumericType extends IRSizedType {
@@ -137,13 +139,27 @@ class IRNumericType extends IRSizedType {
137139
this = TIRUnsignedIntegerType(byteSize) or
138140
this = TIRFloatingPointType(byteSize, _, _)
139141
}
142+
// Don't override `getByteSize()` here. The optimizer seems to generate better code when this is
143+
// overridden only in the leaf classes.
144+
}
145+
146+
/**
147+
* An integer type. This includes `IRSignedIntegerType` and `IRUnsignedIntegerType`.
148+
*/
149+
class IRIntegerType extends IRNumericType {
150+
IRIntegerType() {
151+
this = TIRSignedIntegerType(byteSize) or
152+
this = TIRUnsignedIntegerType(byteSize)
153+
}
154+
// Don't override `getByteSize()` here. The optimizer seems to generate better code when this is
155+
// overridden only in the leaf classes.
140156
}
141157

142158
/**
143159
* A signed two's-complement integer. Also used to represent enums whose underlying type is a signed
144160
* integer, as well as character types whose representation is signed.
145161
*/
146-
class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType {
162+
class IRSignedIntegerType extends IRIntegerType, TIRSignedIntegerType {
147163
final override string toString() { result = "int" + byteSize.toString() }
148164

149165
final override Language::LanguageType getCanonicalLanguageType() {
@@ -158,7 +174,7 @@ class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType {
158174
* An unsigned two's-complement integer. Also used to represent enums whose underlying type is an
159175
* unsigned integer, as well as character types whose representation is unsigned.
160176
*/
161-
class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType {
177+
class IRUnsignedIntegerType extends IRIntegerType, TIRUnsignedIntegerType {
162178
final override string toString() { result = "uint" + byteSize.toString() }
163179

164180
final override Language::LanguageType getCanonicalLanguageType() {

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRFunction.qll

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,12 @@
11
private import internal.IRInternal
2+
private import internal.IRFunctionImports as Imports
3+
import Imports::IRFunctionBase
24
import Instruction
35

4-
private newtype TIRFunction =
5-
MkIRFunction(Language::Function func) { Construction::functionHasIR(func) }
6-
76
/**
8-
* Represents the IR for a function.
7+
* The IR for a function.
98
*/
10-
class IRFunction extends TIRFunction {
11-
Language::Function func;
12-
13-
IRFunction() { this = MkIRFunction(func) }
14-
15-
final string toString() { result = "IR: " + func.toString() }
16-
17-
/**
18-
* Gets the function whose IR is represented.
19-
*/
20-
final Language::Function getFunction() { result = func }
21-
22-
/**
23-
* Gets the location of the function.
24-
*/
25-
final Language::Location getLocation() { result = func.getLocation() }
26-
9+
class IRFunction extends IRFunctionBase {
2710
/**
2811
* Gets the entry point for this function.
2912
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@ private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File fil
2929
/**
3030
* Represents a single operation in the IR.
3131
*/
32-
class Instruction extends Construction::TInstruction {
32+
class Instruction extends Construction::TStageInstruction {
33+
Instruction() {
34+
// The base `TStageInstruction` type is a superset of the actual instructions appearing in this
35+
// stage. This call lets the stage filter out the ones that are not reused from raw IR.
36+
Construction::hasInstruction(this)
37+
}
38+
3339
final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
3440

3541
/**
@@ -194,14 +200,14 @@ class Instruction extends Construction::TInstruction {
194200
* conversion.
195201
*/
196202
final Language::Expr getConvertedResultExpression() {
197-
result = Construction::getInstructionConvertedResultExpression(this)
203+
result = Raw::getInstructionConvertedResultExpression(this)
198204
}
199205

200206
/**
201207
* Gets the unconverted form of the `Expr` whose result is computed by this instruction, if any.
202208
*/
203209
final Language::Expr getUnconvertedResultExpression() {
204-
result = Construction::getInstructionUnconvertedResultExpression(this)
210+
result = Raw::getInstructionUnconvertedResultExpression(this)
205211
}
206212

207213
final Language::LanguageType getResultLanguageType() {
@@ -212,6 +218,7 @@ class Instruction extends Construction::TInstruction {
212218
* Gets the type of the result produced by this instruction. If the instruction does not produce
213219
* a result, its result type will be `IRVoidType`.
214220
*/
221+
cached
215222
final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
216223

217224
/**
@@ -250,7 +257,7 @@ class Instruction extends Construction::TInstruction {
250257
* result of the `Load` instruction is a prvalue of type `int`, representing
251258
* the integer value loaded from variable `x`.
252259
*/
253-
final predicate isGLValue() { Construction::getInstructionResultType(this).hasType(_, true) }
260+
final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
254261

255262
/**
256263
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -259,7 +266,7 @@ class Instruction extends Construction::TInstruction {
259266
* If `this.isGLValue()` holds for this instruction, the value of
260267
* `getResultSize()` will always be the size of a pointer.
261268
*/
262-
final int getResultSize() { result = Construction::getInstructionResultType(this).getByteSize() }
269+
final int getResultSize() { result = getResultLanguageType().getByteSize() }
263270

264271
/**
265272
* Gets the opcode that specifies the operation performed by this instruction.
@@ -395,7 +402,7 @@ class Instruction extends Construction::TInstruction {
395402
class VariableInstruction extends Instruction {
396403
IRVariable var;
397404

398-
VariableInstruction() { var = Construction::getInstructionVariable(this) }
405+
VariableInstruction() { var = Raw::getInstructionVariable(this) }
399406

400407
override string getImmediateString() { result = var.toString() }
401408

@@ -410,7 +417,7 @@ class VariableInstruction extends Instruction {
410417
class FieldInstruction extends Instruction {
411418
Language::Field field;
412419

413-
FieldInstruction() { field = Construction::getInstructionField(this) }
420+
FieldInstruction() { field = Raw::getInstructionField(this) }
414421

415422
final override string getImmediateString() { result = field.toString() }
416423

@@ -420,7 +427,7 @@ class FieldInstruction extends Instruction {
420427
class FunctionInstruction extends Instruction {
421428
Language::Function funcSymbol;
422429

423-
FunctionInstruction() { funcSymbol = Construction::getInstructionFunction(this) }
430+
FunctionInstruction() { funcSymbol = Raw::getInstructionFunction(this) }
424431

425432
final override string getImmediateString() { result = funcSymbol.toString() }
426433

@@ -430,7 +437,7 @@ class FunctionInstruction extends Instruction {
430437
class ConstantValueInstruction extends Instruction {
431438
string value;
432439

433-
ConstantValueInstruction() { value = Construction::getInstructionConstantValue(this) }
440+
ConstantValueInstruction() { value = Raw::getInstructionConstantValue(this) }
434441

435442
final override string getImmediateString() { result = value }
436443

@@ -440,7 +447,7 @@ class ConstantValueInstruction extends Instruction {
440447
class IndexedInstruction extends Instruction {
441448
int index;
442449

443-
IndexedInstruction() { index = Construction::getInstructionIndex(this) }
450+
IndexedInstruction() { index = Raw::getInstructionIndex(this) }
444451

445452
final override string getImmediateString() { result = index.toString() }
446453

@@ -603,11 +610,16 @@ class ConstantInstruction extends ConstantValueInstruction {
603610
}
604611

605612
class IntegerConstantInstruction extends ConstantInstruction {
606-
IntegerConstantInstruction() { getResultType() instanceof Language::IntegralType }
613+
IntegerConstantInstruction() {
614+
exists(IRType resultType |
615+
resultType = getResultIRType() and
616+
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
617+
)
618+
}
607619
}
608620

609621
class FloatConstantInstruction extends ConstantInstruction {
610-
FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType }
622+
FloatConstantInstruction() { getResultIRType() instanceof IRFloatingPointType }
611623
}
612624

613625
class StringConstantInstruction extends VariableInstruction {
@@ -704,7 +716,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
704716

705717
PointerArithmeticInstruction() {
706718
getOpcode() instanceof PointerArithmeticOpcode and
707-
elementSize = Construction::getInstructionElementSize(this)
719+
elementSize = Raw::getInstructionElementSize(this)
708720
}
709721

710722
final override string getImmediateString() { result = elementSize.toString() }
@@ -753,7 +765,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
753765
Language::Class derivedClass;
754766

755767
InheritanceConversionInstruction() {
756-
Construction::getInstructionInheritance(this, baseClass, derivedClass)
768+
Raw::getInstructionInheritance(this, baseClass, derivedClass)
757769
}
758770

759771
final override string getImmediateString() {
@@ -1216,7 +1228,7 @@ class CatchByTypeInstruction extends CatchInstruction {
12161228

12171229
CatchByTypeInstruction() {
12181230
getOpcode() instanceof Opcode::CatchByType and
1219-
exceptionType = Construction::getInstructionExceptionType(this)
1231+
exceptionType = Raw::getInstructionExceptionType(this)
12201232
}
12211233

12221234
final override string getImmediateString() { result = exceptionType.toString() }
@@ -1362,7 +1374,7 @@ class BuiltInOperationInstruction extends Instruction {
13621374

13631375
BuiltInOperationInstruction() {
13641376
getOpcode() instanceof BuiltInOperationOpcode and
1365-
operation = Construction::getInstructionBuiltInOperation(this)
1377+
operation = Raw::getInstructionBuiltInOperation(this)
13661378
}
13671379

13681380
final Language::BuiltInOperation getBuiltInOperation() { result = operation }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import semmle.code.cpp.ir.implementation.internal.IRFunctionBase as IRFunctionBase
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
22
import SSAConstruction as Construction
33
import semmle.code.cpp.ir.implementation.IRConfiguration as IRConfiguration
4+
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction::Raw as Raw

0 commit comments

Comments
 (0)