@@ -3,12 +3,15 @@ private import semmle.code.cpp.commons.Scanf
33private import semmle.code.cpp.controlflow.IRGuards
44private import semmle.code.cpp.ir.ValueNumbering
55
6+ private ConstantInstruction getZeroInstruction ( ) { result .getValue ( ) = "0" }
7+
8+ private Operand zero ( ) { result .getDef ( ) = getZeroInstruction ( ) }
9+
610private predicate exprInBooleanContext ( Expr e ) {
711 exists ( IRGuardCondition gc |
8- exists ( Instruction i , ConstantInstruction zero |
9- zero .getValue ( ) = "0" and
12+ exists ( Instruction i |
1013 i .getUnconvertedResultExpression ( ) = e and
11- gc .comparesEq ( valueNumber ( i ) .getAUse ( ) , zero . getAUse ( ) , 0 , _, _)
14+ gc .comparesEq ( valueNumber ( i ) .getAUse ( ) , zero ( ) , 0 , _, _)
1215 )
1316 or
1417 gc .getUnconvertedResultExpression ( ) = e
@@ -33,15 +36,21 @@ private string getEofValue() {
3336 )
3437}
3538
39+ private ConstantInstruction getEofInstruction ( ) { result .getValue ( ) = getEofValue ( ) }
40+
41+ private Operand eof ( ) { result .getDef ( ) = getEofInstruction ( ) }
42+
3643/**
3744 * Holds if the value of `call` has been checked to not equal `EOF`.
3845 */
3946private predicate checkedForEof ( ScanfFunctionCall call ) {
4047 exists ( IRGuardCondition gc |
41- exists ( Instruction i , ConstantInstruction eof |
42- eof .getValue ( ) = getEofValue ( ) and
43- i .getUnconvertedResultExpression ( ) = call and
44- gc .comparesEq ( valueNumber ( i ) .getAUse ( ) , eof .getAUse ( ) , 0 , _, _)
48+ exists ( Instruction i | i .getUnconvertedResultExpression ( ) = call |
49+ // call == EOF
50+ gc .comparesEq ( valueNumber ( i ) .getAUse ( ) , eof ( ) , 0 , _, _)
51+ or
52+ // call < 0 (EOF is guaranteed to be negative)
53+ gc .comparesLt ( valueNumber ( i ) .getAUse ( ) , zero ( ) , 0 , true , _)
4554 )
4655 )
4756}
0 commit comments