| // Copyright 2021 The Tint Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "src/tint/fuzzers/tint_ast_fuzzer/mutation_finders/change_unary_operators.h" |
| |
| #include <memory> |
| |
| #include "src/tint/ast/unary_op_expression.h" |
| #include "src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator.h" |
| #include "src/tint/fuzzers/tint_ast_fuzzer/util.h" |
| #include "src/tint/sem/reference.h" |
| |
| namespace tint::fuzzers::ast_fuzzer { |
| |
| MutationList MutationFinderChangeUnaryOperators::FindMutations( |
| const tint::Program& program, |
| NodeIdMap* node_id_map, |
| ProbabilityContext* /*unused*/) const { |
| MutationList result; |
| |
| // Iterate through all AST nodes and for each valid unary op expression node, |
| // try to replace the node's unary operator. |
| for (const auto* node : program.ASTNodes().Objects()) { |
| const auto* unary_expr = tint::As<ast::UnaryOpExpression>(node); |
| |
| // Transformation applies only when the node represents a valid unary |
| // expression. |
| if (!unary_expr) { |
| continue; |
| } |
| |
| // Get the type of the unary expression. |
| const auto* type = program.Sem().Get(unary_expr)->Type(); |
| const auto* basic_type = |
| type->Is<sem::Reference>() ? type->As<sem::Reference>()->StoreType() : type; |
| |
| // Only signed integer or vector of signed integer can be mutated. |
| if (!basic_type->is_signed_scalar_or_vector()) { |
| continue; |
| } |
| |
| // Only complement and negation operators can be swapped. |
| if (!(unary_expr->op == ast::UnaryOp::kComplement || |
| unary_expr->op == ast::UnaryOp::kNegation)) { |
| continue; |
| } |
| |
| result.push_back(std::make_unique<MutationChangeUnaryOperator>( |
| node_id_map->GetId(unary_expr), |
| MutationChangeUnaryOperator::ToggleOperator(unary_expr->op))); |
| } |
| |
| return result; |
| } |
| |
| uint32_t MutationFinderChangeUnaryOperators::GetChanceOfApplyingMutation( |
| ProbabilityContext* probability_context) const { |
| return probability_context->GetChanceOfChangingUnaryOperators(); |
| } |
| |
| } // namespace tint::fuzzers::ast_fuzzer |