mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge branch 'master' into fp2762
This commit is contained in:
@@ -6,9 +6,13 @@ private import semmle.code.cpp.dataflow.EscapesTree
|
||||
/**
|
||||
* A C/C++ access expression. This refers to a function, variable, or enum constant.
|
||||
*/
|
||||
abstract class Access extends Expr, NameQualifiableElement {
|
||||
class Access extends Expr, NameQualifiableElement, @access {
|
||||
// As `@access` is a union type containing `@routineexpr` (which describes function accesses
|
||||
// that are called), we need to exclude function calls.
|
||||
Access() { this instanceof @routineexpr implies not iscall(underlyingElement(this), _) }
|
||||
|
||||
/** Gets the accessed function, variable, or enum constant. */
|
||||
abstract Declaration getTarget();
|
||||
Declaration getTarget() { none() } // overridden in subclasses
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ private import semmle.code.cpp.internal.ResolveClass
|
||||
* Instances of this class are not present in the main AST which is navigated by parent/child links. Instead,
|
||||
* instances of this class are attached to nodes in the main AST via special conversion links.
|
||||
*/
|
||||
abstract class Conversion extends Expr {
|
||||
class Conversion extends Expr, @conversion {
|
||||
/** Gets the expression being converted. */
|
||||
Expr getExpr() { result.getConversion() = this }
|
||||
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -27,6 +23,57 @@ private newtype TOperand =
|
||||
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all register operands. This is a placeholder for the IPA union type that we will
|
||||
* eventually use for this purpose.
|
||||
*/
|
||||
private class RegisterOperandBase extends TRegisterOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the register operand with the specified parameters.
|
||||
*/
|
||||
private RegisterOperandBase registerOperand(
|
||||
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
|
||||
) {
|
||||
result = TRegisterOperand(useInstr, tag, defInstr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
|
||||
* will eventually use for this purpose.
|
||||
*/
|
||||
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the non-Phi memory operand with the specified parameters.
|
||||
*/
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
|
||||
* eventually use for this purpose.
|
||||
*/
|
||||
private class PhiOperandBase extends TPhiOperand {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Phi operand with the specified parameters.
|
||||
*/
|
||||
private PhiOperandBase phiOperand(
|
||||
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
) {
|
||||
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
|
||||
}
|
||||
|
||||
/**
|
||||
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
|
||||
*/
|
||||
@@ -165,8 +212,8 @@ class Operand extends TOperand {
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
this = TNonPhiMemoryOperand(_, _, _, _) or
|
||||
this = TPhiOperand(_, _, _, _)
|
||||
this instanceof NonPhiMemoryOperandBase or
|
||||
this instanceof PhiOperandBase
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = TRegisterOperand(useInstr, tag, defInstr) or
|
||||
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() {
|
||||
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
|
||||
}
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
|
||||
*/
|
||||
class AddressOperand extends RegisterOperand {
|
||||
override AddressOperandTag tag;
|
||||
|
||||
override string toString() { result = "Address" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
|
||||
*/
|
||||
class BufferSizeOperand extends RegisterOperand {
|
||||
override BufferSizeOperandTag tag;
|
||||
|
||||
override string toString() { result = "BufferSize" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
|
||||
*/
|
||||
class LoadOperand extends TypedOperand {
|
||||
override LoadOperandTag tag;
|
||||
|
||||
override string toString() { result = "Load" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
|
||||
*/
|
||||
class StoreValueOperand extends RegisterOperand {
|
||||
override StoreValueOperandTag tag;
|
||||
|
||||
override string toString() { result = "StoreValue" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
|
||||
*/
|
||||
class UnaryOperand extends RegisterOperand {
|
||||
override UnaryOperandTag tag;
|
||||
|
||||
override string toString() { result = "Unary" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
|
||||
*/
|
||||
class LeftOperand extends RegisterOperand {
|
||||
override LeftOperandTag tag;
|
||||
|
||||
override string toString() { result = "Left" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
|
||||
*/
|
||||
class RightOperand extends RegisterOperand {
|
||||
override RightOperandTag tag;
|
||||
|
||||
override string toString() { result = "Right" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
|
||||
*/
|
||||
class ConditionOperand extends RegisterOperand {
|
||||
override ConditionOperandTag tag;
|
||||
|
||||
override string toString() { result = "Condition" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
|
||||
*/
|
||||
class CallTargetOperand extends RegisterOperand {
|
||||
override CallTargetOperandTag tag;
|
||||
|
||||
override string toString() { result = "CallTarget" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
|
||||
*/
|
||||
class ThisArgumentOperand extends ArgumentOperand {
|
||||
override ThisArgumentOperandTag tag;
|
||||
|
||||
override string toString() { result = "ThisArgument" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
|
||||
*/
|
||||
class PositionalArgumentOperand extends ArgumentOperand {
|
||||
override PositionalArgumentOperandTag tag;
|
||||
int argIndex;
|
||||
|
||||
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
|
||||
|
||||
override string toString() { result = "Arg(" + argIndex + ")" }
|
||||
|
||||
/**
|
||||
* Gets the zero-based index of the argument.
|
||||
*/
|
||||
final int getIndex() { result = argIndex }
|
||||
final int getIndex() { result = tag.getArgIndex() }
|
||||
}
|
||||
|
||||
class SideEffectOperand extends TypedOperand {
|
||||
override SideEffectOperandTag tag;
|
||||
|
||||
override string toString() { result = "SideEffect" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
Overlap overlap;
|
||||
|
||||
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
|
||||
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
|
||||
|
||||
override string toString() { result = "Phi" }
|
||||
|
||||
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
class ChiTotalOperand extends NonPhiMemoryOperand {
|
||||
override ChiTotalOperandTag tag;
|
||||
|
||||
override string toString() { result = "ChiTotal" }
|
||||
|
||||
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
|
||||
}
|
||||
|
||||
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
|
||||
class ChiPartialOperand extends NonPhiMemoryOperand {
|
||||
override ChiPartialOperandTag tag;
|
||||
|
||||
override string toString() { result = "ChiPartial" }
|
||||
|
||||
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
|
||||
}
|
||||
|
||||
@@ -221,7 +221,9 @@ PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
|
||||
result = TPositionalArgumentOperand(argIndex)
|
||||
}
|
||||
|
||||
class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
|
||||
abstract class ChiOperandTag extends MemoryOperandTag { }
|
||||
|
||||
class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
|
||||
final override string toString() { result = "ChiTotal" }
|
||||
|
||||
final override int getSortOrder() { result = 13 }
|
||||
@@ -231,7 +233,7 @@ class ChiTotalOperandTag extends MemoryOperandTag, TChiTotalOperand {
|
||||
|
||||
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
|
||||
|
||||
class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
|
||||
class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
|
||||
final override string toString() { result = "ChiPartial" }
|
||||
|
||||
final override int getSortOrder() { result = 14 }
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -27,6 +23,57 @@ private newtype TOperand =
|
||||
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all register operands. This is a placeholder for the IPA union type that we will
|
||||
* eventually use for this purpose.
|
||||
*/
|
||||
private class RegisterOperandBase extends TRegisterOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the register operand with the specified parameters.
|
||||
*/
|
||||
private RegisterOperandBase registerOperand(
|
||||
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
|
||||
) {
|
||||
result = TRegisterOperand(useInstr, tag, defInstr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
|
||||
* will eventually use for this purpose.
|
||||
*/
|
||||
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the non-Phi memory operand with the specified parameters.
|
||||
*/
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
|
||||
* eventually use for this purpose.
|
||||
*/
|
||||
private class PhiOperandBase extends TPhiOperand {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Phi operand with the specified parameters.
|
||||
*/
|
||||
private PhiOperandBase phiOperand(
|
||||
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
) {
|
||||
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
|
||||
}
|
||||
|
||||
/**
|
||||
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
|
||||
*/
|
||||
@@ -165,8 +212,8 @@ class Operand extends TOperand {
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
this = TNonPhiMemoryOperand(_, _, _, _) or
|
||||
this = TPhiOperand(_, _, _, _)
|
||||
this instanceof NonPhiMemoryOperandBase or
|
||||
this instanceof PhiOperandBase
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = TRegisterOperand(useInstr, tag, defInstr) or
|
||||
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() {
|
||||
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
|
||||
}
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
|
||||
*/
|
||||
class AddressOperand extends RegisterOperand {
|
||||
override AddressOperandTag tag;
|
||||
|
||||
override string toString() { result = "Address" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
|
||||
*/
|
||||
class BufferSizeOperand extends RegisterOperand {
|
||||
override BufferSizeOperandTag tag;
|
||||
|
||||
override string toString() { result = "BufferSize" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
|
||||
*/
|
||||
class LoadOperand extends TypedOperand {
|
||||
override LoadOperandTag tag;
|
||||
|
||||
override string toString() { result = "Load" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
|
||||
*/
|
||||
class StoreValueOperand extends RegisterOperand {
|
||||
override StoreValueOperandTag tag;
|
||||
|
||||
override string toString() { result = "StoreValue" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
|
||||
*/
|
||||
class UnaryOperand extends RegisterOperand {
|
||||
override UnaryOperandTag tag;
|
||||
|
||||
override string toString() { result = "Unary" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
|
||||
*/
|
||||
class LeftOperand extends RegisterOperand {
|
||||
override LeftOperandTag tag;
|
||||
|
||||
override string toString() { result = "Left" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
|
||||
*/
|
||||
class RightOperand extends RegisterOperand {
|
||||
override RightOperandTag tag;
|
||||
|
||||
override string toString() { result = "Right" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
|
||||
*/
|
||||
class ConditionOperand extends RegisterOperand {
|
||||
override ConditionOperandTag tag;
|
||||
|
||||
override string toString() { result = "Condition" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
|
||||
*/
|
||||
class CallTargetOperand extends RegisterOperand {
|
||||
override CallTargetOperandTag tag;
|
||||
|
||||
override string toString() { result = "CallTarget" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
|
||||
*/
|
||||
class ThisArgumentOperand extends ArgumentOperand {
|
||||
override ThisArgumentOperandTag tag;
|
||||
|
||||
override string toString() { result = "ThisArgument" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
|
||||
*/
|
||||
class PositionalArgumentOperand extends ArgumentOperand {
|
||||
override PositionalArgumentOperandTag tag;
|
||||
int argIndex;
|
||||
|
||||
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
|
||||
|
||||
override string toString() { result = "Arg(" + argIndex + ")" }
|
||||
|
||||
/**
|
||||
* Gets the zero-based index of the argument.
|
||||
*/
|
||||
final int getIndex() { result = argIndex }
|
||||
final int getIndex() { result = tag.getArgIndex() }
|
||||
}
|
||||
|
||||
class SideEffectOperand extends TypedOperand {
|
||||
override SideEffectOperandTag tag;
|
||||
|
||||
override string toString() { result = "SideEffect" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
Overlap overlap;
|
||||
|
||||
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
|
||||
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
|
||||
|
||||
override string toString() { result = "Phi" }
|
||||
|
||||
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
class ChiTotalOperand extends NonPhiMemoryOperand {
|
||||
override ChiTotalOperandTag tag;
|
||||
|
||||
override string toString() { result = "ChiTotal" }
|
||||
|
||||
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
|
||||
}
|
||||
|
||||
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
|
||||
class ChiPartialOperand extends NonPhiMemoryOperand {
|
||||
override ChiPartialOperandTag tag;
|
||||
|
||||
override string toString() { result = "ChiPartial" }
|
||||
|
||||
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
|
||||
}
|
||||
|
||||
@@ -14,12 +14,8 @@ private newtype TOperand =
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
|
||||
} or
|
||||
TNonPhiMemoryOperand(
|
||||
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
|
||||
) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
TNonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
useInstr.getOpcode().hasOperand(tag)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
@@ -27,6 +23,57 @@ private newtype TOperand =
|
||||
defInstr = Construction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all register operands. This is a placeholder for the IPA union type that we will
|
||||
* eventually use for this purpose.
|
||||
*/
|
||||
private class RegisterOperandBase extends TRegisterOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the register operand with the specified parameters.
|
||||
*/
|
||||
private RegisterOperandBase registerOperand(
|
||||
Instruction useInstr, RegisterOperandTag tag, Instruction defInstr
|
||||
) {
|
||||
result = TRegisterOperand(useInstr, tag, defInstr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all non-Phi memory operands. This is a placeholder for the IPA union type that we
|
||||
* will eventually use for this purpose.
|
||||
*/
|
||||
private class NonPhiMemoryOperandBase extends TNonPhiMemoryOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the non-Phi memory operand with the specified parameters.
|
||||
*/
|
||||
private NonPhiMemoryOperandBase nonPhiMemoryOperand(Instruction useInstr, MemoryOperandTag tag) {
|
||||
result = TNonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for all Phi operands. This is a placeholder for the IPA union type that we will
|
||||
* eventually use for this purpose.
|
||||
*/
|
||||
private class PhiOperandBase extends TPhiOperand {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Phi operand with the specified parameters.
|
||||
*/
|
||||
private PhiOperandBase phiOperand(
|
||||
Instruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
) {
|
||||
result = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap)
|
||||
}
|
||||
|
||||
/**
|
||||
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
|
||||
*/
|
||||
@@ -165,8 +212,8 @@ class Operand extends TOperand {
|
||||
*/
|
||||
class MemoryOperand extends Operand {
|
||||
MemoryOperand() {
|
||||
this = TNonPhiMemoryOperand(_, _, _, _) or
|
||||
this = TPhiOperand(_, _, _, _)
|
||||
this instanceof NonPhiMemoryOperandBase or
|
||||
this instanceof PhiOperandBase
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,18 +247,15 @@ class MemoryOperand extends Operand {
|
||||
*/
|
||||
class NonPhiOperand extends Operand {
|
||||
Instruction useInstr;
|
||||
Instruction defInstr;
|
||||
OperandTag tag;
|
||||
|
||||
NonPhiOperand() {
|
||||
this = TRegisterOperand(useInstr, tag, defInstr) or
|
||||
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
|
||||
this = registerOperand(useInstr, tag, _) or
|
||||
this = nonPhiMemoryOperand(useInstr, tag)
|
||||
}
|
||||
|
||||
final override Instruction getUse() { result = useInstr }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
@@ -222,8 +266,15 @@ class NonPhiOperand extends Operand {
|
||||
/**
|
||||
* An operand that consumes a register (non-memory) result.
|
||||
*/
|
||||
class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
class RegisterOperand extends NonPhiOperand, RegisterOperandBase {
|
||||
override RegisterOperandTag tag;
|
||||
Instruction defInstr;
|
||||
|
||||
RegisterOperand() { this = registerOperand(useInstr, tag, defInstr) }
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
// All register results overlap exactly with their uses.
|
||||
@@ -231,13 +282,25 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
}
|
||||
}
|
||||
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOperand {
|
||||
class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, NonPhiMemoryOperandBase {
|
||||
override MemoryOperandTag tag;
|
||||
Overlap overlap;
|
||||
|
||||
NonPhiMemoryOperand() { this = TNonPhiMemoryOperand(useInstr, tag, defInstr, overlap) }
|
||||
NonPhiMemoryOperand() { this = nonPhiMemoryOperand(useInstr, tag) }
|
||||
|
||||
final override Overlap getDefinitionOverlap() { result = overlap }
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
final override Instruction getAnyDef() {
|
||||
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
|
||||
}
|
||||
|
||||
final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
|
||||
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
|
||||
not Construction::isInCycle(useInstr) and
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
}
|
||||
}
|
||||
|
||||
class TypedOperand extends NonPhiMemoryOperand {
|
||||
@@ -254,8 +317,6 @@ class TypedOperand extends NonPhiMemoryOperand {
|
||||
*/
|
||||
class AddressOperand extends RegisterOperand {
|
||||
override AddressOperandTag tag;
|
||||
|
||||
override string toString() { result = "Address" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,8 +325,6 @@ class AddressOperand extends RegisterOperand {
|
||||
*/
|
||||
class BufferSizeOperand extends RegisterOperand {
|
||||
override BufferSizeOperandTag tag;
|
||||
|
||||
override string toString() { result = "BufferSize" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,8 +333,6 @@ class BufferSizeOperand extends RegisterOperand {
|
||||
*/
|
||||
class LoadOperand extends TypedOperand {
|
||||
override LoadOperandTag tag;
|
||||
|
||||
override string toString() { result = "Load" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,8 +340,6 @@ class LoadOperand extends TypedOperand {
|
||||
*/
|
||||
class StoreValueOperand extends RegisterOperand {
|
||||
override StoreValueOperandTag tag;
|
||||
|
||||
override string toString() { result = "StoreValue" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,8 +347,6 @@ class StoreValueOperand extends RegisterOperand {
|
||||
*/
|
||||
class UnaryOperand extends RegisterOperand {
|
||||
override UnaryOperandTag tag;
|
||||
|
||||
override string toString() { result = "Unary" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,8 +354,6 @@ class UnaryOperand extends RegisterOperand {
|
||||
*/
|
||||
class LeftOperand extends RegisterOperand {
|
||||
override LeftOperandTag tag;
|
||||
|
||||
override string toString() { result = "Left" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,8 +361,6 @@ class LeftOperand extends RegisterOperand {
|
||||
*/
|
||||
class RightOperand extends RegisterOperand {
|
||||
override RightOperandTag tag;
|
||||
|
||||
override string toString() { result = "Right" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,8 +368,6 @@ class RightOperand extends RegisterOperand {
|
||||
*/
|
||||
class ConditionOperand extends RegisterOperand {
|
||||
override ConditionOperandTag tag;
|
||||
|
||||
override string toString() { result = "Condition" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,8 +375,6 @@ class ConditionOperand extends RegisterOperand {
|
||||
*/
|
||||
class CallTargetOperand extends RegisterOperand {
|
||||
override CallTargetOperandTag tag;
|
||||
|
||||
override string toString() { result = "CallTarget" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,8 +392,6 @@ class ArgumentOperand extends RegisterOperand {
|
||||
*/
|
||||
class ThisArgumentOperand extends ArgumentOperand {
|
||||
override ThisArgumentOperandTag tag;
|
||||
|
||||
override string toString() { result = "ThisArgument" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,34 +399,27 @@ class ThisArgumentOperand extends ArgumentOperand {
|
||||
*/
|
||||
class PositionalArgumentOperand extends ArgumentOperand {
|
||||
override PositionalArgumentOperandTag tag;
|
||||
int argIndex;
|
||||
|
||||
PositionalArgumentOperand() { argIndex = tag.getArgIndex() }
|
||||
|
||||
override string toString() { result = "Arg(" + argIndex + ")" }
|
||||
|
||||
/**
|
||||
* Gets the zero-based index of the argument.
|
||||
*/
|
||||
final int getIndex() { result = argIndex }
|
||||
final int getIndex() { result = tag.getArgIndex() }
|
||||
}
|
||||
|
||||
class SideEffectOperand extends TypedOperand {
|
||||
override SideEffectOperandTag tag;
|
||||
|
||||
override string toString() { result = "SideEffect" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand of a `PhiInstruction`.
|
||||
*/
|
||||
class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
PhiInstruction useInstr;
|
||||
Instruction defInstr;
|
||||
IRBlock predecessorBlock;
|
||||
Overlap overlap;
|
||||
|
||||
PhiInputOperand() { this = TPhiOperand(useInstr, defInstr, predecessorBlock, overlap) }
|
||||
PhiInputOperand() { this = phiOperand(useInstr, defInstr, predecessorBlock, overlap) }
|
||||
|
||||
override string toString() { result = "Phi" }
|
||||
|
||||
@@ -413,8 +449,6 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
|
||||
class ChiTotalOperand extends NonPhiMemoryOperand {
|
||||
override ChiTotalOperandTag tag;
|
||||
|
||||
override string toString() { result = "ChiTotal" }
|
||||
|
||||
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiTotalMemoryAccess }
|
||||
}
|
||||
|
||||
@@ -424,7 +458,5 @@ class ChiTotalOperand extends NonPhiMemoryOperand {
|
||||
class ChiPartialOperand extends NonPhiMemoryOperand {
|
||||
override ChiPartialOperandTag tag;
|
||||
|
||||
override string toString() { result = "ChiPartial" }
|
||||
|
||||
final override MemoryAccessKind getMemoryAccess() { result instanceof ChiPartialMemoryAccess }
|
||||
}
|
||||
|
||||
@@ -14,3 +14,4 @@ private import implementations.Strdup
|
||||
private import implementations.Strftime
|
||||
private import implementations.StdString
|
||||
private import implementations.Swap
|
||||
private import implementations.GetDelim
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
import semmle.code.cpp.models.interfaces.SideEffect
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
|
||||
/**
|
||||
* The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`.
|
||||
*/
|
||||
class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction, RemoteFlowFunction {
|
||||
GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
|
||||
i.isParameter(3) and o.isParameterDeref(0)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] }
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int index) { none() }
|
||||
|
||||
override predicate hasOnlySpecificReadSideEffects() { any() }
|
||||
|
||||
override predicate hasOnlySpecificWriteSideEffects() { any() }
|
||||
|
||||
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
|
||||
i = [0, 1] and
|
||||
buffer = false and
|
||||
mustWrite = false
|
||||
}
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
i = 3 and buffer = false
|
||||
}
|
||||
|
||||
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
|
||||
output.isParameterDeref(0) and
|
||||
description = "String read by " + this.getName()
|
||||
}
|
||||
}
|
||||
@@ -1143,6 +1143,13 @@ conversionkinds(
|
||||
int kind: int ref
|
||||
);
|
||||
|
||||
@conversion = @cast
|
||||
| @array_to_pointer
|
||||
| @parexpr
|
||||
| @reference_to
|
||||
| @ref_indirect
|
||||
;
|
||||
|
||||
/*
|
||||
case @funbindexpr.kind of
|
||||
0 = @normal_call // a normal call
|
||||
@@ -1800,6 +1807,8 @@ lambda_capture(
|
||||
@addressable = @function | @variable ;
|
||||
@accessible = @addressable | @enumconstant ;
|
||||
|
||||
@access = @varaccess | @routineexpr ;
|
||||
|
||||
fold(
|
||||
int expr: @foldexpr ref,
|
||||
string operator: string ref,
|
||||
|
||||
@@ -1524,7 +1524,7 @@
|
||||
</e>
|
||||
<e>
|
||||
<k>seconds</k>
|
||||
<v>12697</v>
|
||||
<v>12094</v>
|
||||
</e>
|
||||
</columnsizes>
|
||||
<dependencies>
|
||||
@@ -1570,17 +1570,17 @@
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>21</v>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>3</a>
|
||||
<b>4</b>
|
||||
<v>2478</v>
|
||||
<v>2675</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>4</a>
|
||||
<b>5</b>
|
||||
<v>7028</v>
|
||||
<v>6842</v>
|
||||
</b>
|
||||
</bs>
|
||||
</hist>
|
||||
@@ -1626,8 +1626,8 @@
|
||||
<budget>12</budget>
|
||||
<bs>
|
||||
<b>
|
||||
<a>1158</a>
|
||||
<b>1159</b>
|
||||
<a>1103</a>
|
||||
<b>1104</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
</bs>
|
||||
@@ -1679,18 +1679,18 @@
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>14</a>
|
||||
<b>15</b>
|
||||
<a>13</a>
|
||||
<b>14</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>565</a>
|
||||
<b>566</b>
|
||||
<a>579</a>
|
||||
<b>580</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>693</a>
|
||||
<b>694</b>
|
||||
<a>670</a>
|
||||
<b>671</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
</bs>
|
||||
@@ -1707,22 +1707,22 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>8859</v>
|
||||
<v>7949</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>2313</v>
|
||||
<v>2401</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>3</a>
|
||||
<b>5</b>
|
||||
<v>1107</v>
|
||||
<b>4</b>
|
||||
<v>932</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>5</a>
|
||||
<b>614</b>
|
||||
<v>416</v>
|
||||
<a>4</a>
|
||||
<b>627</b>
|
||||
<v>811</v>
|
||||
</b>
|
||||
</bs>
|
||||
</hist>
|
||||
@@ -1738,7 +1738,7 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>12697</v>
|
||||
<v>12094</v>
|
||||
</b>
|
||||
</bs>
|
||||
</hist>
|
||||
@@ -1754,17 +1754,17 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>11403</v>
|
||||
<v>10285</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>1271</v>
|
||||
<v>1798</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>3</a>
|
||||
<b>5</b>
|
||||
<v>21</v>
|
||||
<b>4</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
</bs>
|
||||
</hist>
|
||||
@@ -2143,7 +2143,7 @@
|
||||
</e>
|
||||
<e>
|
||||
<k>cpu_seconds</k>
|
||||
<v>7927</v>
|
||||
<v>8157</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>elapsed_seconds</k>
|
||||
@@ -2193,17 +2193,17 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>6820</v>
|
||||
<v>7160</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>778</v>
|
||||
<v>756</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>3</a>
|
||||
<b>8</b>
|
||||
<v>328</v>
|
||||
<b>6</b>
|
||||
<v>241</v>
|
||||
</b>
|
||||
</bs>
|
||||
</hist>
|
||||
@@ -2219,12 +2219,12 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>7587</v>
|
||||
<v>7675</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>339</v>
|
||||
<v>482</v>
|
||||
</b>
|
||||
</bs>
|
||||
</hist>
|
||||
@@ -2240,66 +2240,66 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>10</v>
|
||||
<v>32</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>21</v>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>3</a>
|
||||
<b>4</b>
|
||||
<v>21</v>
|
||||
<v>32</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>4</a>
|
||||
<b>5</b>
|
||||
<v>21</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>10</a>
|
||||
<b>11</b>
|
||||
<v>21</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>18</a>
|
||||
<b>19</b>
|
||||
<a>7</a>
|
||||
<b>8</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>37</a>
|
||||
<b>38</b>
|
||||
<a>8</a>
|
||||
<b>9</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>51</a>
|
||||
<b>52</b>
|
||||
<a>21</a>
|
||||
<b>22</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>62</a>
|
||||
<b>63</b>
|
||||
<a>26</a>
|
||||
<b>27</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>99</a>
|
||||
<b>100</b>
|
||||
<a>31</a>
|
||||
<b>32</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>158</a>
|
||||
<b>159</b>
|
||||
<a>104</a>
|
||||
<b>105</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>170</a>
|
||||
<b>171</b>
|
||||
<a>137</a>
|
||||
<b>138</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>237</a>
|
||||
<b>238</b>
|
||||
<a>144</a>
|
||||
<b>145</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>173</a>
|
||||
<b>174</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>206</a>
|
||||
<b>207</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
</bs>
|
||||
@@ -2316,66 +2316,66 @@
|
||||
<b>
|
||||
<a>1</a>
|
||||
<b>2</b>
|
||||
<v>10</v>
|
||||
<v>32</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>2</a>
|
||||
<b>3</b>
|
||||
<v>21</v>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>3</a>
|
||||
<b>4</b>
|
||||
<v>21</v>
|
||||
<v>32</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>4</a>
|
||||
<b>5</b>
|
||||
<v>21</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>10</a>
|
||||
<b>11</b>
|
||||
<v>21</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>18</a>
|
||||
<b>19</b>
|
||||
<a>7</a>
|
||||
<b>8</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>35</a>
|
||||
<b>36</b>
|
||||
<a>8</a>
|
||||
<b>9</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>50</a>
|
||||
<b>51</b>
|
||||
<a>21</a>
|
||||
<b>22</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>59</a>
|
||||
<b>60</b>
|
||||
<a>25</a>
|
||||
<b>26</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>74</a>
|
||||
<b>75</b>
|
||||
<a>29</a>
|
||||
<b>30</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>144</a>
|
||||
<b>145</b>
|
||||
<a>84</a>
|
||||
<b>85</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>162</a>
|
||||
<b>163</b>
|
||||
<a>122</a>
|
||||
<b>123</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>173</a>
|
||||
<b>174</b>
|
||||
<a>132</a>
|
||||
<b>133</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>150</a>
|
||||
<b>151</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
<b>
|
||||
<a>196</a>
|
||||
<b>197</b>
|
||||
<v>10</v>
|
||||
</b>
|
||||
</bs>
|
||||
|
||||
@@ -591,3 +591,13 @@
|
||||
| taint.cpp:463:6:463:6 | 0 | taint.cpp:471:7:471:7 | y | |
|
||||
| taint.cpp:468:7:468:7 | ref arg x | taint.cpp:470:7:470:7 | x | |
|
||||
| taint.cpp:468:10:468:10 | ref arg y | taint.cpp:471:7:471:7 | y | |
|
||||
| taint.cpp:480:26:480:32 | source1 | taint.cpp:483:28:483:34 | source1 | |
|
||||
| taint.cpp:481:15:481:21 | 0 | taint.cpp:483:12:483:15 | line | |
|
||||
| taint.cpp:481:15:481:21 | 0 | taint.cpp:485:7:485:10 | line | |
|
||||
| taint.cpp:482:9:482:9 | n | taint.cpp:483:19:483:19 | n | |
|
||||
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:483:12:483:15 | line [inner post update] | |
|
||||
| taint.cpp:483:11:483:15 | ref arg & ... | taint.cpp:485:7:485:10 | line | |
|
||||
| taint.cpp:483:12:483:15 | line | taint.cpp:483:11:483:15 | & ... | |
|
||||
| taint.cpp:483:18:483:19 | ref arg & ... | taint.cpp:483:19:483:19 | n [inner post update] | |
|
||||
| taint.cpp:483:19:483:19 | n | taint.cpp:483:18:483:19 | & ... | |
|
||||
| taint.cpp:483:28:483:34 | source1 | taint.cpp:483:11:483:15 | ref arg & ... | TAINT |
|
||||
|
||||
@@ -470,3 +470,17 @@ void test_swop() {
|
||||
sink(x); // clean [FALSE POSITIVE]
|
||||
sink(y); // tainted
|
||||
}
|
||||
|
||||
// --- getdelim ---
|
||||
|
||||
struct FILE;
|
||||
|
||||
int getdelim(char ** lineptr, size_t * n, int delimiter, FILE *stream);
|
||||
|
||||
void test_getdelim(FILE* source1) {
|
||||
char* line = nullptr;
|
||||
size_t n;
|
||||
getdelim(&line, &n, '\n', source1);
|
||||
|
||||
sink(line);
|
||||
}
|
||||
@@ -67,3 +67,4 @@
|
||||
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |
|
||||
|
||||
@@ -28,3 +28,4 @@
|
||||
| taint.cpp:430:9:430:14 | member | taint.cpp:428:13:428:18 | call to source |
|
||||
| taint.cpp:465:7:465:7 | x | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
|
||||
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
missingOperand
|
||||
unexpectedOperand
|
||||
duplicateOperand
|
||||
| ssa.cpp:301:27:301:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) |
|
||||
missingPhiOperand
|
||||
missingOperandType
|
||||
duplicateChiOperand
|
||||
|
||||
@@ -1480,7 +1480,7 @@ ssa.cpp:
|
||||
# 304| r304_5(char) = Load : &:r304_4, ~m303_8
|
||||
# 304| r304_6(int) = Convert : r304_5
|
||||
# 304| m304_7(int) = Store : &:r304_1, r304_6
|
||||
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, ~m303_11, m303_11
|
||||
# 301| v301_12(void) = ReturnIndirection[argv] : &:r301_10, m303_11
|
||||
# 301| r301_13(glval<int>) = VariableAddress[#return] :
|
||||
# 301| v301_14(void) = ReturnValue : &:r301_13, m304_7
|
||||
# 301| v301_15(void) = AliasedUse : ~m303_8
|
||||
|
||||
2100
cpp/upgrades/2074f1cc7a3659ad555465a8025a8f2b7687896b/old.dbscheme
Normal file
2100
cpp/upgrades/2074f1cc7a3659ad555465a8025a8f2b7687896b/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add union types for casts and accesses
|
||||
compatibility: full
|
||||
Reference in New Issue
Block a user