@@ -125,41 +125,16 @@ module GuardsInput implements SharedGuards::InputSig<Cpp::Location, Instruction,
125125 // In order to have an "integer constant" for a switch case
126126 // we misuse the first instruction (which is always a NoOp instruction)
127127 // as a constant with the switch case's value.
128- exists ( CaseEdge edge |
129- this = any ( SwitchInstruction switch ) .getSuccessor ( edge ) and
130- value = edge .getValue ( ) .toInt ( )
128+ exists ( CaseEdge edge | this = any ( SwitchInstruction switch ) .getSuccessor ( edge ) |
129+ value = edge .getMaxValue ( ) .toInt ( )
130+ or
131+ value = edge .getMinValue ( ) .toInt ( )
131132 )
132133 }
133134
134135 override int asIntegerValue ( ) { result = value }
135136 }
136137
137- /**
138- * The instruction representing the constant expression in a case statement.
139- *
140- * Since the IR does not have an instruction for this (as this is represented
141- * by the edge) we use the `NoOp` instruction which is always generated.
142- */
143- private class CaseConstant extends ConstantExpr instanceof NoOpInstruction {
144- SwitchInstruction switch ;
145- SwitchEdge edge ;
146-
147- CaseConstant ( ) { this = switch .getSuccessor ( edge ) }
148-
149- override ConstantValue asConstantValue ( ) {
150- exists ( string minValue , string maxValue |
151- edge .getMinValue ( ) = minValue and
152- edge .getMaxValue ( ) = maxValue and
153- result .isRange ( minValue , maxValue )
154- )
155- }
156-
157- predicate hasEdge ( SwitchInstruction switch_ , SwitchEdge edge_ ) {
158- switch_ = switch and
159- edge_ = edge
160- }
161- }
162-
163138 private predicate nonNullExpr ( Instruction i ) {
164139 i instanceof VariableAddressInstruction
165140 or
@@ -234,7 +209,12 @@ module GuardsInput implements SharedGuards::InputSig<Cpp::Location, Instruction,
234209 /**
235210 * Gets the constant expression of this case.
236211 */
237- ConstantExpr asConstantCase ( ) { result .( CaseConstant ) .hasEdge ( switch , edge ) }
212+ ConstantExpr asConstantCase ( ) {
213+ // Note: This only has a value if there is a unique value for the case.
214+ // So the will not be a result when using the GCC case range extension.
215+ // Instead, we model these using the `LogicInput_v1::rangeGuard` predicate.
216+ result .asIntegerValue ( ) = this .getEdge ( ) .getValue ( ) .toInt ( )
217+ }
238218 }
239219
240220 abstract private class BinExpr extends Expr instanceof BinaryInstruction {
@@ -446,6 +426,23 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
446426 g1 .( ConditionalBranchInstruction ) .getCondition ( ) = g2 and
447427 v1 .asBooleanValue ( ) = v2 .asBooleanValue ( )
448428 }
429+
430+ predicate rangeGuard (
431+ GuardsImpl:: PreGuard guard , GuardValue val , GuardsInput:: Expr e , int k , boolean upper
432+ ) {
433+ exists ( SwitchInstruction switch , string minValue , string maxValue |
434+ switch .getSuccessor ( EdgeKind:: caseEdge ( minValue , maxValue ) ) = guard and
435+ e = switch .getExpression ( ) and
436+ minValue != maxValue and
437+ val .asBooleanValue ( ) = true
438+ |
439+ upper = false and
440+ k = minValue .toInt ( )
441+ or
442+ upper = true and
443+ k = maxValue .toInt ( )
444+ )
445+ }
449446}
450447
451448class GuardValue = GuardsImpl:: GuardValue ;
@@ -1707,15 +1704,16 @@ private module Cached {
17071704 exists ( string minValue , string maxValue |
17081705 test .getExpressionOperand ( ) = op and
17091706 exists ( test .getSuccessor ( EdgeKind:: caseEdge ( minValue , maxValue ) ) ) and
1710- value .asConstantValue ( ) .isRange ( minValue , maxValue ) and
17111707 minValue < maxValue
17121708 |
17131709 // op <= k => op < k - 1
17141710 isLt = true and
1715- maxValue .toInt ( ) = k - 1
1711+ maxValue .toInt ( ) = k - 1 and
1712+ value .isIntRange ( k - 1 , true )
17161713 or
17171714 isLt = false and
1718- minValue .toInt ( ) = k
1715+ minValue .toInt ( ) = k and
1716+ value .isIntRange ( k , false )
17191717 )
17201718 }
17211719
0 commit comments