Skip to content

Commit a91f10f

Browse files
author
Robert Marsh
authored
Merge pull request #2629 from dbartol/dbartol/missing-vvars
C++/C#: Fix missing virtual variables
2 parents f7278d3 + e60f902 commit a91f10f

File tree

20 files changed

+770
-636
lines changed

20 files changed

+770
-636
lines changed

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ module InstructionSanity {
260260
}
261261
}
262262

263+
/**
264+
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
265+
* `File` and line number. Used for assigning register names when printing IR.
266+
*/
267+
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
268+
exists(Language::Location location |
269+
irFunc = result.getEnclosingIRFunction() and
270+
location = result.getLocation() and
271+
file = location.getFile() and
272+
line = location.getStartLine()
273+
)
274+
}
275+
263276
/**
264277
* Represents a single operation in the IR.
265278
*/
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
324337

325338
private int getLineRank() {
326339
this = rank[result](Instruction instr |
327-
instr.getAST().getFile() = getAST().getFile() and
328-
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine()
340+
instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
341+
getLocation().getStartLine())
329342
|
330343
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
331344
)

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,18 @@ private newtype TMemoryLocation =
4141
IntValue endBitOffset, boolean isMayAccess
4242
) {
4343
(
44-
hasResultMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess) or
44+
hasResultMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess)
45+
or
4546
hasOperandMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess)
47+
or
48+
exists(IRAutomaticVariable autoVar |
49+
// Always create a memory location for the entire variable.
50+
autoVar = var and
51+
type = autoVar.getIRType() and
52+
startBitOffset = 0 and
53+
endBitOffset = type.getByteSize() * 8 and
54+
isMayAccess = false
55+
)
4656
) and
4757
languageType = type.getCanonicalLanguageType()
4858
} or
@@ -78,6 +88,8 @@ abstract class MemoryLocation extends TMemoryLocation {
7888

7989
abstract IRFunction getIRFunction();
8090

91+
abstract Location getLocation();
92+
8193
final IRType getIRType() { result = getType().getIRType() }
8294

8395
abstract predicate isMayAccess();
@@ -141,6 +153,8 @@ class VariableMemoryLocation extends TVariableMemoryLocation, MemoryLocation {
141153

142154
final override IRFunction getIRFunction() { result = var.getEnclosingIRFunction() }
143155

156+
final override Location getLocation() { result = var.getLocation() }
157+
144158
final IntValue getStartBitOffset() { result = startBitOffset }
145159

146160
final IntValue getEndBitOffset() { result = endBitOffset }
@@ -208,6 +222,8 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
208222

209223
final override IRFunction getIRFunction() { result = irFunc }
210224

225+
final override Location getLocation() { result = irFunc.getLocation() }
226+
211227
final override string getUniqueId() { result = "{Unknown}" }
212228

213229
final override predicate isMayAccess() { isMayAccess = true }
@@ -233,6 +249,8 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
233249

234250
final override IRFunction getIRFunction() { result = irFunc }
235251

252+
final override Location getLocation() { result = irFunc.getLocation() }
253+
236254
final override string getUniqueId() { result = "{AllNonLocal}" }
237255

238256
final override predicate isMayAccess() { isMayAccess = true }
@@ -255,6 +273,8 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
255273

256274
final override IRFunction getIRFunction() { result = irFunc }
257275

276+
final override Location getLocation() { result = irFunc.getLocation() }
277+
258278
final override string getUniqueId() { result = " " + toString() }
259279

260280
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,4 +885,13 @@ module SSASanity {
885885
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
886886
)
887887
}
888+
889+
query predicate missingVirtualVariableForMemoryLocation(
890+
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
891+
) {
892+
not exists(location.getVirtualVariable()) and
893+
func = location.getIRFunction() and
894+
funcText = Language::getIdentityString(func.getFunction()) and
895+
message = "Memory location has no virtual variable in function '$@'."
896+
}
888897
}

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ module InstructionSanity {
260260
}
261261
}
262262

263+
/**
264+
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
265+
* `File` and line number. Used for assigning register names when printing IR.
266+
*/
267+
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
268+
exists(Language::Location location |
269+
irFunc = result.getEnclosingIRFunction() and
270+
location = result.getLocation() and
271+
file = location.getFile() and
272+
line = location.getStartLine()
273+
)
274+
}
275+
263276
/**
264277
* Represents a single operation in the IR.
265278
*/
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
324337

325338
private int getLineRank() {
326339
this = rank[result](Instruction instr |
327-
instr.getAST().getFile() = getAST().getFile() and
328-
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine()
340+
instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
341+
getLocation().getStartLine())
329342
|
330343
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
331344
)

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,19 @@ module InstructionSanity {
260260
}
261261
}
262262

263+
/**
264+
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
265+
* `File` and line number. Used for assigning register names when printing IR.
266+
*/
267+
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
268+
exists(Language::Location location |
269+
irFunc = result.getEnclosingIRFunction() and
270+
location = result.getLocation() and
271+
file = location.getFile() and
272+
line = location.getStartLine()
273+
)
274+
}
275+
263276
/**
264277
* Represents a single operation in the IR.
265278
*/
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
324337

325338
private int getLineRank() {
326339
this = rank[result](Instruction instr |
327-
instr.getAST().getFile() = getAST().getFile() and
328-
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine()
340+
instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
341+
getLocation().getStartLine())
329342
|
330343
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
331344
)

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,4 +885,13 @@ module SSASanity {
885885
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
886886
)
887887
}
888+
889+
query predicate missingVirtualVariableForMemoryLocation(
890+
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
891+
) {
892+
not exists(location.getVirtualVariable()) and
893+
func = location.getIRFunction() and
894+
funcText = Language::getIdentityString(func.getFunction()) and
895+
message = "Memory location has no virtual variable in function '$@'."
896+
}
888897
}

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class MemoryLocation extends TMemoryLocation {
5555

5656
final string toString() { result = var.toString() }
5757

58+
final Language::Location getLocation() { result = var.getLocation() }
59+
60+
final IRFunction getIRFunction() { result = var.getEnclosingIRFunction() }
61+
5862
final IRVariable getIRVariable() { result = var }
5963

6064
final VirtualVariable getVirtualVariable() { result = this }

cpp/ql/src/semmle/code/cpp/ir/internal/IRCppLanguage.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class Function = Cpp::Function;
1313

1414
class Location = Cpp::Location;
1515

16+
class File = Cpp::File;
17+
1618
class AST = Cpp::Locatable;
1719

1820
class Type = Cpp::Type;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
multipleOperandMemoryLocations
2+
missingVirtualVariableForMemoryLocation

0 commit comments

Comments
 (0)