Merge pull request #2629 from dbartol/dbartol/missing-vvars

C++/C#: Fix missing virtual variables
This commit is contained in:
Robert Marsh
2020-01-15 08:32:43 -08:00
committed by GitHub
20 changed files with 770 additions and 636 deletions

View File

@@ -260,6 +260,19 @@ module InstructionSanity {
} }
} }
/**
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
* `File` and line number. Used for assigning register names when printing IR.
*/
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and
file = location.getFile() and
line = location.getStartLine()
)
}
/** /**
* Represents a single operation in the IR. * Represents a single operation in the IR.
*/ */
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
private int getLineRank() { private int getLineRank() {
this = rank[result](Instruction instr | this = rank[result](Instruction instr |
instr.getAST().getFile() = getAST().getFile() and instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine() getLocation().getStartLine())
| |
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock() instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
) )

View File

@@ -41,8 +41,18 @@ private newtype TMemoryLocation =
IntValue endBitOffset, boolean isMayAccess IntValue endBitOffset, boolean isMayAccess
) { ) {
( (
hasResultMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess) or hasResultMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess)
or
hasOperandMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess) hasOperandMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess)
or
exists(IRAutomaticVariable autoVar |
// Always create a memory location for the entire variable.
autoVar = var and
type = autoVar.getIRType() and
startBitOffset = 0 and
endBitOffset = type.getByteSize() * 8 and
isMayAccess = false
)
) and ) and
languageType = type.getCanonicalLanguageType() languageType = type.getCanonicalLanguageType()
} or } or
@@ -78,6 +88,8 @@ abstract class MemoryLocation extends TMemoryLocation {
abstract IRFunction getIRFunction(); abstract IRFunction getIRFunction();
abstract Location getLocation();
final IRType getIRType() { result = getType().getIRType() } final IRType getIRType() { result = getType().getIRType() }
abstract predicate isMayAccess(); abstract predicate isMayAccess();
@@ -141,6 +153,8 @@ class VariableMemoryLocation extends TVariableMemoryLocation, MemoryLocation {
final override IRFunction getIRFunction() { result = var.getEnclosingIRFunction() } final override IRFunction getIRFunction() { result = var.getEnclosingIRFunction() }
final override Location getLocation() { result = var.getLocation() }
final IntValue getStartBitOffset() { result = startBitOffset } final IntValue getStartBitOffset() { result = startBitOffset }
final IntValue getEndBitOffset() { result = endBitOffset } final IntValue getEndBitOffset() { result = endBitOffset }
@@ -208,6 +222,8 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
final override IRFunction getIRFunction() { result = irFunc } final override IRFunction getIRFunction() { result = irFunc }
final override Location getLocation() { result = irFunc.getLocation() }
final override string getUniqueId() { result = "{Unknown}" } final override string getUniqueId() { result = "{Unknown}" }
final override predicate isMayAccess() { isMayAccess = true } final override predicate isMayAccess() { isMayAccess = true }
@@ -233,6 +249,8 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
final override IRFunction getIRFunction() { result = irFunc } final override IRFunction getIRFunction() { result = irFunc }
final override Location getLocation() { result = irFunc.getLocation() }
final override string getUniqueId() { result = "{AllNonLocal}" } final override string getUniqueId() { result = "{AllNonLocal}" }
final override predicate isMayAccess() { isMayAccess = true } final override predicate isMayAccess() { isMayAccess = true }
@@ -255,6 +273,8 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
final override IRFunction getIRFunction() { result = irFunc } final override IRFunction getIRFunction() { result = irFunc }
final override Location getLocation() { result = irFunc.getLocation() }
final override string getUniqueId() { result = " " + toString() } final override string getUniqueId() { result = " " + toString() }
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) } final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }

View File

@@ -885,4 +885,13 @@ module SSASanity {
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
) )
} }
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
} }

View File

@@ -260,6 +260,19 @@ module InstructionSanity {
} }
} }
/**
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
* `File` and line number. Used for assigning register names when printing IR.
*/
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and
file = location.getFile() and
line = location.getStartLine()
)
}
/** /**
* Represents a single operation in the IR. * Represents a single operation in the IR.
*/ */
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
private int getLineRank() { private int getLineRank() {
this = rank[result](Instruction instr | this = rank[result](Instruction instr |
instr.getAST().getFile() = getAST().getFile() and instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine() getLocation().getStartLine())
| |
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock() instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
) )

View File

@@ -260,6 +260,19 @@ module InstructionSanity {
} }
} }
/**
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
* `File` and line number. Used for assigning register names when printing IR.
*/
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and
file = location.getFile() and
line = location.getStartLine()
)
}
/** /**
* Represents a single operation in the IR. * Represents a single operation in the IR.
*/ */
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
private int getLineRank() { private int getLineRank() {
this = rank[result](Instruction instr | this = rank[result](Instruction instr |
instr.getAST().getFile() = getAST().getFile() and instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine() getLocation().getStartLine())
| |
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock() instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
) )

View File

@@ -885,4 +885,13 @@ module SSASanity {
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
) )
} }
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
} }

View File

