@@ -38,6 +38,12 @@ module Private {
3838
3939 class Field = CS:: Field ;
4040
41+ class RealLiteral = CS:: RealLiteral ;
42+
43+ class DivExpr = CS:: DivExpr ;
44+
45+ class BinaryOperation = CS:: BinaryOperation ;
46+
4147 predicate ssaRead = SU:: ssaRead / 2 ;
4248}
4349
@@ -196,80 +202,88 @@ private module Impl {
196202 not e instanceof NullCoalescingExpr
197203 }
198204
199- /** Gets a possible sign for `e` from the signs of its child nodes. */
200- Sign specificSubExprSign ( Expr e ) {
201- // The expression types that are handled here should be excluded in `unknownIntegerAccess`.
202- // Keep them in sync.
203- result = exprSign ( e .( AssignExpr ) .getRValue ( ) )
204- or
205- result = exprSign ( e .( AssignOperation ) .getExpandedAssignment ( ) )
206- or
207- result = exprSign ( e .( UnaryPlusExpr ) .getOperand ( ) )
208- or
209- result = exprSign ( e .( PostIncrExpr ) .getOperand ( ) )
210- or
211- result = exprSign ( e .( PostDecrExpr ) .getOperand ( ) )
212- or
213- result = exprSign ( e .( PreIncrExpr ) .getOperand ( ) ) .inc ( )
214- or
215- result = exprSign ( e .( PreDecrExpr ) .getOperand ( ) ) .dec ( )
216- or
217- result = exprSign ( e .( UnaryMinusExpr ) .getOperand ( ) ) .neg ( )
218- or
219- result = exprSign ( e .( ComplementExpr ) .getOperand ( ) ) .bitnot ( )
220- or
221- e =
222- any ( DivExpr div |
223- result = exprSign ( div .getLeftOperand ( ) ) and
224- result != TZero ( ) and
225- div .getRightOperand ( ) .( RealLiteral ) .getValue ( ) .toFloat ( ) = 0
226- )
227- or
228- exists ( Sign s1 , Sign s2 | binaryOpSigns ( e , s1 , s2 ) |
229- e instanceof AddExpr and result = s1 .add ( s2 )
205+ /** Returns a sub expression of `e` for expression types where the sign depends on the child. */
206+ Expr getASubExpr ( Expr e ) {
207+ result = e .( AssignExpr ) .getRValue ( ) or
208+ result = e .( AssignOperation ) .getExpandedAssignment ( ) or
209+ result = e .( UnaryPlusExpr ) .getOperand ( ) or
210+ result = e .( PostIncrExpr ) .getOperand ( ) or
211+ result = e .( PostDecrExpr ) .getOperand ( ) or
212+ result = e .( ConditionalExpr ) .getAChild ( ) or
213+ result = e .( NullCoalescingExpr ) .getAChild ( ) or
214+ result = e .( SwitchExpr ) .getACase ( ) .getBody ( ) or
215+ result = e .( SwitchCaseExpr ) .getBody ( ) or
216+ result = e .( LocalVariableDeclAndInitExpr ) .getInitializer ( ) or
217+ result = e .( RefExpr ) .getExpr ( ) or
218+ result = e .( CastExpr ) .getExpr ( )
219+ }
220+
221+ /** Class to represent unary expressions. */
222+ class UnaryExpr extends Expr {
223+ UnaryExpr ( ) {
224+ this instanceof PreIncrExpr or
225+ this instanceof PreDecrExpr or
226+ this instanceof UnaryMinusExpr or
227+ this instanceof ComplementExpr
228+ }
229+
230+ /** Returns the operand of this expression. */
231+ Expr getOperand ( ) {
232+ result = this .( PreIncrExpr ) .getOperand ( ) or
233+ result = this .( PreDecrExpr ) .getOperand ( ) or
234+ result = this .( UnaryMinusExpr ) .getOperand ( ) or
235+ result = this .( ComplementExpr ) .getOperand ( )
236+ }
237+
238+ /** Returns the operation representing this expression. */
239+ TUnarySignOperation getOp ( ) {
240+ this instanceof PreIncrExpr and result = TIncOp ( )
230241 or
231- e instanceof SubExpr and result = s1 . add ( s2 . neg ( ) )
242+ this instanceof PreDecrExpr and result = TDecOp ( )
232243 or
233- e instanceof MulExpr and result = s1 . mul ( s2 )
244+ this instanceof UnaryMinusExpr and result = TNegOp ( )
234245 or
235- e instanceof DivExpr and result = s1 .div ( s2 )
246+ this instanceof ComplementExpr and result = TBitNotOp ( )
247+ }
248+ }
249+
250+ /** Class to represent binary expressions. */
251+ class BinaryExpr extends Expr {
252+ BinaryExpr ( ) {
253+ this instanceof AddExpr or
254+ this instanceof SubExpr or
255+ this instanceof MulExpr or
256+ this instanceof DivExpr or
257+ this instanceof RemExpr or
258+ this instanceof BitwiseAndExpr or
259+ this instanceof BitwiseOrExpr or
260+ this instanceof BitwiseXorExpr or
261+ this instanceof LShiftExpr or
262+ this instanceof RShiftExpr
263+ }
264+
265+ /** Returns the operation representing this expression. */
266+ TBinarySignOperation getOp ( ) {
267+ this instanceof AddExpr and result = TAddOp ( )
236268 or
237- e instanceof RemExpr and result = s1 . rem ( s2 )
269+ this instanceof SubExpr and result = TSubOp ( )
238270 or
239- e instanceof BitwiseAndExpr and result = s1 . bitand ( s2 )
271+ this instanceof MulExpr and result = TMulOp ( )
240272 or
241- e instanceof BitwiseOrExpr and result = s1 . bitor ( s2 )
273+ this instanceof DivExpr and result = TDivOp ( )
242274 or
243- e instanceof BitwiseXorExpr and result = s1 . bitxor ( s2 )
275+ this instanceof RemExpr and result = TRemOp ( )
244276 or
245- e instanceof LShiftExpr and result = s1 . lshift ( s2 )
277+ this instanceof BitwiseAndExpr and result = TBitAndOp ( )
246278 or
247- e instanceof RShiftExpr and result = s1 .rshift ( s2 )
248- )
249- or
250- result = exprSign ( e .( ConditionalExpr ) .getAChild ( ) )
251- or
252- result = exprSign ( e .( NullCoalescingExpr ) .getAChild ( ) )
253- or
254- result = exprSign ( e .( SwitchExpr ) .getACase ( ) .getBody ( ) )
255- or
256- result = exprSign ( e .( CastExpr ) .getExpr ( ) )
257- or
258- result = exprSign ( e .( SwitchCaseExpr ) .getBody ( ) )
259- or
260- result = exprSign ( e .( LocalVariableDeclAndInitExpr ) .getInitializer ( ) )
261- or
262- result = exprSign ( e .( RefExpr ) .getExpr ( ) )
263- }
264-
265- private Sign binaryOpLhsSign ( BinaryOperation e ) { result = exprSign ( e .getLeftOperand ( ) ) }
266-
267- private Sign binaryOpRhsSign ( BinaryOperation e ) { result = exprSign ( e .getRightOperand ( ) ) }
268-
269- pragma [ noinline]
270- private predicate binaryOpSigns ( Expr e , Sign lhs , Sign rhs ) {
271- lhs = binaryOpLhsSign ( e ) and
272- rhs = binaryOpRhsSign ( e )
279+ this instanceof BitwiseOrExpr and result = TBitOrOp ( )
280+ or
281+ this instanceof BitwiseXorExpr and result = TBitXorOp ( )
282+ or
283+ this instanceof LShiftExpr and result = TLShiftOp ( )
284+ or
285+ this instanceof RShiftExpr and result = TRShiftOp ( )
286+ }
273287 }
274288
275289 Expr getARead ( Ssa:: Definition v ) { result = v .getARead ( ) }
0 commit comments