mirror of
https://github.com/github/codeql.git
synced 2025-12-24 20:56:33 +01:00
Merge branch 'master' into rdmarsh/cpp/ir-flow-through-outparams
This commit is contained in:
@@ -22,16 +22,25 @@ import semmle.code.cpp.models.interfaces.Allocation
|
||||
predicate terminationProblem(AllocationExpr malloc, string msg) {
|
||||
// malloc(strlen(...))
|
||||
exists(StrlenCall strlen | DataFlow::localExprFlow(strlen, malloc.getSizeExpr())) and
|
||||
// flows into a null-terminated string function
|
||||
// flows to a call that implies this is a null-terminated string
|
||||
exists(ArrayFunction af, FunctionCall fc, int arg |
|
||||
DataFlow::localExprFlow(malloc, fc.getArgument(arg)) and
|
||||
fc.getTarget() = af and
|
||||
(
|
||||
// null terminated string
|
||||
// flows into null terminated string argument
|
||||
af.hasArrayWithNullTerminator(arg)
|
||||
or
|
||||
// likely a null terminated string (such as `strcpy`, `strcat`)
|
||||
// flows into likely null terminated string argument (such as `strcpy`, `strcat`)
|
||||
af.hasArrayWithUnknownSize(arg)
|
||||
or
|
||||
// flows into string argument to a formatting function (such as `printf`)
|
||||
exists(int n, FormatLiteral fl |
|
||||
fc.getArgument(arg) = fc.(FormattingFunctionCall).getConversionArgument(n) and
|
||||
fl = fc.(FormattingFunctionCall).getFormat() and
|
||||
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
|
||||
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
|
||||
not fl.hasPrecision(n) // exclude: `%.*s`
|
||||
)
|
||||
)
|
||||
) and
|
||||
msg = "This allocation does not include space to null-terminate the string."
|
||||
|
||||
@@ -139,6 +139,13 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
/** Gets a parameter of this function. */
|
||||
Parameter getAParameter() { params(unresolveElement(result), underlyingElement(this), _, _) }
|
||||
|
||||
/**
|
||||
* Gets an access of this function.
|
||||
*
|
||||
* To get calls to this function, use `getACallToThisFunction` instead.
|
||||
*/
|
||||
FunctionAccess getAnAccess() { result.getTarget() = this }
|
||||
|
||||
/**
|
||||
* Gets the number of parameters of this function, _not_ including any
|
||||
* implicit `this` parameter or any `...` varargs pseudo-parameter.
|
||||
@@ -174,6 +181,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
result = getParameter(index).getTypedName() + ", " + getParameterStringFrom(index + 1)
|
||||
}
|
||||
|
||||
/** Gets a call to this function. */
|
||||
FunctionCall getACallToThisFunction() { result.getTarget() = this }
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -301,3 +301,5 @@ class DataFlowCall extends Expr {
|
||||
}
|
||||
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub implementation
|
||||
|
||||
int accessPathLimit() { result = 5 }
|
||||
|
||||
@@ -337,6 +337,12 @@ private Element adjustedSink(DataFlow::Node sink) {
|
||||
// For compatibility, send flow into a `NotExpr` even if it's part of a
|
||||
// short-circuiting condition and thus might get skipped.
|
||||
result.(NotExpr).getOperand() = sink.asExpr()
|
||||
or
|
||||
// Taint postfix and prefix crement operations when their operand is tainted.
|
||||
result.(CrementOperation).getAnOperand() = sink.asExpr()
|
||||
or
|
||||
// Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted.
|
||||
result.(AssignOperation).getAnOperand() = sink.asExpr()
|
||||
}
|
||||
|
||||
predicate tainted(Expr source, Element tainted) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -265,3 +265,5 @@ class DataFlowCall extends CallInstruction {
|
||||
}
|
||||
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub implementation
|
||||
|
||||
int accessPathLimit() { result = 5 }
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
|
||||
// that the cached IR gets the same checksum here as it does in queries that use
|
||||
// `ValueNumbering` without `DataFlow`.
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
private newtype TIRDataFlowNode =
|
||||
@@ -300,10 +303,12 @@ ParameterNode parameterNode(Parameter p) { result.getParameter() = p }
|
||||
VariableNode variableNode(Variable v) { result.getVariable() = v }
|
||||
|
||||
/**
|
||||
* DEPRECATED: See UninitializedNode.
|
||||
*
|
||||
* Gets the `Node` corresponding to the value of an uninitialized local
|
||||
* variable `v`.
|
||||
*/
|
||||
UninitializedNode uninitializedNode(LocalVariable v) { result.getLocalVariable() = v }
|
||||
Node uninitializedNode(LocalVariable v) { none() }
|
||||
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
@@ -365,10 +370,10 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
|
||||
modelOut.isReturnValueDeref() and
|
||||
iTo = call
|
||||
or
|
||||
exists(WriteSideEffectInstruction outNode |
|
||||
modelOut.isParameterDeref(outNode.getIndex()) and
|
||||
exists(int index, WriteSideEffectInstruction outNode |
|
||||
modelOut.isParameterDeref(index) and
|
||||
iTo = outNode and
|
||||
outNode.getPrimaryInstruction() = call
|
||||
outNode = getSideEffectFor(call, index)
|
||||
)
|
||||
// TODO: add write side effects for qualifiers
|
||||
) and
|
||||
@@ -380,8 +385,7 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
|
||||
or
|
||||
exists(int index, ReadSideEffectInstruction read |
|
||||
modelIn.isParameterDeref(index) and
|
||||
read.getIndex() = index and
|
||||
read.getPrimaryInstruction() = call and
|
||||
read = getSideEffectFor(call, index) and
|
||||
iFrom = read.getSideEffectOperand().getAnyDef()
|
||||
)
|
||||
or
|
||||
@@ -392,6 +396,18 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the result is a side effect for instruction `call` on argument
|
||||
* index `argument`. This helper predicate makes it easy to join on both of
|
||||
* these columns at once, avoiding pathological join orders in case the
|
||||
* argument index should get joined first.
|
||||
*/
|
||||
pragma[noinline]
|
||||
SideEffectInstruction getSideEffectFor(CallInstruction call, int argument) {
|
||||
call = result.getPrimaryInstruction() and
|
||||
argument = result.(IndexedInstruction).getIndex()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data flows from `source` to `sink` in zero or more local
|
||||
* (intra-procedural) steps.
|
||||
|
||||
@@ -11,13 +11,19 @@ cached
|
||||
private newtype TOperand =
|
||||
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
|
||||
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
|
||||
not Construction::isInCycle(useInstr)
|
||||
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)
|
||||
not Construction::isInCycle(useInstr) and
|
||||
(
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
or
|
||||
tag instanceof UnmodeledUseOperandTag
|
||||
)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
|
||||
@@ -2,10 +2,10 @@ private import ValueNumberingImports
|
||||
private import cpp
|
||||
|
||||
newtype TValueNumber =
|
||||
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
variableAddressValueNumber(_, irFunc, var)
|
||||
TVariableAddressValueNumber(IRFunction irFunc, Language::AST ast) {
|
||||
variableAddressValueNumber(_, irFunc, ast)
|
||||
} or
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, Language::AST var) {
|
||||
initializeParameterValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
|
||||
@@ -19,19 +19,18 @@ newtype TValueNumber =
|
||||
fieldAddressValueNumber(_, irFunc, field, objectAddress)
|
||||
} or
|
||||
TBinaryValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand
|
||||
) {
|
||||
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(_, irFunc, opcode, leftOperand, rightOperand)
|
||||
} or
|
||||
TPointerArithmeticValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand,
|
||||
IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
) {
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, elementSize, leftOperand, rightOperand)
|
||||
} or
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, type, operand)
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, TValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, operand)
|
||||
} or
|
||||
TInheritanceConversionValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand
|
||||
@@ -99,28 +98,49 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof LoadTotalOverlapInstruction
|
||||
}
|
||||
|
||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||
// count rather than strictcount to handle missing AST elements
|
||||
// separate instanceof and inline casts to avoid failed casts with a count of 0
|
||||
instr instanceof VariableAddressInstruction and
|
||||
count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1
|
||||
or
|
||||
instr instanceof ConstantInstruction and
|
||||
count(instr.getResultIRType()) != 1
|
||||
or
|
||||
instr instanceof FieldAddressInstruction and
|
||||
count(instr.(FieldAddressInstruction).getField()) != 1
|
||||
}
|
||||
|
||||
private predicate variableAddressValueNumber(
|
||||
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
|
||||
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getIRVariable() = var
|
||||
// The underlying AST element is used as value-numbering key instead of the
|
||||
// `IRVariable` to work around a problem where a variable or expression with
|
||||
// multiple types gives rise to multiple `IRVariable`s.
|
||||
instr.getIRVariable().getAST() = ast and
|
||||
strictcount(instr.getIRVariable().getAST()) = 1
|
||||
}
|
||||
|
||||
private predicate initializeParameterValueNumber(
|
||||
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
|
||||
InitializeParameterInstruction instr, IRFunction irFunc, Language::AST var
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getIRVariable() = var
|
||||
// The underlying AST element is used as value-numbering key instead of the
|
||||
// `IRVariable` to work around a problem where a variable or expression with
|
||||
// multiple types gives rise to multiple `IRVariable`s.
|
||||
instr.getIRVariable().getAST() = var
|
||||
}
|
||||
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc
|
||||
}
|
||||
|
||||
private predicate constantValueNumber(
|
||||
predicate constantValueNumber(
|
||||
ConstantInstruction instr, IRFunction irFunc, IRType type, string value
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
strictcount(instr.getResultIRType()) = 1 and
|
||||
instr.getResultIRType() = type and
|
||||
instr.getValue() = value
|
||||
}
|
||||
@@ -139,42 +159,40 @@ private predicate fieldAddressValueNumber(
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getField() = field and
|
||||
strictcount(instr.getField()) = 1 and
|
||||
tvalueNumber(instr.getObjectAddress()) = objectAddress
|
||||
}
|
||||
|
||||
private predicate binaryValueNumber(
|
||||
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand,
|
||||
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr instanceof PointerArithmeticInstruction and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getLeft()) = leftOperand and
|
||||
tvalueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate pointerArithmeticValueNumber(
|
||||
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, IRType type,
|
||||
int elementSize, TValueNumber leftOperand, TValueNumber rightOperand
|
||||
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize,
|
||||
TValueNumber leftOperand, TValueNumber rightOperand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
instr.getElementSize() = elementSize and
|
||||
tvalueNumber(instr.getLeft()) = leftOperand and
|
||||
tvalueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate unaryValueNumber(
|
||||
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand
|
||||
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber operand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr instanceof InheritanceConversionInstruction and
|
||||
not instr instanceof CopyInstruction and
|
||||
not instr instanceof FieldAddressInstruction and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getUnary()) = operand
|
||||
}
|
||||
|
||||
@@ -194,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
|
||||
TValueNumber operand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and
|
||||
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand
|
||||
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and
|
||||
instr.getResultIRType() = type
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
|
||||
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr.getResultIRType() instanceof IRVoidType and
|
||||
not numberableInstruction(instr)
|
||||
(
|
||||
not numberableInstruction(instr)
|
||||
or
|
||||
filteredNumberableInstruction(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,12 +258,12 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
exists(IRFunction irFunc |
|
||||
irFunc = instr.getEnclosingIRFunction() and
|
||||
(
|
||||
exists(IRVariable var |
|
||||
variableAddressValueNumber(instr, irFunc, var) and
|
||||
result = TVariableAddressValueNumber(irFunc, var)
|
||||
exists(Language::AST ast |
|
||||
variableAddressValueNumber(instr, irFunc, ast) and
|
||||
result = TVariableAddressValueNumber(irFunc, ast)
|
||||
)
|
||||
or
|
||||
exists(IRVariable var |
|
||||
exists(Language::AST var |
|
||||
initializeParameterValueNumber(instr, irFunc, var) and
|
||||
result = TInitializeParameterValueNumber(irFunc, var)
|
||||
)
|
||||
@@ -249,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
initializeThisValueNumber(instr, irFunc) and
|
||||
result = TInitializeThisValueNumber(irFunc)
|
||||
or
|
||||
exists(IRType type, string value |
|
||||
exists(string value, IRType type |
|
||||
constantValueNumber(instr, irFunc, type, value) and
|
||||
result = TConstantValueNumber(irFunc, type, value)
|
||||
)
|
||||
@@ -264,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
|
||||
)
|
||||
or
|
||||
exists(Opcode opcode, IRType type, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
|
||||
exists(Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
binaryValueNumber(instr, irFunc, opcode, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, leftOperand, rightOperand)
|
||||
)
|
||||
or
|
||||
exists(Opcode opcode, IRType type, TValueNumber operand |
|
||||
unaryValueNumber(instr, irFunc, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, type, operand)
|
||||
exists(Opcode opcode, TValueNumber operand |
|
||||
unaryValueNumber(instr, irFunc, opcode, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, operand)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
@@ -281,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
|
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand) and
|
||||
exists(Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, elementSize, leftOperand, rightOperand) and
|
||||
result =
|
||||
TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
TPointerArithmeticValueNumber(irFunc, opcode, elementSize, leftOperand, rightOperand)
|
||||
)
|
||||
or
|
||||
exists(IRType type, TValueNumber memOperand, TValueNumber operand |
|
||||
|
||||
@@ -220,9 +220,12 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
|
||||
/**
|
||||
* Holds if this memory location covers the entire variable.
|
||||
*/
|
||||
final predicate coversEntireVariable() {
|
||||
startBitOffset = 0 and
|
||||
endBitOffset = var.getIRType().getByteSize() * 8
|
||||
final predicate coversEntireVariable() { varIRTypeHasBitRange(startBitOffset, endBitOffset) }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate varIRTypeHasBitRange(int start, int end) {
|
||||
start = 0 and
|
||||
end = var.getIRType().getByteSize() * 8
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getMemoryOperandDefinition(
|
||||
private Instruction getMemoryOperandDefinition0(
|
||||
Instruction instruction, MemoryOperandTag tag, Overlap overlap
|
||||
) {
|
||||
exists(OldInstruction oldInstruction, OldIR::NonPhiMemoryOperand oldOperand |
|
||||
@@ -142,6 +142,19 @@ private module Cached {
|
||||
overlap instanceof MustExactlyOverlap
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getMemoryOperandDefinition(
|
||||
Instruction instruction, MemoryOperandTag tag, Overlap overlap
|
||||
) {
|
||||
// getMemoryOperandDefinition0 currently has a bug where it can match with multiple overlaps.
|
||||
// This predicate ensures that the chosen overlap is the most conservative if there's any doubt.
|
||||
result = getMemoryOperandDefinition0(instruction, tag, overlap) and
|
||||
not (
|
||||
overlap instanceof MustExactlyOverlap and
|
||||
exists(MustTotallyOverlap o | exists(getMemoryOperandDefinition0(instruction, tag, o)))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
|
||||
* through a phi instruction and therefore should be impossible.
|
||||
|
||||
@@ -11,13 +11,19 @@ cached
|
||||
private newtype TOperand =
|
||||
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
|
||||
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
|
||||
not Construction::isInCycle(useInstr)
|
||||
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)
|
||||
not Construction::isInCycle(useInstr) and
|
||||
(
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
or
|
||||
tag instanceof UnmodeledUseOperandTag
|
||||
)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
|
||||
@@ -2,10 +2,10 @@ private import ValueNumberingImports
|
||||
private import cpp
|
||||
|
||||
newtype TValueNumber =
|
||||
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
variableAddressValueNumber(_, irFunc, var)
|
||||
TVariableAddressValueNumber(IRFunction irFunc, Language::AST ast) {
|
||||
variableAddressValueNumber(_, irFunc, ast)
|
||||
} or
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, Language::AST var) {
|
||||
initializeParameterValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
|
||||
@@ -19,19 +19,18 @@ newtype TValueNumber =
|
||||
fieldAddressValueNumber(_, irFunc, field, objectAddress)
|
||||
} or
|
||||
TBinaryValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand
|
||||
) {
|
||||
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(_, irFunc, opcode, leftOperand, rightOperand)
|
||||
} or
|
||||
TPointerArithmeticValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand,
|
||||
IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
) {
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, elementSize, leftOperand, rightOperand)
|
||||
} or
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, type, operand)
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, TValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, operand)
|
||||
} or
|
||||
TInheritanceConversionValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand
|
||||
@@ -99,28 +98,49 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof LoadTotalOverlapInstruction
|
||||
}
|
||||
|
||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||
// count rather than strictcount to handle missing AST elements
|
||||
// separate instanceof and inline casts to avoid failed casts with a count of 0
|
||||
instr instanceof VariableAddressInstruction and
|
||||
count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1
|
||||
or
|
||||
instr instanceof ConstantInstruction and
|
||||
count(instr.getResultIRType()) != 1
|
||||
or
|
||||
instr instanceof FieldAddressInstruction and
|
||||
count(instr.(FieldAddressInstruction).getField()) != 1
|
||||
}
|
||||
|
||||
private predicate variableAddressValueNumber(
|
||||
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
|
||||
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getIRVariable() = var
|
||||
// The underlying AST element is used as value-numbering key instead of the
|
||||
// `IRVariable` to work around a problem where a variable or expression with
|
||||
// multiple types gives rise to multiple `IRVariable`s.
|
||||
instr.getIRVariable().getAST() = ast and
|
||||
strictcount(instr.getIRVariable().getAST()) = 1
|
||||
}
|
||||
|
||||
private predicate initializeParameterValueNumber(
|
||||
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
|
||||
InitializeParameterInstruction instr, IRFunction irFunc, Language::AST var
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getIRVariable() = var
|
||||
// The underlying AST element is used as value-numbering key instead of the
|
||||
// `IRVariable` to work around a problem where a variable or expression with
|
||||
// multiple types gives rise to multiple `IRVariable`s.
|
||||
instr.getIRVariable().getAST() = var
|
||||
}
|
||||
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc
|
||||
}
|
||||
|
||||
private predicate constantValueNumber(
|
||||
predicate constantValueNumber(
|
||||
ConstantInstruction instr, IRFunction irFunc, IRType type, string value
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
strictcount(instr.getResultIRType()) = 1 and
|
||||
instr.getResultIRType() = type and
|
||||
instr.getValue() = value
|
||||
}
|
||||
@@ -139,42 +159,40 @@ private predicate fieldAddressValueNumber(
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getField() = field and
|
||||
strictcount(instr.getField()) = 1 and
|
||||
tvalueNumber(instr.getObjectAddress()) = objectAddress
|
||||
}
|
||||
|
||||
private predicate binaryValueNumber(
|
||||
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand,
|
||||
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr instanceof PointerArithmeticInstruction and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getLeft()) = leftOperand and
|
||||
tvalueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate pointerArithmeticValueNumber(
|
||||
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, IRType type,
|
||||
int elementSize, TValueNumber leftOperand, TValueNumber rightOperand
|
||||
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize,
|
||||
TValueNumber leftOperand, TValueNumber rightOperand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
instr.getElementSize() = elementSize and
|
||||
tvalueNumber(instr.getLeft()) = leftOperand and
|
||||
tvalueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate unaryValueNumber(
|
||||
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand
|
||||
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber operand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr instanceof InheritanceConversionInstruction and
|
||||
not instr instanceof CopyInstruction and
|
||||
not instr instanceof FieldAddressInstruction and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getUnary()) = operand
|
||||
}
|
||||
|
||||
@@ -194,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
|
||||
TValueNumber operand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and
|
||||
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand
|
||||
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and
|
||||
instr.getResultIRType() = type
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
|
||||
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr.getResultIRType() instanceof IRVoidType and
|
||||
not numberableInstruction(instr)
|
||||
(
|
||||
not numberableInstruction(instr)
|
||||
or
|
||||
filteredNumberableInstruction(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,12 +258,12 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
exists(IRFunction irFunc |
|
||||
irFunc = instr.getEnclosingIRFunction() and
|
||||
(
|
||||
exists(IRVariable var |
|
||||
variableAddressValueNumber(instr, irFunc, var) and
|
||||
result = TVariableAddressValueNumber(irFunc, var)
|
||||
exists(Language::AST ast |
|
||||
variableAddressValueNumber(instr, irFunc, ast) and
|
||||
result = TVariableAddressValueNumber(irFunc, ast)
|
||||
)
|
||||
or
|
||||
exists(IRVariable var |
|
||||
exists(Language::AST var |
|
||||
initializeParameterValueNumber(instr, irFunc, var) and
|
||||
result = TInitializeParameterValueNumber(irFunc, var)
|
||||
)
|
||||
@@ -249,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
initializeThisValueNumber(instr, irFunc) and
|
||||
result = TInitializeThisValueNumber(irFunc)
|
||||
or
|
||||
exists(IRType type, string value |
|
||||
exists(string value, IRType type |
|
||||
constantValueNumber(instr, irFunc, type, value) and
|
||||
result = TConstantValueNumber(irFunc, type, value)
|
||||
)
|
||||
@@ -264,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
|
||||
)
|
||||
or
|
||||
exists(Opcode opcode, IRType type, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
|
||||
exists(Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
binaryValueNumber(instr, irFunc, opcode, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, leftOperand, rightOperand)
|
||||
)
|
||||
or
|
||||
exists(Opcode opcode, IRType type, TValueNumber operand |
|
||||
unaryValueNumber(instr, irFunc, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, type, operand)
|
||||
exists(Opcode opcode, TValueNumber operand |
|
||||
unaryValueNumber(instr, irFunc, opcode, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, operand)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
@@ -281,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
|
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand) and
|
||||
exists(Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, elementSize, leftOperand, rightOperand) and
|
||||
result =
|
||||
TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
TPointerArithmeticValueNumber(irFunc, opcode, elementSize, leftOperand, rightOperand)
|
||||
)
|
||||
or
|
||||
exists(IRType type, TValueNumber memOperand, TValueNumber operand |
|
||||
|
||||
@@ -11,13 +11,19 @@ cached
|
||||
private newtype TOperand =
|
||||
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
|
||||
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
|
||||
not Construction::isInCycle(useInstr)
|
||||
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)
|
||||
not Construction::isInCycle(useInstr) and
|
||||
(
|
||||
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
|
||||
or
|
||||
tag instanceof UnmodeledUseOperandTag
|
||||
)
|
||||
} or
|
||||
TPhiOperand(
|
||||
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap
|
||||
|
||||
@@ -2,10 +2,10 @@ private import ValueNumberingImports
|
||||
private import cpp
|
||||
|
||||
newtype TValueNumber =
|
||||
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
variableAddressValueNumber(_, irFunc, var)
|
||||
TVariableAddressValueNumber(IRFunction irFunc, Language::AST ast) {
|
||||
variableAddressValueNumber(_, irFunc, ast)
|
||||
} or
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
|
||||
TInitializeParameterValueNumber(IRFunction irFunc, Language::AST var) {
|
||||
initializeParameterValueNumber(_, irFunc, var)
|
||||
} or
|
||||
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
|
||||
@@ -19,19 +19,18 @@ newtype TValueNumber =
|
||||
fieldAddressValueNumber(_, irFunc, field, objectAddress)
|
||||
} or
|
||||
TBinaryValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand
|
||||
) {
|
||||
binaryValueNumber(_, irFunc, opcode, type, leftOperand, rightOperand)
|
||||
binaryValueNumber(_, irFunc, opcode, leftOperand, rightOperand)
|
||||
} or
|
||||
TPointerArithmeticValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand,
|
||||
IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
) {
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
pointerArithmeticValueNumber(_, irFunc, opcode, elementSize, leftOperand, rightOperand)
|
||||
} or
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, type, operand)
|
||||
TUnaryValueNumber(IRFunction irFunc, Opcode opcode, TValueNumber operand) {
|
||||
unaryValueNumber(_, irFunc, opcode, operand)
|
||||
} or
|
||||
TInheritanceConversionValueNumber(
|
||||
IRFunction irFunc, Opcode opcode, Class baseClass, Class derivedClass, TValueNumber operand
|
||||
@@ -99,28 +98,49 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof LoadTotalOverlapInstruction
|
||||
}
|
||||
|
||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||
// count rather than strictcount to handle missing AST elements
|
||||
// separate instanceof and inline casts to avoid failed casts with a count of 0
|
||||
instr instanceof VariableAddressInstruction and
|
||||
count(instr.(VariableAddressInstruction).getIRVariable().getAST()) != 1
|
||||
or
|
||||
instr instanceof ConstantInstruction and
|
||||
count(instr.getResultIRType()) != 1
|
||||
or
|
||||
instr instanceof FieldAddressInstruction and
|
||||
count(instr.(FieldAddressInstruction).getField()) != 1
|
||||
}
|
||||
|
||||
private predicate variableAddressValueNumber(
|
||||
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
|
||||
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getIRVariable() = var
|
||||
// The underlying AST element is used as value-numbering key instead of the
|
||||
// `IRVariable` to work around a problem where a variable or expression with
|
||||
// multiple types gives rise to multiple `IRVariable`s.
|
||||
instr.getIRVariable().getAST() = ast and
|
||||
strictcount(instr.getIRVariable().getAST()) = 1
|
||||
}
|
||||
|
||||
private predicate initializeParameterValueNumber(
|
||||
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
|
||||
InitializeParameterInstruction instr, IRFunction irFunc, Language::AST var
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getIRVariable() = var
|
||||
// The underlying AST element is used as value-numbering key instead of the
|
||||
// `IRVariable` to work around a problem where a variable or expression with
|
||||
// multiple types gives rise to multiple `IRVariable`s.
|
||||
instr.getIRVariable().getAST() = var
|
||||
}
|
||||
|
||||
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc
|
||||
}
|
||||
|
||||
private predicate constantValueNumber(
|
||||
predicate constantValueNumber(
|
||||
ConstantInstruction instr, IRFunction irFunc, IRType type, string value
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
strictcount(instr.getResultIRType()) = 1 and
|
||||
instr.getResultIRType() = type and
|
||||
instr.getValue() = value
|
||||
}
|
||||
@@ -139,42 +159,40 @@ private predicate fieldAddressValueNumber(
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getField() = field and
|
||||
strictcount(instr.getField()) = 1 and
|
||||
tvalueNumber(instr.getObjectAddress()) = objectAddress
|
||||
}
|
||||
|
||||
private predicate binaryValueNumber(
|
||||
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber leftOperand,
|
||||
BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr instanceof PointerArithmeticInstruction and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getLeft()) = leftOperand and
|
||||
tvalueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate pointerArithmeticValueNumber(
|
||||
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, IRType type,
|
||||
int elementSize, TValueNumber leftOperand, TValueNumber rightOperand
|
||||
PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize,
|
||||
TValueNumber leftOperand, TValueNumber rightOperand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
instr.getElementSize() = elementSize and
|
||||
tvalueNumber(instr.getLeft()) = leftOperand and
|
||||
tvalueNumber(instr.getRight()) = rightOperand
|
||||
}
|
||||
|
||||
private predicate unaryValueNumber(
|
||||
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, IRType type, TValueNumber operand
|
||||
UnaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber operand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr instanceof InheritanceConversionInstruction and
|
||||
not instr instanceof CopyInstruction and
|
||||
not instr instanceof FieldAddressInstruction and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getUnary()) = operand
|
||||
}
|
||||
|
||||
@@ -194,9 +212,9 @@ private predicate loadTotalOverlapValueNumber(
|
||||
TValueNumber operand
|
||||
) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
instr.getResultIRType() = type and
|
||||
tvalueNumber(instr.getAnOperand().(MemoryOperand).getAnyDef()) = memOperand and
|
||||
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand
|
||||
tvalueNumberOfOperand(instr.getAnOperand().(AddressOperand)) = operand and
|
||||
instr.getResultIRType() = type
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,7 +224,11 @@ private predicate loadTotalOverlapValueNumber(
|
||||
private predicate uniqueValueNumber(Instruction instr, IRFunction irFunc) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
not instr.getResultIRType() instanceof IRVoidType and
|
||||
not numberableInstruction(instr)
|
||||
(
|
||||
not numberableInstruction(instr)
|
||||
or
|
||||
filteredNumberableInstruction(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,12 +258,12 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
exists(IRFunction irFunc |
|
||||
irFunc = instr.getEnclosingIRFunction() and
|
||||
(
|
||||
exists(IRVariable var |
|
||||
variableAddressValueNumber(instr, irFunc, var) and
|
||||
result = TVariableAddressValueNumber(irFunc, var)
|
||||
exists(Language::AST ast |
|
||||
variableAddressValueNumber(instr, irFunc, ast) and
|
||||
result = TVariableAddressValueNumber(irFunc, ast)
|
||||
)
|
||||
or
|
||||
exists(IRVariable var |
|
||||
exists(Language::AST var |
|
||||
initializeParameterValueNumber(instr, irFunc, var) and
|
||||
result = TInitializeParameterValueNumber(irFunc, var)
|
||||
)
|
||||
@@ -249,7 +271,7 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
initializeThisValueNumber(instr, irFunc) and
|
||||
result = TInitializeThisValueNumber(irFunc)
|
||||
or
|
||||
exists(IRType type, string value |
|
||||
exists(string value, IRType type |
|
||||
constantValueNumber(instr, irFunc, type, value) and
|
||||
result = TConstantValueNumber(irFunc, type, value)
|
||||
)
|
||||
@@ -264,14 +286,14 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
result = TFieldAddressValueNumber(irFunc, field, objectAddress)
|
||||
)
|
||||
or
|
||||
exists(Opcode opcode, IRType type, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
binaryValueNumber(instr, irFunc, opcode, type, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, type, leftOperand, rightOperand)
|
||||
exists(Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
binaryValueNumber(instr, irFunc, opcode, leftOperand, rightOperand) and
|
||||
result = TBinaryValueNumber(irFunc, opcode, leftOperand, rightOperand)
|
||||
)
|
||||
or
|
||||
exists(Opcode opcode, IRType type, TValueNumber operand |
|
||||
unaryValueNumber(instr, irFunc, opcode, type, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, type, operand)
|
||||
exists(Opcode opcode, TValueNumber operand |
|
||||
unaryValueNumber(instr, irFunc, opcode, operand) and
|
||||
result = TUnaryValueNumber(irFunc, opcode, operand)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
@@ -281,14 +303,10 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
result = TInheritanceConversionValueNumber(irFunc, opcode, baseClass, derivedClass, operand)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
Opcode opcode, IRType type, int elementSize, TValueNumber leftOperand,
|
||||
TValueNumber rightOperand
|
||||
|
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, type, elementSize, leftOperand,
|
||||
rightOperand) and
|
||||
exists(Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand |
|
||||
pointerArithmeticValueNumber(instr, irFunc, opcode, elementSize, leftOperand, rightOperand) and
|
||||
result =
|
||||
TPointerArithmeticValueNumber(irFunc, opcode, type, elementSize, leftOperand, rightOperand)
|
||||
TPointerArithmeticValueNumber(irFunc, opcode, elementSize, leftOperand, rightOperand)
|
||||
)
|
||||
or
|
||||
exists(IRType type, TValueNumber memOperand, TValueNumber operand |
|
||||
|
||||
@@ -96,7 +96,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getMemoryOperandDefinition(
|
||||
private Instruction getMemoryOperandDefinition0(
|
||||
Instruction instruction, MemoryOperandTag tag, Overlap overlap
|
||||
) {
|
||||
exists(OldInstruction oldInstruction, OldIR::NonPhiMemoryOperand oldOperand |
|
||||
@@ -142,6 +142,19 @@ private module Cached {
|
||||
overlap instanceof MustExactlyOverlap
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getMemoryOperandDefinition(
|
||||
Instruction instruction, MemoryOperandTag tag, Overlap overlap
|
||||
) {
|
||||
// getMemoryOperandDefinition0 currently has a bug where it can match with multiple overlaps.
|
||||
// This predicate ensures that the chosen overlap is the most conservative if there's any doubt.
|
||||
result = getMemoryOperandDefinition0(instruction, tag, overlap) and
|
||||
not (
|
||||
overlap instanceof MustExactlyOverlap and
|
||||
exists(MustTotallyOverlap o | exists(getMemoryOperandDefinition0(instruction, tag, o)))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
|
||||
* through a phi instruction and therefore should be impossible.
|
||||
|
||||
@@ -97,6 +97,8 @@ class GVN extends TValueNumber {
|
||||
or
|
||||
this instanceof TInheritanceConversionValueNumber and result = "InheritanceConversion"
|
||||
or
|
||||
this instanceof TLoadTotalOverlapValueNumber and result = "LoadTotalOverlap"
|
||||
or
|
||||
this instanceof TUniqueValueNumber and result = "Unique"
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,22 @@ abstract class FunctionWithWrappers extends Function {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether 'func' is a (possibly nested) wrapper function that feeds a parameter at the given index
|
||||
* through to an interesting parameter of 'this' function.
|
||||
*
|
||||
* The 'cause' gives the name of 'this' interesting function and its relevant parameter
|
||||
* at the end of the call chain.
|
||||
*
|
||||
* If there is more than one possible 'cause', a unique one is picked (by lexicographic order).
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private string wrapperFunctionAnyDepthUnique(Function func, int paramIndex) {
|
||||
result =
|
||||
toCause(func, paramIndex) + ", which ends up calling " +
|
||||
min(string targetCause | this.wrapperFunctionAnyDepth(func, paramIndex, targetCause))
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether 'func' is a (possibly nested) wrapper function that feeds a parameter at the given index
|
||||
* through to an interesting parameter of 'this' function.
|
||||
@@ -114,13 +130,7 @@ abstract class FunctionWithWrappers extends Function {
|
||||
)
|
||||
or
|
||||
not this.wrapperFunctionLimitedDepth(func, paramIndex, _, _) and
|
||||
cause =
|
||||
min(string targetCause, string possibleCause |
|
||||
this.wrapperFunctionAnyDepth(func, paramIndex, targetCause) and
|
||||
possibleCause = toCause(func, paramIndex) + ", which ends up calling " + targetCause
|
||||
|
|
||||
possibleCause
|
||||
)
|
||||
cause = wrapperFunctionAnyDepthUnique(func, paramIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
* Support for tracking tainted data through the program.
|
||||
*/
|
||||
|
||||
import TaintTrackingImpl
|
||||
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking
|
||||
|
||||
@@ -1 +1 @@
|
||||
import GlobalValueNumberingImpl
|
||||
import semmle.code.cpp.ir.internal.ASTValueNumbering
|
||||
|
||||
@@ -15,39 +15,27 @@
|
||||
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:28 | call to getenv | |
|
||||
| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:40 | (const char *)... | |
|
||||
| test.cpp:38:23:38:28 | call to getenv | test.cpp:40:14:40:19 | envStr | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:8:24:8:25 | s1 | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:8:24:8:25 | s1 | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:45:13:45:24 | envStrGlobal | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:45:13:45:24 | envStrGlobal | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:14:49:19 | envStr | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:28 | call to getenv | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:40 | (const char *)... | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:15:50:24 | envStr_ptr | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:15:50:24 | envStr_ptr | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:28:50:40 | & ... | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:29:50:40 | envStrGlobal | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:2:52:12 | * ... | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:3:52:12 | envStr_ptr | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:16:52:21 | envStr | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal | envStrGlobal |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... | |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal | |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:10:27:10:27 | s | |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:18:60:25 | userName | |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:34 | call to getenv | |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:47 | (const char *)... | |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:20:11:21 | s1 | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:36:11:37 | s2 | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:67:7:67:13 | copying | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:17:68:24 | userName | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:33 | call to getenv | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:46 | (const char *)... | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:69:10:69:13 | copy | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:5:70:10 | call to strcpy | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:12:70:15 | copy | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:18:70:25 | userName | |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | |
|
||||
| test.cpp:75:20:75:25 | call to getenv | test.cpp:15:22:15:25 | nptr | |
|
||||
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | |
|
||||
| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import semmle.code.cpp.security.TaintTracking as AST
|
||||
import semmle.code.cpp.security.TaintTrackingImpl as AST
|
||||
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IR
|
||||
import cpp
|
||||
|
||||
|
||||
@@ -1,40 +1,42 @@
|
||||
| test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 |
|
||||
| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 |
|
||||
| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 |
|
||||
| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 |
|
||||
| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 |
|
||||
| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 |
|
||||
| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 |
|
||||
| test.cpp:16:7:16:24 | ... + ... | 16:c7-c24 17:c7-c24 18:c7-c7 |
|
||||
| test.cpp:16:12:16:13 | p1 | 16:c12-c13 17:c12-c13 |
|
||||
| test.cpp:16:17:16:24 | global01 | 16:c17-c24 17:c17-c24 |
|
||||
| test.cpp:29:7:29:8 | p0 | 29:c7-c8 31:c7-c8 |
|
||||
| test.cpp:29:7:29:13 | ... + ... | 29:c7-c13 31:c7-c13 |
|
||||
| test.cpp:29:12:29:13 | p1 | 29:c12-c13 31:c12-c13 |
|
||||
| test.cpp:31:7:31:24 | ... + ... | 31:c7-c24 32:c7-c7 |
|
||||
| test.cpp:43:7:43:8 | p0 | 43:c7-c8 45:c7-c8 |
|
||||
| test.cpp:43:7:43:13 | ... + ... | 43:c7-c13 45:c7-c13 |
|
||||
| test.cpp:43:12:43:13 | p1 | 43:c12-c13 45:c12-c13 |
|
||||
| test.cpp:44:9:44:9 | 0 | 44:c9-c9 51:c25-c25 53:c18-c21 56:c39-c42 59:c17-c20 88:c12-c12 |
|
||||
| test.cpp:45:7:45:24 | ... + ... | 45:c7-c24 46:c7-c7 |
|
||||
| test.cpp:53:10:53:13 | (int)... | 53:c10-c13 56:c21-c24 |
|
||||
| test.cpp:53:10:53:13 | * ... | 53:c10-c13 56:c21-c24 |
|
||||
| test.cpp:53:11:53:13 | str | 53:c11-c13 56:c22-c24 |
|
||||
| test.cpp:53:18:53:21 | 0 | 53:c18-c21 56:c39-c42 59:c17-c20 |
|
||||
| test.cpp:56:13:56:16 | (int)... | 56:c13-c16 56:c31-c34 59:c9-c12 |
|
||||
| test.cpp:56:13:56:16 | * ... | 56:c13-c16 56:c31-c34 59:c9-c12 |
|
||||
| test.cpp:56:14:56:16 | ptr | 56:c14-c16 56:c32-c34 56:c47-c49 59:c10-c12 |
|
||||
| test.cpp:62:5:62:10 | result | 62:c5-c10 65:c10-c15 |
|
||||
| test.cpp:77:20:77:30 | (signed short)... | 77:c20-c30 79:c7-c7 |
|
||||
| test.cpp:79:11:79:14 | vals | 79:c11-c14 79:c24-c27 |
|
||||
| test.cpp:105:11:105:12 | (Base *)... | 105:c11-c12 106:c14-c35 107:c11-c12 |
|
||||
| test.cpp:105:11:105:12 | pd | 105:c11-c12 106:c33-c34 |
|
||||
| test.cpp:105:15:105:15 | b | 105:c15-c15 107:c15-c15 109:c10-c10 |
|
||||
| test.cpp:125:11:125:12 | pa | 125:c11-c12 126:c11-c12 128:c3-c4 129:c11-c12 |
|
||||
| test.cpp:125:15:125:15 | x | 125:c15-c15 126:c15-c15 128:c7-c7 |
|
||||
| test.cpp:136:11:136:18 | global_a | 136:c11-c18 137:c11-c18 139:c3-c10 |
|
||||
| test.cpp:136:21:136:21 | x | 136:c21-c21 137:c21-c21 139:c13-c13 |
|
||||
| test.cpp:144:11:144:12 | pa | 144:c11-c12 145:c11-c12 147:c3-c4 149:c11-c12 |
|
||||
| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 |
|
||||
| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
||||
| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 |
|
||||
| test.cpp:5:3:5:3 | GVN | 5:c3-c3 6:c3-c3 |
|
||||
| test.cpp:5:7:5:8 | GVN | 5:c7-c8 6:c7-c8 |
|
||||
| test.cpp:5:7:5:13 | GVN | 5:c7-c13 6:c7-c13 7:c7-c7 |
|
||||
| test.cpp:5:12:5:13 | GVN | 5:c12-c13 6:c12-c13 |
|
||||
| test.cpp:16:3:16:3 | GVN | 16:c3-c3 17:c3-c3 |
|
||||
| test.cpp:16:7:16:8 | GVN | 16:c7-c8 17:c7-c8 |
|
||||
| test.cpp:16:7:16:13 | GVN | 16:c7-c13 17:c7-c13 |
|
||||
| test.cpp:16:7:16:24 | GVN | 16:c7-c24 17:c7-c24 18:c7-c7 |
|
||||
| test.cpp:16:12:16:13 | GVN | 16:c12-c13 17:c12-c13 |
|
||||
| test.cpp:16:17:16:24 | GVN | 16:c17-c24 17:c17-c24 |
|
||||
| test.cpp:29:3:29:3 | GVN | 29:c3-c3 31:c3-c3 |
|
||||
| test.cpp:29:7:29:8 | GVN | 29:c7-c8 31:c7-c8 |
|
||||
| test.cpp:29:7:29:13 | GVN | 29:c7-c13 31:c7-c13 |
|
||||
| test.cpp:29:12:29:13 | GVN | 29:c12-c13 31:c12-c13 |
|
||||
| test.cpp:31:7:31:24 | GVN | 31:c7-c24 32:c7-c7 |
|
||||
| test.cpp:43:3:43:3 | GVN | 43:c3-c3 45:c3-c3 |
|
||||
| test.cpp:43:7:43:8 | GVN | 43:c7-c8 45:c7-c8 |
|
||||
| test.cpp:43:7:43:13 | GVN | 43:c7-c13 45:c7-c13 |
|
||||
| test.cpp:43:7:43:24 | GVN | 43:c7-c24 45:c7-c24 46:c7-c7 |
|
||||
| test.cpp:43:12:43:13 | GVN | 43:c12-c13 45:c12-c13 |
|
||||
| test.cpp:43:17:43:24 | GVN | 43:c17-c24 45:c17-c24 |
|
||||
| test.cpp:44:3:44:5 | GVN | 44:c3-c5 44:c4-c5 |
|
||||
| test.cpp:53:10:53:13 | GVN | 53:c10-c13 56:c21-c24 |
|
||||
| test.cpp:53:10:53:13 | GVN | 53:c10-c13 56:c21-c24 |
|
||||
| test.cpp:53:11:53:13 | GVN | 53:c11-c13 56:c22-c24 |
|
||||
| test.cpp:53:18:53:21 | GVN | 53:c18-c21 56:c39-c42 59:c17-c20 |
|
||||
| test.cpp:56:14:56:16 | GVN | 56:c14-c16 56:c32-c34 56:c47-c49 59:c10-c12 |
|
||||
| test.cpp:62:5:62:10 | GVN | 62:c5-c10 65:c10-c15 |
|
||||
| test.cpp:77:20:77:28 | GVN | 77:c20-c28 79:c7-c7 |
|
||||
| test.cpp:79:11:79:14 | GVN | 79:c11-c14 79:c24-c27 |
|
||||
| test.cpp:92:11:92:16 | GVN | 92:c11-c16 92:c15-c16 93:c10-c10 |
|
||||
| test.cpp:105:11:105:12 | GVN | 105:c11-c12 106:c33-c34 |
|
||||
| test.cpp:105:11:105:12 | GVN | 105:c11-c12 106:c33-c34 107:c11-c12 |
|
||||
| test.cpp:105:15:105:15 | GVN | 105:c15-c15 107:c15-c15 109:c10-c10 |
|
||||
| test.cpp:113:3:113:5 | GVN | 113:c3-c5 115:c3-c5 |
|
||||
| test.cpp:125:11:125:12 | GVN | 125:c11-c12 126:c11-c12 128:c3-c4 129:c11-c12 |
|
||||
| test.cpp:125:15:125:15 | GVN | 125:c15-c15 126:c15-c15 |
|
||||
| test.cpp:128:11:128:11 | GVN | 128:c11-c11 129:c15-c15 |
|
||||
| test.cpp:136:11:136:18 | GVN | 136:c11-c18 137:c11-c18 139:c3-c10 |
|
||||
| test.cpp:144:11:144:12 | GVN | 144:c11-c12 145:c11-c12 147:c3-c4 149:c11-c12 |
|
||||
| test.cpp:144:15:144:15 | GVN | 144:c15-c15 149:c15-c15 |
|
||||
| test.cpp:153:11:153:18 | GVN | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
| test.cpp:5:3:5:13 | ... = ... | |
|
||||
| test.cpp:6:3:6:13 | ... = ... | |
|
||||
| test.cpp:7:3:7:7 | ... = ... | |
|
||||
| test.cpp:10:16:10:16 | 1 | |
|
||||
| test.cpp:16:3:16:24 | ... = ... | |
|
||||
| test.cpp:17:3:17:24 | ... = ... | |
|
||||
| test.cpp:18:3:18:7 | ... = ... | |
|
||||
| test.cpp:21:16:21:16 | 2 | |
|
||||
| test.cpp:29:3:29:24 | ... = ... | |
|
||||
| test.cpp:30:3:30:17 | call to change_global02 | |
|
||||
| test.cpp:31:3:31:24 | ... = ... | |
|
||||
| test.cpp:32:3:32:7 | ... = ... | |
|
||||
| test.cpp:35:16:35:16 | 3 | |
|
||||
| test.cpp:43:3:43:24 | ... = ... | |
|
||||
| test.cpp:44:3:44:9 | ... = ... | |
|
||||
| test.cpp:45:3:45:24 | ... = ... | |
|
||||
| test.cpp:46:3:46:7 | ... = ... | |
|
||||
| test.cpp:51:25:51:25 | (unsigned int)... | |
|
||||
| test.cpp:53:10:53:13 | (int)... | |
|
||||
| test.cpp:53:10:53:13 | * ... | LoadTotalOverlap, Unary |
|
||||
| test.cpp:53:18:53:21 | (int)... | |
|
||||
| test.cpp:55:5:55:15 | ... = ... | |
|
||||
| test.cpp:56:12:56:25 | (...) | |
|
||||
| test.cpp:56:12:56:43 | ... && ... | |
|
||||
| test.cpp:56:13:56:16 | (int)... | |
|
||||
| test.cpp:56:13:56:16 | * ... | Unary, Unique |
|
||||
| test.cpp:56:21:56:24 | (int)... | |
|
||||
| test.cpp:56:21:56:24 | * ... | LoadTotalOverlap, Unary |
|
||||
| test.cpp:56:30:56:43 | (...) | |
|
||||
| test.cpp:56:31:56:34 | (int)... | |
|
||||
| test.cpp:56:31:56:34 | * ... | Unary, Unique |
|
||||
| test.cpp:56:39:56:42 | (int)... | |
|
||||
| test.cpp:56:47:56:51 | ... ++ | |
|
||||
| test.cpp:59:9:59:12 | (int)... | |
|
||||
| test.cpp:59:9:59:12 | * ... | Unary, Unique |
|
||||
| test.cpp:59:17:59:20 | (int)... | |
|
||||
| test.cpp:62:5:62:12 | ... ++ | |
|
||||
| test.cpp:77:20:77:28 | call to getAValue | Unary, Unique |
|
||||
| test.cpp:77:20:77:30 | (signed short)... | |
|
||||
| test.cpp:79:7:79:7 | (int)... | |
|
||||
| test.cpp:79:7:79:7 | v | Unary, Unary |
|
||||
| test.cpp:79:11:79:20 | (int)... | |
|
||||
| test.cpp:79:17:79:20 | val1 | LoadTotalOverlap, Unary |
|
||||
| test.cpp:79:24:79:33 | (int)... | |
|
||||
| test.cpp:79:30:79:33 | val2 | LoadTotalOverlap, Unary |
|
||||
| test.cpp:80:5:80:19 | ... = ... | |
|
||||
| test.cpp:80:9:80:17 | call to getAValue | Unary, Unique |
|
||||
| test.cpp:80:9:80:19 | (signed short)... | |
|
||||
| test.cpp:88:3:88:20 | ... = ... | |
|
||||
| test.cpp:88:12:88:12 | (void *)... | |
|
||||
| test.cpp:105:11:105:12 | (Base *)... | |
|
||||
| test.cpp:105:11:105:12 | pd | InheritanceConversion, InitializeParameter |
|
||||
| test.cpp:106:14:106:35 | static_cast<Base *>... | |
|
||||
| test.cpp:106:33:106:34 | pd | InheritanceConversion, InitializeParameter |
|
||||
| test.cpp:128:3:128:11 | ... = ... | |
|
||||
| test.cpp:139:3:139:24 | ... = ... | |
|
||||
| test.cpp:147:3:147:18 | ... = ... | |
|
||||
| test.cpp:156:3:156:17 | ... = ... | |
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
|
||||
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
|
||||
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |
|
||||
| test.cpp:10:16:10:16 | 1 | test.cpp:10:16:10:16 | 1 | AST only |
|
||||
| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only |
|
||||
| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only |
|
||||
| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only |
|
||||
| test.cpp:21:16:21:16 | 2 | test.cpp:21:16:21:16 | 2 | AST only |
|
||||
| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only |
|
||||
| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only |
|
||||
| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only |
|
||||
| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only |
|
||||
| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only |
|
||||
| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only |
|
||||
| test.cpp:35:16:35:16 | 3 | test.cpp:35:16:35:16 | 3 | AST only |
|
||||
| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only |
|
||||
| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only |
|
||||
| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only |
|
||||
| test.cpp:43:7:43:24 | ... + ... | test.cpp:46:7:46:7 | x | IR only |
|
||||
| test.cpp:43:17:43:24 | global03 | test.cpp:45:17:45:24 | global03 | IR only |
|
||||
| test.cpp:44:3:44:5 | * ... | test.cpp:44:4:44:5 | p2 | IR only |
|
||||
| test.cpp:44:3:44:9 | ... = ... | test.cpp:44:3:44:9 | ... = ... | AST only |
|
||||
| test.cpp:44:4:44:5 | p2 | test.cpp:44:3:44:5 | * ... | IR only |
|
||||
| test.cpp:44:9:44:9 | 0 | test.cpp:51:25:51:25 | 0 | AST only |
|
||||
| test.cpp:44:9:44:9 | 0 | test.cpp:53:18:53:21 | (int)... | AST only |
|
||||
| test.cpp:44:9:44:9 | 0 | test.cpp:56:39:56:42 | (int)... | AST only |
|
||||
| test.cpp:44:9:44:9 | 0 | test.cpp:59:17:59:20 | (int)... | AST only |
|
||||
| test.cpp:44:9:44:9 | 0 | test.cpp:88:12:88:12 | 0 | AST only |
|
||||
| test.cpp:45:3:45:3 | x | test.cpp:43:3:43:3 | x | IR only |
|
||||
| test.cpp:45:3:45:24 | ... = ... | test.cpp:45:3:45:24 | ... = ... | AST only |
|
||||
| test.cpp:45:7:45:24 | ... + ... | test.cpp:43:7:43:24 | ... + ... | IR only |
|
||||
| test.cpp:45:17:45:24 | global03 | test.cpp:43:17:43:24 | global03 | IR only |
|
||||
| test.cpp:46:3:46:7 | ... = ... | test.cpp:46:3:46:7 | ... = ... | AST only |
|
||||
| test.cpp:46:7:46:7 | x | test.cpp:43:7:43:24 | ... + ... | IR only |
|
||||
| test.cpp:51:25:51:25 | 0 | test.cpp:44:9:44:9 | 0 | AST only |
|
||||
| test.cpp:51:25:51:25 | 0 | test.cpp:53:18:53:21 | (int)... | AST only |
|
||||
| test.cpp:51:25:51:25 | 0 | test.cpp:56:39:56:42 | (int)... | AST only |
|
||||
| test.cpp:51:25:51:25 | 0 | test.cpp:59:17:59:20 | (int)... | AST only |
|
||||
| test.cpp:51:25:51:25 | 0 | test.cpp:88:12:88:12 | 0 | AST only |
|
||||
| test.cpp:51:25:51:25 | (unsigned int)... | test.cpp:51:25:51:25 | (unsigned int)... | AST only |
|
||||
| test.cpp:53:10:53:13 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only |
|
||||
| test.cpp:53:10:53:13 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only |
|
||||
| test.cpp:53:18:53:21 | (int)... | test.cpp:44:9:44:9 | 0 | AST only |
|
||||
| test.cpp:53:18:53:21 | (int)... | test.cpp:51:25:51:25 | 0 | AST only |
|
||||
| test.cpp:53:18:53:21 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only |
|
||||
| test.cpp:53:18:53:21 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only |
|
||||
| test.cpp:53:18:53:21 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only |
|
||||
| test.cpp:53:18:53:21 | (int)... | test.cpp:88:12:88:12 | 0 | AST only |
|
||||
| test.cpp:55:5:55:15 | ... = ... | test.cpp:55:5:55:15 | ... = ... | AST only |
|
||||
| test.cpp:56:12:56:25 | (...) | test.cpp:56:12:56:25 | (...) | AST only |
|
||||
| test.cpp:56:12:56:43 | ... && ... | test.cpp:56:12:56:43 | ... && ... | AST only |
|
||||
| test.cpp:56:13:56:16 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only |
|
||||
| test.cpp:56:13:56:16 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only |
|
||||
| test.cpp:56:13:56:16 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only |
|
||||
| test.cpp:56:13:56:16 | * ... | test.cpp:56:31:56:34 | * ... | AST only |
|
||||
| test.cpp:56:13:56:16 | * ... | test.cpp:59:9:59:12 | * ... | AST only |
|
||||
| test.cpp:56:21:56:24 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only |
|
||||
| test.cpp:56:21:56:24 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only |
|
||||
| test.cpp:56:30:56:43 | (...) | test.cpp:56:30:56:43 | (...) | AST only |
|
||||
| test.cpp:56:31:56:34 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only |
|
||||
| test.cpp:56:31:56:34 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only |
|
||||
| test.cpp:56:31:56:34 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only |
|
||||
| test.cpp:56:31:56:34 | * ... | test.cpp:56:13:56:16 | * ... | AST only |
|
||||
| test.cpp:56:31:56:34 | * ... | test.cpp:59:9:59:12 | * ... | AST only |
|
||||
| test.cpp:56:39:56:42 | (int)... | test.cpp:44:9:44:9 | 0 | AST only |
|
||||
| test.cpp:56:39:56:42 | (int)... | test.cpp:51:25:51:25 | 0 | AST only |
|
||||
| test.cpp:56:39:56:42 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only |
|
||||
| test.cpp:56:39:56:42 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only |
|
||||
| test.cpp:56:39:56:42 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only |
|
||||
| test.cpp:56:39:56:42 | (int)... | test.cpp:88:12:88:12 | 0 | AST only |
|
||||
| test.cpp:56:47:56:51 | ... ++ | test.cpp:56:47:56:51 | ... ++ | AST only |
|
||||
| test.cpp:59:9:59:12 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only |
|
||||
| test.cpp:59:9:59:12 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only |
|
||||
| test.cpp:59:9:59:12 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only |
|
||||
| test.cpp:59:9:59:12 | * ... | test.cpp:56:13:56:16 | * ... | AST only |
|
||||
| test.cpp:59:9:59:12 | * ... | test.cpp:56:31:56:34 | * ... | AST only |
|
||||
| test.cpp:59:17:59:20 | (int)... | test.cpp:44:9:44:9 | 0 | AST only |
|
||||
| test.cpp:59:17:59:20 | (int)... | test.cpp:51:25:51:25 | 0 | AST only |
|
||||
| test.cpp:59:17:59:20 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only |
|
||||
| test.cpp:59:17:59:20 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only |
|
||||
| test.cpp:59:17:59:20 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only |
|
||||
| test.cpp:59:17:59:20 | (int)... | test.cpp:88:12:88:12 | 0 | AST only |
|
||||
| test.cpp:62:5:62:12 | ... ++ | test.cpp:62:5:62:12 | ... ++ | AST only |
|
||||
| test.cpp:77:20:77:28 | call to getAValue | test.cpp:79:7:79:7 | v | IR only |
|
||||
| test.cpp:77:20:77:30 | (signed short)... | test.cpp:77:20:77:30 | (signed short)... | AST only |
|
||||
| test.cpp:77:20:77:30 | (signed short)... | test.cpp:79:7:79:7 | v | AST only |
|
||||
| test.cpp:79:7:79:7 | (int)... | test.cpp:79:7:79:7 | (int)... | AST only |
|
||||
| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:28 | call to getAValue | IR only |
|
||||
| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:30 | (signed short)... | AST only |
|
||||
| test.cpp:79:11:79:20 | (int)... | test.cpp:79:11:79:20 | (int)... | AST only |
|
||||
| test.cpp:79:24:79:33 | (int)... | test.cpp:79:24:79:33 | (int)... | AST only |
|
||||
| test.cpp:80:5:80:19 | ... = ... | test.cpp:80:5:80:19 | ... = ... | AST only |
|
||||
| test.cpp:80:9:80:19 | (signed short)... | test.cpp:80:9:80:19 | (signed short)... | AST only |
|
||||
| test.cpp:88:3:88:20 | ... = ... | test.cpp:88:3:88:20 | ... = ... | AST only |
|
||||
| test.cpp:88:12:88:12 | 0 | test.cpp:44:9:44:9 | 0 | AST only |
|
||||
| test.cpp:88:12:88:12 | 0 | test.cpp:51:25:51:25 | 0 | AST only |
|
||||
| test.cpp:88:12:88:12 | 0 | test.cpp:53:18:53:21 | (int)... | AST only |
|
||||
| test.cpp:88:12:88:12 | 0 | test.cpp:56:39:56:42 | (int)... | AST only |
|
||||
| test.cpp:88:12:88:12 | 0 | test.cpp:59:17:59:20 | (int)... | AST only |
|
||||
| test.cpp:88:12:88:12 | (void *)... | test.cpp:88:12:88:12 | (void *)... | AST only |
|
||||
| test.cpp:92:11:92:16 | ... = ... | test.cpp:92:15:92:16 | 10 | IR only |
|
||||
| test.cpp:92:11:92:16 | ... = ... | test.cpp:93:10:93:10 | x | IR only |
|
||||
| test.cpp:92:15:92:16 | 10 | test.cpp:92:11:92:16 | ... = ... | IR only |
|
||||
| test.cpp:92:15:92:16 | 10 | test.cpp:93:10:93:10 | x | IR only |
|
||||
| test.cpp:93:10:93:10 | x | test.cpp:92:11:92:16 | ... = ... | IR only |
|
||||
| test.cpp:93:10:93:10 | x | test.cpp:92:15:92:16 | 10 | IR only |
|
||||
| test.cpp:105:11:105:12 | (Base *)... | test.cpp:105:11:105:12 | (Base *)... | AST only |
|
||||
| test.cpp:105:11:105:12 | (Base *)... | test.cpp:106:14:106:35 | static_cast<Base *>... | AST only |
|
||||
| test.cpp:105:11:105:12 | (Base *)... | test.cpp:107:11:107:12 | pb | AST only |
|
||||
| test.cpp:105:11:105:12 | pd | test.cpp:107:11:107:12 | pb | IR only |
|
||||
| test.cpp:106:14:106:35 | static_cast<Base *>... | test.cpp:105:11:105:12 | (Base *)... | AST only |
|
||||
| test.cpp:106:14:106:35 | static_cast<Base *>... | test.cpp:106:14:106:35 | static_cast<Base *>... | AST only |
|
||||
| test.cpp:106:14:106:35 | static_cast<Base *>... | test.cpp:107:11:107:12 | pb | AST only |
|
||||
| test.cpp:106:33:106:34 | pd | test.cpp:107:11:107:12 | pb | IR only |
|
||||
| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | (Base *)... | AST only |
|
||||
| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | pd | IR only |
|
||||
| test.cpp:107:11:107:12 | pb | test.cpp:106:14:106:35 | static_cast<Base *>... | AST only |
|
||||
| test.cpp:107:11:107:12 | pb | test.cpp:106:33:106:34 | pd | IR only |
|
||||
| test.cpp:113:3:113:5 | a | test.cpp:115:3:115:5 | a | IR only |
|
||||
| test.cpp:115:3:115:5 | a | test.cpp:113:3:113:5 | a | IR only |
|
||||
| test.cpp:125:15:125:15 | x | test.cpp:128:7:128:7 | x | AST only |
|
||||
| test.cpp:126:15:126:15 | x | test.cpp:128:7:128:7 | x | AST only |
|
||||
| test.cpp:128:3:128:11 | ... = ... | test.cpp:128:3:128:11 | ... = ... | AST only |
|
||||
| test.cpp:128:7:128:7 | x | test.cpp:125:15:125:15 | x | AST only |
|
||||
| test.cpp:128:7:128:7 | x | test.cpp:126:15:126:15 | x | AST only |
|
||||
| test.cpp:128:11:128:11 | n | test.cpp:129:15:129:15 | x | IR only |
|
||||
| test.cpp:129:15:129:15 | x | test.cpp:128:11:128:11 | n | IR only |
|
||||
| test.cpp:136:21:136:21 | x | test.cpp:137:21:137:21 | x | AST only |
|
||||
| test.cpp:136:21:136:21 | x | test.cpp:139:13:139:13 | x | AST only |
|
||||
| test.cpp:137:21:137:21 | x | test.cpp:136:21:136:21 | x | AST only |
|
||||
| test.cpp:137:21:137:21 | x | test.cpp:139:13:139:13 | x | AST only |
|
||||
| test.cpp:139:3:139:24 | ... = ... | test.cpp:139:3:139:24 | ... = ... | AST only |
|
||||
| test.cpp:139:13:139:13 | x | test.cpp:136:21:136:21 | x | AST only |
|
||||
| test.cpp:139:13:139:13 | x | test.cpp:137:21:137:21 | x | AST only |
|
||||
| test.cpp:144:15:144:15 | x | test.cpp:149:15:149:15 | x | IR only |
|
||||
| test.cpp:145:15:145:15 | y | test.cpp:147:7:147:7 | y | AST only |
|
||||
| test.cpp:147:3:147:18 | ... = ... | test.cpp:147:3:147:18 | ... = ... | AST only |
|
||||
| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only |
|
||||
| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only |
|
||||
| test.cpp:153:21:153:21 | x | test.cpp:154:21:154:21 | x | AST only |
|
||||
| test.cpp:154:21:154:21 | x | test.cpp:153:21:153:21 | x | AST only |
|
||||
| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only |
|
||||
|
||||
@@ -12,6 +12,5 @@
|
||||
| test.cpp:46:2:46:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
|
||||
| test.cpp:47:2:47:9 | call to strcpy_s | Potentially unsafe call to strcpy_s; second argument should be size of destination. |
|
||||
| test.cpp:60:3:60:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
|
||||
| test.cpp:63:3:63:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
|
||||
| test.cpp:68:2:68:8 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
|
||||
| test.cpp:79:3:79:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
|
||||
| test.cpp:82:3:82:9 | call to strncpy | Potentially unsafe call to strncpy; third argument should be size of destination. |
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
| tests.c:28:3:28:9 | call to sprintf | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
|
||||
| tests.c:29:3:29:9 | call to sprintf | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
|
||||
| tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
|
||||
| tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
|
||||
| tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
|
||||
| tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
|
||||
| tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
|
||||
| tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
|
||||
| tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 |
|
||||
| tests.c:34:25:34:33 | buffer100 | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
| test1.c:18:16:18:16 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value |
|
||||
| test1.c:33:11:33:11 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value |
|
||||
| test1.c:37:11:37:11 | i | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value |
|
||||
| test1.c:53:15:53:15 | j | $@ flows to here and is used in an array indexing expression, potentially causing an invalid access. | test1.c:8:16:8:19 | argv | User-provided value |
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||
|
||||
@@ -51,7 +51,7 @@ void decode(char *dest, char *src);
|
||||
void wdecode(wchar_t *dest, wchar_t *src);
|
||||
|
||||
void bad4(char *str) {
|
||||
// BAD -- zero-termination proved by wprintf (as parameter) [NOT DETECTED]
|
||||
// BAD -- zero-termination proved by wprintf (as parameter)
|
||||
char *buffer = (char *)malloc(strlen(str));
|
||||
decode(buffer, str);
|
||||
wprintf(L"%s", buffer);
|
||||
@@ -107,3 +107,19 @@ void bad9(wchar_t *wstr) {
|
||||
wcscpy(wbuffer, wstr);
|
||||
delete wbuffer;
|
||||
}
|
||||
|
||||
void good3(char *str) {
|
||||
// GOOD -- zero-termination not required for this printf
|
||||
char *buffer = (char *)malloc(strlen(str));
|
||||
decode(buffer, str);
|
||||
wprintf(L"%p", buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void good4(char *str) {
|
||||
// GOOD -- zero-termination not required for this printf
|
||||
char *buffer = (char *)malloc(strlen(str));
|
||||
decode(buffer, str);
|
||||
wprintf(L"%.*s", strlen(str), buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,7 @@
|
||||
| argvLocal.c:132:15:132:20 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:136:15:136:18 | -- ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:139:9:139:26 | ... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:140:15:140:32 | ... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:144:9:144:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
||||
| argvLocal.c:145:15:145:16 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
||||
| argvLocal.c:150:9:150:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:149:15:149:18 | argv | argv |
|
||||
| argvLocal.c:151:15:151:16 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:149:15:149:18 | argv | argv |
|
||||
| argvLocal.c:156:9:156:10 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:155:23:155:26 | argv | argv |
|
||||
| argvLocal.c:157:15:157:16 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:155:23:155:26 | argv | argv |
|
||||
| argvLocal.c:162:9:162:11 | i91 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:161:42:161:45 | argv | argv |
|
||||
| argvLocal.c:163:15:163:17 | i91 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:161:42:161:45 | argv | argv |
|
||||
| argvLocal.c:167:18:167:20 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:166:18:166:21 | argv | argv |
|
||||
| argvLocal.c:168:24:168:26 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:166:18:166:21 | argv | argv |
|
||||
|
||||
@@ -3,6 +3,3 @@
|
||||
| funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:13:31:17 | call to fgets | fgets |
|
||||
| funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:36:7:36:8 | i5 | gets |
|
||||
| funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:13:41:16 | call to gets | gets |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:46:7:46:9 | * ... | gets |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:52:8:52:11 | call to gets | gets |
|
||||
| funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| ifs.c:62:9:62:10 | c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:61:8:61:11 | argv | argv |
|
||||
| ifs.c:69:9:69:10 | c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:68:8:68:11 | argv | argv |
|
||||
| ifs.c:75:9:75:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:74:8:74:11 | argv | argv |
|
||||
| ifs.c:81:9:81:10 | i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:80:8:80:11 | argv | argv |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
| test.cpp:42:31:42:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:43:31:43:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:45:31:45:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:48:25:48:30 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:49:17:49:30 | new[] | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:52:21:52:27 | call to realloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:52:35:52:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:55:11:55:24 | new[] | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
| test.c:17:10:17:12 | min | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:8:9:8:15 | 2147483647 | Extreme value |
|
||||
| test.c:48:3:48:5 | sc2 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:47:9:47:16 | - ... | Extreme value |
|
||||
| test.c:50:3:50:5 | sc3 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:49:9:49:16 | 127 | Extreme value |
|
||||
| test.c:56:3:56:5 | sc5 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:54:9:54:16 | 127 | Extreme value |
|
||||
| test.c:59:3:59:5 | sc6 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:58:9:58:16 | 127 | Extreme value |
|
||||
| test.c:63:3:63:5 | sc8 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:62:9:62:16 | - ... | Extreme value |
|
||||
| test.c:75:3:75:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
|
||||
|
||||
@@ -8,4 +8,3 @@
|
||||
| test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | ... ^ ... | Uncontrolled value |
|
||||
| test.c:100:5:100:5 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:99:14:99:19 | call to rand | Uncontrolled value |
|
||||
| test.cpp:25:7:25:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | Uncontrolled value |
|
||||
| test.cpp:37:7:37:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | Uncontrolled value |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
| test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... |
|
||||
| test.cpp:41:10:41:38 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:42:8:42:26 | ... = ... | ... = ... |
|
||||
|
||||
Reference in New Issue
Block a user