@@ -45,6 +45,7 @@ import cpp
4545private import RangeAnalysisUtils
4646import RangeSSA
4747import SimpleRangeAnalysisCached
48+ import NanAnalysis
4849
4950/**
5051 * This fixed set of lower bounds is used when the lower bounds of an
@@ -993,6 +994,25 @@ predicate unanalyzableDefBounds(
993994 ub = varMaxVal ( v )
994995}
995996
997+ /**
998+ * Holds if in the `branch` branch of a guard `guard` involving `v`,
999+ * we know that `v` is not NaN, and therefore it is safe to make range
1000+ * inferences about `v`.
1001+ */
1002+ bindingset [ guard, v, branch]
1003+ predicate nonNanGuardedVariable ( ComparisonOperation guard , VariableAccess v , boolean branch ) {
1004+ v .getType ( ) .getUnspecifiedType ( ) instanceof IntegralType
1005+ or
1006+ v .getType ( ) .getUnspecifiedType ( ) instanceof FloatingPointType and v instanceof NonNanVariableAccess
1007+ or
1008+ // The reason the following case is here is to ensure that when we say
1009+ // `if (x > 5) { ...then... } else { ...else... }`
1010+ // it is ok to conclude that `x > 5` in the `then`, (though not safe
1011+ // to conclude that x <= 5 in `else`) even if we had no prior
1012+ // knowledge of `x` not being `NaN`.
1013+ nanExcludingComparison ( guard , branch )
1014+ }
1015+
9961016/**
9971017 * If the guard is a comparison of the form `p*v + q <CMP> r`, then this
9981018 * predicate uses the bounds information for `r` to compute a lower bound
@@ -1004,10 +1024,12 @@ predicate lowerBoundFromGuard(
10041024) {
10051025 exists ( float childLB , RelationStrictness strictness
10061026 | boundFromGuard ( guard , v , childLB , true , strictness , branch )
1007- | if ( strictness = Nonstrict ( ) or
1008- not ( v .getType ( ) .getUnspecifiedType ( ) instanceof IntegralType ) )
1009- then lb = childLB
1010- else lb = childLB + 1 )
1027+ | if nonNanGuardedVariable ( guard , v , branch )
1028+ then ( if ( strictness = Nonstrict ( ) or
1029+ not ( v .getType ( ) .getUnspecifiedType ( ) instanceof IntegralType ) )
1030+ then lb = childLB
1031+ else lb = childLB + 1 )
1032+ else lb = varMinVal ( v .getTarget ( ) ) )
10111033}
10121034
10131035/**
@@ -1021,10 +1043,12 @@ predicate upperBoundFromGuard(
10211043) {
10221044 exists ( float childUB , RelationStrictness strictness
10231045 | boundFromGuard ( guard , v , childUB , false , strictness , branch )
1024- | if ( strictness = Nonstrict ( ) or
1025- not ( v .getType ( ) .getUnspecifiedType ( ) instanceof IntegralType ) )
1026- then ub = childUB
1027- else ub = childUB - 1 )
1046+ | if nonNanGuardedVariable ( guard , v , branch )
1047+ then ( if ( strictness = Nonstrict ( ) or
1048+ not ( v .getType ( ) .getUnspecifiedType ( ) instanceof IntegralType ) )
1049+ then ub = childUB
1050+ else ub = childUB - 1 )
1051+ else ub = varMaxVal ( v .getTarget ( ) ) )
10281052}
10291053
10301054/**
0 commit comments