@@ -55,6 +55,10 @@ class MemoryLocation extends TMemoryLocation {
final string toString() { result = var.toString() } final string toString() { result = var.toString() }
final Language::Location getLocation() { result = var.getLocation() }
final IRFunction getIRFunction() { result = var.getEnclosingIRFunction() }
final IRVariable getIRVariable() { result = var } final IRVariable getIRVariable() { result = var }
final VirtualVariable getVirtualVariable() { result = this } final VirtualVariable getVirtualVariable() { result = this }

View File

@@ -13,6 +13,8 @@ class Function = Cpp::Function;
class Location = Cpp::Location; class Location = Cpp::Location;
class File = Cpp::File;
class AST = Cpp::Locatable; class AST = Cpp::Locatable;
class Type = Cpp::Type; class Type = Cpp::Type;

View File

@@ -0,0 +1,2 @@
multipleOperandMemoryLocations
missingVirtualVariableForMemoryLocation

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
multipleOperandMemoryLocations
missingVirtualVariableForMemoryLocation

View File

@@ -0,0 +1,2 @@
multipleOperandMemoryLocations
missingVirtualVariableForMemoryLocation

View File

@@ -0,0 +1,2 @@
multipleOperandMemoryLocations
missingVirtualVariableForMemoryLocation

View File

@@ -260,6 +260,19 @@ module InstructionSanity {
} }
} }
/**
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
* `File` and line number. Used for assigning register names when printing IR.
*/
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and
file = location.getFile() and
line = location.getStartLine()
)
}
/** /**
* Represents a single operation in the IR. * Represents a single operation in the IR.
*/ */
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
private int getLineRank() { private int getLineRank() {
this = rank[result](Instruction instr | this = rank[result](Instruction instr |
instr.getAST().getFile() = getAST().getFile() and instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine() getLocation().getStartLine())
| |
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock() instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
) )

View File

@@ -260,6 +260,19 @@ module InstructionSanity {
} }
} }
/**
* Gets an `Instruction` that is contained in `IRFunction`, and has a location with the specified
* `File` and line number. Used for assigning register names when printing IR.
*/
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and
file = location.getFile() and
line = location.getStartLine()
)
}
/** /**
* Represents a single operation in the IR. * Represents a single operation in the IR.
*/ */
@@ -324,8 +337,8 @@ class Instruction extends Construction::TInstruction {
private int getLineRank() { private int getLineRank() {
this = rank[result](Instruction instr | this = rank[result](Instruction instr |
instr.getAST().getFile() = getAST().getFile() and instr = getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
instr.getAST().getLocation().getStartLine() = getAST().getLocation().getStartLine() getLocation().getStartLine())
| |
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock() instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
) )

View File

@@ -885,4 +885,13 @@ module SSASanity {
message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'."
) )
} }
query predicate missingVirtualVariableForMemoryLocation(
Alias::MemoryLocation location, string message, OldIR::IRFunction func, string funcText
) {
not exists(location.getVirtualVariable()) and
func = location.getIRFunction() and
funcText = Language::getIdentityString(func.getFunction()) and
message = "Memory location has no virtual variable in function '$@'."
}
} }

View File

@@ -55,6 +55,10 @@ class MemoryLocation extends TMemoryLocation {
final string toString() { result = var.toString() } final string toString() { result = var.toString() }
final Language::Location getLocation() { result = var.getLocation() }
final IRFunction getIRFunction() { result = var.getEnclosingIRFunction() }
final IRVariable getIRVariable() { result = var } final IRVariable getIRVariable() { result = var }
final VirtualVariable getVirtualVariable() { result = this } final VirtualVariable getVirtualVariable() { result = this }

View File

@@ -10,6 +10,8 @@ class Function = CSharp::Callable;
class Location = CSharp::Location; class Location = CSharp::Location;
class File = CSharp::File;
class AST = CSharp::Element; class AST = CSharp::Element;
class Type = CSharp::Type; class Type = CSharp::Type;

View File

@@ -733,7 +733,7 @@ indexers.cs:
# 8| mu8_3(<unknown>) = UnmodeledDefinition : # 8| mu8_3(<unknown>) = UnmodeledDefinition :
# 8| r8_4(glval<MyClass>) = InitializeThis : # 8| r8_4(glval<MyClass>) = InitializeThis :
# 6| r6_1(glval<Int32>) = VariableAddress[index] : # 6| r6_1(glval<Int32>) = VariableAddress[index] :
# 6| mu6_3(Int32) = InitializeParameter[index] : &:r6_1 # 6| mu6_2(Int32) = InitializeParameter[index] : &:r6_1
# 10| r10_1(glval<String>) = VariableAddress[#return] : # 10| r10_1(glval<String>) = VariableAddress[#return] :
# 10| r10_2(MyClass) = CopyValue : r8_4 # 10| r10_2(MyClass) = CopyValue : r8_4
# 10| r10_3(glval<String[]>) = FieldAddress[address] : r10_2 # 10| r10_3(glval<String[]>) = FieldAddress[address] : r10_2
@@ -756,7 +756,7 @@ indexers.cs:
# 12| mu12_3(<unknown>) = UnmodeledDefinition : # 12| mu12_3(<unknown>) = UnmodeledDefinition :
# 12| r12_4(glval<MyClass>) = InitializeThis : # 12| r12_4(glval<MyClass>) = InitializeThis :
# 6| r6_1(glval<Int32>) = VariableAddress[index] : # 6| r6_1(glval<Int32>) = VariableAddress[index] :
# 6| mu6_3(Int32) = InitializeParameter[index] : &:r6_1 # 6| mu6_2(Int32) = InitializeParameter[index] : &:r6_1
# 12| r12_5(glval<String>) = VariableAddress[value] : # 12| r12_5(glval<String>) = VariableAddress[value] :
# 12| mu12_6(String) = InitializeParameter[value] : &:r12_5 # 12| mu12_6(String) = InitializeParameter[value] : &:r12_5
# 14| r14_1(glval<String>) = VariableAddress[value] : # 14| r14_1(glval<String>) = VariableAddress[value] :

View File

@@ -0,0 +1,2 @@
multipleOperandMemoryLocations
missingVirtualVariableForMemoryLocation