mirror of
https://github.com/github/codeql.git
synced 2026-05-05 05:35:13 +02:00
C++: Fix global variable flow for array types.
This commit is contained in:
@@ -645,6 +645,24 @@ class GlobalLikeVariable extends Variable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest indirection for the type `t`.
|
||||
*
|
||||
* For most types this is `1`, but for `ArrayType`s (which are allocated on
|
||||
* the stack) this is `0`
|
||||
*/
|
||||
int getMinIndirectionsForType(Type t) {
|
||||
if t.getUnspecifiedType() instanceof Cpp::ArrayType then result = 0 else result = 1
|
||||
}
|
||||
|
||||
private int getMinIndirectionForGlobalUse(Ssa::GlobalUse use) {
|
||||
result = getMinIndirectionsForType(use.getUnspecifiedType())
|
||||
}
|
||||
|
||||
private int getMinIndirectionForGlobalDef(Ssa::GlobalDef def) {
|
||||
result = getMinIndirectionsForType(def.getUnspecifiedType())
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -656,7 +674,7 @@ predicate jumpStep(Node n1, Node n2) {
|
||||
v = globalUse.getVariable() and
|
||||
n1.(FinalGlobalValue).getGlobalUse() = globalUse
|
||||
|
|
||||
globalUse.getIndirection() = 1 and
|
||||
globalUse.getIndirection() = getMinIndirectionForGlobalUse(globalUse) and
|
||||
v = n2.asVariable()
|
||||
or
|
||||
v = n2.asIndirectVariable(globalUse.getIndirection())
|
||||
@@ -666,7 +684,7 @@ predicate jumpStep(Node n1, Node n2) {
|
||||
v = globalDef.getVariable() and
|
||||
n2.(InitialGlobalValue).getGlobalDef() = globalDef
|
||||
|
|
||||
globalDef.getIndirection() = 1 and
|
||||
globalDef.getIndirection() = getMinIndirectionForGlobalDef(globalDef) and
|
||||
v = n1.asVariable()
|
||||
or
|
||||
v = n1.asIndirectVariable(globalDef.getIndirection())
|
||||
|
||||
@@ -34,7 +34,8 @@ cached
|
||||
private newtype TIRDataFlowNode =
|
||||
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
|
||||
TVariableNode(Variable var, int indirectionIndex) {
|
||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
indirectionIndex =
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
} or
|
||||
TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) {
|
||||
indirectionIndex =
|
||||
@@ -346,7 +347,9 @@ 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() {
|
||||
this = TVariableNode(result, getMinIndirectionsForType(result.getUnspecifiedType()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `indirectionIndex`'th indirection of this node's underlying variable, if any.
|
||||
@@ -354,7 +357,7 @@ class Node extends TIRDataFlowNode {
|
||||
* This can be used for modeling flow in and out of global variables.
|
||||
*/
|
||||
Variable asIndirectVariable(int indirectionIndex) {
|
||||
indirectionIndex > 1 and
|
||||
indirectionIndex > getMinIndirectionsForType(result.getUnspecifiedType()) and
|
||||
this = TVariableNode(result, indirectionIndex)
|
||||
}
|
||||
|
||||
|
||||
@@ -872,7 +872,7 @@ private module Cached {
|
||||
upper = countIndirectionsForCppType(type) and
|
||||
ind = ind0 + [lower .. upper] and
|
||||
indirectionIndex = ind - (ind0 + lower) and
|
||||
(if type.hasType(any(Cpp::ArrayType arrayType), true) then lower = 0 else lower = 1)
|
||||
lower = getMinIndirectionsForType(any(Type t | type.hasUnspecifiedType(t, _)))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user