Skip to content

Commit 10608bc

Browse files
authoredJan 17, 2025
Merge pull request #18526 from MathiasVP/negated-conjunctions-2
C++: Guard conditions from simple boolean identities
2 parents d8ec6dd + 5c494c3 commit 10608bc

File tree

6 files changed

+186
-0
lines changed

6 files changed

+186
-0
lines changed
 

‎cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

+12
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,18 @@ private module Cached {
994994
)
995995
or
996996
unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value)
997+
or
998+
exists(BinaryLogicalOperation logical, Expr operand, boolean b |
999+
test.getAnInstruction().getUnconvertedResultExpression() = logical and
1000+
op.getDef().getUnconvertedResultExpression() = operand and
1001+
logical.impliesValue(operand, b, value.(BooleanValue).getValue())
1002+
|
1003+
k = 1 and
1004+
areEqual = b
1005+
or
1006+
k = 0 and
1007+
areEqual = b.booleanNot()
1008+
)
9971009
}
9981010

9991011
/** Rearrange various simple comparisons into `left == right + k` form. */

‎cpp/ql/test/library-tests/controlflow/guards/Guards.expected

+8
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,11 @@
6969
| test.cpp:168:8:168:8 | b |
7070
| test.cpp:176:7:176:8 | ! ... |
7171
| test.cpp:176:8:176:8 | c |
72+
| test.cpp:182:6:182:16 | ! ... |
73+
| test.cpp:182:8:182:9 | b1 |
74+
| test.cpp:182:8:182:15 | ... && ... |
75+
| test.cpp:182:14:182:15 | b2 |
76+
| test.cpp:193:6:193:16 | ! ... |
77+
| test.cpp:193:8:193:9 | b1 |
78+
| test.cpp:193:8:193:15 | ... \|\| ... |
79+
| test.cpp:193:14:193:15 | b2 |

‎cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected

