From 12daa76b7052962a26825b0ad402e5337f5f0a34 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 14 Aug 2019 13:48:34 -0700 Subject: [PATCH 01/10] C++: Make `duplicateOperand` query report function name --- .../aliased_ssa/Instruction.qll | 20 +++++++++++++------ .../cpp/ir/implementation/raw/Instruction.qll | 20 +++++++++++++------ .../unaliased_ssa/Instruction.qll | 20 +++++++++++++------ .../ir/implementation/raw/Instruction.qll | 20 +++++++++++++------ .../unaliased_ssa/Instruction.qll | 20 +++++++++++++------ 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index e3c78f476e9..bfd04a279e0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -94,12 +94,20 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, OperandTag tag) { - strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) > 1 and - not tag instanceof UnmodeledUseOperandTag + query predicate duplicateOperand(Instruction instr, string message, IRFunction func, + string funcText) { + exists(OperandTag tag, int operandCount | + operandCount = strictcount(NonPhiOperand operand | + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and + operandCount > 1 and + not tag instanceof UnmodeledUseOperandTag and + message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + + " in function '$@'." and + func = instr.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + ) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index e3c78f476e9..bfd04a279e0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -94,12 +94,20 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, OperandTag tag) { - strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) > 1 and - not tag instanceof UnmodeledUseOperandTag + query predicate duplicateOperand(Instruction instr, string message, IRFunction func, + string funcText) { + exists(OperandTag tag, int operandCount | + operandCount = strictcount(NonPhiOperand operand | + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and + operandCount > 1 and + not tag instanceof UnmodeledUseOperandTag and + message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + + " in function '$@'." and + func = instr.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + ) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index e3c78f476e9..bfd04a279e0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -94,12 +94,20 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, OperandTag tag) { - strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) > 1 and - not tag instanceof UnmodeledUseOperandTag + query predicate duplicateOperand(Instruction instr, string message, IRFunction func, + string funcText) { + exists(OperandTag tag, int operandCount | + operandCount = strictcount(NonPhiOperand operand | + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and + operandCount > 1 and + not tag instanceof UnmodeledUseOperandTag and + message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + + " in function '$@'." and + func = instr.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + ) } /** diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index e3c78f476e9..bfd04a279e0 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -94,12 +94,20 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, OperandTag tag) { - strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) > 1 and - not tag instanceof UnmodeledUseOperandTag + query predicate duplicateOperand(Instruction instr, string message, IRFunction func, + string funcText) { + exists(OperandTag tag, int operandCount | + operandCount = strictcount(NonPhiOperand operand | + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and + operandCount > 1 and + not tag instanceof UnmodeledUseOperandTag and + message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + + " in function '$@'." and + func = instr.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + ) } /** diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index e3c78f476e9..bfd04a279e0 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -94,12 +94,20 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, OperandTag tag) { - strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) > 1 and - not tag instanceof UnmodeledUseOperandTag + query predicate duplicateOperand(Instruction instr, string message, IRFunction func, + string funcText) { + exists(OperandTag tag, int operandCount | + operandCount = strictcount(NonPhiOperand operand | + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and + operandCount > 1 and + not tag instanceof UnmodeledUseOperandTag and + message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + + " in function '$@'." and + func = instr.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + ) } /** From bc48c25690f98945ad6470c69877650809d6e63c Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Fri, 22 Nov 2019 12:13:39 -0700 Subject: [PATCH 02/10] C++/C#: Make `IRVariable` and its derived classes non-abstract --- .../implementation/aliased_ssa/IRVariable.qll | 63 ++++++++++++++++--- .../cpp/ir/implementation/raw/IRVariable.qll | 63 ++++++++++++++++--- .../unaliased_ssa/IRVariable.qll | 63 ++++++++++++++++--- .../ir/implementation/raw/IRVariable.qll | 63 ++++++++++++++++--- .../unaliased_ssa/IRVariable.qll | 63 ++++++++++++++++--- 5 files changed, 270 insertions(+), 45 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll index e10e266b2ab..349ff7cd6bd 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll @@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var * be a user-declared variable (`IRUserVariable`) or a temporary variable * generated by the AST-to-IR translation (`IRTempVariable`). */ -abstract class IRVariable extends TIRVariable { +class IRVariable extends TIRVariable { Language::Function func; - abstract string toString(); + IRVariable() { + this = TIRUserVariable(_, _, func) or + this = TIRTempVariable(func, _, _, _) or + this = TIRStringLiteral(func, _, _, _) + } + + string toString() { none() } /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - abstract Language::LanguageType getLanguageType(); + Language::LanguageType getLanguageType() { none() } /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - abstract Language::AST getAST(); + Language::AST getAST() { none() } /** * Gets an identifier string for the variable. This identifier is unique * within the function. */ - abstract string getUniqueId(); + string getUniqueId() { none() } /** * Gets the source location of this variable. @@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * stack. This includes all parameters, non-static local variables, and * temporary variables. */ -abstract class IRAutomaticVariable extends IRVariable { } +class IRAutomaticVariable extends IRVariable { + IRAutomaticVariable() { + exists(Language::Variable var | + this = TIRUserVariable(var, _, func) and + Language::isVariableAutomatic(var) + ) or + this = TIRTempVariable(func, _, _, _) + } +} +/** + * Represents a user-declared variable that is allocated on the stack. This + * includes all parameters and non-static local variables. + */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; - IRAutomaticUserVariable() { Language::isVariableAutomatic(var) } - final override Language::AutomaticVariable getVariable() { result = var } } +/** + * Represents a user-declared variable that is not allocated on the stack. This + * includes all global variables, namespace-scope variables, static fields, and + * static local variables. + */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } -abstract class IRGeneratedVariable extends IRVariable { +/** + * Represents a variable that is not user-declared. This includes temporary + * variables generated as part of IR construction, as well as string literals. + */ +class IRGeneratedVariable extends IRVariable { Language::AST ast; Language::LanguageType type; + IRGeneratedVariable() { + this = TIRTempVariable(func, ast, _, type) or + this = TIRStringLiteral(func, ast, type, _) + } + final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAST() { result = ast } @@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getTag() = tag } +/** + * Represents a temporary variable introduced by IR construction. The most common examples are the + * variable generated to hold the return value of afunction, or the variable generated to hold the + * result of a condition operator (`a ? b : c`). + */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa override string getBaseString() { result = "#temp" } } +/** + * The temporary variable generated to hold the return value of a function. + */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } final override string toString() { result = "#return" } } +/** + * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } override string getBaseString() { result = "#throw" } } +/** + * The variable generated to represent the contents of a string literal. This variable acts much + * like a read-only global variable. + */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll index e10e266b2ab..349ff7cd6bd 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll @@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var * be a user-declared variable (`IRUserVariable`) or a temporary variable * generated by the AST-to-IR translation (`IRTempVariable`). */ -abstract class IRVariable extends TIRVariable { +class IRVariable extends TIRVariable { Language::Function func; - abstract string toString(); + IRVariable() { + this = TIRUserVariable(_, _, func) or + this = TIRTempVariable(func, _, _, _) or + this = TIRStringLiteral(func, _, _, _) + } + + string toString() { none() } /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - abstract Language::LanguageType getLanguageType(); + Language::LanguageType getLanguageType() { none() } /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - abstract Language::AST getAST(); + Language::AST getAST() { none() } /** * Gets an identifier string for the variable. This identifier is unique * within the function. */ - abstract string getUniqueId(); + string getUniqueId() { none() } /** * Gets the source location of this variable. @@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * stack. This includes all parameters, non-static local variables, and * temporary variables. */ -abstract class IRAutomaticVariable extends IRVariable { } +class IRAutomaticVariable extends IRVariable { + IRAutomaticVariable() { + exists(Language::Variable var | + this = TIRUserVariable(var, _, func) and + Language::isVariableAutomatic(var) + ) or + this = TIRTempVariable(func, _, _, _) + } +} +/** + * Represents a user-declared variable that is allocated on the stack. This + * includes all parameters and non-static local variables. + */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; - IRAutomaticUserVariable() { Language::isVariableAutomatic(var) } - final override Language::AutomaticVariable getVariable() { result = var } } +/** + * Represents a user-declared variable that is not allocated on the stack. This + * includes all global variables, namespace-scope variables, static fields, and + * static local variables. + */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } -abstract class IRGeneratedVariable extends IRVariable { +/** + * Represents a variable that is not user-declared. This includes temporary + * variables generated as part of IR construction, as well as string literals. + */ +class IRGeneratedVariable extends IRVariable { Language::AST ast; Language::LanguageType type; + IRGeneratedVariable() { + this = TIRTempVariable(func, ast, _, type) or + this = TIRStringLiteral(func, ast, type, _) + } + final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAST() { result = ast } @@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getTag() = tag } +/** + * Represents a temporary variable introduced by IR construction. The most common examples are the + * variable generated to hold the return value of afunction, or the variable generated to hold the + * result of a condition operator (`a ? b : c`). + */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa override string getBaseString() { result = "#temp" } } +/** + * The temporary variable generated to hold the return value of a function. + */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } final override string toString() { result = "#return" } } +/** + * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } override string getBaseString() { result = "#throw" } } +/** + * The variable generated to represent the contents of a string literal. This variable acts much + * like a read-only global variable. + */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll index e10e266b2ab..349ff7cd6bd 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var * be a user-declared variable (`IRUserVariable`) or a temporary variable * generated by the AST-to-IR translation (`IRTempVariable`). */ -abstract class IRVariable extends TIRVariable { +class IRVariable extends TIRVariable { Language::Function func; - abstract string toString(); + IRVariable() { + this = TIRUserVariable(_, _, func) or + this = TIRTempVariable(func, _, _, _) or + this = TIRStringLiteral(func, _, _, _) + } + + string toString() { none() } /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - abstract Language::LanguageType getLanguageType(); + Language::LanguageType getLanguageType() { none() } /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - abstract Language::AST getAST(); + Language::AST getAST() { none() } /** * Gets an identifier string for the variable. This identifier is unique * within the function. */ - abstract string getUniqueId(); + string getUniqueId() { none() } /** * Gets the source location of this variable. @@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * stack. This includes all parameters, non-static local variables, and * temporary variables. */ -abstract class IRAutomaticVariable extends IRVariable { } +class IRAutomaticVariable extends IRVariable { + IRAutomaticVariable() { + exists(Language::Variable var | + this = TIRUserVariable(var, _, func) and + Language::isVariableAutomatic(var) + ) or + this = TIRTempVariable(func, _, _, _) + } +} +/** + * Represents a user-declared variable that is allocated on the stack. This + * includes all parameters and non-static local variables. + */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; - IRAutomaticUserVariable() { Language::isVariableAutomatic(var) } - final override Language::AutomaticVariable getVariable() { result = var } } +/** + * Represents a user-declared variable that is not allocated on the stack. This + * includes all global variables, namespace-scope variables, static fields, and + * static local variables. + */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } -abstract class IRGeneratedVariable extends IRVariable { +/** + * Represents a variable that is not user-declared. This includes temporary + * variables generated as part of IR construction, as well as string literals. + */ +class IRGeneratedVariable extends IRVariable { Language::AST ast; Language::LanguageType type; + IRGeneratedVariable() { + this = TIRTempVariable(func, ast, _, type) or + this = TIRStringLiteral(func, ast, type, _) + } + final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAST() { result = ast } @@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getTag() = tag } +/** + * Represents a temporary variable introduced by IR construction. The most common examples are the + * variable generated to hold the return value of afunction, or the variable generated to hold the + * result of a condition operator (`a ? b : c`). + */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa override string getBaseString() { result = "#temp" } } +/** + * The temporary variable generated to hold the return value of a function. + */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } final override string toString() { result = "#return" } } +/** + * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } override string getBaseString() { result = "#throw" } } +/** + * The variable generated to represent the contents of a string literal. This variable acts much + * like a read-only global variable. + */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll index e10e266b2ab..349ff7cd6bd 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll @@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var * be a user-declared variable (`IRUserVariable`) or a temporary variable * generated by the AST-to-IR translation (`IRTempVariable`). */ -abstract class IRVariable extends TIRVariable { +class IRVariable extends TIRVariable { Language::Function func; - abstract string toString(); + IRVariable() { + this = TIRUserVariable(_, _, func) or + this = TIRTempVariable(func, _, _, _) or + this = TIRStringLiteral(func, _, _, _) + } + + string toString() { none() } /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - abstract Language::LanguageType getLanguageType(); + Language::LanguageType getLanguageType() { none() } /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - abstract Language::AST getAST(); + Language::AST getAST() { none() } /** * Gets an identifier string for the variable. This identifier is unique * within the function. */ - abstract string getUniqueId(); + string getUniqueId() { none() } /** * Gets the source location of this variable. @@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * stack. This includes all parameters, non-static local variables, and * temporary variables. */ -abstract class IRAutomaticVariable extends IRVariable { } +class IRAutomaticVariable extends IRVariable { + IRAutomaticVariable() { + exists(Language::Variable var | + this = TIRUserVariable(var, _, func) and + Language::isVariableAutomatic(var) + ) or + this = TIRTempVariable(func, _, _, _) + } +} +/** + * Represents a user-declared variable that is allocated on the stack. This + * includes all parameters and non-static local variables. + */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; - IRAutomaticUserVariable() { Language::isVariableAutomatic(var) } - final override Language::AutomaticVariable getVariable() { result = var } } +/** + * Represents a user-declared variable that is not allocated on the stack. This + * includes all global variables, namespace-scope variables, static fields, and + * static local variables. + */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } -abstract class IRGeneratedVariable extends IRVariable { +/** + * Represents a variable that is not user-declared. This includes temporary + * variables generated as part of IR construction, as well as string literals. + */ +class IRGeneratedVariable extends IRVariable { Language::AST ast; Language::LanguageType type; + IRGeneratedVariable() { + this = TIRTempVariable(func, ast, _, type) or + this = TIRStringLiteral(func, ast, type, _) + } + final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAST() { result = ast } @@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getTag() = tag } +/** + * Represents a temporary variable introduced by IR construction. The most common examples are the + * variable generated to hold the return value of afunction, or the variable generated to hold the + * result of a condition operator (`a ? b : c`). + */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa override string getBaseString() { result = "#temp" } } +/** + * The temporary variable generated to hold the return value of a function. + */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } final override string toString() { result = "#return" } } +/** + * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } override string getBaseString() { result = "#throw" } } +/** + * The variable generated to represent the contents of a string literal. This variable acts much + * like a read-only global variable. + */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll index e10e266b2ab..349ff7cd6bd 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -17,10 +17,16 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var * be a user-declared variable (`IRUserVariable`) or a temporary variable * generated by the AST-to-IR translation (`IRTempVariable`). */ -abstract class IRVariable extends TIRVariable { +class IRVariable extends TIRVariable { Language::Function func; - abstract string toString(); + IRVariable() { + this = TIRUserVariable(_, _, func) or + this = TIRTempVariable(func, _, _, _) or + this = TIRStringLiteral(func, _, _, _) + } + + string toString() { none() } /** * Holds if this variable's value cannot be changed within a function. Currently used for string @@ -41,19 +47,19 @@ abstract class IRVariable extends TIRVariable { /** * Gets the type of the variable. */ - abstract Language::LanguageType getLanguageType(); + Language::LanguageType getLanguageType() { none() } /** * Gets the AST node that declared this variable, or that introduced this * variable as part of the AST-to-IR translation. */ - abstract Language::AST getAST(); + Language::AST getAST() { none() } /** * Gets an identifier string for the variable. This identifier is unique * within the function. */ - abstract string getUniqueId(); + string getUniqueId() { none() } /** * Gets the source location of this variable. @@ -101,16 +107,31 @@ class IRUserVariable extends IRVariable, TIRUserVariable { * stack. This includes all parameters, non-static local variables, and * temporary variables. */ -abstract class IRAutomaticVariable extends IRVariable { } +class IRAutomaticVariable extends IRVariable { + IRAutomaticVariable() { + exists(Language::Variable var | + this = TIRUserVariable(var, _, func) and + Language::isVariableAutomatic(var) + ) or + this = TIRTempVariable(func, _, _, _) + } +} +/** + * Represents a user-declared variable that is allocated on the stack. This + * includes all parameters and non-static local variables. + */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; - IRAutomaticUserVariable() { Language::isVariableAutomatic(var) } - final override Language::AutomaticVariable getVariable() { result = var } } +/** + * Represents a user-declared variable that is not allocated on the stack. This + * includes all global variables, namespace-scope variables, static fields, and + * static local variables. + */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -119,10 +140,19 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } -abstract class IRGeneratedVariable extends IRVariable { +/** + * Represents a variable that is not user-declared. This includes temporary + * variables generated as part of IR construction, as well as string literals. + */ +class IRGeneratedVariable extends IRVariable { Language::AST ast; Language::LanguageType type; + IRGeneratedVariable() { + this = TIRTempVariable(func, ast, _, type) or + this = TIRStringLiteral(func, ast, type, _) + } + final override Language::LanguageType getLanguageType() { result = type } final override Language::AST getAST() { result = ast } @@ -144,6 +174,11 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getTag() = tag } +/** + * Represents a temporary variable introduced by IR construction. The most common examples are the + * variable generated to hold the return value of afunction, or the variable generated to hold the + * result of a condition operator (`a ? b : c`). + */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -158,18 +193,28 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa override string getBaseString() { result = "#temp" } } +/** + * The temporary variable generated to hold the return value of a function. + */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } final override string toString() { result = "#return" } } +/** + * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } override string getBaseString() { result = "#throw" } } +/** + * The variable generated to represent the contents of a string literal. This variable acts much + * like a read-only global variable. + */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; From 51ff262cbc6fee9fab7a7186416649bb5b15e4ee Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 14 Aug 2019 13:53:48 -0700 Subject: [PATCH 03/10] C++/C#: Add IR SSA sanity tests --- config/identical-files.json | 5 +++++ .../aliased_ssa/internal/SSAConstruction.qll | 13 +++++++++++++ .../aliased_ssa/internal/SSASanity.ql | 8 ++++++++ .../aliased_ssa/internal/SSASanity.qll | 2 ++ .../unaliased_ssa/internal/SSAConstruction.qll | 13 +++++++++++++ .../unaliased_ssa/internal/SSASanity.ql | 8 ++++++++ .../unaliased_ssa/internal/SSASanity.qll | 2 ++ .../ir/ssa/aliased_ssa_ssa_sanity.expected | 0 .../ir/ssa/aliased_ssa_ssa_sanity.qlref | 1 + .../ir/ssa/unaliased_ssa_ssa_sanity.expected | 0 .../ir/ssa/unaliased_ssa_ssa_sanity.qlref | 1 + .../unaliased_ssa/internal/SSAConstruction.qll | 13 +++++++++++++ .../unaliased_ssa/internal/SSASanity.ql | 8 ++++++++ .../unaliased_ssa/internal/SSASanity.qll | 2 ++ .../ir/ir/unaliased_ssa_ssa_sanity.expected | 0 .../ir/ir/unaliased_ssa_ssa_sanity.qlref | 1 + 16 files changed, 77 insertions(+) create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql create mode 100644 cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll create mode 100644 cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.expected create mode 100644 cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref create mode 100644 cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.expected create mode 100644 cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref create mode 100644 csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql create mode 100644 csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll create mode 100644 csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected create mode 100644 csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref diff --git a/config/identical-files.json b/config/identical-files.json index 4fdac5c7fea..29601d19510 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -143,6 +143,11 @@ "cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll", "csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll" ], + "IR SSASanity": [ + "cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll", + "cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll", + "csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll" + ], "C++ IR InstructionImports": [ "cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionImports.qll", "cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/InstructionImports.qll", diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index a789edc7590..ebb111efc03 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -865,3 +865,16 @@ private module CachedForDebugging { result.getTag() = var.getTag() } } + +module SSASanity { + query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message, + OldIR::IRFunction func, string funcText) { + exists(int locationCount | + locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and + locationCount > 1 and + func = operand.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) and + message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." + ) + } +} \ No newline at end of file diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql new file mode 100644 index 00000000000..50368cdc6d9 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql @@ -0,0 +1,8 @@ +/** + * @name Aliased SSA Sanity Check + * @description Performs sanity checks on the SSA construction. This query should have no results. + * @kind table + * @id cpp/aliased-ssa-sanity-check + */ + +import SSASanity diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll new file mode 100644 index 00000000000..95e8443b2a3 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.qll @@ -0,0 +1,2 @@ +private import SSAConstruction as SSA +import SSA::SSASanity diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index a789edc7590..ebb111efc03 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -865,3 +865,16 @@ private module CachedForDebugging { result.getTag() = var.getTag() } } + +module SSASanity { + query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message, + OldIR::IRFunction func, string funcText) { + exists(int locationCount | + locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and + locationCount > 1 and + func = operand.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) and + message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." + ) + } +} \ No newline at end of file diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql new file mode 100644 index 00000000000..b67f6f281be --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql @@ -0,0 +1,8 @@ +/** + * @name Unaliased SSA Sanity Check + * @description Performs sanity checks on the SSA construction. This query should have no results. + * @kind table + * @id cpp/unaliased-ssa-sanity-check + */ + +import SSASanity diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll new file mode 100644 index 00000000000..95e8443b2a3 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.qll @@ -0,0 +1,2 @@ +private import SSAConstruction as SSA +import SSA::SSASanity diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref new file mode 100644 index 00000000000..8e348011785 --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ssa_sanity.qlref @@ -0,0 +1 @@ +semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref new file mode 100644 index 00000000000..18bf9212dbf --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ssa_sanity.qlref @@ -0,0 +1 @@ +semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql \ No newline at end of file diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index a789edc7590..ebb111efc03 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -865,3 +865,16 @@ private module CachedForDebugging { result.getTag() = var.getTag() } } + +module SSASanity { + query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message, + OldIR::IRFunction func, string funcText) { + exists(int locationCount | + locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and + locationCount > 1 and + func = operand.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) and + message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." + ) + } +} \ No newline at end of file diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql new file mode 100644 index 00000000000..11d7add514b --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql @@ -0,0 +1,8 @@ +/** + * @name Unaliased SSA Sanity Check + * @description Performs sanity checks on the SSA construction. This query should have no results. + * @kind table + * @id csharp/unaliased-ssa-sanity-check + */ + +import SSASanity diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll new file mode 100644 index 00000000000..95e8443b2a3 --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.qll @@ -0,0 +1,2 @@ +private import SSAConstruction as SSA +import SSA::SSASanity diff --git a/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref new file mode 100644 index 00000000000..1b7d4a7996a --- /dev/null +++ b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref @@ -0,0 +1 @@ +semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql \ No newline at end of file From df218357590cf1a1a9646b63481dead245f5e5dc Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 14 Aug 2019 13:54:52 -0700 Subject: [PATCH 04/10] C++/C#: Refactor some integer constant code Make `bitsToBytesAndBits` omit the leftover bits if zero. --- .../code/cpp/ir/internal/IntegerConstant.qll | 33 +++++++++++++++++++ .../code/cpp/ir/internal/IntegerInterval.qll | 2 +- .../csharp/ir/internal/IntegerConstant.qll | 33 +++++++++++++++++++ .../csharp/ir/internal/IntegerInterval.qll | 2 +- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll index 55546ba380f..0d845303c28 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll @@ -192,3 +192,36 @@ predicate isGT(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a > b } */ bindingset[a, b] predicate isGE(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a >= b } + +/** + * Converts the bit count in `bits` to a byte count and a bit count in the form + * "bytes:bits". If `bits` represents an integer number of bytes, the ":bits" section is omitted. + * If `bits` does not have a known value, the result is "?". + */ +bindingset[bits] +string bitsToBytesAndBits(IntValue bits) { + exists(int bytes, int leftoverBits | + hasValue(bits) and + bytes = bits / 8 and + leftoverBits = bits % 8 and + if leftoverBits = 0 then + result = bytes.toString() + else + result = bytes + ":" + leftoverBits + ) or + not hasValue(bits) and result = "?" +} + +/** + * Gets a printable string for a bit offset with possibly unknown value. + */ +bindingset[bitOffset] +string getBitOffsetString(IntValue bitOffset) { + if hasValue(bitOffset) then + if bitOffset >= 0 then + result = "+" + bitsToBytesAndBits(bitOffset) + else + result = "-" + bitsToBytesAndBits(neg(bitOffset)) + else + result = "+?" +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll index bc09f9c2243..cd12b9b627a 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerInterval.qll @@ -30,5 +30,5 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal bindingset[start, end] string getIntervalString(IntValue start, IntValue end) { // We represent an interval has half-open, so print it as "[start..end)". - result = "[" + intValueToString(start) + ".." + intValueToString(end) + ")" + result = "[" + bitsToBytesAndBits(start) + ".." + bitsToBytesAndBits(end) + ")" } diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll index 55546ba380f..0d845303c28 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll @@ -192,3 +192,36 @@ predicate isGT(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a > b } */ bindingset[a, b] predicate isGE(IntValue a, IntValue b) { hasValue(a) and hasValue(b) and a >= b } + +/** + * Converts the bit count in `bits` to a byte count and a bit count in the form + * "bytes:bits". If `bits` represents an integer number of bytes, the ":bits" section is omitted. + * If `bits` does not have a known value, the result is "?". + */ +bindingset[bits] +string bitsToBytesAndBits(IntValue bits) { + exists(int bytes, int leftoverBits | + hasValue(bits) and + bytes = bits / 8 and + leftoverBits = bits % 8 and + if leftoverBits = 0 then + result = bytes.toString() + else + result = bytes + ":" + leftoverBits + ) or + not hasValue(bits) and result = "?" +} + +/** + * Gets a printable string for a bit offset with possibly unknown value. + */ +bindingset[bitOffset] +string getBitOffsetString(IntValue bitOffset) { + if hasValue(bitOffset) then + if bitOffset >= 0 then + result = "+" + bitsToBytesAndBits(bitOffset) + else + result = "-" + bitsToBytesAndBits(neg(bitOffset)) + else + result = "+?" +} diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll index bc09f9c2243..cd12b9b627a 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerInterval.qll @@ -30,5 +30,5 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal bindingset[start, end] string getIntervalString(IntValue start, IntValue end) { // We represent an interval has half-open, so print it as "[start..end)". - result = "[" + intValueToString(start) + ".." + intValueToString(end) + ")" + result = "[" + bitsToBytesAndBits(start) + ".." + bitsToBytesAndBits(end) + ")" } From bd78f689752fc34801641f293358316dec285d64 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Fri, 22 Nov 2019 16:08:49 -0700 Subject: [PATCH 05/10] C++/C#: Fix formatting --- .../ir/implementation/aliased_ssa/IRVariable.qll | 3 ++- .../ir/implementation/aliased_ssa/Instruction.qll | 13 +++++++------ .../aliased_ssa/internal/SSAConstruction.qll | 7 ++++--- .../aliased_ssa/internal/SSASanity.ql | 2 +- .../code/cpp/ir/implementation/raw/IRVariable.qll | 3 ++- .../code/cpp/ir/implementation/raw/Instruction.qll | 13 +++++++------ .../ir/implementation/unaliased_ssa/IRVariable.qll | 3 ++- .../ir/implementation/unaliased_ssa/Instruction.qll | 13 +++++++------ .../unaliased_ssa/internal/SSAConstruction.qll | 7 ++++--- .../csharp/ir/implementation/raw/IRVariable.qll | 3 ++- .../csharp/ir/implementation/raw/Instruction.qll | 13 +++++++------ .../ir/implementation/unaliased_ssa/IRVariable.qll | 3 ++- .../ir/implementation/unaliased_ssa/Instruction.qll | 13 +++++++------ .../unaliased_ssa/internal/SSAConstruction.qll | 7 ++++--- 14 files changed, 58 insertions(+), 45 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll index 349ff7cd6bd..1092acc0003 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll @@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable { exists(Language::Variable var | this = TIRUserVariable(var, _, func) and Language::isVariableAutomatic(var) - ) or + ) + or this = TIRTempVariable(func, _, _, _) } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index bfd04a279e0..8819826d5c3 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -94,17 +94,18 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, string message, IRFunction func, - string funcText) { + query predicate duplicateOperand( + Instruction instr, string message, IRFunction func, string funcText + ) { exists(OperandTag tag, int operandCount | operandCount = strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) and + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and operandCount > 1 and not tag instanceof UnmodeledUseOperandTag and message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + - " in function '$@'." and + " in function '$@'." and func = instr.getEnclosingIRFunction() and funcText = Language::getIdentityString(func.getFunction()) ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index ebb111efc03..96b4c28db82 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -867,8 +867,9 @@ private module CachedForDebugging { } module SSASanity { - query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message, - OldIR::IRFunction func, string funcText) { + query predicate multipleOperandMemoryLocations( + OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText + ) { exists(int locationCount | locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and locationCount > 1 and @@ -877,4 +878,4 @@ module SSASanity { message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." ) } -} \ No newline at end of file +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql index 50368cdc6d9..3bd709a93dc 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql @@ -1,6 +1,6 @@ /** * @name Aliased SSA Sanity Check - * @description Performs sanity checks on the SSA construction. This query should have no results. + * @description Performs sanity checks on the SSA construction. This query should have no results. * @kind table * @id cpp/aliased-ssa-sanity-check */ diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll index 349ff7cd6bd..1092acc0003 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll @@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable { exists(Language::Variable var | this = TIRUserVariable(var, _, func) and Language::isVariableAutomatic(var) - ) or + ) + or this = TIRTempVariable(func, _, _, _) } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index bfd04a279e0..8819826d5c3 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -94,17 +94,18 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, string message, IRFunction func, - string funcText) { + query predicate duplicateOperand( + Instruction instr, string message, IRFunction func, string funcText + ) { exists(OperandTag tag, int operandCount | operandCount = strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) and + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and operandCount > 1 and not tag instanceof UnmodeledUseOperandTag and message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + - " in function '$@'." and + " in function '$@'." and func = instr.getEnclosingIRFunction() and funcText = Language::getIdentityString(func.getFunction()) ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll index 349ff7cd6bd..1092acc0003 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable { exists(Language::Variable var | this = TIRUserVariable(var, _, func) and Language::isVariableAutomatic(var) - ) or + ) + or this = TIRTempVariable(func, _, _, _) } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index bfd04a279e0..8819826d5c3 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -94,17 +94,18 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, string message, IRFunction func, - string funcText) { + query predicate duplicateOperand( + Instruction instr, string message, IRFunction func, string funcText + ) { exists(OperandTag tag, int operandCount | operandCount = strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) and + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and operandCount > 1 and not tag instanceof UnmodeledUseOperandTag and message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + - " in function '$@'." and + " in function '$@'." and func = instr.getEnclosingIRFunction() and funcText = Language::getIdentityString(func.getFunction()) ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index ebb111efc03..96b4c28db82 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -867,8 +867,9 @@ private module CachedForDebugging { } module SSASanity { - query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message, - OldIR::IRFunction func, string funcText) { + query predicate multipleOperandMemoryLocations( + OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText + ) { exists(int locationCount | locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and locationCount > 1 and @@ -877,4 +878,4 @@ module SSASanity { message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." ) } -} \ No newline at end of file +} diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll index 349ff7cd6bd..1092acc0003 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll @@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable { exists(Language::Variable var | this = TIRUserVariable(var, _, func) and Language::isVariableAutomatic(var) - ) or + ) + or this = TIRTempVariable(func, _, _, _) } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index bfd04a279e0..8819826d5c3 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -94,17 +94,18 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, string message, IRFunction func, - string funcText) { + query predicate duplicateOperand( + Instruction instr, string message, IRFunction func, string funcText + ) { exists(OperandTag tag, int operandCount | operandCount = strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) and + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and operandCount > 1 and not tag instanceof UnmodeledUseOperandTag and message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + - " in function '$@'." and + " in function '$@'." and func = instr.getEnclosingIRFunction() and funcText = Language::getIdentityString(func.getFunction()) ) diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll index 349ff7cd6bd..1092acc0003 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -112,7 +112,8 @@ class IRAutomaticVariable extends IRVariable { exists(Language::Variable var | this = TIRUserVariable(var, _, func) and Language::isVariableAutomatic(var) - ) or + ) + or this = TIRTempVariable(func, _, _, _) } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index bfd04a279e0..8819826d5c3 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -94,17 +94,18 @@ module InstructionSanity { /** * Holds if instruction `instr` has multiple operands with tag `tag`. */ - query predicate duplicateOperand(Instruction instr, string message, IRFunction func, - string funcText) { + query predicate duplicateOperand( + Instruction instr, string message, IRFunction func, string funcText + ) { exists(OperandTag tag, int operandCount | operandCount = strictcount(NonPhiOperand operand | - operand = instr.getAnOperand() and - operand.getOperandTag() = tag - ) and + operand = instr.getAnOperand() and + operand.getOperandTag() = tag + ) and operandCount > 1 and not tag instanceof UnmodeledUseOperandTag and message = "Instruction has " + operandCount + " operands with tag '" + tag.toString() + "'" + - " in function '$@'." and + " in function '$@'." and func = instr.getEnclosingIRFunction() and funcText = Language::getIdentityString(func.getFunction()) ) diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index ebb111efc03..96b4c28db82 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -867,8 +867,9 @@ private module CachedForDebugging { } module SSASanity { - query predicate multipleOperandMemoryLocations(OldIR::MemoryOperand operand, string message, - OldIR::IRFunction func, string funcText) { + query predicate multipleOperandMemoryLocations( + OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText + ) { exists(int locationCount | locationCount = strictcount(Alias::getOperandMemoryLocation(operand)) and locationCount > 1 and @@ -877,4 +878,4 @@ module SSASanity { message = "Operand has " + locationCount.toString() + " memory accesses in function '$@'." ) } -} \ No newline at end of file +} From eda47bfc5175a8dfb28cf7b5b44562366e5b024f Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Wed, 14 Aug 2019 13:59:41 -0700 Subject: [PATCH 06/10] C++: Add SSA sanity tests to IR tests --- cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected | 0 cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref | 1 + .../test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected | 0 cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref | 1 + 4 files changed, 2 insertions(+) create mode 100644 cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected create mode 100644 cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref create mode 100644 cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected create mode 100644 cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref new file mode 100644 index 00000000000..8e348011785 --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_ssa_sanity.qlref @@ -0,0 +1 @@ +semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref new file mode 100644 index 00000000000..18bf9212dbf --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_ssa_sanity.qlref @@ -0,0 +1 @@ +semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql \ No newline at end of file From 521fbb125e7466fb65d312f7c93ab4314ac2c6c7 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Mon, 25 Nov 2019 11:12:23 -0700 Subject: [PATCH 07/10] C++/C#: Fix formatting --- .../cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql | 2 +- .../ir/implementation/unaliased_ssa/internal/SSASanity.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql index b67f6f281be..1b5ee80b603 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql @@ -1,6 +1,6 @@ /** * @name Unaliased SSA Sanity Check - * @description Performs sanity checks on the SSA construction. This query should have no results. + * @description Performs sanity checks on the SSA construction. This query should have no results. * @kind table * @id cpp/unaliased-ssa-sanity-check */ diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql index 11d7add514b..43f303dd024 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSASanity.ql @@ -1,6 +1,6 @@ /** * @name Unaliased SSA Sanity Check - * @description Performs sanity checks on the SSA construction. This query should have no results. + * @description Performs sanity checks on the SSA construction. This query should have no results. * @kind table * @id csharp/unaliased-ssa-sanity-check */ From 44c1c5a7abb24641e18413d8ab98c067edd807e4 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Mon, 25 Nov 2019 11:13:02 -0700 Subject: [PATCH 08/10] C++: Update `points_to.ql` test to use new bit offset format --- .../aliased_ssa/internal/AliasAnalysis.qll | 26 +-- .../unaliased_ssa/internal/AliasAnalysis.qll | 26 +-- .../ir/escape/points_to.expected | 172 +++++++++--------- .../test/library-tests/ir/escape/points_to.ql | 9 +- 4 files changed, 101 insertions(+), 132 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll index 6ecfd1470bb..bc67acc1be2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll @@ -6,26 +6,6 @@ private import semmle.code.cpp.models.interfaces.Alias private class IntValue = Ints::IntValue; -/** - * Converts the bit count in `bits` to a byte count and a bit count in the form - * bytes:bits. - */ -bindingset[bits] -string bitsToBytesAndBits(int bits) { result = (bits / 8).toString() + ":" + (bits % 8).toString() } - -/** - * Gets a printable string for a bit offset with possibly unknown value. - */ -bindingset[bitOffset] -string getBitOffsetString(IntValue bitOffset) { - if Ints::hasValue(bitOffset) - then - if bitOffset >= 0 - then result = "+" + bitsToBytesAndBits(bitOffset) - else result = "-" + bitsToBytesAndBits(Ints::neg(bitOffset)) - else result = "+?" -} - /** * Gets the offset of field `field` in bits. */ @@ -137,7 +117,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { or // Adding an integer to or subtracting an integer from a pointer propagates // the address with an offset. - bitOffset = getPointerBitOffset(instr.(PointerOffsetInstruction)) + exists(PointerOffsetInstruction ptrOffset | + ptrOffset = instr and + operand = ptrOffset.getLeftOperand() and + bitOffset = getPointerBitOffset(ptrOffset) + ) or // Computing a field address from a pointer propagates the address plus the // offset of the field. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll index 6ecfd1470bb..bc67acc1be2 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll @@ -6,26 +6,6 @@ private import semmle.code.cpp.models.interfaces.Alias private class IntValue = Ints::IntValue; -/** - * Converts the bit count in `bits` to a byte count and a bit count in the form - * bytes:bits. - */ -bindingset[bits] -string bitsToBytesAndBits(int bits) { result = (bits / 8).toString() + ":" + (bits % 8).toString() } - -/** - * Gets a printable string for a bit offset with possibly unknown value. - */ -bindingset[bitOffset] -string getBitOffsetString(IntValue bitOffset) { - if Ints::hasValue(bitOffset) - then - if bitOffset >= 0 - then result = "+" + bitsToBytesAndBits(bitOffset) - else result = "-" + bitsToBytesAndBits(Ints::neg(bitOffset)) - else result = "+?" -} - /** * Gets the offset of field `field` in bits. */ @@ -137,7 +117,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { or // Adding an integer to or subtracting an integer from a pointer propagates // the address with an offset. - bitOffset = getPointerBitOffset(instr.(PointerOffsetInstruction)) + exists(PointerOffsetInstruction ptrOffset | + ptrOffset = instr and + operand = ptrOffset.getLeftOperand() and + bitOffset = getPointerBitOffset(ptrOffset) + ) or // Computing a field address from a pointer propagates the address plus the // offset of the field. diff --git a/cpp/ql/test/library-tests/ir/escape/points_to.expected b/cpp/ql/test/library-tests/ir/escape/points_to.expected index ac518b5dd79..6447bd81a5f 100644 --- a/cpp/ql/test/library-tests/ir/escape/points_to.expected +++ b/cpp/ql/test/library-tests/ir/escape/points_to.expected @@ -1,86 +1,86 @@ -| escape.cpp:111:18:111:21 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:115:19:115:28 | PointerAdd[4] | no_+0:0 | no_+0:0 | -| escape.cpp:115:20:115:23 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:116:19:116:28 | PointerSub[4] | no_+0:0 | no_+0:0 | -| escape.cpp:116:20:116:23 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:117:19:117:26 | PointerAdd[4] | no_+0:0 | no_+0:0 | -| escape.cpp:117:23:117:26 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:118:9:118:12 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:120:12:120:15 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:123:14:123:17 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:124:15:124:18 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:127:9:127:12 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:129:12:129:15 | CopyValue | no_+0:0 | no_+0:0 | -| escape.cpp:134:5:134:18 | Convert | no_Array+0:0 | no_Array+0:0 | -| escape.cpp:134:11:134:18 | Convert | no_Array+0:0 | no_Array+0:0 | -| escape.cpp:135:5:135:12 | Convert | no_Array+0:0 | no_Array+0:0 | -| escape.cpp:135:5:135:15 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 | -| escape.cpp:136:5:136:15 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 | -| escape.cpp:136:7:136:14 | Convert | no_Array+0:0 | no_Array+0:0 | -| escape.cpp:137:17:137:24 | Convert | no_Array+0:0 | no_Array+0:0 | -| escape.cpp:137:17:137:27 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 | -| escape.cpp:138:17:138:27 | PointerAdd[4] | no_Array+20:0 | no_Array+20:0 | -| escape.cpp:138:19:138:26 | Convert | no_Array+0:0 | no_Array+0:0 | -| escape.cpp:140:21:140:32 | FieldAddress[x] | no_Point+0:0 | no_Point+0:0 | -| escape.cpp:140:21:140:32 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | -| escape.cpp:140:21:140:32 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:141:27:141:27 | FieldAddress[x] | no_Point+0:0 | no_Point+0:0 | -| escape.cpp:142:14:142:14 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | -| escape.cpp:143:19:143:27 | CopyValue | no_Point+0:0 | no_Point+0:0 | -| escape.cpp:143:31:143:31 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | -| escape.cpp:144:6:144:14 | CopyValue | no_Point+0:0 | no_Point+0:0 | -| escape.cpp:144:18:144:18 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | -| escape.cpp:145:20:145:30 | CopyValue | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:145:30:145:30 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:146:5:146:18 | CopyValue | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:146:7:146:17 | CopyValue | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:146:17:146:17 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:149:16:149:16 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:150:29:150:29 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:151:5:151:14 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 | -| escape.cpp:151:16:151:17 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 | -| escape.cpp:152:19:152:28 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 | -| escape.cpp:152:30:152:31 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 | -| escape.cpp:155:17:155:30 | CopyValue | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 | -| escape.cpp:155:17:155:30 | Store | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 | -| escape.cpp:158:17:158:28 | CopyValue | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 | -| escape.cpp:158:17:158:28 | Store | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 | -| escape.cpp:161:19:161:42 | Convert | no_ssa_refToArrayElement+0:0 | no_ssa_refToArrayElement+0:0 | -| escape.cpp:161:19:161:45 | CopyValue | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 | -| escape.cpp:161:19:161:45 | PointerAdd[4] | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 | -| escape.cpp:161:19:161:45 | Store | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 | -| escape.cpp:164:24:164:40 | CopyValue | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 | -| escape.cpp:164:24:164:40 | Store | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 | -| escape.cpp:167:19:167:28 | CopyValue | passByPtr+0:0 | passByPtr+0:0 | -| escape.cpp:170:21:170:29 | CopyValue | passByRef+0:0 | passByRef+0:0 | -| escape.cpp:173:22:173:38 | CopyValue | no_ssa_passByPtr+0:0 | no_ssa_passByPtr+0:0 | -| escape.cpp:176:24:176:39 | CopyValue | no_ssa_passByRef+0:0 | no_ssa_passByRef+0:0 | -| escape.cpp:179:22:179:42 | CopyValue | no_ssa_passByPtr_ret+0:0 | no_ssa_passByPtr_ret+0:0 | -| escape.cpp:182:24:182:43 | CopyValue | no_ssa_passByRef_ret+0:0 | no_ssa_passByRef_ret+0:0 | -| escape.cpp:185:30:185:40 | CopyValue | passByPtr2+0:0 | passByPtr2+0:0 | -| escape.cpp:188:32:188:41 | CopyValue | passByRef2+0:0 | passByRef2+0:0 | -| escape.cpp:191:30:191:42 | Call | none | passByPtr3+0:0 | -| escape.cpp:191:44:191:54 | CopyValue | passByPtr3+0:0 | passByPtr3+0:0 | -| escape.cpp:194:32:194:46 | Call | none | passByRef3+0:0 | -| escape.cpp:194:32:194:59 | CopyValue | none | passByRef3+0:0 | -| escape.cpp:194:48:194:57 | CopyValue | passByRef3+0:0 | passByRef3+0:0 | -| escape.cpp:199:17:199:34 | CopyValue | no_ssa_passByPtr4+0:0 | no_ssa_passByPtr4+0:0 | -| escape.cpp:199:37:199:54 | CopyValue | no_ssa_passByPtr5+0:0 | no_ssa_passByPtr5+0:0 | -| escape.cpp:202:5:202:19 | Call | none | passByRef6+0:0 | -| escape.cpp:202:5:202:32 | CopyValue | none | passByRef6+0:0 | -| escape.cpp:202:21:202:30 | CopyValue | passByRef6+0:0 | passByRef6+0:0 | -| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0:0 | -| escape.cpp:205:5:205:39 | CopyValue | none | no_ssa_passByRef7+0:0 | -| escape.cpp:205:21:205:37 | CopyValue | no_ssa_passByRef7+0:0 | no_ssa_passByRef7+0:0 | -| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0:0 | -| escape.cpp:217:14:217:16 | CopyValue | c2+0:0 | c2+0:0 | -| escape.cpp:221:8:221:19 | Call | none | c3+0:0 | -| escape.cpp:225:17:225:28 | Call | none | c4+0:0 | -| escape.cpp:247:2:247:27 | Store | condEscape1+0:0 | condEscape1+0:0 | -| escape.cpp:247:16:247:27 | CopyValue | condEscape1+0:0 | condEscape1+0:0 | -| escape.cpp:249:9:249:34 | Store | condEscape2+0:0 | condEscape2+0:0 | -| escape.cpp:249:23:249:34 | CopyValue | condEscape2+0:0 | condEscape2+0:0 | +| escape.cpp:111:18:111:21 | CopyValue | no_+0 | no_+0 | +| escape.cpp:115:19:115:28 | PointerAdd[4] | no_+0 | no_+0 | +| escape.cpp:115:20:115:23 | CopyValue | no_+0 | no_+0 | +| escape.cpp:116:19:116:28 | PointerSub[4] | no_+0 | no_+0 | +| escape.cpp:116:20:116:23 | CopyValue | no_+0 | no_+0 | +| escape.cpp:117:19:117:26 | PointerAdd[4] | no_+0 | no_+0 | +| escape.cpp:117:23:117:26 | CopyValue | no_+0 | no_+0 | +| escape.cpp:118:9:118:12 | CopyValue | no_+0 | no_+0 | +| escape.cpp:120:12:120:15 | CopyValue | no_+0 | no_+0 | +| escape.cpp:123:14:123:17 | CopyValue | no_+0 | no_+0 | +| escape.cpp:124:15:124:18 | CopyValue | no_+0 | no_+0 | +| escape.cpp:127:9:127:12 | CopyValue | no_+0 | no_+0 | +| escape.cpp:129:12:129:15 | CopyValue | no_+0 | no_+0 | +| escape.cpp:134:5:134:18 | Convert | no_Array+0 | no_Array+0 | +| escape.cpp:134:11:134:18 | Convert | no_Array+0 | no_Array+0 | +| escape.cpp:135:5:135:12 | Convert | no_Array+0 | no_Array+0 | +| escape.cpp:135:5:135:15 | PointerAdd[4] | no_Array+20 | no_Array+20 | +| escape.cpp:136:5:136:15 | PointerAdd[4] | no_Array+20 | no_Array+20 | +| escape.cpp:136:7:136:14 | Convert | no_Array+0 | no_Array+0 | +| escape.cpp:137:17:137:24 | Convert | no_Array+0 | no_Array+0 | +| escape.cpp:137:17:137:27 | PointerAdd[4] | no_Array+20 | no_Array+20 | +| escape.cpp:138:17:138:27 | PointerAdd[4] | no_Array+20 | no_Array+20 | +| escape.cpp:138:19:138:26 | Convert | no_Array+0 | no_Array+0 | +| escape.cpp:140:21:140:32 | FieldAddress[x] | no_Point+0 | no_Point+0 | +| escape.cpp:140:21:140:32 | FieldAddress[y] | no_Point+4 | no_Point+4 | +| escape.cpp:140:21:140:32 | FieldAddress[z] | no_Point+8 | no_Point+8 | +| escape.cpp:141:27:141:27 | FieldAddress[x] | no_Point+0 | no_Point+0 | +| escape.cpp:142:14:142:14 | FieldAddress[y] | no_Point+4 | no_Point+4 | +| escape.cpp:143:19:143:27 | CopyValue | no_Point+0 | no_Point+0 | +| escape.cpp:143:31:143:31 | FieldAddress[y] | no_Point+4 | no_Point+4 | +| escape.cpp:144:6:144:14 | CopyValue | no_Point+0 | no_Point+0 | +| escape.cpp:144:18:144:18 | FieldAddress[y] | no_Point+4 | no_Point+4 | +| escape.cpp:145:20:145:30 | CopyValue | no_Point+8 | no_Point+8 | +| escape.cpp:145:30:145:30 | FieldAddress[z] | no_Point+8 | no_Point+8 | +| escape.cpp:146:5:146:18 | CopyValue | no_Point+8 | no_Point+8 | +| escape.cpp:146:7:146:17 | CopyValue | no_Point+8 | no_Point+8 | +| escape.cpp:146:17:146:17 | FieldAddress[z] | no_Point+8 | no_Point+8 | +| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0 | no_Derived+0 | +| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0 | no_Derived+0 | +| escape.cpp:149:16:149:16 | FieldAddress[b] | no_Derived+0 | no_Derived+0 | +| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0 | no_Derived+0 | +| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0 | no_Derived+0 | +| escape.cpp:150:29:150:29 | FieldAddress[b] | no_Derived+0 | no_Derived+0 | +| escape.cpp:151:5:151:14 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12 | no_Derived+12 | +| escape.cpp:151:16:151:17 | FieldAddress[i2] | no_Derived+16 | no_Derived+16 | +| escape.cpp:152:19:152:28 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12 | no_Derived+12 | +| escape.cpp:152:30:152:31 | FieldAddress[i2] | no_Derived+16 | no_Derived+16 | +| escape.cpp:155:17:155:30 | CopyValue | no_ssa_addrOf+0 | no_ssa_addrOf+0 | +| escape.cpp:155:17:155:30 | Store | no_ssa_addrOf+0 | no_ssa_addrOf+0 | +| escape.cpp:158:17:158:28 | CopyValue | no_ssa_refTo+0 | no_ssa_refTo+0 | +| escape.cpp:158:17:158:28 | Store | no_ssa_refTo+0 | no_ssa_refTo+0 | +| escape.cpp:161:19:161:42 | Convert | no_ssa_refToArrayElement+0 | no_ssa_refToArrayElement+0 | +| escape.cpp:161:19:161:45 | CopyValue | no_ssa_refToArrayElement+20 | no_ssa_refToArrayElement+20 | +| escape.cpp:161:19:161:45 | PointerAdd[4] | no_ssa_refToArrayElement+20 | no_ssa_refToArrayElement+20 | +| escape.cpp:161:19:161:45 | Store | no_ssa_refToArrayElement+20 | no_ssa_refToArrayElement+20 | +| escape.cpp:164:24:164:40 | CopyValue | no_ssa_refToArray+0 | no_ssa_refToArray+0 | +| escape.cpp:164:24:164:40 | Store | no_ssa_refToArray+0 | no_ssa_refToArray+0 | +| escape.cpp:167:19:167:28 | CopyValue | passByPtr+0 | passByPtr+0 | +| escape.cpp:170:21:170:29 | CopyValue | passByRef+0 | passByRef+0 | +| escape.cpp:173:22:173:38 | CopyValue | no_ssa_passByPtr+0 | no_ssa_passByPtr+0 | +| escape.cpp:176:24:176:39 | CopyValue | no_ssa_passByRef+0 | no_ssa_passByRef+0 | +| escape.cpp:179:22:179:42 | CopyValue | no_ssa_passByPtr_ret+0 | no_ssa_passByPtr_ret+0 | +| escape.cpp:182:24:182:43 | CopyValue | no_ssa_passByRef_ret+0 | no_ssa_passByRef_ret+0 | +| escape.cpp:185:30:185:40 | CopyValue | passByPtr2+0 | passByPtr2+0 | +| escape.cpp:188:32:188:41 | CopyValue | passByRef2+0 | passByRef2+0 | +| escape.cpp:191:30:191:42 | Call | none | passByPtr3+0 | +| escape.cpp:191:44:191:54 | CopyValue | passByPtr3+0 | passByPtr3+0 | +| escape.cpp:194:32:194:46 | Call | none | passByRef3+0 | +| escape.cpp:194:32:194:59 | CopyValue | none | passByRef3+0 | +| escape.cpp:194:48:194:57 | CopyValue | passByRef3+0 | passByRef3+0 | +| escape.cpp:199:17:199:34 | CopyValue | no_ssa_passByPtr4+0 | no_ssa_passByPtr4+0 | +| escape.cpp:199:37:199:54 | CopyValue | no_ssa_passByPtr5+0 | no_ssa_passByPtr5+0 | +| escape.cpp:202:5:202:19 | Call | none | passByRef6+0 | +| escape.cpp:202:5:202:32 | CopyValue | none | passByRef6+0 | +| escape.cpp:202:21:202:30 | CopyValue | passByRef6+0 | passByRef6+0 | +| escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0 | +| escape.cpp:205:5:205:39 | CopyValue | none | no_ssa_passByRef7+0 | +| escape.cpp:205:21:205:37 | CopyValue | no_ssa_passByRef7+0 | no_ssa_passByRef7+0 | +| escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0 | +| escape.cpp:217:14:217:16 | CopyValue | c2+0 | c2+0 | +| escape.cpp:221:8:221:19 | Call | none | c3+0 | +| escape.cpp:225:17:225:28 | Call | none | c4+0 | +| escape.cpp:247:2:247:27 | Store | condEscape1+0 | condEscape1+0 | +| escape.cpp:247:16:247:27 | CopyValue | condEscape1+0 | condEscape1+0 | +| escape.cpp:249:9:249:34 | Store | condEscape2+0 | condEscape2+0 | +| escape.cpp:249:23:249:34 | CopyValue | condEscape2+0 | condEscape2+0 | diff --git a/cpp/ql/test/library-tests/ir/escape/points_to.ql b/cpp/ql/test/library-tests/ir/escape/points_to.ql index 04dbf0e0060..7c265974b10 100644 --- a/cpp/ql/test/library-tests/ir/escape/points_to.ql +++ b/cpp/ql/test/library-tests/ir/escape/points_to.ql @@ -4,6 +4,7 @@ import semmle.code.cpp.ir.implementation.raw.IR as Raw import semmle.code.cpp.ir.implementation.aliased_ssa.internal.AliasAnalysis as UnAA import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as Un import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction +import semmle.code.cpp.ir.internal.IntegerConstant from Raw::Instruction rawInstr, Un::Instruction unInstr, string rawPointsTo, string unPointsTo where @@ -12,21 +13,21 @@ where ( exists(Variable var, int rawBitOffset, int unBitOffset | RawAA::resultPointsTo(rawInstr, Raw::getIRUserVariable(_, var), rawBitOffset) and - rawPointsTo = var.toString() + RawAA::getBitOffsetString(rawBitOffset) and + rawPointsTo = var.toString() + getBitOffsetString(rawBitOffset) and UnAA::resultPointsTo(unInstr, Un::getIRUserVariable(_, var), unBitOffset) and - unPointsTo = var.toString() + UnAA::getBitOffsetString(unBitOffset) + unPointsTo = var.toString() + getBitOffsetString(unBitOffset) ) or exists(Variable var, int unBitOffset | not RawAA::resultPointsTo(rawInstr, Raw::getIRUserVariable(_, var), _) and rawPointsTo = "none" and UnAA::resultPointsTo(unInstr, Un::getIRUserVariable(_, var), unBitOffset) and - unPointsTo = var.toString() + UnAA::getBitOffsetString(unBitOffset) + unPointsTo = var.toString() + getBitOffsetString(unBitOffset) ) or exists(Variable var, int rawBitOffset | RawAA::resultPointsTo(rawInstr, Raw::getIRUserVariable(_, var), rawBitOffset) and - rawPointsTo = var.toString() + RawAA::getBitOffsetString(rawBitOffset) and + rawPointsTo = var.toString() + getBitOffsetString(rawBitOffset) and not UnAA::resultPointsTo(unInstr, Un::getIRUserVariable(_, var), _) and unPointsTo = "none" ) From 7d48220a76c393ecc27b67c0cf1639b252918935 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Mon, 25 Nov 2019 11:26:45 -0700 Subject: [PATCH 09/10] C++/C#: Make QLDoc conform to style guide --- .../implementation/aliased_ssa/IRVariable.qll | 40 +++++++++---------- .../cpp/ir/implementation/raw/IRVariable.qll | 40 +++++++++---------- .../unaliased_ssa/IRVariable.qll | 40 +++++++++---------- .../ir/implementation/raw/IRVariable.qll | 40 +++++++++---------- .../unaliased_ssa/IRVariable.qll | 40 +++++++++---------- 5 files changed, 95 insertions(+), 105 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll index 1092acc0003..f9efad42fb0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll @@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var } /** - * Represents a variable referenced by the IR for a function. The variable may - * be a user-declared variable (`IRUserVariable`) or a temporary variable - * generated by the AST-to-IR translation (`IRTempVariable`). + * A variable referenced by the IR for a function. The variable may be a user-declared variable + * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation + * (`IRTempVariable`). */ class IRVariable extends TIRVariable { Language::Function func; @@ -78,7 +78,7 @@ class IRVariable extends TIRVariable { } /** - * Represents a user-declared variable referenced by the IR for a function. + * A user-declared variable referenced by the IR for a function. */ class IRUserVariable extends IRVariable, TIRUserVariable { Language::Variable var; @@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable { } /** - * Represents a variable (user-declared or temporary) that is allocated on the - * stack. This includes all parameters, non-static local variables, and - * temporary variables. + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. */ class IRAutomaticVariable extends IRVariable { IRAutomaticVariable() { @@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable { } /** - * Represents a user-declared variable that is allocated on the stack. This - * includes all parameters and non-static local variables. + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; @@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { } /** - * Represents a user-declared variable that is not allocated on the stack. This - * includes all global variables, namespace-scope variables, static fields, and - * static local variables. + * A user-declared variable that is not allocated on the stack. This includes all global variables, + * namespace-scope variables, static fields, and static local variables. */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable { } /** - * Represents a variable that is not user-declared. This includes temporary - * variables generated as part of IR construction, as well as string literals. + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. */ class IRGeneratedVariable extends IRVariable { Language::AST ast; @@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { } /** - * Represents a temporary variable introduced by IR construction. The most common examples are the - * variable generated to hold the return value of afunction, or the variable generated to hold the - * result of a condition operator (`a ? b : c`). + * A temporary variable introduced by IR construction. The most common examples are the variable + * generated to hold the return value of afunction, or the variable generated to hold the result of + * a condition operator (`a ? b : c`). */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa } /** - * The temporary variable generated to hold the return value of a function. + * A temporary variable generated to hold the return value of a function. */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } @@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable { } /** - * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } @@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable { } /** - * The variable generated to represent the contents of a string literal. This variable acts much - * like a read-only global variable. + * A variable generated to represent the contents of a string literal. This variable acts much like + * a read-only global variable. */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll index 1092acc0003..f9efad42fb0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll @@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var } /** - * Represents a variable referenced by the IR for a function. The variable may - * be a user-declared variable (`IRUserVariable`) or a temporary variable - * generated by the AST-to-IR translation (`IRTempVariable`). + * A variable referenced by the IR for a function. The variable may be a user-declared variable + * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation + * (`IRTempVariable`). */ class IRVariable extends TIRVariable { Language::Function func; @@ -78,7 +78,7 @@ class IRVariable extends TIRVariable { } /** - * Represents a user-declared variable referenced by the IR for a function. + * A user-declared variable referenced by the IR for a function. */ class IRUserVariable extends IRVariable, TIRUserVariable { Language::Variable var; @@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable { } /** - * Represents a variable (user-declared or temporary) that is allocated on the - * stack. This includes all parameters, non-static local variables, and - * temporary variables. + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. */ class IRAutomaticVariable extends IRVariable { IRAutomaticVariable() { @@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable { } /** - * Represents a user-declared variable that is allocated on the stack. This - * includes all parameters and non-static local variables. + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; @@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { } /** - * Represents a user-declared variable that is not allocated on the stack. This - * includes all global variables, namespace-scope variables, static fields, and - * static local variables. + * A user-declared variable that is not allocated on the stack. This includes all global variables, + * namespace-scope variables, static fields, and static local variables. */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable { } /** - * Represents a variable that is not user-declared. This includes temporary - * variables generated as part of IR construction, as well as string literals. + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. */ class IRGeneratedVariable extends IRVariable { Language::AST ast; @@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { } /** - * Represents a temporary variable introduced by IR construction. The most common examples are the - * variable generated to hold the return value of afunction, or the variable generated to hold the - * result of a condition operator (`a ? b : c`). + * A temporary variable introduced by IR construction. The most common examples are the variable + * generated to hold the return value of afunction, or the variable generated to hold the result of + * a condition operator (`a ? b : c`). */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa } /** - * The temporary variable generated to hold the return value of a function. + * A temporary variable generated to hold the return value of a function. */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } @@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable { } /** - * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } @@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable { } /** - * The variable generated to represent the contents of a string literal. This variable acts much - * like a read-only global variable. + * A variable generated to represent the contents of a string literal. This variable acts much like + * a read-only global variable. */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll index 1092acc0003..f9efad42fb0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var } /** - * Represents a variable referenced by the IR for a function. The variable may - * be a user-declared variable (`IRUserVariable`) or a temporary variable - * generated by the AST-to-IR translation (`IRTempVariable`). + * A variable referenced by the IR for a function. The variable may be a user-declared variable + * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation + * (`IRTempVariable`). */ class IRVariable extends TIRVariable { Language::Function func; @@ -78,7 +78,7 @@ class IRVariable extends TIRVariable { } /** - * Represents a user-declared variable referenced by the IR for a function. + * A user-declared variable referenced by the IR for a function. */ class IRUserVariable extends IRVariable, TIRUserVariable { Language::Variable var; @@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable { } /** - * Represents a variable (user-declared or temporary) that is allocated on the - * stack. This includes all parameters, non-static local variables, and - * temporary variables. + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. */ class IRAutomaticVariable extends IRVariable { IRAutomaticVariable() { @@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable { } /** - * Represents a user-declared variable that is allocated on the stack. This - * includes all parameters and non-static local variables. + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; @@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { } /** - * Represents a user-declared variable that is not allocated on the stack. This - * includes all global variables, namespace-scope variables, static fields, and - * static local variables. + * A user-declared variable that is not allocated on the stack. This includes all global variables, + * namespace-scope variables, static fields, and static local variables. */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable { } /** - * Represents a variable that is not user-declared. This includes temporary - * variables generated as part of IR construction, as well as string literals. + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. */ class IRGeneratedVariable extends IRVariable { Language::AST ast; @@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { } /** - * Represents a temporary variable introduced by IR construction. The most common examples are the - * variable generated to hold the return value of afunction, or the variable generated to hold the - * result of a condition operator (`a ? b : c`). + * A temporary variable introduced by IR construction. The most common examples are the variable + * generated to hold the return value of afunction, or the variable generated to hold the result of + * a condition operator (`a ? b : c`). */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa } /** - * The temporary variable generated to hold the return value of a function. + * A temporary variable generated to hold the return value of a function. */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } @@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable { } /** - * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } @@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable { } /** - * The variable generated to represent the contents of a string literal. This variable acts much - * like a read-only global variable. + * A variable generated to represent the contents of a string literal. This variable acts much like + * a read-only global variable. */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll index 1092acc0003..f9efad42fb0 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll @@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var } /** - * Represents a variable referenced by the IR for a function. The variable may - * be a user-declared variable (`IRUserVariable`) or a temporary variable - * generated by the AST-to-IR translation (`IRTempVariable`). + * A variable referenced by the IR for a function. The variable may be a user-declared variable + * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation + * (`IRTempVariable`). */ class IRVariable extends TIRVariable { Language::Function func; @@ -78,7 +78,7 @@ class IRVariable extends TIRVariable { } /** - * Represents a user-declared variable referenced by the IR for a function. + * A user-declared variable referenced by the IR for a function. */ class IRUserVariable extends IRVariable, TIRUserVariable { Language::Variable var; @@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable { } /** - * Represents a variable (user-declared or temporary) that is allocated on the - * stack. This includes all parameters, non-static local variables, and - * temporary variables. + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. */ class IRAutomaticVariable extends IRVariable { IRAutomaticVariable() { @@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable { } /** - * Represents a user-declared variable that is allocated on the stack. This - * includes all parameters and non-static local variables. + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; @@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { } /** - * Represents a user-declared variable that is not allocated on the stack. This - * includes all global variables, namespace-scope variables, static fields, and - * static local variables. + * A user-declared variable that is not allocated on the stack. This includes all global variables, + * namespace-scope variables, static fields, and static local variables. */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable { } /** - * Represents a variable that is not user-declared. This includes temporary - * variables generated as part of IR construction, as well as string literals. + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. */ class IRGeneratedVariable extends IRVariable { Language::AST ast; @@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { } /** - * Represents a temporary variable introduced by IR construction. The most common examples are the - * variable generated to hold the return value of afunction, or the variable generated to hold the - * result of a condition operator (`a ? b : c`). + * A temporary variable introduced by IR construction. The most common examples are the variable + * generated to hold the return value of afunction, or the variable generated to hold the result of + * a condition operator (`a ? b : c`). */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa } /** - * The temporary variable generated to hold the return value of a function. + * A temporary variable generated to hold the return value of a function. */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } @@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable { } /** - * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } @@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable { } /** - * The variable generated to represent the contents of a string literal. This variable acts much - * like a read-only global variable. + * A variable generated to represent the contents of a string literal. This variable acts much like + * a read-only global variable. */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll index 1092acc0003..f9efad42fb0 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -13,9 +13,9 @@ IRUserVariable getIRUserVariable(Language::Function func, Language::Variable var } /** - * Represents a variable referenced by the IR for a function. The variable may - * be a user-declared variable (`IRUserVariable`) or a temporary variable - * generated by the AST-to-IR translation (`IRTempVariable`). + * A variable referenced by the IR for a function. The variable may be a user-declared variable + * (`IRUserVariable`) or a temporary variable generated by the AST-to-IR translation + * (`IRTempVariable`). */ class IRVariable extends TIRVariable { Language::Function func; @@ -78,7 +78,7 @@ class IRVariable extends TIRVariable { } /** - * Represents a user-declared variable referenced by the IR for a function. + * A user-declared variable referenced by the IR for a function. */ class IRUserVariable extends IRVariable, TIRUserVariable { Language::Variable var; @@ -103,9 +103,8 @@ class IRUserVariable extends IRVariable, TIRUserVariable { } /** - * Represents a variable (user-declared or temporary) that is allocated on the - * stack. This includes all parameters, non-static local variables, and - * temporary variables. + * A variable (user-declared or temporary) that is allocated on the stack. This includes all + * parameters, non-static local variables, and temporary variables. */ class IRAutomaticVariable extends IRVariable { IRAutomaticVariable() { @@ -119,8 +118,8 @@ class IRAutomaticVariable extends IRVariable { } /** - * Represents a user-declared variable that is allocated on the stack. This - * includes all parameters and non-static local variables. + * A user-declared variable that is allocated on the stack. This includes all parameters and + * non-static local variables. */ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { override Language::AutomaticVariable var; @@ -129,9 +128,8 @@ class IRAutomaticUserVariable extends IRUserVariable, IRAutomaticVariable { } /** - * Represents a user-declared variable that is not allocated on the stack. This - * includes all global variables, namespace-scope variables, static fields, and - * static local variables. + * A user-declared variable that is not allocated on the stack. This includes all global variables, + * namespace-scope variables, static fields, and static local variables. */ class IRStaticUserVariable extends IRUserVariable { override Language::StaticVariable var; @@ -142,8 +140,8 @@ class IRStaticUserVariable extends IRUserVariable { } /** - * Represents a variable that is not user-declared. This includes temporary - * variables generated as part of IR construction, as well as string literals. + * A variable that is not user-declared. This includes temporary variables generated as part of IR + * construction, as well as string literals. */ class IRGeneratedVariable extends IRVariable { Language::AST ast; @@ -176,9 +174,9 @@ IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { } /** - * Represents a temporary variable introduced by IR construction. The most common examples are the - * variable generated to hold the return value of afunction, or the variable generated to hold the - * result of a condition operator (`a ? b : c`). + * A temporary variable introduced by IR construction. The most common examples are the variable + * generated to hold the return value of afunction, or the variable generated to hold the result of + * a condition operator (`a ? b : c`). */ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; @@ -195,7 +193,7 @@ class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVa } /** - * The temporary variable generated to hold the return value of a function. + * A temporary variable generated to hold the return value of a function. */ class IRReturnVariable extends IRTempVariable { IRReturnVariable() { tag = ReturnValueTempVar() } @@ -204,7 +202,7 @@ class IRReturnVariable extends IRTempVariable { } /** - * The temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. + * A temporary variable generated to hold the exception thrown by a `ThrowValue` instruction. */ class IRThrowVariable extends IRTempVariable { IRThrowVariable() { tag = ThrowTempVar() } @@ -213,8 +211,8 @@ class IRThrowVariable extends IRTempVariable { } /** - * The variable generated to represent the contents of a string literal. This variable acts much - * like a read-only global variable. + * A variable generated to represent the contents of a string literal. This variable acts much like + * a read-only global variable. */ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { Language::StringLiteral literal; From 4e1ee7a998b52b2654f2e9d3901155050b2fd577 Mon Sep 17 00:00:00 2001 From: Dave Bartolomeo Date: Tue, 26 Nov 2019 10:48:24 -0700 Subject: [PATCH 10/10] C++/C#: Fix formatting --- .../code/cpp/ir/internal/IntegerConstant.qll | 21 ++++++++----------- .../csharp/ir/internal/IntegerConstant.qll | 21 ++++++++----------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll index 0d845303c28..6034ebc5674 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/IntegerConstant.qll @@ -204,11 +204,9 @@ string bitsToBytesAndBits(IntValue bits) { hasValue(bits) and bytes = bits / 8 and leftoverBits = bits % 8 and - if leftoverBits = 0 then - result = bytes.toString() - else - result = bytes + ":" + leftoverBits - ) or + if leftoverBits = 0 then result = bytes.toString() else result = bytes + ":" + leftoverBits + ) + or not hasValue(bits) and result = "?" } @@ -217,11 +215,10 @@ string bitsToBytesAndBits(IntValue bits) { */ bindingset[bitOffset] string getBitOffsetString(IntValue bitOffset) { - if hasValue(bitOffset) then - if bitOffset >= 0 then - result = "+" + bitsToBytesAndBits(bitOffset) - else - result = "-" + bitsToBytesAndBits(neg(bitOffset)) - else - result = "+?" + if hasValue(bitOffset) + then + if bitOffset >= 0 + then result = "+" + bitsToBytesAndBits(bitOffset) + else result = "-" + bitsToBytesAndBits(neg(bitOffset)) + else result = "+?" } diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll index 0d845303c28..6034ebc5674 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/internal/IntegerConstant.qll @@ -204,11 +204,9 @@ string bitsToBytesAndBits(IntValue bits) { hasValue(bits) and bytes = bits / 8 and leftoverBits = bits % 8 and - if leftoverBits = 0 then - result = bytes.toString() - else - result = bytes + ":" + leftoverBits - ) or + if leftoverBits = 0 then result = bytes.toString() else result = bytes + ":" + leftoverBits + ) + or not hasValue(bits) and result = "?" } @@ -217,11 +215,10 @@ string bitsToBytesAndBits(IntValue bits) { */ bindingset[bitOffset] string getBitOffsetString(IntValue bitOffset) { - if hasValue(bitOffset) then - if bitOffset >= 0 then - result = "+" + bitsToBytesAndBits(bitOffset) - else - result = "-" + bitsToBytesAndBits(neg(bitOffset)) - else - result = "+?" + if hasValue(bitOffset) + then + if bitOffset >= 0 + then result = "+" + bitsToBytesAndBits(bitOffset) + else result = "-" + bitsToBytesAndBits(neg(bitOffset)) + else result = "+?" }