diff --git a/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/ast.d b/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/ast.d index 178b23b34..7b02e764e 100644 --- a/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/ast.d +++ b/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/ast.d @@ -258,6 +258,9 @@ class AstPrintVisitor : DepthFirstVisitor { } } + if (auto tmp = cast(Operator) n) + formattedWrite(buf, " o:%s", tmp.isOverloaded); + if (auto tmp = cast(BinaryOp) n) { if (tmp.lhs !is null) formattedWrite(buf, " l:%s", tmp.lhs.id); @@ -678,6 +681,10 @@ class FloatLiteral : Expr { /// The operator itself in a binary operator expression. class Operator : Node { mixin(nodeImpl!(typeof(this))); + + // TODO: crude way of carrying operator overload info but needed. Refactor + // in the future to be more precise. + bool isOverloaded; } /** A block of code such such as a local scope enclosed by brackets, `{}`. diff --git a/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_clang.d b/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_clang.d index 28e6c1250..3c689d2d0 100644 --- a/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_clang.d +++ b/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_clang.d @@ -1161,6 +1161,7 @@ final class BaseVisitor : ExtendedVisitor { CXCursorKind.classTemplatePartialSpecialization, CXCursorKind.functionTemplate) != 0; astOp.operator = op.operator; + astOp.operator.isOverloaded = op.isOverload; astOp.operator.blacklist = isBlacklist(cursor, op.opLoc); op.put(nstack.back, ast.get); @@ -1237,6 +1238,7 @@ final class BaseVisitor : ExtendedVisitor { CXCursorKind.classTemplatePartialSpecialization, CXCursorKind.functionTemplate) != 0; astOp.operator = op.operator; + astOp.operator.isOverloaded = op.isOverload; astOp.operator.blacklist = isBlacklist(cursor, op.opLoc); astOp.operator.schemaBlacklist = blockSchema; diff --git a/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_mutant.d b/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_mutant.d index bd745aab6..2d3fb662a 100644 --- a/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_mutant.d +++ b/plugin/mutate/source/dextool/plugin/mutate/backend/analyze/pass_mutant.d @@ -786,16 +786,12 @@ class MutantVisitor : DepthFirstVisitor { { import dextool.plugin.mutate.backend.mutation_type.aor; - auto m = aorMutations(AorInfo(n.kind, ast.type(n.lhs), ast.type(n.rhs))); - op ~= m.op; + auto m = aorMutations(AorInfo(n.kind, ast.type(n.lhs), + ast.type(n.rhs), n.operator.isOverloaded)); + op ~= m.op ~ m.simple; lhs ~= m.lhs; rhs ~= m.rhs; } - { - import dextool.plugin.mutate.backend.mutation_type.aors; - - op ~= aorsMutations(n.kind); - } if (isDirectParent(Kind.Block)) { expr ~= stmtDelMutations(n.kind); } diff --git a/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aor.d b/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aor.d index f11761be0..6b3a07781 100644 --- a/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aor.d +++ b/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aor.d @@ -24,48 +24,50 @@ struct AorInfo { Kind operator; Type lhs; Type rhs; + bool isOverloaded; } auto aorMutations(AorInfo info) @safe { // TODO: for AORs it is probably better to do one op and then lhs+rhs. - alias Rval = Tuple!(Mutation.Kind[], "op", Mutation.Kind[], "lhs", Mutation.Kind[], "rhs"); + alias Rval = Tuple!(Mutation.Kind[], "op", Mutation.Kind[], "lhs", + Mutation.Kind[], "rhs", Mutation.Kind, "simple"); Rval rval; switch (info.operator) with (Mutation.Kind) { case Kind.OpAdd: - rval = Rval([aorMul, aorDiv, aorRem, aorSub], null, null); + rval = Rval([aorMul, aorDiv, aorRem, aorSub], null, null, aorsSub); break; case Kind.OpDiv: - rval = Rval([aorMul, aorRem, aorAdd, aorSub], null, null); + rval = Rval([aorMul, aorRem, aorAdd, aorSub], null, null, aorsMul); break; case Kind.OpMod: - rval = Rval([aorMul, aorDiv, aorAdd, aorSub], null, null); + rval = Rval([aorMul, aorDiv, aorAdd, aorSub], null, null, aorsDiv); break; case Kind.OpMul: - rval = Rval([aorDiv, aorRem, aorAdd, aorSub], null, null); + rval = Rval([aorDiv, aorRem, aorAdd, aorSub], null, null, aorsDiv); break; case Kind.OpSub: - rval = Rval([aorMul, aorDiv, aorRem, aorAdd], null, null); + rval = Rval([aorMul, aorDiv, aorRem, aorAdd], null, null, aorsAdd); break; case Kind.OpAssignAdd: rval = Rval([aorDivAssign, aorRemAssign, - aorMulAssign, aorSubAssign], null, null); + aorMulAssign, aorSubAssign], null, null, aorsSubAssign); break; case Kind.OpAssignDiv: rval = Rval([aorAddAssign, aorRemAssign, - aorMulAssign, aorSubAssign], null, null); + aorMulAssign, aorSubAssign], null, null, aorsMulAssign); break; case Kind.OpAssignMod: rval = Rval([aorAddAssign, aorDivAssign, - aorMulAssign, aorSubAssign], null, null); + aorMulAssign, aorSubAssign], null, null, aorsDivAssign); break; case Kind.OpAssignMul: rval = Rval([aorAddAssign, aorDivAssign, - aorRemAssign, aorSubAssign], null, null); + aorRemAssign, aorSubAssign], null, null, aorsDivAssign); break; case Kind.OpAssignSub: rval = Rval([aorAddAssign, aorDivAssign, - aorRemAssign, aorMulAssign], null, null); + aorRemAssign, aorMulAssign], null, null, aorsAddAssign); break; default: } @@ -76,9 +78,13 @@ auto aorMutations(AorInfo info) @safe { rval = typeof(rval).init; } else if (info.lhs.kind.among(TypeKind.unordered, TypeKind.bottom) || info.rhs.kind.among(TypeKind.unordered, TypeKind.bottom)) { - // TODO: unfortunately this also blocks operator overloading which is [unordered, unordered] - // block aor when the type is a pointer - //rval = typeof(rval).init; + if (info.isOverloaded) { + // TODO: unfortunately this also blocks operator overloading which is [unordered, unordered]. + // block aor when the type is a pointer + } else { + // block AOR for pointers. + rval = typeof(rval).init; + } } else if (info.lhs.kind == TypeKind.continues || info.rhs.kind == TypeKind.continues) { // modulo do not work when either side is a floating point. rval.op = rval.op.filter!(a => !a.among(Mutation.Kind.aorRem, diff --git a/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aors.d b/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aors.d index d3c2899b0..fd966e945 100644 --- a/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aors.d +++ b/plugin/mutate/source/dextool/plugin/mutate/backend/mutation_type/aors.d @@ -9,47 +9,7 @@ one at http://mozilla.org/MPL/2.0/. */ module dextool.plugin.mutate.backend.mutation_type.aors; -import dextool.plugin.mutate.backend.type; -import dextool.plugin.mutate.backend.analyze.ast; - -Mutation.Kind aorsMutations(Kind operand) @safe { - Mutation.Kind rval; - switch (operand) with (Mutation.Kind) { - case Kind.OpAdd: - rval = aorsSub; - break; - case Kind.OpDiv: - rval = aorsMul; - break; - case Kind.OpMod: - rval = aorsDiv; - break; - case Kind.OpMul: - rval = aorsDiv; - break; - case Kind.OpSub: - rval = aorsAdd; - break; - case Kind.OpAssignAdd: - rval = aorsSubAssign; - break; - case Kind.OpAssignDiv: - rval = aorsMulAssign; - break; - case Kind.OpAssignMod: - rval = aorsDivAssign; - break; - case Kind.OpAssignMul: - rval = aorsDivAssign; - break; - case Kind.OpAssignSub: - rval = aorsAddAssign; - break; - default: - } - - return rval; -} +import dextool.plugin.mutate.backend.type : Mutation; immutable Mutation.Kind[] aorsMutationsAll; immutable Mutation.Kind[] aorsAssignMutationsAll;