+52
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,12 @@
545545
| 182 | ! ... == 1 when ... && ... is false |
546546
| 182 | ... && ... != 0 when ! ... is false |
547547
| 182 | ... && ... != 0 when ... && ... is true |
548+
| 182 | ... && ... != 1 when ! ... is true |
549+
| 182 | ... && ... != 1 when ... && ... is false |
548550
| 182 | ... && ... == 0 when ! ... is true |
549551
| 182 | ... && ... == 0 when ... && ... is false |
552+
| 182 | ... && ... == 1 when ! ... is false |
553+
| 182 | ... && ... == 1 when ... && ... is true |
550554
| 182 | ... < ... != 0 when ... && ... is true |
551555
| 182 | ... < ... != 0 when ... < ... is true |
552556
| 182 | ... < ... != 1 when ... < ... is false |
@@ -559,6 +563,22 @@
559563
| 182 | ... >= ... == 0 when ... >= ... is false |
560564
| 182 | ... >= ... == 1 when ... && ... is true |
561565
| 182 | ... >= ... == 1 when ... >= ... is true |
566+
| 182 | b1 != 0 when ! ... is false |
567+
| 182 | b1 != 0 when ... && ... is true |
568+
| 182 | b1 != 0 when b1 is true |
569+
| 182 | b1 != 1 when b1 is false |
570+
| 182 | b1 == 0 when b1 is false |
571+
| 182 | b1 == 1 when ! ... is false |
572+
| 182 | b1 == 1 when ... && ... is true |
573+
| 182 | b1 == 1 when b1 is true |
574+
| 182 | b2 != 0 when ! ... is false |
575+
| 182 | b2 != 0 when ... && ... is true |
576+
| 182 | b2 != 0 when b2 is true |
577+
| 182 | b2 != 1 when b2 is false |
578+
| 182 | b2 == 0 when b2 is false |
579+
| 182 | b2 == 1 when ! ... is false |
580+
| 182 | b2 == 1 when ... && ... is true |
581+
| 182 | b2 == 1 when b2 is true |
562582
| 182 | foo < 1.0+0 when ... && ... is true |
563583
| 182 | foo < 1.0+0 when ... < ... is true |
564584
| 182 | foo < 9.999999999999999547e-07+0 when ... >= ... is false |
@@ -577,6 +597,38 @@
577597
| 190 | c != 0 when c is true |
578598
| 190 | c == 0 when ! ... is true |
579599
| 190 | c == 0 when c is false |
600+
| 193 | ! ... != 0 when ! ... is true |
601+
| 193 | ! ... != 0 when ... \|\| ... is false |
602+
| 193 | ! ... != 1 when ! ... is false |
603+
| 193 | ! ... != 1 when ... \|\| ... is true |
604+
| 193 | ! ... == 0 when ! ... is false |
605+
| 193 | ! ... == 0 when ... \|\| ... is true |
606+
| 193 | ! ... == 1 when ! ... is true |
607+
| 193 | ! ... == 1 when ... \|\| ... is false |
608+
| 193 | ... \|\| ... != 0 when ! ... is false |
609+
| 193 | ... \|\| ... != 0 when ... \|\| ... is true |
610+
| 193 | ... \|\| ... != 1 when ! ... is true |
611+
| 193 | ... \|\| ... != 1 when ... \|\| ... is false |
612+
| 193 | ... \|\| ... == 0 when ! ... is true |
613+
| 193 | ... \|\| ... == 0 when ... \|\| ... is false |
614+
| 193 | ... \|\| ... == 1 when ! ... is false |
615+
| 193 | ... \|\| ... == 1 when ... \|\| ... is true |
616+
| 193 | b1 != 0 when b1 is true |
617+
| 193 | b1 != 1 when ! ... is true |
618+
| 193 | b1 != 1 when ... \|\| ... is false |
619+
| 193 | b1 != 1 when b1 is false |
620+
| 193 | b1 == 0 when ! ... is true |
621+
| 193 | b1 == 0 when ... \|\| ... is false |
622+
| 193 | b1 == 0 when b1 is false |
623+
| 193 | b1 == 1 when b1 is true |
624+
| 193 | b2 != 0 when b2 is true |
625+
| 193 | b2 != 1 when ! ... is true |
626+
| 193 | b2 != 1 when ... \|\| ... is false |
627+
| 193 | b2 != 1 when b2 is false |
628+
| 193 | b2 == 0 when ! ... is true |
629+
| 193 | b2 == 0 when ... \|\| ... is false |
630+
| 193 | b2 == 0 when b2 is false |
631+
| 193 | b2 == 1 when b2 is true |
580632
| 198 | ! ... != 0 when ! ... is true |
581633
| 198 | ! ... != 0 when b is false |
582634
| 198 | ! ... != 1 when ! ... is false |

‎cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected

+16
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,19 @@
130130
| test.cpp:168:8:168:8 | b | false | 168 | 170 |
131131
| test.cpp:176:7:176:8 | ! ... | true | 176 | 178 |
132132
| test.cpp:176:8:176:8 | c | false | 176 | 178 |
133+
| test.cpp:182:6:182:16 | ! ... | false | 185 | 188 |
134+
| test.cpp:182:6:182:16 | ! ... | true | 182 | 184 |
135+
| test.cpp:182:8:182:9 | b1 | true | 181 | 182 |
136+
| test.cpp:182:8:182:9 | b1 | true | 182 | 182 |
137+
| test.cpp:182:8:182:15 | ... && ... | false | 182 | 184 |
138+
| test.cpp:182:8:182:15 | ... && ... | true | 181 | 182 |
139+
| test.cpp:182:8:182:15 | ... && ... | true | 185 | 188 |
140+
| test.cpp:182:14:182:15 | b2 | true | 181 | 182 |
141+
| test.cpp:193:6:193:16 | ! ... | false | 197 | 199 |
142+
| test.cpp:193:6:193:16 | ! ... | true | 193 | 196 |
143+
| test.cpp:193:8:193:9 | b1 | false | 192 | 193 |
144+
| test.cpp:193:8:193:9 | b1 | false | 193 | 193 |
145+
| test.cpp:193:8:193:15 | ... \|\| ... | false | 192 | 193 |
146+
| test.cpp:193:8:193:15 | ... \|\| ... | false | 193 | 196 |
147+
| test.cpp:193:8:193:15 | ... \|\| ... | true | 197 | 199 |
148+
| test.cpp:193:14:193:15 | b2 | false | 192 | 193 |

