@@ -525,20 +525,48 @@ 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+
533+ private predicate isSingleFieldClass ( Type type , Class cTo ) {
534+ exists ( int size |
535+ cTo .getSize ( ) = size and
536+ getFieldSizeOfClass ( cTo , type , size )
537+ )
538+ }
539+
528540private predicate simpleOperandLocalFlowStep ( Instruction iFrom , Operand opTo ) {
529- opTo .getAnyDef ( ) = iFrom
541+ // Propagate flow from an instruction to its exact uses.
542+ opTo .getDef ( ) = iFrom
543+ or
544+ opTo = any ( ReadSideEffectInstruction read ) .getSideEffectOperand ( ) and
545+ not iFrom .isResultConflated ( ) and
546+ iFrom = opTo .getAnyDef ( )
547+ or
548+ exists ( InitializeIndirectionInstruction init |
549+ iFrom = init and
550+ opTo .( LoadOperand ) .getAnyDef ( ) = init and
551+ initializeParameterOfType ( init , opTo .getType ( ) )
552+ )
553+ or
554+ exists ( LoadInstruction load |
555+ load .getSourceValueOperand ( ) = opTo and
556+ opTo .getAnyDef ( ) = iFrom and
557+ isSingleFieldClass ( iFrom .getResultType ( ) , opTo .getType ( ) )
558+ )
530559}
531560
532561cached
533562private predicate simpleInstructionLocalFlowStep ( Operand opFrom , Instruction iTo ) {
534- iTo .( CopyInstruction ) .getSourceValueOperand ( ) = opFrom and not opFrom . isDefinitionInexact ( )
563+ iTo .( CopyInstruction ) .getSourceValueOperand ( ) = opFrom
535564 or
536- iTo .( PhiInstruction ) .getAnInputOperand ( ) = opFrom and not opFrom . isDefinitionInexact ( )
565+ iTo .( PhiInstruction ) .getAnInputOperand ( ) = opFrom
537566 or
538567 // A read side effect is almost never exact since we don't know exactly how
539568 // much memory the callee will read.
540- iTo .( ReadSideEffectInstruction ) .getSideEffectOperand ( ) = opFrom and
541- not opFrom .getAnyDef ( ) .isResultConflated ( )
569+ iTo .( ReadSideEffectInstruction ) .getSideEffectOperand ( ) = opFrom
542570 or
543571 // Loading a single `int` from an `int *` parameter is not an exact load since
544572 // the parameter may point to an entire array rather than a single `int`. The
@@ -556,18 +584,15 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
556584 // Check that the types match. Otherwise we can get flow from an object to
557585 // its fields, which leads to field conflation when there's flow from other
558586 // fields to the object elsewhere.
559- init .getParameter ( ) .getType ( ) .getUnspecifiedType ( ) .( DerivedType ) .getBaseType ( ) =
560- iTo .getResultType ( ) .getUnspecifiedType ( )
587+ initializeParameterOfType ( init , iTo .getResultType ( ) )
561588 )
562589 or
563590 // Treat all conversions as flow, even conversions between different numeric types.
564- iTo .( ConvertInstruction ) .getUnaryOperand ( ) = opFrom and not opFrom . isDefinitionInexact ( )
591+ iTo .( ConvertInstruction ) .getUnaryOperand ( ) = opFrom
565592 or
566- iTo .( CheckedConvertOrNullInstruction ) .getUnaryOperand ( ) = opFrom and
567- not opFrom .isDefinitionInexact ( )
593+ iTo .( CheckedConvertOrNullInstruction ) .getUnaryOperand ( ) = opFrom
568594 or
569- iTo .( InheritanceConversionInstruction ) .getUnaryOperand ( ) = opFrom and
570- not opFrom .isDefinitionInexact ( )
595+ iTo .( InheritanceConversionInstruction ) .getUnaryOperand ( ) = opFrom
571596 or
572597 // A chi instruction represents a point where a new value (the _partial_
573598 // operand) may overwrite an old value (the _total_ operand), but the alias
@@ -602,12 +627,7 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
602627 or
603628 // Flow from stores to structs with a single field to a load of that field.
604629 iTo .( LoadInstruction ) .getSourceValueOperand ( ) = opFrom and
605- exists ( int size , Type type , Class cTo |
606- type = opFrom .getAnyDef ( ) .getResultType ( ) and
607- cTo = iTo .getResultType ( ) and
608- cTo .getSize ( ) = size and
609- getFieldSizeOfClass ( cTo , type , size )
610- )
630+ isSingleFieldClass ( opFrom .getAnyDef ( ) .getResultType ( ) , iTo .getResultType ( ) )
611631 or
612632 // Flow through modeled functions
613633 modelFlow ( opFrom , iTo )
0 commit comments