[tint][fuzzers] Port tint_ast_clone_fuzzer to tint_wgsl_fuzzer
Change-Id: Id32540a27513f252a8e75f4fb8b2a7b369d6c8ef
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/154543
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.cmake b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
index 9ba6530..022ae21 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.cmake
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
@@ -51,6 +51,7 @@
tint_lang_wgsl
tint_lang_wgsl_ast
tint_lang_wgsl_program
+ tint_lang_wgsl_program_fuzz
tint_lang_wgsl_sem
tint_lang_wgsl_fuzz
tint_utils_cli
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.gn b/src/tint/cmd/fuzz/wgsl/BUILD.gn
index 5c4ccc6..15e4a15 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.gn
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.gn
@@ -86,6 +86,7 @@
"${tint_src_dir}/lang/wgsl:fuzz",
"${tint_src_dir}/lang/wgsl/ast",
"${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/program:fuzz",
"${tint_src_dir}/lang/wgsl/sem",
"${tint_src_dir}/utils/cli",
"${tint_src_dir}/utils/containers",
diff --git a/src/tint/fuzzers/BUILD.gn b/src/tint/fuzzers/BUILD.gn
index 7f5b0cd..e13d89c 100644
--- a/src/tint/fuzzers/BUILD.gn
+++ b/src/tint/fuzzers/BUILD.gn
@@ -134,20 +134,6 @@
}
if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
- fuzzer_test("tint_ast_clone_fuzzer") {
- sources = [ "tint_ast_clone_fuzzer.cc" ]
- deps = [ ":tint_fuzzer_common_with_init_src" ]
- deps += [
- "${tint_src_dir}/lang/wgsl/reader",
- "${tint_src_dir}/lang/wgsl/reader/parser",
- ]
-
- dict = "dictionary.txt"
- libfuzzer_options = tint_fuzzer_common_libfuzzer_options
- seed_corpus = fuzzer_corpus_wgsl_dir
- seed_corpus_deps = [ ":tint_generate_wgsl_corpus" ]
- }
-
if (build_with_chromium) {
fuzzer_test("tint_ast_wgsl_writer_fuzzer") {
sources = [ "tint_ast_fuzzer/tint_ast_wgsl_writer_fuzzer.cc" ]
@@ -344,7 +330,6 @@
if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
deps += [
- ":tint_ast_clone_fuzzer",
":tint_regex_wgsl_writer_fuzzer",
":tint_wgsl_reader_wgsl_writer_fuzzer",
]
diff --git a/src/tint/fuzzers/CMakeLists.txt b/src/tint/fuzzers/CMakeLists.txt
index cd5a057..d76b452 100644
--- a/src/tint/fuzzers/CMakeLists.txt
+++ b/src/tint/fuzzers/CMakeLists.txt
@@ -95,10 +95,6 @@
add_tint_fuzzer(tint_spv_reader_msl_writer_fuzzer)
endif()
-if (${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_WGSL_WRITER})
- add_tint_fuzzer(tint_ast_clone_fuzzer)
-endif()
-
if (${TINT_BUILD_AST_FUZZER})
add_subdirectory(tint_ast_fuzzer)
endif()
diff --git a/src/tint/fuzzers/tint_ast_clone_fuzzer.cc b/src/tint/fuzzers/tint_ast_clone_fuzzer.cc
deleted file mode 100644
index e33d3f9..0000000
--- a/src/tint/fuzzers/tint_ast_clone_fuzzer.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2020 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <iostream>
-#include <string>
-#include <unordered_set>
-
-#include "src/tint/lang/wgsl/reader/parser/parser.h"
-#include "src/tint/lang/wgsl/writer/writer.h"
-
-#define ASSERT_EQ(A, B) \
- do { \
- decltype(A) assert_a = (A); \
- decltype(B) assert_b = (B); \
- if (assert_a != assert_b) { \
- std::cerr << "ASSERT_EQ(" #A ", " #B ") failed:\n" \
- << #A << " was: " << assert_a << "\n" \
- << #B << " was: " << assert_b << "\n"; \
- __builtin_trap(); \
- } \
- } while (false)
-
-#define ASSERT_TRUE(A) \
- do { \
- decltype(A) assert_a = (A); \
- if (!assert_a) { \
- std::cerr << "ASSERT_TRUE(" #A ") failed:\n" << #A << " was: " << assert_a << "\n"; \
- __builtin_trap(); \
- } \
- } while (false)
-
-[[noreturn]] void TintInternalCompilerErrorReporter(const tint::InternalCompilerError& err) {
- std::cerr << err.Error() << std::endl;
- __builtin_trap();
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- std::string str(reinterpret_cast<const char*>(data), size);
-
- tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);
-
- tint::Source::File file("test.wgsl", str);
-
- // Parse the wgsl, create the src program
- tint::wgsl::reader::Parser parser(&file);
- parser.set_max_errors(1);
- if (!parser.Parse()) {
- return 0;
- }
- auto src = parser.program();
- if (!src.IsValid()) {
- return 0;
- }
-
- // Clone the src program to dst
- tint::Program dst(src.Clone());
-
- // Expect the printed strings to match
- ASSERT_EQ(tint::Program::printer(src), tint::Program::printer(dst));
-
- // Check that none of the AST nodes or type pointers in dst are found in src
- std::unordered_set<const tint::ast::Node*> src_nodes;
- for (auto* src_node : src.ASTNodes().Objects()) {
- src_nodes.emplace(src_node);
- }
- std::unordered_set<const tint::core::type::Type*> src_types;
- for (auto* src_type : src.Types()) {
- src_types.emplace(src_type);
- }
- for (auto* dst_node : dst.ASTNodes().Objects()) {
- ASSERT_EQ(src_nodes.count(dst_node), 0u);
- }
- for (auto* dst_type : dst.Types()) {
- ASSERT_EQ(src_types.count(dst_type), 0u);
- }
-
- // Regenerate the wgsl for the src program. We use this instead of the
- // original source so that reformatting doesn't impact the final wgsl
- // comparison.
- std::string src_wgsl;
- tint::wgsl::writer::Options wgsl_options;
- {
- auto result = tint::wgsl::writer::Generate(src, wgsl_options);
- ASSERT_TRUE(result == true);
- src_wgsl = result->wgsl;
-
- // Move the src program to a temporary that'll be dropped, so that the src
- // program is released before we attempt to print the dst program. This
- // guarantee that all the source program nodes and types are destructed and
- // freed. ASAN should error if there's any remaining references in dst when
- // we try to reconstruct the WGSL.
- auto tmp = std::move(src);
- }
-
- // Print the dst program, check it matches the original source
- auto result = tint::wgsl::writer::Generate(dst, wgsl_options);
- ASSERT_TRUE(result == true);
- auto dst_wgsl = result->wgsl;
- ASSERT_EQ(src_wgsl, dst_wgsl);
-
- return 0;
-}
diff --git a/src/tint/lang/wgsl/ast/module_clone_test.cc b/src/tint/lang/wgsl/ast/module_clone_test.cc
index 6e64f65..3444805 100644
--- a/src/tint/lang/wgsl/ast/module_clone_test.cc
+++ b/src/tint/lang/wgsl/ast/module_clone_test.cc
@@ -38,7 +38,6 @@
TEST(ModuleCloneTest, Clone) {
// Shader that exercises the bulk of the AST nodes and types.
- // See also fuzzers/tint_ast_clone_fuzzer.cc for further coverage of cloning.
Source::File file("test.wgsl", R"(enable f16;
diagnostic(off, chromium.unreachable_code);
diff --git a/src/tint/lang/wgsl/program/BUILD.bazel b/src/tint/lang/wgsl/program/BUILD.bazel
index 0cc90fa..1906aad 100644
--- a/src/tint/lang/wgsl/program/BUILD.bazel
+++ b/src/tint/lang/wgsl/program/BUILD.bazel
@@ -111,3 +111,21 @@
visibility = ["//visibility:public"],
)
+alias(
+ name = "tint_build_wgsl_reader",
+ actual = "//src/tint:tint_build_wgsl_reader_true",
+)
+
+alias(
+ name = "tint_build_wgsl_writer",
+ actual = "//src/tint:tint_build_wgsl_writer_true",
+)
+
+selects.config_setting_group(
+ name = "tint_build_wgsl_reader_and_tint_build_wgsl_writer",
+ match_all = [
+ ":tint_build_wgsl_reader",
+ ":tint_build_wgsl_writer",
+ ],
+)
+
diff --git a/src/tint/lang/wgsl/program/BUILD.cmake b/src/tint/lang/wgsl/program/BUILD.cmake
index 07c09e0..eea928d 100644
--- a/src/tint/lang/wgsl/program/BUILD.cmake
+++ b/src/tint/lang/wgsl/program/BUILD.cmake
@@ -109,3 +109,54 @@
tint_target_add_external_dependencies(tint_lang_wgsl_program_test test
"gtest"
)
+
+################################################################################
+# Target: tint_lang_wgsl_program_fuzz
+# Kind: fuzz
+################################################################################
+tint_add_target(tint_lang_wgsl_program_fuzz fuzz
+)
+
+tint_target_add_dependencies(tint_lang_wgsl_program_fuzz fuzz
+ tint_api_common
+ tint_lang_core
+ tint_lang_core_constant
+ tint_lang_core_type
+ tint_lang_wgsl
+ tint_lang_wgsl_ast
+ tint_lang_wgsl_program
+ tint_lang_wgsl_resolver
+ tint_lang_wgsl_sem
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_WGSL_READER)
+ tint_target_add_dependencies(tint_lang_wgsl_program_fuzz fuzz
+ tint_cmd_fuzz_wgsl_fuzz
+ tint_lang_wgsl_reader_parser
+ )
+endif(TINT_BUILD_WGSL_READER)
+
+if(TINT_BUILD_WGSL_READER AND TINT_BUILD_WGSL_WRITER)
+ tint_target_add_sources(tint_lang_wgsl_program_fuzz fuzz
+ "lang/wgsl/program/clone_context_fuzz.cc"
+ )
+endif(TINT_BUILD_WGSL_READER AND TINT_BUILD_WGSL_WRITER)
+
+if(TINT_BUILD_WGSL_WRITER)
+ tint_target_add_dependencies(tint_lang_wgsl_program_fuzz fuzz
+ tint_lang_wgsl_writer
+ )
+endif(TINT_BUILD_WGSL_WRITER)
diff --git a/src/tint/lang/wgsl/program/BUILD.gn b/src/tint/lang/wgsl/program/BUILD.gn
index 6cf7d8b..5641e61 100644
--- a/src/tint/lang/wgsl/program/BUILD.gn
+++ b/src/tint/lang/wgsl/program/BUILD.gn
@@ -109,3 +109,46 @@
]
}
}
+
+tint_fuzz_source_set("fuzz") {
+ sources = []
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/lang/core",
+ "${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/type",
+ "${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/lang/wgsl/ast",
+ "${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/resolver",
+ "${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_wgsl_reader) {
+ deps += [
+ "${tint_src_dir}/cmd/fuzz/wgsl:fuzz",
+ "${tint_src_dir}/lang/wgsl/reader/parser",
+ ]
+ }
+
+ if (tint_build_wgsl_reader && tint_build_wgsl_writer) {
+ sources += [ "clone_context_fuzz.cc" ]
+ }
+
+ if (tint_build_wgsl_writer) {
+ deps += [ "${tint_src_dir}/lang/wgsl/writer" ]
+ }
+}
diff --git a/src/tint/lang/wgsl/program/clone_context_fuzz.cc b/src/tint/lang/wgsl/program/clone_context_fuzz.cc
new file mode 100644
index 0000000..e4cfc2f
--- /dev/null
+++ b/src/tint/lang/wgsl/program/clone_context_fuzz.cc
@@ -0,0 +1,94 @@
+// Copyright 2020 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// GEN_BUILD:CONDITION(tint_build_wgsl_reader && tint_build_wgsl_writer)
+
+#include <string>
+#include <unordered_set>
+
+#include "src/tint/cmd/fuzz/wgsl/wgsl_fuzz.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
+#include "src/tint/lang/wgsl/writer/writer.h"
+
+namespace tint::program {
+
+#define ASSERT_EQ(A, B) \
+ do { \
+ decltype(A) assert_a = (A); \
+ decltype(B) assert_b = (B); \
+ if (assert_a != assert_b) { \
+ TINT_ICE() << "ASSERT_EQ(" #A ", " #B ") failed:\n" \
+ << #A << " was: " << assert_a << "\n" \
+ << #B << " was: " << assert_b << "\n"; \
+ } \
+ } while (false)
+
+#define ASSERT_TRUE(A) \
+ do { \
+ decltype(A) assert_a = (A); \
+ if (!assert_a) { \
+ TINT_ICE() << "ASSERT_TRUE(" #A ") failed:\n" << #A << " was: " << assert_a << "\n"; \
+ } \
+ } while (false)
+
+void CloneContextFuzzer(const tint::Program& src) {
+ // Clone the src program to dst
+ tint::Program dst(src.Clone());
+
+ // Expect the printed strings to match
+ ASSERT_EQ(tint::Program::printer(src), tint::Program::printer(dst));
+
+ // Check that none of the AST nodes or type pointers in dst are found in src
+ std::unordered_set<const tint::ast::Node*> src_nodes;
+ for (auto* src_node : src.ASTNodes().Objects()) {
+ src_nodes.emplace(src_node);
+ }
+ std::unordered_set<const tint::core::type::Type*> src_types;
+ for (auto* src_type : src.Types()) {
+ src_types.emplace(src_type);
+ }
+ for (auto* dst_node : dst.ASTNodes().Objects()) {
+ ASSERT_EQ(src_nodes.count(dst_node), 0u);
+ }
+ for (auto* dst_type : dst.Types()) {
+ ASSERT_EQ(src_types.count(dst_type), 0u);
+ }
+
+ tint::wgsl::writer::Options wgsl_options;
+
+ auto src_wgsl = tint::wgsl::writer::Generate(src, wgsl_options);
+ ASSERT_TRUE(src_wgsl);
+
+ auto dst_wgsl = tint::wgsl::writer::Generate(dst, wgsl_options);
+ ASSERT_TRUE(dst_wgsl);
+
+ ASSERT_EQ(src_wgsl->wgsl, dst_wgsl->wgsl);
+}
+
+} // namespace tint::program
+
+TINT_WGSL_PROGRAM_FUZZER(tint::program::CloneContextFuzzer);