@@ -144,7 +144,7 @@ private newtype TDefOrUseImpl =
144144 indirectionIndex = [ 0 .. defIndex ] + 1
145145 )
146146 } or
147- TGlobalDef ( Cpp:: GlobalOrNamespaceVariable v , IRFunction f , int indirectionIndex ) {
147+ TGlobalDefImpl ( Cpp:: GlobalOrNamespaceVariable v , IRFunction f , int indirectionIndex ) {
148148 // Represents the initial "definition" of a global variable when entering
149149 // a function body.
150150 exists ( VariableAddressInstruction vai |
@@ -475,12 +475,12 @@ class GlobalUse extends UseImpl, TGlobalUse {
475475 override BaseSourceVariableInstruction getBase ( ) { none ( ) }
476476}
477477
478- class GlobalDef extends TGlobalDef {
478+ class GlobalDefImpl extends DefOrUseImpl , TGlobalDefImpl {
479479 Cpp:: GlobalOrNamespaceVariable global ;
480480 IRFunction f ;
481481 int indirectionIndex ;
482482
483- GlobalDef ( ) { this = TGlobalDef ( global , f , indirectionIndex ) }
483+ GlobalDefImpl ( ) { this = TGlobalDefImpl ( global , f , indirectionIndex ) }
484484
485485 /** Gets the global variable associated with this definition. */
486486 Cpp:: GlobalOrNamespaceVariable getVariable ( ) { result = global }
@@ -489,43 +489,32 @@ class GlobalDef extends TGlobalDef {
489489 IRFunction getIRFunction ( ) { result = f }
490490
491491 /** Gets the global variable associated with this definition. */
492- int getIndirectionIndex ( ) { result = indirectionIndex }
492+ override int getIndirectionIndex ( ) { result = indirectionIndex }
493493
494494 /** Holds if this definition or use has index `index` in block `block`. */
495- final predicate hasIndexInBlock ( IRBlock block , int index ) {
495+ final override predicate hasIndexInBlock ( IRBlock block , int index ) {
496496 exists ( EnterFunctionInstruction enter |
497497 enter = f .getEnterFunctionInstruction ( ) and
498498 block .getInstruction ( index ) = enter
499499 )
500500 }
501501
502502 /** Gets the global variable associated with this definition. */
503- SourceVariable getSourceVariable ( ) { sourceVariableIsGlobal ( result , global , f , indirectionIndex ) }
504-
505- /**
506- * Holds if this definition has index `index` in block `block`, and
507- * is a definition of the variable `sv`
508- */
509- final predicate hasIndexInBlock ( IRBlock block , int index , SourceVariable sv ) {
510- this .hasIndexInBlock ( block , index ) and
511- sv = this .getSourceVariable ( )
512- }
513-
514- /** Gets the location of this element. */
515- final Cpp:: Location getLocation ( ) { result = f .getLocation ( ) }
516-
517- /** Gets a textual representation of this element. */
518- string toString ( ) {
519- if indirectionIndex = 0
520- then result = global .toString ( )
521- else result = global .toString ( ) + " indirection"
503+ override SourceVariable getSourceVariable ( ) {
504+ sourceVariableIsGlobal ( result , global , f , indirectionIndex )
522505 }
523506
524507 /**
525508 * Gets the type of this use after specifiers have been deeply stripped
526509 * and typedefs have been resolved.
527510 */
528511 Type getUnspecifiedType ( ) { result = global .getUnspecifiedType ( ) }
512+
513+ override string toString ( ) { result = "GlobalDef" }
514+
515+ override Location getLocation ( ) { result = f .getLocation ( ) }
516+
517+ override BaseSourceVariableInstruction getBase ( ) { none ( ) }
529518}
530519
531520/**
@@ -641,33 +630,31 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
641630 * So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the
642631 * first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`.
643632 */
644- private predicate adjustForPointerArith ( Node nodeFrom , UseOrPhi use , boolean uncertain ) {
633+ private predicate adjustForPointerArith (
634+ DefOrUse defOrUse , Node nodeFrom , UseOrPhi use , boolean uncertain
635+ ) {
645636 nodeFrom = any ( PostUpdateNode pun ) .getPreUpdateNode ( ) and
646- exists ( DefOrUse defOrUse , Node adjusted |
637+ exists ( Node adjusted |
647638 indirectConversionFlowStep * ( adjusted , nodeFrom ) and
648639 nodeToDefOrUse ( adjusted , defOrUse , uncertain ) and
649640 adjacentDefRead ( defOrUse , use )
650641 )
651642}
652643
653- private predicate ssaFlowImpl ( Node nodeFrom , Node nodeTo , boolean uncertain ) {
644+ private predicate ssaFlowImpl ( SsaDefOrUse defOrUse , Node nodeFrom , Node nodeTo , boolean uncertain ) {
654645 // `nodeFrom = any(PostUpdateNode pun).getPreUpdateNode()` is implied by adjustedForPointerArith.
655646 exists ( UseOrPhi use |
656- adjustForPointerArith ( nodeFrom , use , uncertain ) and
647+ adjustForPointerArith ( defOrUse , nodeFrom , use , uncertain ) and
657648 useToNode ( use , nodeTo )
658- )
659- or
660- not nodeFrom = any ( PostUpdateNode pun ) .getPreUpdateNode ( ) and
661- exists ( DefOrUse defOrUse1 , UseOrPhi use |
662- nodeToDefOrUse ( nodeFrom , defOrUse1 , uncertain ) and
663- adjacentDefRead ( defOrUse1 , use ) and
649+ or
650+ not nodeFrom = any ( PostUpdateNode pun ) .getPreUpdateNode ( ) and
651+ nodeToDefOrUse ( nodeFrom , defOrUse , uncertain ) and
652+ adjacentDefRead ( defOrUse , use ) and
664653 useToNode ( use , nodeTo )
665- )
666- or
667- // Initial global variable value to a first use
668- exists ( GlobalDef globalDef , UseOrPhi use |
669- nodeFrom .( InitialGlobalValue ) .getGlobalDef ( ) = globalDef and
670- globalDefToUse ( globalDef , use ) and
654+ or
655+ // Initial global variable value to a first use
656+ nodeFrom .( InitialGlobalValue ) .getGlobalDef ( ) = defOrUse and
657+ globalDefToUse ( defOrUse , use ) and
671658 useToNode ( use , nodeTo ) and
672659 uncertain = false
673660 )
@@ -677,29 +664,28 @@ private predicate ssaFlowImpl(Node nodeFrom, Node nodeTo, boolean uncertain) {
677664 * Holds if `def` is the corresponding definition of
678665 * the SSA library's `definition`.
679666 */
680- private predicate ssaDefinition ( Def def , Definition definition ) {
667+ private Definition ssaDefinition ( Def def ) {
681668 exists ( IRBlock block , int i , SourceVariable sv |
682669 def .hasIndexInBlock ( block , i , sv ) and
683- definition .definesAt ( sv , block , i )
670+ result .definesAt ( sv , block , i )
684671 )
685672}
686673
687674/** Gets a node that represents the prior definition of `node`. */
688- private Node getAPriorDefinition ( Node node ) {
689- exists ( Def def , Definition definition , Definition inp , Def input |
690- defToNode ( node , def , true ) and
691- ssaDefinition ( def , definition ) and
692- uncertainWriteDefinitionInput ( pragma [ only_bind_into ] ( definition ) , pragma [ only_bind_into ] ( inp ) ) and
693- ssaDefinition ( input , inp ) and
694- defToNode ( result , input , _)
675+ private Node getAPriorDefinition ( SsaDefOrUse defOrUse ) {
676+ exists ( IRBlock bb , int i , SourceVariable sv , Definition def , DefOrUse defOrUse0 |
677+ SsaCached:: lastRefRedef ( def , bb , i , ssaDefinition ( defOrUse ) ) and
678+ def .getSourceVariable ( ) = sv and
679+ defOrUse0 .hasIndexInBlock ( bb , i , sv ) and
680+ nodeToDefOrUse ( result , defOrUse0 , _)
695681 )
696682}
697683
698684/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
699685predicate ssaFlow ( Node nodeFrom , Node nodeTo ) {
700- exists ( Node nFrom , boolean uncertain |
701- ssaFlowImpl ( nFrom , nodeTo , uncertain ) and
702- if uncertain = true then nodeFrom = [ nFrom , getAPriorDefinition ( nFrom ) ] else nodeFrom = nFrom
686+ exists ( Node nFrom , boolean uncertain , SsaDefOrUse defOrUse |
687+ ssaFlowImpl ( defOrUse , nFrom , nodeTo , uncertain ) and
688+ if uncertain = true then nodeFrom = [ nFrom , getAPriorDefinition ( defOrUse ) ] else nodeFrom = nFrom
703689 )
704690}
705691
@@ -774,7 +760,7 @@ private module SsaInput implements SsaImplCommon::InputSig {
774760 if def .isCertain ( ) then certain = true else certain = false
775761 )
776762 or
777- exists ( GlobalDef global |
763+ exists ( GlobalDefImpl global |
778764 global .hasIndexInBlock ( bb , i , v ) and
779765 certain = true
780766 )
@@ -839,15 +825,20 @@ private newtype TSsaDefOrUse =
839825 defOrUse .( DefImpl ) .hasIndexInBlock ( bb , i , sv )
840826 )
841827 } or
842- TPhi ( PhiNode phi )
828+ TPhi ( PhiNode phi ) or
829+ TGlobalDef ( GlobalDefImpl global )
843830
844831abstract private class SsaDefOrUse extends TSsaDefOrUse {
832+ /** Gets a textual representation of this element. */
845833 string toString ( ) { none ( ) }
846834
835+ /** Gets the underlying non-phi definition or use. */
847836 DefOrUseImpl asDefOrUse ( ) { none ( ) }
848837
838+ /** Gets the underlying phi node. */
849839 PhiNode asPhi ( ) { none ( ) }
850840
841+ /** Gets the location of this element. */
851842 abstract Location getLocation ( ) ;
852843}
853844
@@ -864,11 +855,50 @@ class DefOrUse extends TDefOrUse, SsaDefOrUse {
864855
865856 override string toString ( ) { result = defOrUse .toString ( ) }
866857
858+ /**
859+ * Holds if this definition (or use) has index `index` in block `block`,
860+ * and is a definition (or use) of the variable `sv`.
861+ */
867862 predicate hasIndexInBlock ( IRBlock block , int index , SourceVariable sv ) {
868863 defOrUse .hasIndexInBlock ( block , index , sv )
869864 }
870865}
871866
867+ class GlobalDef extends TGlobalDef , SsaDefOrUse {
868+ GlobalDefImpl global ;
869+
870+ GlobalDef ( ) { this = TGlobalDef ( global ) }
871+
872+ /** Gets the location of this definition. */
873+ final override Location getLocation ( ) { result = global .getLocation ( ) }
874+
875+ /** Gets a textual representation of this definition. */
876+ override string toString ( ) { result = "GlobalDef" }
877+
878+ /**
879+ * Holds if this definition has index `index` in block `block`, and
880+ * is a definition of the variable `sv`.
881+ */
882+ predicate hasIndexInBlock ( IRBlock block , int index , SourceVariable sv ) {
883+ global .hasIndexInBlock ( block , index , sv )
884+ }
885+
886+ /** Gets the indirection index of this definition. */
887+ int getIndirectionIndex ( ) { result = global .getIndirectionIndex ( ) }
888+
889+ /**
890+ * Gets the type of this definition after specifiers have been deeply stripped
891+ * and typedefs have been resolved.
892+ */
893+ DataFlowType getUnspecifiedType ( ) { result = global .getUnspecifiedType ( ) }
894+
895+ /** Gets the `IRFunction` whose body is evaluated after this definition. */
896+ IRFunction getIRFunction ( ) { result = global .getIRFunction ( ) }
897+
898+ /** Gets the global variable associated with this definition. */
899+ Cpp:: GlobalOrNamespaceVariable getVariable ( ) { result = global .getVariable ( ) }
900+ }
901+
872902class Phi extends TPhi , SsaDefOrUse {
873903 PhiNode phi ;
874904
0 commit comments