@@ -956,27 +956,27 @@ module Internal {
956956 */
957957 private predicate guardImpliesNotEqual ( Expr guard , AbstractValue vGuard , PreSsa:: Definition def , AbstractValue vDef ) {
958958 relevantEq ( def , vDef ) and
959- exists ( DereferenceableExpr de |
960- de = def .getARead ( ) |
959+ exists ( AssignableRead ar |
960+ ar = def .getARead ( ) |
961961 // For example:
962962 // if (de == null); vGuard = TBooleanValue(false); vDef = TNullValue(true)
963963 // but not
964964 // if (de == "abc"); vGuard = TBooleanValue(false); vDef = TNullValue(false)
965- guard = getAnEqualityCheckVal ( de , vGuard .getDualValue ( ) , vDef ) and
965+ guard = getAnEqualityCheckVal ( ar , vGuard .getDualValue ( ) , vDef ) and
966966 vDef .isSingleton ( )
967967 or
968968 // For example:
969969 // if (de != null); vGuard = TBooleanValue(true); vDef = TNullValue(true)
970970 // or
971971 // if (de == null); vGuard = TBooleanValue(true); vDef = TNullValue(false)
972972 exists ( NullValue nv |
973- guard = de .getANullCheck ( vGuard , any ( boolean b | nv = TNullValue ( b ) ) ) |
973+ guard = ar . ( DereferenceableExpr ) .getANullCheck ( vGuard , any ( boolean b | nv = TNullValue ( b ) ) ) |
974974 vDef = nv .getDualValue ( )
975975 )
976976 or
977977 // For example:
978- // if (de == null ); vGuard = TBooleanValue(true); vDef = TNullValue(false )
979- guard = getAnEqualityCheckVal ( de , vGuard , vDef .getDualValue ( ) )
978+ // if (de == false ); vGuard = TBooleanValue(true); vDef = TBooleanValue(true )
979+ guard = getAnEqualityCheckVal ( ar , vGuard , vDef .getDualValue ( ) )
980980 )
981981 }
982982
@@ -1040,7 +1040,7 @@ module Internal {
10401040 * Holds if `e` has abstract value `v` and may be assigned to `def` without going
10411041 * through back edges, and all other possible ultimate definitions of `def` do not
10421042 * have abstract value `v`. The trivial case where `def` is an explicit update with
1043- * source `e is excluded.
1043+ * source `e` is excluded.
10441044 */
10451045 private predicate uniqueValue ( PreSsa:: Definition def , Expr e , AbstractValue v ) {
10461046 possibleValue ( def , false , e , v ) and
@@ -1178,30 +1178,41 @@ module Internal {
11781178 polarity = false
11791179 )
11801180 or
1181- exists ( ConditionalExpr cond , boolean branch , BoolLiteral boolLit , boolean b |
1182- b = boolLit . getBoolValue ( ) and
1181+ exists ( ConditionalExpr cond , boolean branch , Expr e , AbstractValue v |
1182+ e = v . getAnExpr ( ) and
11831183 (
1184- cond .getThen ( ) = boolLit and branch = true
1184+ cond .getThen ( ) = e and branch = true
11851185 or
1186- cond .getElse ( ) = boolLit and branch = false
1186+ cond .getElse ( ) = e and branch = false
11871187 )
11881188 |
11891189 g1 = cond and
1190- v1 = TBooleanValue ( b . booleanNot ( ) ) and
1190+ v1 = v . getDualValue ( ) and
11911191 (
1192+ // g1 === g2 ? e : ...;
11921193 g2 = cond .getCondition ( ) and
11931194 v2 = TBooleanValue ( branch .booleanNot ( ) )
11941195 or
1196+ // g1 === ... ? g2 : e
11951197 g2 = cond .getThen ( ) and
11961198 branch = false and
11971199 v2 = v1
11981200 or
1201+ // g1 === g2 ? ... : e
11991202 g2 = cond .getElse ( ) and
12001203 branch = true and
12011204 v2 = v1
12021205 )
12031206 )
12041207 or
1208+ v1 = g1 .getAValue ( ) and
1209+ v1 = any ( MatchValue mv |
1210+ mv .isMatch ( ) and
1211+ g2 = g1 and
1212+ v2 .getAnExpr ( ) = mv .getCaseStmt ( ) .( ConstCase ) .getExpr ( ) and
1213+ v1 != v2
1214+ )
1215+ or
12051216 exists ( boolean isNull |
12061217 g1 = g2 .( DereferenceableExpr ) .getANullCheck ( v1 , isNull ) |
12071218 v2 = any ( NullValue nv | if nv .isNull ( ) then isNull = true else isNull = false ) and
@@ -1238,15 +1249,16 @@ module Internal {
12381249 )
12391250 or
12401251 exists ( PreSsa:: Definition def , AbstractValue v |
1241- // If `def = g2 ? v : ...` or `def = g2 ? ... : v` then a guard `g1`
1242- // proving `def != v` ensures that `g2` evaluates to `b2 `.
1252+ // If for example `def = g2 ? v : ...`, then a guard `g1` proving `def != v `
1253+ // ensures that `g2` evaluates to `false `.
12431254 conditionalAssignVal ( g2 , v2 .getDualValue ( ) , def , v ) and
12441255 guardImpliesNotEqual ( g1 , v1 , def , v )
12451256 )
12461257 or
12471258 exists ( PreSsa:: Definition def , Expr e , AbstractValue v |
1248- // If `def = g2 ? v : ...` and all other assignments to `def` are different from
1249- // `v` then a guard proving `def == v` ensures that `g2` evaluates to `v2`.
1259+ // If for example `def = g2 ? v : ...` and all other assignments to `def` are
1260+ // different from `v`, then a guard proving `def == v` ensures that `g2`
1261+ // evaluates to `true`.
12501262 uniqueValue ( def , e , v ) and
12511263 guardImpliesEqual ( g1 , v1 , def , v ) and
12521264 g2 .preControlsDirect ( any ( PreBasicBlocks:: PreBasicBlock bb | e = bb .getAnElement ( ) ) , v2 ) and
0 commit comments