Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

27 cppnon constant format bug local #29

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,26 @@ class GlobalLikeVariable extends Variable {
}
}

/**
* Returns the smallest indirection for `use`.
*
* For most types this is `1`, but for `ArrayType`s (which are allocated on
* the stack) this is `0`
*/
private int getLowerForGlobalUse(Ssa::GlobalUse use) {
if use.getUnspecifiedType() instanceof Cpp::ArrayType then result = 0 else result = 1
}

/**
* Returns the smallest indirection for `def`.
*
* For most types this is `1`, but for `ArrayType`s (which are allocated on
* the stack) this is `0`
*/
private int getLowerForGlobalDef(Ssa::GlobalDef def) {
if def.getUnspecifiedType() instanceof Cpp::ArrayType then result = 0 else result = 1
}

/**
* Holds if data can flow from `node1` to `node2` in a way that loses the
* calling context. For example, this would happen with flow through a
Expand All @@ -632,20 +652,20 @@ predicate jumpStep(Node n1, Node n2) {
v = globalUse.getVariable() and
n1.(FinalGlobalValue).getGlobalUse() = globalUse
|
globalUse.getIndirectionIndex() = 1 and
globalUse.getIndirection() = getLowerForGlobalUse(globalUse) and
v = n2.asVariable()
or
v = n2.asIndirectVariable(globalUse.getIndirectionIndex())
v = n2.asIndirectVariable(globalUse.getIndirection())
)
or
exists(Ssa::GlobalDef globalDef |
v = globalDef.getVariable() and
n2.(InitialGlobalValue).getGlobalDef() = globalDef
|
globalDef.getIndirectionIndex() = 1 and
globalDef.getIndirection() = getLowerForGlobalDef(globalDef) and
v = n1.asVariable()
or
v = n1.asIndirectVariable(globalDef.getIndirectionIndex())
v = n1.asIndirectVariable(globalDef.getIndirection())
)
)
}
Expand Down
18 changes: 15 additions & 3 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ cached
private newtype TIRDataFlowNode =
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
TVariableNode(Variable var, int indirectionIndex) {
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
exists(int lower |
if var.getUnspecifiedType() instanceof ArrayType then lower = 0 else lower = 1
|
indirectionIndex = [lower .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
)
} or
TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) {
indirectionIndex =
Expand Down Expand Up @@ -345,15 +349,23 @@ class Node extends TIRDataFlowNode {
* Gets the variable corresponding to this node, if any. This can be used for
* modeling flow in and out of global variables.
*/
Variable asVariable() { this = TVariableNode(result, 1) }
Variable asVariable() {
if result.getUnspecifiedType() instanceof ArrayType
then this = TVariableNode(result, 0)
else this = TVariableNode(result, 1)
}

/**
* Gets the `indirectionIndex`'th indirection of this node's underlying variable, if any.
*
* This can be used for modeling flow in and out of global variables.
*/
Variable asIndirectVariable(int indirectionIndex) {
indirectionIndex > 1 and
(
if result.getUnspecifiedType() instanceof ArrayType
then indirectionIndex > 0
else indirectionIndex > 1
) and
this = TVariableNode(result, indirectionIndex)
}

Expand Down
52 changes: 35 additions & 17 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,12 @@ private newtype TDefOrUseImpl =
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents a final "use" of a global variable to ensure that
// the assignment to a global variable isn't ruled out as dead.
exists(VariableAddressInstruction vai, int defIndex |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isDef(_, _, _, vai, _, defIndex) and
indirectionIndex = [0 .. defIndex] + 1
)
isGlobalUse(v, f, _, indirectionIndex)
} or
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents the initial "definition" of a global variable when entering
// a function body.
exists(VariableAddressInstruction vai |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isUse(_, _, vai, _, indirectionIndex) and
not isDef(_, _, vai.getAUse(), _, _, _)
)
isGlobalDefImpl(v, f, _, indirectionIndex)
} or
TIteratorDef(
Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex
Expand All @@ -150,6 +140,27 @@ private newtype TDefOrUseImpl =
)
}

private predicate isGlobalUse(
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
) {
exists(VariableAddressInstruction vai |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isDef(_, _, _, vai, indirection, indirectionIndex)
)
}

private predicate isGlobalDefImpl(
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
) {
exists(VariableAddressInstruction vai |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isUse(_, _, vai, indirection, indirectionIndex) and
not isDef(_, _, _, vai, _, indirectionIndex)
)
}

private predicate unspecifiedTypeIsModifiableAt(Type unspecified, int indirectionIndex) {
indirectionIndex = [1 .. getIndirectionForUnspecifiedType(unspecified).getNumberOfIndirections()] and
exists(CppType cppType |
Expand Down Expand Up @@ -438,7 +449,7 @@ class GlobalUse extends UseImpl, TGlobalUse {

override FinalGlobalValue getNode() { result.getGlobalUse() = this }

override int getIndirection() { result = ind + 1 }
override int getIndirection() { isGlobalUse(global, f, result, ind) }

/** Gets the global variable associated with this use. */
GlobalLikeVariable getVariable() { result = global }
Expand All @@ -460,7 +471,9 @@ class GlobalUse extends UseImpl, TGlobalUse {
)
}

override SourceVariable getSourceVariable() { sourceVariableIsGlobal(result, global, f, ind) }
override SourceVariable getSourceVariable() {
sourceVariableIsGlobal(result, global, f, this.getIndirection())
}

final override Cpp::Location getLocation() { result = f.getLocation() }

Expand Down Expand Up @@ -501,16 +514,18 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {

/** Gets the global variable associated with this definition. */
override SourceVariable getSourceVariable() {
sourceVariableIsGlobal(result, global, f, indirectionIndex)
sourceVariableIsGlobal(result, global, f, this.getIndirection())
}

int getIndirection() { result = indirectionIndex }

/**
* Gets the type of this use after specifiers have been deeply stripped
* and typedefs have been resolved.
*/
Type getUnspecifiedType() { result = global.getUnspecifiedType() }

override string toString() { result = "GlobalDef" }
override string toString() { result = "Def of " + this.getSourceVariable() }

override Location getLocation() { result = f.getLocation() }

Expand Down Expand Up @@ -980,7 +995,7 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
final override Location getLocation() { result = global.getLocation() }

/** Gets a textual representation of this definition. */
override string toString() { result = "GlobalDef" }
override string toString() { result = global.toString() }

/**
* Holds if this definition has index `index` in block `block`, and
Expand All @@ -990,6 +1005,9 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
global.hasIndexInBlock(block, index, sv)
}

/** Gets the indirection index of this definition. */
int getIndirection() { result = global.getIndirection() }

/** Gets the indirection index of this definition. */
int getIndirectionIndex() { result = global.getIndirectionIndex() }

Expand Down
Loading