Skip to content

Commit 28743dd

Browse files
authored
fix: is_commutative returned TRUE for non-commutative operators (#120)
* fix: is_commutative returned TRUE for non-commutative operators * chore: cleanup tests to avoid code dup * fix: unused import * fix: regenerate expected files * fix: avoid panic * fix: adapt tests to new commutative semantics
1 parent 0334123 commit 28743dd

File tree

7 files changed

+317
-225
lines changed

7 files changed

+317
-225
lines changed

move-mutator/src/operators/binary_swap.rs

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ use crate::{
88
report::{Mutation, Range},
99
};
1010
use codespan::FileId;
11-
use move_model::{
12-
ast::{ExpData, Operation},
13-
model::Loc,
14-
};
11+
use move_model::{ast::Operation, model::Loc};
1512
use std::fmt;
1613

1714
pub const OPERATOR_NAME: &str = "binary_operator_swap";
@@ -37,38 +34,16 @@ impl BinarySwap {
3734

3835
// Check whether the binary operation is commutative.
3936
fn is_commutative(&self) -> bool {
40-
match self.operation {
37+
matches!(
38+
self.operation,
4139
Operation::Add
42-
| Operation::Mul
43-
| Operation::Eq
44-
| Operation::Neq
45-
| Operation::BitOr
46-
| Operation::BitAnd
47-
| Operation::Or
48-
| Operation::And
49-
| Operation::Xor => {
50-
for ExpLoc { exp, loc: _ } in self.exps.iter() {
51-
let mut calls_function = |e: &ExpData| {
52-
matches!(
53-
e,
54-
ExpData::Call(_, Operation::MoveFunction(..), _)
55-
| ExpData::Lambda(..)
56-
| ExpData::Invoke(..)
57-
)
58-
};
59-
60-
if exp.any(&mut calls_function) {
61-
// If any expression around the operator is a closure or a function,
62-
// it's not possible to guarantee that the operation is commutative,
63-
// since the operand order might matter in that case.
64-
return false;
65-
}
66-
}
67-
},
68-
_ => (),
69-
}
70-
71-
true
40+
| Operation::Mul
41+
| Operation::Eq
42+
| Operation::Neq
43+
| Operation::BitOr
44+
| Operation::BitAnd
45+
| Operation::Xor
46+
)
7247
}
7348
}
7449

@@ -102,6 +77,10 @@ impl MutationOperator for BinarySwap {
10277
let end = source[..end]
10378
.rfind(|c: char| !c.is_whitespace())
10479
.map_or(end, |i| i + 1);
80+
if start >= end {
81+
warn!("BinarySwapOperator: Could not locate operator between expressions.");
82+
return vec![];
83+
}
10584
let binop_str = &source[start..end];
10685

10786
let start = left.span().start().to_usize();
@@ -168,4 +147,50 @@ mod tests {
168147
let operator = BinarySwap::new(Operation::Add, loc, vec![]);
169148
assert_eq!(operator.get_file_id(), fid);
170149
}
150+
151+
#[test]
152+
fn test_is_commutative() {
153+
let mut files = Files::new();
154+
let fid = files.add("test", "test");
155+
156+
let span = codespan::Span::new(0, 0);
157+
for operation in [
158+
Operation::Add,
159+
Operation::Mul,
160+
Operation::Eq,
161+
Operation::Neq,
162+
Operation::BitOr,
163+
Operation::BitAnd,
164+
Operation::Xor,
165+
] {
166+
let loc = Loc::new(fid, span);
167+
let operator = BinarySwap::new(operation, loc, vec![]);
168+
assert!(operator.is_commutative());
169+
}
170+
}
171+
172+
#[test]
173+
fn test_is_not_commutative() {
174+
let mut files = Files::new();
175+
let fid = files.add("test", "test");
176+
177+
let span = codespan::Span::new(0, 0);
178+
for operation in [
179+
Operation::Lt,
180+
Operation::Gt,
181+
Operation::Le,
182+
Operation::Ge,
183+
Operation::Div,
184+
Operation::Sub,
185+
Operation::Shl,
186+
Operation::Shr,
187+
// Logical operations could be not commutative due to short-circuit evaluation.
188+
Operation::And,
189+
Operation::Or,
190+
] {
191+
let loc = Loc::new(fid, span);
192+
let operator = BinarySwap::new(operation, loc, vec![]);
193+
assert!(!operator.is_commutative());
194+
}
195+
}
171196
}

move-mutator/tests/basic_tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,11 @@ fn check_mutator_swap_operator_works_correctly_for_corner_cases() {
257257

258258
// Function names and number of swap mutation operations
259259
let functions_and_exected_swap_op_count = [
260-
("swap_op_should_mutate_once_v1", 1),
261-
("swap_op_should_mutate_once_v2", 1),
262-
("swap_op_should_mutate_once_v3", 1),
263-
("swap_op_should_mutate_seven_times", 7),
264-
("swap_op_should_mutate_three_times", 3),
260+
("swap_op_should_not_mutate_binary_swap", 0),
261+
("swap_op_should_not_mutate_binary_swap_v2", 0),
262+
("swap_op_should_not_mutate_binary_swap_v3", 0),
263+
("swap_op_should_mutate_four_times", 4),
264+
("swap_op_should_not_mutate_binary_swap_v4", 0),
265265
("swap_op_should_not_mutate", 0),
266266
];
267267

move-mutator/tests/move-assets/breakcontinue/report.txt.mutation-exp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"sources/Break.move": [
44
{
55
"module_func": "Break::smallest_factor",
6-
"tested": 35,
7-
"killed": 34,
6+
"tested": 37,
7+
"killed": 36,
88
"mutants_alive_diffs": [
99
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun smallest_factor(n: u64): u64 {\n // assuming the input is not 0 or 1\n let i = 2;\n- while (i <= n) {\n+ while (i < n) {\n if (n % i == 0) break;\n i = i + 1\n };\n"
1010
],
@@ -20,6 +20,7 @@
2020
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun smallest_factor(n: u64): u64 {\n // assuming the input is not 0 or 1\n let i = 2;\n- while (i <= n) {\n+ while (i != n) {\n if (n % i == 0) break;\n i = i + 1\n };\n",
2121
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun smallest_factor(n: u64): u64 {\n // assuming the input is not 0 or 1\n let i = 2;\n- while (i <= n) {\n+ while (i > n) {\n if (n % i == 0) break;\n i = i + 1\n };\n",
2222
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun smallest_factor(n: u64): u64 {\n // assuming the input is not 0 or 1\n let i = 2;\n- while (i <= n) {\n+ while (i >= n) {\n if (n % i == 0) break;\n i = i + 1\n };\n",
23+
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun smallest_factor(n: u64): u64 {\n // assuming the input is not 0 or 1\n let i = 2;\n- while (i <= n) {\n+ while (n <= i) {\n if (n % i == 0) break;\n i = i + 1\n };\n",
2324
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (true) break;\n i = i + 1\n };\n\n",
2425
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (false) break;\n i = i + 1\n };\n\n",
2526
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (!(n % i == 0)) break;\n i = i + 1\n };\n\n",
@@ -31,6 +32,7 @@
3132
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (n - i == 0) break;\n i = i + 1\n };\n\n",
3233
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (n * i == 0) break;\n i = i + 1\n };\n\n",
3334
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (n / i == 0) break;\n i = i + 1\n };\n\n",
35+
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (i % n == 0) break;\n i = i + 1\n };\n\n",
3436
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (n % i == 18446744073709551615) break;\n i = i + 1\n };\n\n",
3537
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (n % i == 1) break;\n i = i + 1\n };\n\n",
3638
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n // assuming the input is not 0 or 1\n let i = 2;\n while (i <= n) {\n- if (n % i == 0) break;\n+ if (n % i == 0) continue;\n i = i + 1\n };\n\n",
@@ -49,8 +51,8 @@
4951
"sources/BreakContinue.move": [
5052
{
5153
"module_func": "BreakContinue::sum_intermediate",
52-
"tested": 45,
53-
"killed": 45,
54+
"tested": 47,
55+
"killed": 47,
5456
"mutants_alive_diffs": [],
5557
"mutants_killed_diff": [
5658
"--- original\n+++ modified\n@@ -1,6 +1,6 @@\n module TestAccount::BreakContinue {\n fun sum_intermediate(n: u64): u64 {\n- let sum = 0;\n+ let sum = 18446744073709551615;\n let i = 0;\n loop {\n i = i + 1;\n",
@@ -76,6 +78,7 @@
7678
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i - 10 == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
7779
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i * 10 == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
7880
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i / 10 == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
81+
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (10 % i == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
7982
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i % 0 == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
8083
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i % 18446744073709551615 == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
8184
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n loop {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i % 11 == 0) continue;\n if (i > n) break;\n sum = sum + i\n };\n",
@@ -92,6 +95,7 @@
9295
"--- original\n+++ modified\n@@ -5,7 +5,7 @@\n loop {\n i = i + 1;\n if (i % 10 == 0) continue;\n- if (i > n) break;\n+ if (i < n) break;\n sum = sum + i\n };\n\n",
9396
"--- original\n+++ modified\n@@ -5,7 +5,7 @@\n loop {\n i = i + 1;\n if (i % 10 == 0) continue;\n- if (i > n) break;\n+ if (i <= n) break;\n sum = sum + i\n };\n\n",
9497
"--- original\n+++ modified\n@@ -5,7 +5,7 @@\n loop {\n i = i + 1;\n if (i % 10 == 0) continue;\n- if (i > n) break;\n+ if (i >= n) break;\n sum = sum + i\n };\n\n",
98+
"--- original\n+++ modified\n@@ -5,7 +5,7 @@\n loop {\n i = i + 1;\n if (i % 10 == 0) continue;\n- if (i > n) break;\n+ if (n > i) break;\n sum = sum + i\n };\n\n",
9599
"--- original\n+++ modified\n@@ -5,7 +5,7 @@\n loop {\n i = i + 1;\n if (i % 10 == 0) continue;\n- if (i > n) break;\n+ if (i > n) continue;\n sum = sum + i\n };\n\n",
96100
"--- original\n+++ modified\n@@ -5,7 +5,7 @@\n loop {\n i = i + 1;\n if (i % 10 == 0) continue;\n- if (i > n) break;\n+ if (i > n) {};\n sum = sum + i\n };\n\n",
97101
"--- original\n+++ modified\n@@ -6,7 +6,7 @@\n i = i + 1;\n if (i % 10 == 0) continue;\n if (i > n) break;\n- sum = sum + i\n+ sum = sum - i\n };\n\n sum\n",
@@ -104,8 +108,8 @@
104108
"sources/Continue.move": [
105109
{
106110
"module_func": "Continue::sum_intermediate",
107-
"tested": 43,
108-
"killed": 42,
111+
"tested": 45,
112+
"killed": 44,
109113
"mutants_alive_diffs": [
110114
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun sum_intermediate(n: u64): u64 {\n let sum = 0;\n let i = 0;\n- while (i < n) {\n+ while (i != n) {\n i = i + 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n"
111115
],
@@ -121,6 +125,7 @@
121125
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun sum_intermediate(n: u64): u64 {\n let sum = 0;\n let i = 0;\n- while (i < n) {\n+ while (i > n) {\n i = i + 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n",
122126
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun sum_intermediate(n: u64): u64 {\n let sum = 0;\n let i = 0;\n- while (i < n) {\n+ while (i <= n) {\n i = i + 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n",
123127
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun sum_intermediate(n: u64): u64 {\n let sum = 0;\n let i = 0;\n- while (i < n) {\n+ while (i >= n) {\n i = i + 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n",
128+
"--- original\n+++ modified\n@@ -2,7 +2,7 @@\n fun sum_intermediate(n: u64): u64 {\n let sum = 0;\n let i = 0;\n- while (i < n) {\n+ while (n < i) {\n i = i + 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n",
124129
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n let sum = 0;\n let i = 0;\n while (i < n) {\n- i = i + 1;\n+ i = i - 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n };\n",
125130
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n let sum = 0;\n let i = 0;\n while (i < n) {\n- i = i + 1;\n+ i = i * 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n };\n",
126131
"--- original\n+++ modified\n@@ -3,7 +3,7 @@\n let sum = 0;\n let i = 0;\n while (i < n) {\n- i = i + 1;\n+ i = i / 1;\n if (i % 10 == 0) continue;\n sum = sum + i;\n };\n",
@@ -140,6 +145,7 @@
140145
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i - 10 == 0) continue;\n sum = sum + i;\n };\n\n",
141146
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i * 10 == 0) continue;\n sum = sum + i;\n };\n\n",
142147
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i / 10 == 0) continue;\n sum = sum + i;\n };\n\n",
148+
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (10 % i == 0) continue;\n sum = sum + i;\n };\n\n",
143149
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i % 0 == 0) continue;\n sum = sum + i;\n };\n\n",
144150
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i % 18446744073709551615 == 0) continue;\n sum = sum + i;\n };\n\n",
145151
"--- original\n+++ modified\n@@ -4,7 +4,7 @@\n let i = 0;\n while (i < n) {\n i = i + 1;\n- if (i % 10 == 0) continue;\n+ if (i % 11 == 0) continue;\n sum = sum + i;\n };\n\n",
@@ -156,8 +162,8 @@
156162
},
157163
{
158164
"module_func": "Continue::sum_intermediate_in_for",
159-
"tested": 49,
160-
"killed": 48,
165+
"tested": 50,
166+
"killed": 49,
161167
"mutants_alive_diffs": [
162168
"--- original\n+++ modified\n@@ -18,7 +18,7 @@\n fun sum_intermediate_in_for(n: u64): u64 {\n let sum = 0;\n\n- for (i in 0..(n + 1)) {\n+ for (i in 1..(n + 1)) {\n if (i % 10 == 0) continue;\n sum = sum + i\n };\n"
163169
],
@@ -198,6 +204,7 @@
198204
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (i - 10 == 0) continue;\n sum = sum + i\n };\n\n",
199205
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (i * 10 == 0) continue;\n sum = sum + i\n };\n\n",
200206
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (i / 10 == 0) continue;\n sum = sum + i\n };\n\n",
207+
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (10 % i == 0) continue;\n sum = sum + i\n };\n\n",
201208
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (i % 0 == 0) continue;\n sum = sum + i\n };\n\n",
202209
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (i % 18446744073709551615 == 0) continue;\n sum = sum + i\n };\n\n",
203210
"--- original\n+++ modified\n@@ -19,7 +19,7 @@\n let sum = 0;\n\n for (i in 0..(n + 1)) {\n- if (i % 10 == 0) continue;\n+ if (i % 11 == 0) continue;\n sum = sum + i\n };\n\n",
@@ -214,5 +221,5 @@
214221
}
215222
]
216223
},
217-
"package_dir": "move-spec-testing/move-mutator/tests/move-assets/breakcontinue"
218-
}
224+
"package_dir": "/home/jos/Projects/move-mutation-tools/move-mutator/tests/move-assets/breakcontinue"
225+
}

0 commit comments

Comments
 (0)