@@ -55,6 +55,12 @@ signature module InputSig<TypSig BasicBlock> {
5555 */
5656 predicate ssaControlsBranchEdge ( SsaDefinition def , BasicBlock bb1 , BasicBlock bb2 , GuardValue v ) ;
5757
58+ /**
59+ * Holds if `def` evaluating to `v` controls the basic block `bb`.
60+ * That is, execution of `bb` implies that `def` evaluated to `v`.
61+ */
62+ predicate ssaControls ( SsaDefinition def , BasicBlock bb , GuardValue v ) ;
63+
5864 bindingset [ gv1, gv2]
5965 predicate disjointValues ( GuardValue gv1 , GuardValue gv2 ) ;
6066}
@@ -70,23 +76,35 @@ module Make<LocationSig Location, BB::CfgSig<Location> Cfg, InputSig<Cfg::BasicB
7076 ssaControlsBranchEdge ( def , bb1 , bb2 , v )
7177 }
7278
73- query predicate problems ( Guard g , string msg , Guard reason , string reasonMsg ) {
74- exists (
75- BasicBlock bb , GuardValue gv , GuardValue dual , SsaDefinition def , GuardValue v1 ,
76- GuardValue v2 , BasicBlock bb1 , BasicBlock bb2
77- |
79+ /** Holds if `g` cannot have value `gv` in `bb` due to `def` controlling `bb` with value `v2`. */
80+ pragma [ nomagic]
81+ private predicate impossibleValue (
82+ Guard g , GuardValue gv , SsaDefinition def , BasicBlock bb , GuardValue v2
83+ ) {
84+ exists ( GuardValue dual , GuardValue v1 |
7885 // If `g` in `bb` evaluates to `gv` then `def` has value `v1`,
7986 ssaControlsGuardEdge ( def , v1 , g , bb , _, gv ) and
8087 dual = gv .getDualValue ( ) and
8188 not gv .isThrowsException ( ) and
8289 not dual .isThrowsException ( ) and
83- // but `def` controls `bb` with value `v2` via the guard `reason` taking the branch `bb1` to `bb2`,
90+ // but `def` controls `bb` with value `v2` via some guard,
91+ ssaControls ( def , bb , v2 ) and
92+ // and `v1` and `v2` are disjoint so `g` cannot be `gv`.
93+ disjointValues ( v1 , v2 )
94+ )
95+ }
96+
97+ query predicate problems ( Guard g , string msg , Guard reason , string reasonMsg ) {
98+ exists (
99+ BasicBlock bb , GuardValue gv , SsaDefinition def , GuardValue v2 , BasicBlock bb1 , BasicBlock bb2
100+ |
101+ // `g` cannot have value `gv` in `bb` due to `def` controlling `bb` with value `v2`,
102+ impossibleValue ( g , gv , def , bb , v2 ) and
103+ // and this is because of `reason` taking the branch `bb1` to `bb2`,
84104 ssaControlsGuardEdge ( def , v2 , reason , bb1 , bb2 , _) and
85105 dominatingEdge ( bb1 , bb2 ) and
86106 bb2 .dominates ( bb ) and
87- // and `v1` and `v2` are disjoint so `g` cannot be `gv`.
88- disjointValues ( v1 , v2 ) and
89- msg = "Condition is always " + dual + " because of $@." and
107+ msg = "Condition is always " + gv .getDualValue ( ) + " because of $@." and
90108 reasonMsg = reason .toString ( )
91109 )
92110 }
0 commit comments