@@ -33,7 +33,11 @@ private module Impl {
3333 /** Holds if SSA definition `def` equals `e + delta`. */
3434 predicate ssaUpdateStep ( ExplicitDefinition def , ExprNode e , int delta ) {
3535 exists ( ControlFlow:: Node cfn | cfn = def .getControlFlowNode ( ) |
36- e = cfn .( ExprNode:: Assignment ) .getRValue ( ) and delta = 0
36+ e = cfn .( ExprNode:: Assignment ) .getRValue ( ) and
37+ delta = 0 and
38+ not cfn instanceof ExprNode:: AssignOperation
39+ or
40+ e = cfn .( ExprNode:: AssignOperation ) and delta = 0
3741 or
3842 e = cfn .( ExprNode:: PostIncrExpr ) .getOperand ( ) and delta = 1
3943 or
@@ -230,6 +234,11 @@ module ExprNode {
230234 override CS:: AssignExpr e ;
231235 }
232236
237+ /** A compound assignment operation. */
238+ class AssignOperation extends Assignment , BinaryOperation {
239+ override CS:: AssignOperation e ;
240+ }
241+
233242 /** A unary operation. */
234243 class UnaryOperation extends ExprNode {
235244 override CS:: UnaryOperation e ;
@@ -321,80 +330,168 @@ module ExprNode {
321330 }
322331
323332 /** An addition operation. */
324- class AddExpr extends BinaryOperation {
333+ abstract private class AddExprImpl extends BinaryOperation {
334+ override TAddOp getOp ( ) { any ( ) }
335+ }
336+
337+ final class AddExpr = AddExprImpl ;
338+
339+ private class AddAddExpr extends AddExprImpl {
325340 override CS:: AddExpr e ;
341+ }
326342
327- override TAddOp getOp ( ) { any ( ) }
343+ private class AddAssignAddExpr extends AddExprImpl , AssignOperation {
344+ override CS:: AssignAddExpr e ;
328345 }
329346
330347 /** A subtraction operation. */
331- class SubExpr extends BinaryOperation {
348+ abstract private class SubExprImpl extends BinaryOperation {
349+ override TSubOp getOp ( ) { any ( ) }
350+ }
351+
352+ final class SubExpr = SubExprImpl ;
353+
354+ private class AddSubExpr extends SubExprImpl {
332355 override CS:: SubExpr e ;
356+ }
333357
334- override TSubOp getOp ( ) { any ( ) }
358+ private class AddAssignSubExpr extends SubExprImpl , AssignOperation {
359+ override CS:: AssignSubExpr e ;
335360 }
336361
337362 /** A multiplication operation. */
338- class MulExpr extends BinaryOperation {
363+ abstract private class MulExprImpl extends BinaryOperation {
364+ override TMulOp getOp ( ) { any ( ) }
365+ }
366+
367+ final class MulExpr = MulExprImpl ;
368+
369+ private class AddMulExpr extends MulExprImpl {
339370 override CS:: MulExpr e ;
371+ }
340372
341- override TMulOp getOp ( ) { any ( ) }
373+ private class AddAssignMulExpr extends MulExprImpl , AssignOperation {
374+ override CS:: AssignMulExpr e ;
342375 }
343376
344377 /** A division operation. */
345- class DivExpr extends BinaryOperation {
378+ abstract private class DivExprImpl extends BinaryOperation {
379+ override TDivOp getOp ( ) { any ( ) }
380+ }
381+
382+ final class DivExpr = DivExprImpl ;
383+
384+ private class AddDivExpr extends DivExprImpl {
346385 override CS:: DivExpr e ;
386+ }
347387
348- override TDivOp getOp ( ) { any ( ) }
388+ private class AddAssignDivExpr extends DivExprImpl , AssignOperation {
389+ override CS:: AssignDivExpr e ;
349390 }
350391
351392 /** A remainder operation. */
352- class RemExpr extends BinaryOperation {
393+ abstract private class RemExprImpl extends BinaryOperation {
394+ override TRemOp getOp ( ) { any ( ) }
395+ }
396+
397+ final class RemExpr = RemExprImpl ;
398+
399+ private class AddRemExpr extends RemExprImpl {
353400 override CS:: RemExpr e ;
401+ }
354402
355- override TRemOp getOp ( ) { any ( ) }
403+ private class AddAssignRemExpr extends RemExprImpl , AssignOperation {
404+ override CS:: AssignRemExpr e ;
356405 }
357406
358407 /** A bitwise-and operation. */
359- class BitwiseAndExpr extends BinaryOperation {
408+ abstract private class BitwiseAndExprImpl extends BinaryOperation {
409+ override TBitAndOp getOp ( ) { any ( ) }
410+ }
411+
412+ final class BitwiseAndExpr = BitwiseAndExprImpl ;
413+
414+ private class AddBitwiseAndExpr extends BitwiseAndExprImpl {
360415 override CS:: BitwiseAndExpr e ;
416+ }
361417
362- override TBitAndOp getOp ( ) { any ( ) }
418+ private class AddAssignAndExpr extends BitwiseAndExprImpl , AssignOperation {
419+ override CS:: AssignAndExpr e ;
363420 }
364421
365422 /** A bitwise-or operation. */
366- class BitwiseOrExpr extends BinaryOperation {
423+ abstract private class BitwiseOrExprImpl extends BinaryOperation {
424+ override TBitOrOp getOp ( ) { any ( ) }
425+ }
426+
427+ final class BitwiseOrExpr = BitwiseOrExprImpl ;
428+
429+ private class AddBitwiseOrExpr extends BitwiseOrExprImpl {
367430 override CS:: BitwiseOrExpr e ;
431+ }
368432
369- override TBitOrOp getOp ( ) { any ( ) }
433+ private class AddAssignOrExpr extends BitwiseOrExprImpl , AssignOperation {
434+ override CS:: AssignOrExpr e ;
370435 }
371436
372437 /** A bitwise-xor operation. */
373- class BitwiseXorExpr extends BinaryOperation {
438+ abstract private class BitwiseXorExprImpl extends BinaryOperation {
439+ override TBitXorOp getOp ( ) { any ( ) }
440+ }
441+
442+ final class BitwiseXorExpr = BitwiseXorExprImpl ;
443+
444+ private class AddBitwiseXorExpr extends BitwiseXorExprImpl {
374445 override CS:: BitwiseXorExpr e ;
446+ }
375447
376- override TBitXorOp getOp ( ) { any ( ) }
448+ private class AddAssignXorExpr extends BitwiseXorExprImpl , AssignOperation {
449+ override CS:: AssignXorExpr e ;
377450 }
378451
379452 /** A left-shift operation. */
380- class LeftShiftExpr extends BinaryOperation {
453+ abstract private class LeftShiftExprImpl extends BinaryOperation {
454+ override TLeftShiftOp getOp ( ) { any ( ) }
455+ }
456+
457+ final class LeftShiftExpr = LeftShiftExprImpl ;
458+
459+ private class AddLeftShiftExpr extends LeftShiftExprImpl {
381460 override CS:: LeftShiftExpr e ;
461+ }
382462
383- override TLeftShiftOp getOp ( ) { any ( ) }
463+ private class AddAssignLeftShiftExpr extends LeftShiftExprImpl , AssignOperation {
464+ override CS:: AssignLeftShiftExpr e ;
384465 }
385466
386467 /** A right-shift operation. */
387- class RightShiftExpr extends BinaryOperation {
468+ abstract private class RightShiftExprImpl extends BinaryOperation {
469+ override TRightShiftOp getOp ( ) { any ( ) }
470+ }
471+
472+ final class RightShiftExpr = RightShiftExprImpl ;
473+
474+ private class AddRightShiftExpr extends RightShiftExprImpl {
388475 override CS:: RightShiftExpr e ;
476+ }
389477
390- override TRightShiftOp getOp ( ) { any ( ) }
478+ private class AddAssignRightShiftExpr extends RightShiftExprImpl , AssignOperation {
479+ override CS:: AssignRightShiftExpr e ;
391480 }
392481
393482 /** An unsigned right-shift operation. */
394- class UnsignedRightShiftExpr extends BinaryOperation {
483+ abstract private class UnsignedRightShiftExprImpl extends BinaryOperation {
484+ override TUnsignedRightShiftOp getOp ( ) { any ( ) }
485+ }
486+
487+ final class UnsignedRightShiftExpr = UnsignedRightShiftExprImpl ;
488+
489+ private class AddUnsignedRightShiftExpr extends UnsignedRightShiftExprImpl {
395490 override CS:: UnsignedRightShiftExpr e ;
491+ }
396492
397- override TUnsignedRightShiftOp getOp ( ) { any ( ) }
493+ private class AddAssignUnsignedRightShiftExpr extends UnsignedRightShiftExprImpl , AssignOperation {
494+ override CS:: AssignUnsighedRightShiftExpr e ;
398495 }
399496
400497 /** A conditional expression. */
0 commit comments