‎cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected

+76
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,79 @@ unary
636636
| test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | == | 1 | 176 | 178 |
637637
| test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | != | 1 | 176 | 178 |
638638
| test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | == | 0 | 176 | 178 |
639+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 0 | 182 | 184 |
640+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 185 | 188 |
641+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 185 | 188 |
642+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 1 | 182 | 184 |
643+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | != | 0 | 185 | 188 |
644+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | == | 1 | 185 | 188 |
645+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 185 | 188 |
646+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | 182 | 184 |
647+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | 182 | 184 |
648+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 185 | 188 |
649+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | != | 0 | 185 | 188 |
650+
| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | == | 1 | 185 | 188 |
651+
| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | 181 | 182 |
652+
| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | 182 | 182 |
653+
| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | 181 | 182 |
654+
| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | 182 | 182 |
655+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 0 | 182 | 184 |
656+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 181 | 182 |
657+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 185 | 188 |
658+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 181 | 182 |
659+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 185 | 188 |
660+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 1 | 182 | 184 |
661+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | 181 | 182 |
662+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | 185 | 188 |
663+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | 181 | 182 |
664+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | 185 | 188 |
665+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 181 | 182 |
666+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 185 | 188 |
667+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | 182 | 184 |
668+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | 182 | 184 |
669+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 181 | 182 |
670+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 185 | 188 |
671+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | 181 | 182 |
672+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | 185 | 188 |
673+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | 181 | 182 |
674+
| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | 185 | 188 |
675+
| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | 181 | 182 |
676+
| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | 181 | 182 |
677+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 193 | 196 |
678+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 1 | 197 | 199 |
679+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 0 | 197 | 199 |
680+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 193 | 196 |
681+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 196 |
682+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 196 |
683+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | 197 | 199 |
684+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 193 | 196 |
685+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 193 | 196 |
686+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | 197 | 199 |
687+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | != | 1 | 193 | 196 |
688+
| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 |
689+
| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | 192 | 193 |
690+
| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 193 |
691+
| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | 192 | 193 |
692+
| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 193 |
693+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 192 | 193 |
694+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 193 | 196 |
695+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 1 | 197 | 199 |
696+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 0 | 197 | 199 |
697+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 192 | 193 |
698+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 193 | 196 |
699+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | 192 | 193 |
700+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 196 |
701+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | 192 | 193 |
702+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 196 |
703+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | 197 | 199 |
704+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 192 | 193 |
705+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 193 | 196 |
706+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 192 | 193 |
707+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 193 | 196 |
708+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | 197 | 199 |
709+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 |
710+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | 193 | 196 |
711+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 |
712+
| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 |
713+
| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 |
714+
| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 |

‎cpp/ql/test/library-tests/controlflow/guards/test.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,26 @@ void test_with_negated_binary_relational(int a, int b) {
176176
if (!c) {
177177

178178
}
179+
}
180+
181+
void test_logical_and(bool b1, bool b2) {
182+
if(!(b1 && b2)) {
183+
use(b1);
184+
use(b2);
185+
} else {
186+
// b1 = true and b2 = true
187+
use(b1);
188+
use(b2);
189+
}
190+
}
191+
192+
void test_logical_or(bool b1, bool b2) {
193+
if(!(b1 || b2)) {
194+
// b1 = false and b2 = false
195+
use(b1);
196+
use(b2);
197+
} else {
198+
use(b1);
199+
use(b2);
200+
}
179201
}

0 commit comments

Comments
 (0)