@@ -59,10 +59,12 @@ class Node extends TIRDataFlowNode {
5959 Parameter asParameter ( ) { result = instr .( InitializeParameterInstruction ) .getParameter ( ) }
6060
6161 /**
62+ * DEPRECATED: See UninitializedNode.
63+ *
6264 * Gets the uninitialized local variable corresponding to this node, if
6365 * any.
6466 */
65- LocalVariable asUninitialized ( ) { result = instr . ( UninitializedInstruction ) . getLocalVariable ( ) }
67+ LocalVariable asUninitialized ( ) { none ( ) }
6668
6769 /**
6870 * Gets an upper bound on the type of this node.
@@ -140,15 +142,19 @@ private class ThisParameterNode extends Node {
140142}
141143
142144/**
145+ * DEPRECATED: Data flow was never an accurate way to determine what
146+ * expressions might be uninitialized. It errs on the side of saying that
147+ * everything is uninitialized, and this is even worse in the IR because the IR
148+ * doesn't use syntactic hints to rule out variables that are definitely
149+ * initialized.
150+ *
143151 * The value of an uninitialized local variable, viewed as a node in a data
144152 * flow graph.
145153 */
146- class UninitializedNode extends Node {
147- override UninitializedInstruction instr ;
148-
149- LocalVariable getLocalVariable ( ) { result = instr .getLocalVariable ( ) }
154+ deprecated class UninitializedNode extends Node {
155+ UninitializedNode ( ) { none ( ) }
150156
151- override string toString ( ) { result = this . getLocalVariable ( ) . toString ( ) }
157+ LocalVariable getLocalVariable ( ) { none ( ) }
152158}
153159
154160/**
@@ -259,7 +265,21 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
259265 iTo .( PhiInstruction ) .getAnOperand ( ) .getDef ( ) = iFrom or
260266 // Treat all conversions as flow, even conversions between different numeric types.
261267 iTo .( ConvertInstruction ) .getUnary ( ) = iFrom or
262- iTo .( InheritanceConversionInstruction ) .getUnary ( ) = iFrom
268+ iTo .( InheritanceConversionInstruction ) .getUnary ( ) = iFrom or
269+ // A chi instruction represents a point where a new value (the _partial_
270+ // operand) may overwrite an old value (the _total_ operand), but the alias
271+ // analysis couldn't determine that it surely will overwrite every bit of it or
272+ // that it surely will overwrite no bit of it.
273+ //
274+ // By allowing flow through the total operand, we ensure that flow is not lost
275+ // due to shortcomings of the alias analysis. We may get false flow in cases
276+ // where the data is indeed overwritten.
277+ //
278+ // Allowing flow through the partial operand would be more noisy, especially
279+ // for variables that have escaped: for soundness, the IR has to assume that
280+ // every write to an unknown address can affect every escaped variable, and
281+ // this assumption shows up as data flowing through partial chi operands.
282+ iTo .getAnOperand ( ) .( ChiTotalOperand ) .getDef ( ) = iFrom
263283}
264284
265285/**
0 commit comments