Skip to content

Commit 398678a

Browse files
author
Dave Bartolomeo
authored
Merge pull request github#3637 from jbj/dispatch-global-perf
C++: Fix data-flow dispatch perf with globals
2 parents 1a7570e + c62220e commit 398678a

File tree

1 file changed

+21
-23
lines changed

1 file changed

+21
-23
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -82,47 +82,45 @@ private module VirtualDispatch {
8282
exists(LoadInstruction load, GlobalOrNamespaceVariable var |
8383
var = src.asVariable() and
8484
other.asInstruction() = load and
85+
addressOfGlobal(load.getSourceAddress(), var) and
8586
// The `allowFromArg` concept doesn't play a role when `src` is a
8687
// global variable, so we just set it to a single arbitrary value for
8788
// performance.
8889
allowFromArg = true
89-
|
90-
// Load directly from the global variable
91-
load.getSourceAddress().(VariableAddressInstruction).getASTVariable() = var
92-
or
93-
// Load from a field on a global union
94-
exists(FieldAddressInstruction fa |
95-
fa = load.getSourceAddress() and
96-
fa.getObjectAddress().(VariableAddressInstruction).getASTVariable() = var and
97-
fa.getField().getDeclaringType() instanceof Union
98-
)
9990
)
10091
or
101-
// Flow from store to global variable. These cases are similar to the
102-
// above but have `StoreInstruction` instead of `LoadInstruction` and
103-
// have the roles swapped between `other` and `src`.
92+
// Flow from store to global variable.
10493
exists(StoreInstruction store, GlobalOrNamespaceVariable var |
10594
var = other.asVariable() and
10695
store = src.asInstruction() and
96+
storeIntoGlobal(store, var) and
10797
// Setting `allowFromArg` to `true` like in the base case means we
10898
// treat a store to a global variable like the dispatch itself: flow
10999
// may come from anywhere.
110100
allowFromArg = true
111-
|
112-
// Store directly to the global variable
113-
store.getDestinationAddress().(VariableAddressInstruction).getASTVariable() = var
114-
or
115-
// Store to a field on a global union
116-
exists(FieldAddressInstruction fa |
117-
fa = store.getDestinationAddress() and
118-
fa.getObjectAddress().(VariableAddressInstruction).getASTVariable() = var and
119-
fa.getField().getDeclaringType() instanceof Union
120-
)
121101
)
122102
)
123103
}
124104
}
125105

106+
pragma[noinline]
107+
private predicate storeIntoGlobal(StoreInstruction store, GlobalOrNamespaceVariable var) {
108+
addressOfGlobal(store.getDestinationAddress(), var)
109+
}
110+
111+
/** Holds if `addressInstr` is an instruction that produces the address of `var`. */
112+
private predicate addressOfGlobal(Instruction addressInstr, GlobalOrNamespaceVariable var) {
113+
// Access directly to the global variable
114+
addressInstr.(VariableAddressInstruction).getASTVariable() = var
115+
or
116+
// Access to a field on a global union
117+
exists(FieldAddressInstruction fa |
118+
fa = addressInstr and
119+
fa.getObjectAddress().(VariableAddressInstruction).getASTVariable() = var and
120+
fa.getField().getDeclaringType() instanceof Union
121+
)
122+
}
123+
126124
/**
127125
* A ReturnNode with its ReturnKind and its enclosing callable.
128126
*

0 commit comments

Comments
 (0)