@@ -324,6 +324,30 @@ private module Cached {
324324 use .hasRankInBlock ( bb2 , i2 ) and
325325 flowOutOfAddressStep ( use .getOperand ( ) , nodeTo )
326326 )
327+ or
328+ // This final case is a bit annoying. The write side effect on an expression like `a = new A;` writes
329+ // to a fresh address returned by `operator new`, and there's no easy way to use the shared SSA
330+ // library to hook that up to the assignment to `a`. So instead we flow to the _first_ use of the
331+ // value computed by `operator new` that occurs after `nodeFrom` (to avoid a loop in the
332+ // dataflow graph).
333+ exists ( WriteSideEffectInstruction write , IRBlock bb , int i1 , int i2 , Operand op |
334+ nodeFrom .getInstruction ( ) .( CallInstruction ) .getStaticCallTarget ( ) instanceof
335+ Alloc:: OperatorNewAllocationFunction and
336+ write = nodeFrom .getStoreInstruction ( ) and
337+ bb .getInstruction ( i1 ) = write and
338+ bb .getInstruction ( i2 ) = op .getUse ( ) and
339+ // Flow to an instruction that occurs later in the block.
340+ valueFlow * ( nodeFrom .getInstruction ( ) , op .getDef ( ) ) and
341+ nodeTo .asOperand ( ) = op and
342+ i2 > i1 and
343+ // There is no previous instruction that also occurs after `nodeFrom`.
344+ not exists ( Instruction instr , int i |
345+ bb .getInstruction ( i ) = instr and
346+ valueFlow ( instr , op .getDef ( ) ) and
347+ i1 < i and
348+ i < i2
349+ )
350+ )
327351 }
328352
329353 private predicate fromReadNode ( ReadNode nodeFrom , Node nodeTo ) {
@@ -402,6 +426,16 @@ private module Cached {
402426 )
403427 }
404428
429+ private predicate valueFlow ( Instruction iFrom , Instruction iTo ) {
430+ iTo .( CopyValueInstruction ) .getSourceValue ( ) = iFrom
431+ or
432+ iTo .( ConvertInstruction ) .getUnary ( ) = iFrom
433+ or
434+ iTo .( CheckedConvertOrNullInstruction ) .getUnary ( ) = iFrom
435+ or
436+ iTo .( InheritanceConversionInstruction ) .getUnary ( ) = iFrom
437+ }
438+
405439 private predicate flowOutOfAddressStep ( Operand operand , Node nTo ) {
406440 // Flow into a read node
407441 exists ( ReadNode readNode | readNode = nTo |
0 commit comments