Skip to content

Commit 8c9e817

Browse files
authored
Merge pull request #7188 from github/redsun82/fix-operand-location
C++: take IR Operand locations from definitions
2 parents bb38c4d + 055017d commit 8c9e817

File tree

21 files changed

+8002
-881
lines changed

21 files changed

+8002
-881
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll

+24-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ private import internal.OperandInternal
2020
private class TStageOperand =
2121
TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand;
2222

23+
/**
24+
* A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as
25+
* opposed to testing `not loc isntanceof UnknownLocation`
26+
*/
27+
private class KnownLocation extends Language::Location {
28+
KnownLocation() { not this instanceof Language::UnknownLocation }
29+
}
30+
2331
/**
2432
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
2533
* (the defining instruction) in another instruction (the use instruction)
@@ -45,8 +53,10 @@ class Operand extends TStageOperand {
4553

4654
/**
4755
* Gets the location of the source code for this operand.
56+
* By default this is where the operand is used, but some subclasses may override this
57+
* using `getAnyDef()` if it makes more sense.
4858
*/
49-
final Language::Location getLocation() { result = this.getUse().getLocation() }
59+
Language::Location getLocation() { result = this.getUse().getLocation() }
5060

5161
/**
5262
* Gets the function that contains this operand.
@@ -269,6 +279,10 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
269279

270280
final override string toString() { result = tag.toString() }
271281

282+
// most `RegisterOperands` have a more meaningful location at the definition
283+
// the only exception are specific cases of `ThisArgumentOperand`
284+
override Language::Location getLocation() { result = this.getAnyDef().getLocation() }
285+
272286
final override Instruction getAnyDef() { result = defInstr }
273287

274288
final override Overlap getDefinitionOverlap() {
@@ -401,11 +415,19 @@ class ArgumentOperand extends RegisterOperand {
401415
}
402416

403417
/**
404-
* An operand representing the implicit 'this' argument to a member function
418+
* An operand representing the implicit `this` argument to a member function
405419
* call.
406420
*/
407421
class ThisArgumentOperand extends ArgumentOperand {
408422
override ThisArgumentOperandTag tag;
423+
424+
// in most cases the def location makes more sense, but in some corner cases it
425+
// has an unknown location: in those cases we fall back to the use location
426+
override Language::Location getLocation() {
427+
if this.getAnyDef().getLocation() instanceof KnownLocation
428+
then result = this.getAnyDef().getLocation()
429+
else result = this.getUse().getLocation()
430+
}
409431
}
410432

411433
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll

+24-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ private import internal.OperandInternal
2020
private class TStageOperand =
2121
TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand;
2222

23+
/**
24+
* A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as
25+
* opposed to testing `not loc isntanceof UnknownLocation`
26+
*/
27+
private class KnownLocation extends Language::Location {
28+
KnownLocation() { not this instanceof Language::UnknownLocation }
29+
}
30+
2331
/**
2432
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
2533
* (the defining instruction) in another instruction (the use instruction)
@@ -45,8 +53,10 @@ class Operand extends TStageOperand {
4553

4654
/**
4755
* Gets the location of the source code for this operand.
56+
* By default this is where the operand is used, but some subclasses may override this
57+
* using `getAnyDef()` if it makes more sense.
4858
*/
49-
final Language::Location getLocation() { result = this.getUse().getLocation() }
59+
Language::Location getLocation() { result = this.getUse().getLocation() }
5060

5161
/**
5262
* Gets the function that contains this operand.
@@ -269,6 +279,10 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
269279

270280
final override string toString() { result = tag.toString() }
271281

282+
// most `RegisterOperands` have a more meaningful location at the definition
283+
// the only exception are specific cases of `ThisArgumentOperand`
284+
override Language::Location getLocation() { result = this.getAnyDef().getLocation() }
285+
272286
final override Instruction getAnyDef() { result = defInstr }
273287

274288
final override Overlap getDefinitionOverlap() {
@@ -401,11 +415,19 @@ class ArgumentOperand extends RegisterOperand {
401415
}
402416

403417
/**
404-
* An operand representing the implicit 'this' argument to a member function
418+
* An operand representing the implicit `this` argument to a member function
405419
* call.
406420
*/
407421
class ThisArgumentOperand extends ArgumentOperand {
408422
override ThisArgumentOperandTag tag;
423+
424+
// in most cases the def location makes more sense, but in some corner cases it
425+
// has an unknown location: in those cases we fall back to the use location
426+
override Language::Location getLocation() {
427+
if this.getAnyDef().getLocation() instanceof KnownLocation
428+
then result = this.getAnyDef().getLocation()
429+
else result = this.getUse().getLocation()
430+
}
409431
}
410432

411433
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll

+24-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ private import internal.OperandInternal
2020
private class TStageOperand =
2121
TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand;
2222

23+
/**
24+
* A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as
25+
* opposed to testing `not loc isntanceof UnknownLocation`
26+
*/
27+
private class KnownLocation extends Language::Location {
28+
KnownLocation() { not this instanceof Language::UnknownLocation }
29+
}
30+
2331
/**
2432
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
2533
* (the defining instruction) in another instruction (the use instruction)
@@ -45,8 +53,10 @@ class Operand extends TStageOperand {
4553

4654
/**
4755
* Gets the location of the source code for this operand.
56+
* By default this is where the operand is used, but some subclasses may override this
57+
* using `getAnyDef()` if it makes more sense.
4858
*/
49-
final Language::Location getLocation() { result = this.getUse().getLocation() }
59+
Language::Location getLocation() { result = this.getUse().getLocation() }
5060

5161
/**
5262
* Gets the function that contains this operand.
@@ -269,6 +279,10 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
269279

270280
final override string toString() { result = tag.toString() }
271281

282+
// most `RegisterOperands` have a more meaningful location at the definition
283+
// the only exception are specific cases of `ThisArgumentOperand`
284+
override Language::Location getLocation() { result = this.getAnyDef().getLocation() }
285+
272286
final override Instruction getAnyDef() { result = defInstr }
273287

274288
final override Overlap getDefinitionOverlap() {
@@ -401,11 +415,19 @@ class ArgumentOperand extends RegisterOperand {
401415
}
402416

403417
/**
404-
* An operand representing the implicit 'this' argument to a member function
418+
* An operand representing the implicit `this` argument to a member function
405419
* call.
406420
*/
407421
class ThisArgumentOperand extends ArgumentOperand {
408422
override ThisArgumentOperandTag tag;
423+
424+
// in most cases the def location makes more sense, but in some corner cases it
425+
// has an unknown location: in those cases we fall back to the use location
426+
override Language::Location getLocation() {
427+
if this.getAnyDef().getLocation() instanceof KnownLocation
428+
then result = this.getAnyDef().getLocation()
429+
else result = this.getUse().getLocation()
430+
}
409431
}
410432

411433
/**

0 commit comments

Comments
 (0)