@@ -525,11 +525,6 @@ private predicate getFieldSizeOfClass(Class c, Type type, int size) {
525525 )
526526}
527527
528- private predicate initializeParameterOfType ( InitializeIndirectionInstruction init , Type type ) {
529- init .getParameter ( ) .getType ( ) .getUnspecifiedType ( ) .( DerivedType ) .getBaseType ( ) =
530- type .getUnspecifiedType ( )
531- }
532-
533528private predicate isSingleFieldClass ( Type type , Class cTo ) {
534529 exists ( int size |
535530 cTo .getSize ( ) = size and
@@ -545,12 +540,27 @@ private predicate simpleOperandLocalFlowStep(Instruction iFrom, Operand opTo) {
545540 not iFrom .isResultConflated ( ) and
546541 iFrom = opTo .getAnyDef ( )
547542 or
543+ // Loading a single `int` from an `int *` parameter is not an exact load since
544+ // the parameter may point to an entire array rather than a single `int`. The
545+ // following rule ensures that any flow going into the
546+ // `InitializeIndirectionInstruction`, even if it's for a different array
547+ // element, will propagate to a load of the first element.
548+ //
549+ // Since we're linking `InitializeIndirectionInstruction` and
550+ // `LoadInstruction` together directly, this rule will break if there's any
551+ // reassignment of the parameter indirection, including a conditional one that
552+ // leads to a phi node.
548553 exists ( InitializeIndirectionInstruction init |
549554 iFrom = init and
550555 opTo .( LoadOperand ) .getAnyDef ( ) = init and
551- initializeParameterOfType ( init , opTo .getType ( ) )
556+ // Check that the types match. Otherwise we can get flow from an object to
557+ // its fields, which leads to field conflation when there's flow from other
558+ // fields to the object elsewhere.
559+ init .getParameter ( ) .getType ( ) .getUnspecifiedType ( ) .( DerivedType ) .getBaseType ( ) =
560+ opTo .getType ( ) .getUnspecifiedType ( )
552561 )
553562 or
563+ // Flow from stores to structs with a single field to a load of that field.
554564 exists ( LoadInstruction load |
555565 load .getSourceValueOperand ( ) = opTo and
556566 opTo .getAnyDef ( ) = iFrom and
@@ -568,25 +578,6 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
568578 // much memory the callee will read.
569579 iTo .( ReadSideEffectInstruction ) .getSideEffectOperand ( ) = opFrom
570580 or
571- // Loading a single `int` from an `int *` parameter is not an exact load since
572- // the parameter may point to an entire array rather than a single `int`. The
573- // following rule ensures that any flow going into the
574- // `InitializeIndirectionInstruction`, even if it's for a different array
575- // element, will propagate to a load of the first element.
576- //
577- // Since we're linking `InitializeIndirectionInstruction` and
578- // `LoadInstruction` together directly, this rule will break if there's any
579- // reassignment of the parameter indirection, including a conditional one that
580- // leads to a phi node.
581- exists ( InitializeIndirectionInstruction init |
582- opFrom .getAnyDef ( ) = init and
583- iTo .( LoadInstruction ) .getSourceValueOperand ( ) = opFrom and
584- // Check that the types match. Otherwise we can get flow from an object to
585- // its fields, which leads to field conflation when there's flow from other
586- // fields to the object elsewhere.
587- initializeParameterOfType ( init , iTo .getResultType ( ) )
588- )
589- or
590581 // Treat all conversions as flow, even conversions between different numeric types.
591582 iTo .( ConvertInstruction ) .getUnaryOperand ( ) = opFrom
592583 or
@@ -625,10 +616,6 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
625616 not chi .isResultConflated ( )
626617 )
627618 or
628- // Flow from stores to structs with a single field to a load of that field.
629- iTo .( LoadInstruction ) .getSourceValueOperand ( ) = opFrom and
630- isSingleFieldClass ( opFrom .getAnyDef ( ) .getResultType ( ) , iTo .getResultType ( ) )
631- or
632619 // Flow through modeled functions
633620 modelFlow ( opFrom , iTo )
634621}
0 commit comments