Merge pull request #2975 from rdmarsh2/printir-generate-all

C++/C#: generate IR for funcs excluded in PrintIR
This commit is contained in:
Dave Bartolomeo
2020-03-25 09:45:02 -04:00
committed by GitHub
23 changed files with 140 additions and 49 deletions

View File

@@ -16,6 +16,8 @@ class IRConfiguration extends TIRConfiguration {
* Holds if IR should be created for function `func`. By default, holds for all functions. * Holds if IR should be created for function `func`. By default, holds for all functions.
*/ */
predicate shouldCreateIRForFunction(Language::Function func) { any() } predicate shouldCreateIRForFunction(Language::Function func) { any() }
predicate shouldEvaluateDebugStringsForFunction(Language::Function func) { any() }
} }
private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration() private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration()

View File

@@ -27,6 +27,9 @@ class IRBlockBase extends TIRBlock {
* by debugging and printing code only. * by debugging and printing code only.
*/ */
int getDisplayIndex() { int getDisplayIndex() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this = this =
rank[result + 1](IRBlock funcBlock | rank[result + 1](IRBlock funcBlock |
funcBlock.getEnclosingFunction() = getEnclosingFunction() funcBlock.getEnclosingFunction() = getEnclosingFunction()

View File

@@ -15,6 +15,9 @@ private import Imports::OperandTag
* `File` and line number. Used for assigning register names when printing IR. * `File` and line number. Used for assigning register names when printing IR.
*/ */
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) { private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(irFunc.getFunction())
) and
exists(Language::Location location | exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and location = result.getLocation() and
@@ -39,6 +42,12 @@ class Instruction extends Construction::TInstruction {
result = getResultString() + " = " + getOperationString() + " " + getOperandsString() result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
} }
predicate shouldGenerateDumpStrings() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
)
}
/** /**
* Gets a string describing the operation of this instruction. This includes * Gets a string describing the operation of this instruction. This includes
* the opcode and the immediate value, if any. For example: * the opcode and the immediate value, if any. For example:
@@ -46,6 +55,7 @@ class Instruction extends Construction::TInstruction {
* VariableAddress[x] * VariableAddress[x]
*/ */
final string getOperationString() { final string getOperationString() {
shouldGenerateDumpStrings() and
if exists(getImmediateString()) if exists(getImmediateString())
then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]" then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
else result = getOperationPrefix() + getOpcode().toString() else result = getOperationPrefix() + getOpcode().toString()
@@ -57,10 +67,12 @@ class Instruction extends Construction::TInstruction {
string getImmediateString() { none() } string getImmediateString() { none() }
private string getOperationPrefix() { private string getOperationPrefix() {
shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = "" if this instanceof SideEffectInstruction then result = "^" else result = ""
} }
private string getResultPrefix() { private string getResultPrefix() {
shouldGenerateDumpStrings() and
if getResultIRType() instanceof IRVoidType if getResultIRType() instanceof IRVoidType
then result = "v" then result = "v"
else else
@@ -74,6 +86,7 @@ class Instruction extends Construction::TInstruction {
* used by debugging and printing code only. * used by debugging and printing code only.
*/ */
int getDisplayIndexInBlock() { int getDisplayIndexInBlock() {
shouldGenerateDumpStrings() and
exists(IRBlock block | exists(IRBlock block |
this = block.getInstruction(result) this = block.getInstruction(result)
or or
@@ -87,6 +100,7 @@ class Instruction extends Construction::TInstruction {
} }
private int getLineRank() { private int getLineRank() {
shouldGenerateDumpStrings() and
this = this =
rank[result](Instruction instr | rank[result](Instruction instr |
instr = instr =
@@ -105,6 +119,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1` * Example: `r1_1`
*/ */
string getResultId() { string getResultId() {
shouldGenerateDumpStrings() and
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank() result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
} }
@@ -116,6 +131,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1(int*)` * Example: `r1_1(int*)`
*/ */
final string getResultString() { final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")" result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
} }
@@ -126,6 +142,7 @@ class Instruction extends Construction::TInstruction {
* Example: `func:r3_4, this:r3_5` * Example: `func:r3_4, this:r3_5`
*/ */
string getOperandsString() { string getOperandsString() {
shouldGenerateDumpStrings() and
result = result =
concat(Operand operand | concat(Operand operand |
operand = getAnOperand() operand = getAnOperand()

View File

@@ -18,19 +18,19 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
predicate shouldPrintFunction(Language::Function func) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
/** /**
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Language::Function func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
} }

View File

@@ -1,2 +1,3 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import SSAConstruction as Construction import SSAConstruction as Construction
import semmle.code.cpp.ir.implementation.IRConfiguration as IRConfiguration

View File

@@ -27,6 +27,9 @@ class IRBlockBase extends TIRBlock {
* by debugging and printing code only. * by debugging and printing code only.
*/ */
int getDisplayIndex() { int getDisplayIndex() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this = this =
rank[result + 1](IRBlock funcBlock | rank[result + 1](IRBlock funcBlock |
funcBlock.getEnclosingFunction() = getEnclosingFunction() funcBlock.getEnclosingFunction() = getEnclosingFunction()

View File

@@ -15,6 +15,9 @@ private import Imports::OperandTag
* `File` and line number. Used for assigning register names when printing IR. * `File` and line number. Used for assigning register names when printing IR.
*/ */
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) { private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(irFunc.getFunction())
) and
exists(Language::Location location | exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and location = result.getLocation() and
@@ -39,6 +42,12 @@ class Instruction extends Construction::TInstruction {
result = getResultString() + " = " + getOperationString() + " " + getOperandsString() result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
} }
predicate shouldGenerateDumpStrings() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
)
}
/** /**
* Gets a string describing the operation of this instruction. This includes * Gets a string describing the operation of this instruction. This includes
* the opcode and the immediate value, if any. For example: * the opcode and the immediate value, if any. For example:
@@ -46,6 +55,7 @@ class Instruction extends Construction::TInstruction {
* VariableAddress[x] * VariableAddress[x]
*/ */
final string getOperationString() { final string getOperationString() {
shouldGenerateDumpStrings() and
if exists(getImmediateString()) if exists(getImmediateString())
then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]" then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
else result = getOperationPrefix() + getOpcode().toString() else result = getOperationPrefix() + getOpcode().toString()
@@ -57,10 +67,12 @@ class Instruction extends Construction::TInstruction {
string getImmediateString() { none() } string getImmediateString() { none() }
private string getOperationPrefix() { private string getOperationPrefix() {
shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = "" if this instanceof SideEffectInstruction then result = "^" else result = ""
} }
private string getResultPrefix() { private string getResultPrefix() {
shouldGenerateDumpStrings() and
if getResultIRType() instanceof IRVoidType if getResultIRType() instanceof IRVoidType
then result = "v" then result = "v"
else else
@@ -74,6 +86,7 @@ class Instruction extends Construction::TInstruction {
* used by debugging and printing code only. * used by debugging and printing code only.
*/ */
int getDisplayIndexInBlock() { int getDisplayIndexInBlock() {
shouldGenerateDumpStrings() and
exists(IRBlock block | exists(IRBlock block |
this = block.getInstruction(result) this = block.getInstruction(result)
or or
@@ -87,6 +100,7 @@ class Instruction extends Construction::TInstruction {
} }
private int getLineRank() { private int getLineRank() {
shouldGenerateDumpStrings() and
this = this =
rank[result](Instruction instr | rank[result](Instruction instr |
instr = instr =
@@ -105,6 +119,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1` * Example: `r1_1`
*/ */
string getResultId() { string getResultId() {
shouldGenerateDumpStrings() and
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank() result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
} }
@@ -116,6 +131,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1(int*)` * Example: `r1_1(int*)`
*/ */
final string getResultString() { final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")" result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
} }
@@ -126,6 +142,7 @@ class Instruction extends Construction::TInstruction {
* Example: `func:r3_4, this:r3_5` * Example: `func:r3_4, this:r3_5`
*/ */
string getOperandsString() { string getOperandsString() {
shouldGenerateDumpStrings() and
result = result =
concat(Operand operand | concat(Operand operand |
operand = getAnOperand() operand = getAnOperand()

View File

@@ -18,19 +18,19 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
predicate shouldPrintFunction(Language::Function func) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
/** /**
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Language::Function func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
} }

View File

@@ -1,2 +1,3 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import IRConstruction as Construction import IRConstruction as Construction
import semmle.code.cpp.ir.implementation.IRConfiguration as IRConfiguration

View File

@@ -27,6 +27,9 @@ class IRBlockBase extends TIRBlock {
* by debugging and printing code only. * by debugging and printing code only.
*/ */
int getDisplayIndex() { int getDisplayIndex() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this = this =
rank[result + 1](IRBlock funcBlock | rank[result + 1](IRBlock funcBlock |
funcBlock.getEnclosingFunction() = getEnclosingFunction() funcBlock.getEnclosingFunction() = getEnclosingFunction()

View File

@@ -15,6 +15,9 @@ private import Imports::OperandTag
* `File` and line number. Used for assigning register names when printing IR. * `File` and line number. Used for assigning register names when printing IR.
*/ */
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) { private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(irFunc.getFunction())
) and
exists(Language::Location location | exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and location = result.getLocation() and
@@ -39,6 +42,12 @@ class Instruction extends Construction::TInstruction {
result = getResultString() + " = " + getOperationString() + " " + getOperandsString() result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
} }
predicate shouldGenerateDumpStrings() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
)
}
/** /**
* Gets a string describing the operation of this instruction. This includes * Gets a string describing the operation of this instruction. This includes
* the opcode and the immediate value, if any. For example: * the opcode and the immediate value, if any. For example:
@@ -46,6 +55,7 @@ class Instruction extends Construction::TInstruction {
* VariableAddress[x] * VariableAddress[x]
*/ */
final string getOperationString() { final string getOperationString() {
shouldGenerateDumpStrings() and
if exists(getImmediateString()) if exists(getImmediateString())
then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]" then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
else result = getOperationPrefix() + getOpcode().toString() else result = getOperationPrefix() + getOpcode().toString()
@@ -57,10 +67,12 @@ class Instruction extends Construction::TInstruction {
string getImmediateString() { none() } string getImmediateString() { none() }
private string getOperationPrefix() { private string getOperationPrefix() {
shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = "" if this instanceof SideEffectInstruction then result = "^" else result = ""
} }
private string getResultPrefix() { private string getResultPrefix() {
shouldGenerateDumpStrings() and
if getResultIRType() instanceof IRVoidType if getResultIRType() instanceof IRVoidType
then result = "v" then result = "v"
else else
@@ -74,6 +86,7 @@ class Instruction extends Construction::TInstruction {
* used by debugging and printing code only. * used by debugging and printing code only.
*/ */
int getDisplayIndexInBlock() { int getDisplayIndexInBlock() {
shouldGenerateDumpStrings() and
exists(IRBlock block | exists(IRBlock block |
this = block.getInstruction(result) this = block.getInstruction(result)
or or
@@ -87,6 +100,7 @@ class Instruction extends Construction::TInstruction {
} }
private int getLineRank() { private int getLineRank() {
shouldGenerateDumpStrings() and
this = this =
rank[result](Instruction instr | rank[result](Instruction instr |
instr = instr =
@@ -105,6 +119,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1` * Example: `r1_1`
*/ */
string getResultId() { string getResultId() {
shouldGenerateDumpStrings() and
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank() result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
} }
@@ -116,6 +131,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1(int*)` * Example: `r1_1(int*)`
*/ */
final string getResultString() { final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")" result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
} }
@@ -126,6 +142,7 @@ class Instruction extends Construction::TInstruction {
* Example: `func:r3_4, this:r3_5` * Example: `func:r3_4, this:r3_5`
*/ */
string getOperandsString() { string getOperandsString() {
shouldGenerateDumpStrings() and
result = result =
concat(Operand operand | concat(Operand operand |
operand = getAnOperand() operand = getAnOperand()

View File

@@ -18,19 +18,19 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
predicate shouldPrintFunction(Language::Function func) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
/** /**
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Language::Function func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
} }

View File

@@ -1,2 +1,3 @@
import semmle.code.cpp.ir.internal.IRCppLanguage as Language import semmle.code.cpp.ir.internal.IRCppLanguage as Language
import SSAConstruction as Construction import SSAConstruction as Construction
import semmle.code.cpp.ir.implementation.IRConfiguration as IRConfiguration

View File

@@ -1,19 +1 @@
/** import implementation.IRConfiguration
* Module used to configure the IR generation process.
*/
import csharp
private newtype TIRConfiguration = MkIRConfiguration()
/**
* The query can extend this class to control which functions have IR generated for them.
*/
class IRConfiguration extends TIRConfiguration {
string toString() { result = "IRConfiguration" }
/**
* Holds if IR should be created for callable `callable`. By default, holds for all callables.
*/
predicate shouldCreateIRForFunction(Callable callable) { any() }
}

View File

@@ -16,6 +16,8 @@ class IRConfiguration extends TIRConfiguration {
* Holds if IR should be created for function `func`. By default, holds for all functions. * Holds if IR should be created for function `func`. By default, holds for all functions.
*/ */
predicate shouldCreateIRForFunction(Language::Function func) { any() } predicate shouldCreateIRForFunction(Language::Function func) { any() }
predicate shouldEvaluateDebugStringsForFunction(Language::Function func) { any() }
} }
private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration() private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration()

View File

@@ -27,6 +27,9 @@ class IRBlockBase extends TIRBlock {
* by debugging and printing code only. * by debugging and printing code only.
*/ */
int getDisplayIndex() { int getDisplayIndex() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this = this =
rank[result + 1](IRBlock funcBlock | rank[result + 1](IRBlock funcBlock |
funcBlock.getEnclosingFunction() = getEnclosingFunction() funcBlock.getEnclosingFunction() = getEnclosingFunction()

View File

@@ -15,6 +15,9 @@ private import Imports::OperandTag
* `File` and line number. Used for assigning register names when printing IR. * `File` and line number. Used for assigning register names when printing IR.
*/ */
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) { private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(irFunc.getFunction())
) and
exists(Language::Location location | exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and location = result.getLocation() and
@@ -39,6 +42,12 @@ class Instruction extends Construction::TInstruction {
result = getResultString() + " = " + getOperationString() + " " + getOperandsString() result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
} }
predicate shouldGenerateDumpStrings() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
)
}
/** /**
* Gets a string describing the operation of this instruction. This includes * Gets a string describing the operation of this instruction. This includes
* the opcode and the immediate value, if any. For example: * the opcode and the immediate value, if any. For example:
@@ -46,6 +55,7 @@ class Instruction extends Construction::TInstruction {
* VariableAddress[x] * VariableAddress[x]
*/ */
final string getOperationString() { final string getOperationString() {
shouldGenerateDumpStrings() and
if exists(getImmediateString()) if exists(getImmediateString())
then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]" then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
else result = getOperationPrefix() + getOpcode().toString() else result = getOperationPrefix() + getOpcode().toString()
@@ -57,10 +67,12 @@ class Instruction extends Construction::TInstruction {
string getImmediateString() { none() } string getImmediateString() { none() }
private string getOperationPrefix() { private string getOperationPrefix() {
shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = "" if this instanceof SideEffectInstruction then result = "^" else result = ""
} }
private string getResultPrefix() { private string getResultPrefix() {
shouldGenerateDumpStrings() and
if getResultIRType() instanceof IRVoidType if getResultIRType() instanceof IRVoidType
then result = "v" then result = "v"
else else
@@ -74,6 +86,7 @@ class Instruction extends Construction::TInstruction {
* used by debugging and printing code only. * used by debugging and printing code only.
*/ */
int getDisplayIndexInBlock() { int getDisplayIndexInBlock() {
shouldGenerateDumpStrings() and
exists(IRBlock block | exists(IRBlock block |
this = block.getInstruction(result) this = block.getInstruction(result)
or or
@@ -87,6 +100,7 @@ class Instruction extends Construction::TInstruction {
} }
private int getLineRank() { private int getLineRank() {
shouldGenerateDumpStrings() and
this = this =
rank[result](Instruction instr | rank[result](Instruction instr |
instr = instr =
@@ -105,6 +119,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1` * Example: `r1_1`
*/ */
string getResultId() { string getResultId() {
shouldGenerateDumpStrings() and
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank() result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
} }
@@ -116,6 +131,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1(int*)` * Example: `r1_1(int*)`
*/ */
final string getResultString() { final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")" result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
} }
@@ -126,6 +142,7 @@ class Instruction extends Construction::TInstruction {
* Example: `func:r3_4, this:r3_5` * Example: `func:r3_4, this:r3_5`
*/ */
string getOperandsString() { string getOperandsString() {
shouldGenerateDumpStrings() and
result = result =
concat(Operand operand | concat(Operand operand |
operand = getAnOperand() operand = getAnOperand()

View File

@@ -18,19 +18,19 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
predicate shouldPrintFunction(Language::Function func) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
/** /**
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Language::Function func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
} }

View File

@@ -1,2 +1,3 @@
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
import IRConstruction as Construction import IRConstruction as Construction
import semmle.code.csharp.ir.implementation.IRConfiguration as IRConfiguration

View File

@@ -27,6 +27,9 @@ class IRBlockBase extends TIRBlock {
* by debugging and printing code only. * by debugging and printing code only.
*/ */
int getDisplayIndex() { int getDisplayIndex() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this = this =
rank[result + 1](IRBlock funcBlock | rank[result + 1](IRBlock funcBlock |
funcBlock.getEnclosingFunction() = getEnclosingFunction() funcBlock.getEnclosingFunction() = getEnclosingFunction()

View File

@@ -15,6 +15,9 @@ private import Imports::OperandTag
* `File` and line number. Used for assigning register names when printing IR. * `File` and line number. Used for assigning register names when printing IR.
*/ */
private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) { private Instruction getAnInstructionAtLine(IRFunction irFunc, Language::File file, int line) {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(irFunc.getFunction())
) and
exists(Language::Location location | exists(Language::Location location |
irFunc = result.getEnclosingIRFunction() and irFunc = result.getEnclosingIRFunction() and
location = result.getLocation() and location = result.getLocation() and
@@ -39,6 +42,12 @@ class Instruction extends Construction::TInstruction {
result = getResultString() + " = " + getOperationString() + " " + getOperandsString() result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
} }
predicate shouldGenerateDumpStrings() {
exists(IRConfiguration::IRConfiguration config |
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
)
}
/** /**
* Gets a string describing the operation of this instruction. This includes * Gets a string describing the operation of this instruction. This includes
* the opcode and the immediate value, if any. For example: * the opcode and the immediate value, if any. For example:
@@ -46,6 +55,7 @@ class Instruction extends Construction::TInstruction {
* VariableAddress[x] * VariableAddress[x]
*/ */
final string getOperationString() { final string getOperationString() {
shouldGenerateDumpStrings() and
if exists(getImmediateString()) if exists(getImmediateString())
then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]" then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
else result = getOperationPrefix() + getOpcode().toString() else result = getOperationPrefix() + getOpcode().toString()
@@ -57,10 +67,12 @@ class Instruction extends Construction::TInstruction {
string getImmediateString() { none() } string getImmediateString() { none() }
private string getOperationPrefix() { private string getOperationPrefix() {
shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = "" if this instanceof SideEffectInstruction then result = "^" else result = ""
} }
private string getResultPrefix() { private string getResultPrefix() {
shouldGenerateDumpStrings() and
if getResultIRType() instanceof IRVoidType if getResultIRType() instanceof IRVoidType
then result = "v" then result = "v"
else else
@@ -74,6 +86,7 @@ class Instruction extends Construction::TInstruction {
* used by debugging and printing code only. * used by debugging and printing code only.
*/ */
int getDisplayIndexInBlock() { int getDisplayIndexInBlock() {
shouldGenerateDumpStrings() and
exists(IRBlock block | exists(IRBlock block |
this = block.getInstruction(result) this = block.getInstruction(result)
or or
@@ -87,6 +100,7 @@ class Instruction extends Construction::TInstruction {
} }
private int getLineRank() { private int getLineRank() {
shouldGenerateDumpStrings() and
this = this =
rank[result](Instruction instr | rank[result](Instruction instr |
instr = instr =
@@ -105,6 +119,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1` * Example: `r1_1`
*/ */
string getResultId() { string getResultId() {
shouldGenerateDumpStrings() and
result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank() result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
} }
@@ -116,6 +131,7 @@ class Instruction extends Construction::TInstruction {
* Example: `r1_1(int*)` * Example: `r1_1(int*)`
*/ */
final string getResultString() { final string getResultString() {
shouldGenerateDumpStrings() and
result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")" result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
} }
@@ -126,6 +142,7 @@ class Instruction extends Construction::TInstruction {
* Example: `func:r3_4, this:r3_5` * Example: `func:r3_4, this:r3_5`
*/ */
string getOperandsString() { string getOperandsString() {
shouldGenerateDumpStrings() and
result = result =
concat(Operand operand | concat(Operand operand |
operand = getAnOperand() operand = getAnOperand()

View File

@@ -18,19 +18,19 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
predicate shouldPrintFunction(Language::Function func) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
/** /**
* Override of `IRConfiguration` to only create IR for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldCreateIRForFunction(Language::Function func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key)) exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
} }

View File

@@ -1,2 +1,3 @@
import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language import semmle.code.csharp.ir.internal.IRCSharpLanguage as Language
import SSAConstruction as Construction import SSAConstruction as Construction
import semmle.code.csharp.ir.implementation.IRConfiguration as IRConfiguration