[tint][fuzzer] Fix bad mutation
An ast::CallStatement's expression must only be an ast::CallExpression.
Prevent the mutator fuzzer from attempting to mutate the CallExpression with something else.
Bug: chromium:1383368
Change-Id: I55ae2b9dfb16214ad708baa61005e00a80ce9a63
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/140180
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.cc
index 25ac065..6f6efc2 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator.cc
@@ -18,6 +18,8 @@
#include <vector>
#include "src/tint/program_builder.h"
+#include "src/tint/sem/call.h"
+#include "src/tint/sem/statement.h"
#include "src/tint/type/abstract_float.h"
#include "src/tint/type/abstract_int.h"
@@ -94,6 +96,16 @@
std::vector<ast::UnaryOp> MutationWrapUnaryOperator::GetValidUnaryWrapper(
const sem::ValueExpression& expr) {
+ if (auto* call_expr = expr.As<sem::Call>()) {
+ if (auto* stmt = call_expr->Stmt()) {
+ if (auto* call_stmt = stmt->Declaration()->As<ast::CallStatement>()) {
+ if (call_stmt->expr == expr.Declaration()) {
+ return {}; // A call statement must only wrap a call expression.
+ }
+ }
+ }
+ }
+
const auto* expr_type = expr.Type();
if (expr_type->is_bool_scalar_or_vector()) {
return {ast::UnaryOp::kNot};
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc
index c73c1b3..91c9453 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc
@@ -519,5 +519,34 @@
node_id_map, &program, &node_id_map, nullptr));
}
+TEST(WrapUnaryOperatorTest, NotApplicable_CallStmt) {
+ std::string content = R"(
+ fn main() {
+ f();
+ }
+ fn f() -> bool {
+ return false;
+ }
+ )";
+ Source::File file("test.wgsl", content);
+ auto program = reader::wgsl::Parse(&file);
+ ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
+
+ NodeIdMap node_id_map(program);
+
+ const auto& main_fn_statements = program.AST().Functions()[0]->body->statements;
+
+ const auto* call_stmt = main_fn_statements[0]->As<ast::CallStatement>();
+ ASSERT_NE(call_stmt, nullptr);
+
+ const auto expr_id = node_id_map.GetId(call_stmt->expr);
+ ASSERT_NE(expr_id, 0);
+
+ // The id provided for the expression is not a valid expression type.
+ ASSERT_FALSE(MaybeApplyMutation(
+ program, MutationWrapUnaryOperator(expr_id, node_id_map.TakeFreshId(), ast::UnaryOp::kNot),
+ node_id_map, &program, &node_id_map, nullptr));
+}
+
} // namespace
} // namespace tint::fuzzers::ast_fuzzer