Skip to content

Commit ee7b137

Browse files
committed
C++: Add dataflow for static locals.
1 parent 3eca60c commit ee7b137

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,21 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
607607
result.getReturnKind() = kind
608608
}
609609

610+
/** A variable that behaves like a global variable. */
611+
class GlobalLikeVariable extends Variable {
612+
GlobalLikeVariable() {
613+
this instanceof Cpp::GlobalOrNamespaceVariable or
614+
this instanceof Cpp::StaticLocalVariable
615+
}
616+
}
617+
610618
/**
611619
* Holds if data can flow from `node1` to `node2` in a way that loses the
612620
* calling context. For example, this would happen with flow through a
613621
* global or static variable.
614622
*/
615623
predicate jumpStep(Node n1, Node n2) {
616-
exists(Cpp::GlobalOrNamespaceVariable v |
624+
exists(GlobalLikeVariable v |
617625
exists(Ssa::GlobalUse globalUse |
618626
v = globalUse.getVariable() and
619627
n1.(FinalGlobalValue).getGlobalUse() = globalUse

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,14 @@ private newtype TDefOrUseImpl =
145145
or
146146
// Since the pruning stage doesn't know about global variables we can't use the above check to
147147
// rule out dead assignments to globals.
148-
base.(VariableAddressInstruction).getAstVariable() instanceof Cpp::GlobalOrNamespaceVariable
148+
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
149149
)
150150
} or
151151
TUseImpl(Operand operand, int indirectionIndex) {
152152
isUse(_, operand, _, _, indirectionIndex) and
153153
not isDef(_, _, operand, _, _, _)
154154
} or
155-
TGlobalUse(Cpp::GlobalOrNamespaceVariable v, IRFunction f, int indirectionIndex) {
155+
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
156156
// Represents a final "use" of a global variable to ensure that
157157
// the assignment to a global variable isn't ruled out as dead.
158158
exists(VariableAddressInstruction vai, int defIndex |
@@ -162,7 +162,7 @@ private newtype TDefOrUseImpl =
162162
indirectionIndex = [0 .. defIndex] + 1
163163
)
164164
} or
165-
TGlobalDefImpl(Cpp::GlobalOrNamespaceVariable v, IRFunction f, int indirectionIndex) {
165+
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
166166
// Represents the initial "definition" of a global variable when entering
167167
// a function body.
168168
exists(VariableAddressInstruction vai |
@@ -458,7 +458,7 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
458458
}
459459

460460
class GlobalUse extends UseImpl, TGlobalUse {
461-
Cpp::GlobalOrNamespaceVariable global;
461+
GlobalLikeVariable global;
462462
IRFunction f;
463463

464464
GlobalUse() { this = TGlobalUse(global, f, ind) }
@@ -468,7 +468,7 @@ class GlobalUse extends UseImpl, TGlobalUse {
468468
override int getIndirection() { result = ind + 1 }
469469

470470
/** Gets the global variable associated with this use. */
471-
Cpp::GlobalOrNamespaceVariable getVariable() { result = global }
471+
GlobalLikeVariable getVariable() { result = global }
472472

473473
/** Gets the `IRFunction` whose body is exited from after this use. */
474474
IRFunction getIRFunction() { result = f }
@@ -496,14 +496,14 @@ class GlobalUse extends UseImpl, TGlobalUse {
496496
}
497497

498498
class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
499-
Cpp::GlobalOrNamespaceVariable global;
499+
GlobalLikeVariable global;
500500
IRFunction f;
501501
int indirectionIndex;
502502

503503
GlobalDefImpl() { this = TGlobalDefImpl(global, f, indirectionIndex) }
504504

505505
/** Gets the global variable associated with this definition. */
506-
Cpp::GlobalOrNamespaceVariable getVariable() { result = global }
506+
GlobalLikeVariable getVariable() { result = global }
507507

508508
/** Gets the `IRFunction` whose body is evaluated after this definition. */
509509
IRFunction getIRFunction() { result = f }
@@ -760,7 +760,7 @@ private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) {
760760
}
761761

762762
private predicate sourceVariableIsGlobal(
763-
SourceVariable sv, Cpp::GlobalOrNamespaceVariable global, IRFunction func, int indirectionIndex
763+
SourceVariable sv, GlobalLikeVariable global, IRFunction func, int indirectionIndex
764764
) {
765765
exists(IRVariable irVar, BaseIRVariable base |
766766
sourceVariableHasBaseAndIndex(sv, base, indirectionIndex) and
@@ -919,7 +919,7 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
919919
IRFunction getIRFunction() { result = global.getIRFunction() }
920920

921921
/** Gets the global variable associated with this definition. */
922-
Cpp::GlobalOrNamespaceVariable getVariable() { result = global.getVariable() }
922+
GlobalLikeVariable getVariable() { result = global.getVariable() }
923923
}
924924

925925
class Phi extends TPhi, SsaDefOrUse {

0 commit comments

Comments
 (0)